* **GSS_C_NT_EXPORT_NAME**: The value must be the result of a
gss_export_name_ call.
+* **GSS_KRB5_NT_ENTERPRISE_NAME**: The value should be a krb5
+ enterprise name string (see :rfc:`6806` section 5), in the form
+ ``user@suffix``. This name type is used to convey alias names, and
+ is defined in the ``<gssapi/gssapi_krb5.h>`` header. (New in
+ release 1.17.)
+
Initiator credentials
---------------------
{NO_CI_FLAGS_X_OID_LENGTH, NO_CI_FLAGS_X_OID},
/* this is an inquire cred OID */
{GET_CRED_IMPERSONATOR_OID_LENGTH, GET_CRED_IMPERSONATOR_OID},
+ /* GSS_KRB5_NT_ENTERPRISE_NAME */
+ {10, "\052\206\110\206\367\022\001\002\002\006"},
{ 0, 0 }
};
const gss_OID GSS_KRB5_CRED_NO_CI_FLAGS_X = &kg_oids[7];
const gss_OID GSS_KRB5_GET_CRED_IMPERSONATOR = &kg_oids[8];
+const gss_OID GSS_KRB5_NT_ENTERPRISE_NAME = &kg_oids[9];
static const gss_OID_set_desc oidsets[] = {
{1, &kg_oids[0]}, /* RFC OID */
* generic(1) string_uid_name(3)}. The recommended symbolic name for
* this type is "GSS_KRB5_NT_STRING_UID_NAME". */
+/* Kerberos Enterprise Name Form (see RFC 6806 section 5): */
+GSS_DLLIMP extern const gss_OID GSS_KRB5_NT_ENTERPRISE_NAME;
+/* {iso(1) member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * krb5(2) krb5-enterprise-name(6)}. */
+
GSS_DLLIMP extern const gss_OID gss_mech_krb5;
GSS_DLLIMP extern const gss_OID gss_mech_krb5_old;
GSS_DLLIMP extern const gss_OID gss_mech_krb5_wrong;
krb5_authdata_context ad_context = NULL;
OM_uint32 status = GSS_S_FAILURE;
krb5_gss_name_t name;
+ int flags = 0;
*output_name = NULL;
*minor_status = 0;
if ((input_name_type == GSS_C_NULL_OID) ||
g_OID_equal(input_name_type, gss_nt_krb5_name) ||
g_OID_equal(input_name_type, gss_nt_user_name)) {
- stringrep = (char *) tmp;
+ stringrep = tmp;
+ } else if (g_OID_equal(input_name_type, GSS_KRB5_NT_ENTERPRISE_NAME)) {
+ stringrep = tmp;
+ flags |= KRB5_PRINCIPAL_PARSE_ENTERPRISE;
#ifndef NO_PASSWORD
} else if (g_OID_equal(input_name_type, gss_nt_machine_uid_name)) {
uid = *(uid_t *) input_name_buffer->value;
/* At this point, stringrep is set, or if not, code is. */
if (stringrep) {
- code = krb5_parse_name(context, (char *)stringrep, &princ);
+ code = krb5_parse_name_flags(context, stringrep, flags, &princ);
if (code)
goto cleanup;
} else {
GSS_C_NT_STRING_UID_NAME
GSS_C_NT_USER_NAME
GSS_KRB5_NT_PRINCIPAL_NAME
+GSS_KRB5_NT_ENTERPRISE_NAME
GSS_KRB5_CRED_NO_CI_FLAGS_X
GSS_KRB5_GET_CRED_IMPERSONATOR
GSS_C_MA_MECH_CONCRETE
; Added in 1.16
GSS_KRB5_GET_CRED_IMPERSONATOR @148 DATA
GSS_C_SEC_CONTEXT_SASL_SSF @149 DATA
+; Added in 1.17
+ GSS_KRB5_NT_ENTERPRISE_NAME @150 DATA
&search_name));
canon = get_string(h, "alias", search_name, NULL);
if (canon != NULL) {
- if (!(flags & KRB5_KDB_FLAG_ALIAS_OK)) {
+ if (!(flags & KRB5_KDB_FLAG_ALIAS_OK) &&
+ search_for->type != KRB5_NT_ENTERPRISE_PRINCIPAL) {
ret = KRB5_KDB_NOENTRY;
goto cleanup;
}
$(RUN_TEST) ./t_invalid
$(RUN_TEST) ./t_oid
$(RUN_TEST) ./t_prf
+ $(RUN_TEST) ./t_imp_name
check-pytests: ccinit ccrefresh t_accname t_add_cred t_ccselect t_ciflags \
t_credstore t_enctypes t_err t_export_cred t_export_name t_imp_cred \
nametype = GSS_C_NT_USER_NAME;
else if (*str == 'p')
nametype = (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME;
+ else if (*str == 'e')
+ nametype = (gss_OID)GSS_KRB5_NT_ENTERPRISE_NAME;
else if (*str == 'h')
nametype = GSS_C_NT_HOSTBASED_SERVICE;
if (nametype == NULL || str[1] != ':')
- errout("names must begin with u: or p: or h:");
+ errout("names must begin with u: or p: or e: or h:");
buf.value = (char *)str + 2;
buf.length = strlen(str) - 2;
major = gss_import_name(&minor, &buf, nametype, &name);
*/
#include <stdio.h>
+#include <string.h>
#include "common.h"
-int
-main(int argc, char **argv)
+static const char *
+oid_str(char type)
+{
+ switch (type) {
+ case 'p': /* GSS_KRB5_NT_PRINCIPAL_NAME */
+ return "{ 1 2 840 113554 1 2 2 1 }";
+ case 'e': /* GSS_KRB5_NT_ENTERPRISE_NAME */
+ return "{ 1 2 840 113554 1 2 2 6 }";
+ case 'h': /* GSS_C_NT_HOSTBASED_SERVICE */
+ return "{ 1 2 840 113554 1 2 1 4 }";
+ }
+ return "no_oid";
+}
+
+/* Return true if buf has the same contents as str, plus a zero byte if
+ * indicated by buf_includes_nullterm. */
+static int
+buf_eq_str(gss_buffer_t buf, const char *str, int buf_includes_nullterm)
+{
+ size_t len = strlen(str) + (buf_includes_nullterm ? 1 : 0);
+
+ return (buf->length == len && memcmp(buf->value, str, len) == 0);
+}
+
+static void
+test_import_name(const char *name)
{
- const char *name = "host@dcl.mit.edu";
OM_uint32 major, minor;
gss_name_t gss_name;
gss_buffer_desc buf;
major = gss_display_name(&minor, gss_name, &buf, &name_oid);
check_gsserr("gss_display_name", major, minor);
- printf("name is: %.*s\n", (int)buf.length, (char *)buf.value);
+ if (!buf_eq_str(&buf, name + 2, 0))
+ errout("wrong name string");
(void)gss_release_buffer(&minor, &buf);
major = gss_oid_to_str(&minor, name_oid, &buf);
check_gsserr("gss_oid_to_str", major, minor);
- printf("name type is: %.*s\n", (int)buf.length, (char *)buf.value);
+ if (!buf_eq_str(&buf, oid_str(*name), 1))
+ errout("wrong name type");
(void)gss_release_buffer(&minor, &buf);
(void)gss_release_name(&minor, &gss_name);
+}
+
+int
+main(int argc, char **argv)
+{
+ test_import_name("p:user@MIT.EDU");
+ test_import_name("e:enterprise@mit.edu@MIT.EDU");
+ test_import_name("h:HOST@dc1.mit.edu");
return 0;
}
/* GSS_KRB5_NT_PRINCIPAL_NAME */
{ "{ 1 2 840 113554 1 2 2 1 }", " {01 2 840 113554 1 2 2 1 } ",
{ 10, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x01" } },
+ /* GSS_KRB5_NT_ENTERPRISE_NAME */
+ { "{ 1 2 840 113554 1 2 2 6 }", " {1.2.840.113554.1.2.2.6} ",
+ { 10, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x06" } },
/* gss_krb5_nt_principal */
{ "{ 1 2 840 113554 1 2 2 2 }", "{1.2.840.113554.1.2.2.2}",
{ 10, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x02" } },
mark('cross-realm S4U2Self')
testprincs = {'krbtgt/SREALM': {'keys': 'aes128-cts'},
'krbtgt/UREALM': {'keys': 'aes128-cts'},
- 'user': {'keys': 'aes128-cts'}}
+ 'user': {'keys': 'aes128-cts', 'flags': '+preauth'}}
kdcconf1 = {'realms': {'$realm': {'database_module': 'test'}},
'dbmodules': {'test': {'db_library': 'test',
- 'princs': testprincs }}}
+ 'princs': testprincs,
+ 'alias': {'enterprise@abc': '@UREALM'}}}}
kdcconf2 = {'realms': {'$realm': {'database_module': 'test'}},
'dbmodules': {'test': {'db_library': 'test',
'princs': testprincs,
- 'alias': {'user@SREALM': '@SREALM'}}}}
+ 'alias': {'user@SREALM': '@SREALM',
+ 'enterprise@abc': 'user'}}}}
r1, r2 = cross_realms(2, xtgts=(),
args=({'realm': 'SREALM', 'kdc_conf': kdcconf1},
{'realm': 'UREALM', 'kdc_conf': kdcconf2}),
r1.run(['./t_s4u', 'p:' + r2.user_princ, '-', r1.keytab], env=no_default,
expected_trace=msgs)
+# Test realm identification of enterprise principal names ([MS-S4U]
+# 3.1.5.1.1.1). Attach a bogus realm to the enterprise name to verify
+# that we start at the server realm.
+mark('cross-realm S4U2Self with enterprise name')
+msgs = ('Getting initial credentials for enterprise\\@abc@SREALM',
+ 'Processing preauth types: PA-FOR-X509-USER (130)',
+ 'Sending unauthenticated request',
+ '/Realm not local to KDC',
+ 'Following referral to realm UREALM',
+ 'Processing preauth types: PA-FOR-X509-USER (130)',
+ 'Sending unauthenticated request',
+ '/Additional pre-authentication required',
+ '/Generic preauthentication failure',
+ 'Getting credentials enterprise\\@abc@UREALM -> user@SREALM',
+ 'TGS reply is for enterprise\@abc@UREALM -> user@SREALM')
+r1.run(['./t_s4u', 'e:enterprise@abc@NOREALM', '-', r1.keytab],
+ expected_trace=msgs)
+
r1.stop()
r2.stop()