svn rev #23511: branches/anonymous/src/ clients/kinit/ include/krb5/ lib/krb5/ ...

hartmans@MIT.EDU hartmans at MIT.EDU
Wed Dec 23 16:10:56 EST 2009


http://src.mit.edu/fisheye/changelog/krb5/?cs=23511
Commit By: hartmans
Log Message:
Change kinit -n logic to support an interface for both fully and
partially anonymous principals.

* New API krb5_get_init_creds_opt_set_anonymous
* In krb5_get_init_creds_init, map @REALM to WELLKNOWN/ANONYMOUS at REALM
* Change logic for what canonicalization is acceptable to support realm-exposed anonymous principals too
* Use the above in kinit


Changed Files:
U   branches/anonymous/src/clients/kinit/kinit.c
U   branches/anonymous/src/include/krb5/krb5.hin
U   branches/anonymous/src/lib/krb5/krb/get_in_tkt.c
U   branches/anonymous/src/lib/krb5/krb/gic_opt.c
U   branches/anonymous/src/lib/krb5/libkrb5.exports
Modified: branches/anonymous/src/clients/kinit/kinit.c
===================================================================
--- branches/anonymous/src/clients/kinit/kinit.c	2009-12-23 21:10:52 UTC (rev 23510)
+++ branches/anonymous/src/clients/kinit/kinit.c	2009-12-23 21:10:55 UTC (rev 23511)
@@ -467,71 +467,74 @@
 
     if (opts->principal_name)
     {
-        if (opts->anonymous) {
-            code = krb5_build_principal_ext(k5->ctx, &k5->me, strlen(opts->principal_name),
-                                            opts->principal_name,
-                                            strlen(KRB5_WELLKNOWN_NAMESTR), KRB5_WELLKNOWN_NAMESTR,
-                                            strlen(KRB5_ANONYMOUS_PRINCSTR),
-                                            KRB5_ANONYMOUS_PRINCSTR, 0);
-            if (code) {
-                com_err(progname, code, "while setting up anonymous principal");
-                return 0;
-            }
-        } else {
-            /* Use specified name */
-            if ((code = krb5_parse_name_flags(k5->ctx, opts->principal_name,
-                                              flags, &k5->me))) {
-                com_err(progname, code, "when parsing name %s",
-                        opts->principal_name);
-                return 0;
-            }
+        /* Use specified name */
+        if ((code = krb5_parse_name_flags(k5->ctx, opts->principal_name,
+                                          flags, &k5->me))) {
+            com_err(progname, code, "when parsing name %s",
+                    opts->principal_name);
+            return 0;
         }
     }
     else
     {
         /* No principal name specified */
         if (opts->anonymous) {
-            fprintf(stderr, "%s: please specify realm for anonymous authentication\n", progname);
-            return 0;
-        }
-        if (opts->action == INIT_KT) {
-            /* Use the default host/service name */
-            code = krb5_sname_to_principal(k5->ctx, NULL, NULL,
-                                           KRB5_NT_SRV_HST, &k5->me);
+            char *defrealm;
+            code = krb5_get_default_realm(k5->ctx, &defrealm);
             if (code) {
-                com_err(progname, code,
-                        "when creating default server principal name");
+                com_err(progname, code, "while getting default realm");
                 return 0;
             }
-            if (k5->me->realm.data[0] == 0) {
-                code = krb5_unparse_name(k5->ctx, k5->me, &k5->name);
-                if (code == 0)
-                    com_err(progname, KRB5_ERR_HOST_REALM_UNKNOWN,
-                            "(principal %s)", k5->name);
-                else
-                    com_err(progname, KRB5_ERR_HOST_REALM_UNKNOWN,
-                            "for local services");
+            code = krb5_build_principal_ext(k5->ctx, &k5->me,
+                                            strlen(defrealm), defrealm,
+                                            strlen(KRB5_WELLKNOWN_NAMESTR), KRB5_WELLKNOWN_NAMESTR,
+                                            strlen(KRB5_ANONYMOUS_PRINCSTR), KRB5_ANONYMOUS_PRINCSTR,
+                                            0);
+            krb5_free_default_realm( k5->ctx, defrealm);
+            if (code) {
+                com_err(progname, code, "while building principal");
                 return 0;
             }
         } else {
-            /* Get default principal from cache if one exists */
-            code = krb5_cc_get_principal(k5->ctx, k5->cc,
-                                         &k5->me);
-            if (code)
-            {
-                char *name = get_name_from_os();
-                if (!name)
-                {
-                    fprintf(stderr, "Unable to identify user\n");
+            if (opts->action == INIT_KT) {
+                /* Use the default host/service name */
+                code = krb5_sname_to_principal(k5->ctx, NULL, NULL,
+                                               KRB5_NT_SRV_HST, &k5->me);
+                if (code) {
+                    com_err(progname, code,
+                            "when creating default server principal name");
                     return 0;
                 }
-                if ((code = krb5_parse_name_flags(k5->ctx, name,
-                                                  flags, &k5->me)))
-                {
-                    com_err(progname, code, "when parsing name %s",
-                            name);
+                if (k5->me->realm.data[0] == 0) {
+                    code = krb5_unparse_name(k5->ctx, k5->me, &k5->name);
+                    if (code == 0)
+                        com_err(progname, KRB5_ERR_HOST_REALM_UNKNOWN,
+                                "(principal %s)", k5->name);
+                    else
+                        com_err(progname, KRB5_ERR_HOST_REALM_UNKNOWN,
+                                "for local services");
                     return 0;
                 }
+            } else {
+                /* Get default principal from cache if one exists */
+                code = krb5_cc_get_principal(k5->ctx, k5->cc,
+                                             &k5->me);
+                if (code)
+                {
+                    char *name = get_name_from_os();
+                    if (!name)
+                    {
+                        fprintf(stderr, "Unable to identify user\n");
+                        return 0;
+                    }
+                    if ((code = krb5_parse_name_flags(k5->ctx, name,
+                                                      flags, &k5->me)))
+                    {
+                        com_err(progname, code, "when parsing name %s",
+                                name);
+                        return 0;
+                    }
+                }
             }
         }
     }
@@ -615,6 +618,8 @@
         krb5_get_init_creds_opt_set_proxiable(options, 0);
     if (opts->canonicalize)
         krb5_get_init_creds_opt_set_canonicalize(options, 1);
+    if (opts->anonymous)
+        krb5_get_init_creds_opt_set_anonymous(options, 1);
     if (opts->addresses)
     {
         krb5_address **addresses = NULL;

Modified: branches/anonymous/src/include/krb5/krb5.hin
===================================================================
--- branches/anonymous/src/include/krb5/krb5.hin	2009-12-23 21:10:52 UTC (rev 23510)
+++ branches/anonymous/src/include/krb5/krb5.hin	2009-12-23 21:10:55 UTC (rev 23511)
@@ -2204,6 +2204,7 @@
 #define KRB5_GET_INIT_CREDS_OPT_SALT            0x0080
 #define KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT   0x0100
 #define KRB5_GET_INIT_CREDS_OPT_CANONICALIZE    0x0200
+#define KRB5_GET_INIT_CREDS_OPT_ANONYMOUS 0x0400
 
 
 krb5_error_code KRB5_CALLCONV
@@ -2237,6 +2238,20 @@
 krb5_get_init_creds_opt_set_canonicalize(krb5_get_init_creds_opt *opt,
                                          int canonicalize);
 
+/**
+ * Request anonymous credentials from the KDC.  If the  client name looks like
+ * "@REALM" (an empty principal name), then fully anonymous credentials are
+ * requested.  If the client name looks like "name at REALM," then credentials
+ * tied to a specific realm are requested.
+ *
+ * Credentials tied to a specific realm are not supported in this version.
+ *
+ * Note that anonymous credentials are only a request; clients must verify that
+ * credentials are anonymous if that is a requirement.
+ */
+krb5_get_init_creds_opt_set_anonymous(krb5_get_init_creds_opt *opt,
+                                      int anonymous);
+
 void KRB5_CALLCONV
 krb5_get_init_creds_opt_set_etype_list(krb5_get_init_creds_opt *opt,
                                        krb5_enctype *etype_list,

Modified: branches/anonymous/src/lib/krb5/krb/get_in_tkt.c
===================================================================
--- branches/anonymous/src/lib/krb5/krb/get_in_tkt.c	2009-12-23 21:10:52 UTC (rev 23510)
+++ branches/anonymous/src/lib/krb5/krb/get_in_tkt.c	2009-12-23 21:10:55 UTC (rev 23511)
@@ -305,13 +305,12 @@
      */
     canon_req = ((request->kdc_options & KDC_OPT_CANONICALIZE) != 0) ||
         (krb5_princ_type(context, request->client) == KRB5_NT_ENTERPRISE_PRINCIPAL)
-        || (krb5_principal_compare_any_realm(context, request->client,
-                                             krb5_anonymous_principal()));
+        || (request->kdc_options & KDC_OPT_REQUEST_ANONYMOUS);
     if (canon_req) {
         canon_ok = IS_TGS_PRINC(context, request->server) &&
             IS_TGS_PRINC(context, as_reply->enc_part2->server);
         if ((!canon_ok ) && (request->kdc_options &KDC_OPT_REQUEST_ANONYMOUS))
-            canon_ok = krb5_principal_compare(context, as_reply->client,
+            canon_ok = krb5_principal_compare_any_realm(context, as_reply->client,
                                               krb5_anonymous_principal());
     } else
         canon_ok = 0;
@@ -1535,6 +1534,26 @@
     }
 
     /*Anonymous*/
+    if(opte->flags & KRB5_GET_INIT_CREDS_OPT_ANONYMOUS) {
+        ctx->request->kdc_options |= KDC_OPT_REQUEST_ANONYMOUS;
+        /*Remap @REALM to WELLKNOWN/ANONYMOUS at REALM*/
+        if (client->length == 1 && client->data[0].length ==0) {
+            krb5_principal new_client;
+            code = krb5_build_principal_ext(context, &new_client, client->realm.length,
+                                           client->realm.data,
+                                           strlen(KRB5_WELLKNOWN_NAMESTR),
+                                           KRB5_WELLKNOWN_NAMESTR,
+                                           strlen(KRB5_ANONYMOUS_PRINCSTR),
+                                           KRB5_ANONYMOUS_PRINCSTR,
+                                           0);
+            if (code)
+                goto cleanup;
+            krb5_free_principal(context, ctx->request->client);
+            ctx->request->client = new_client;
+                    krb5_princ_type(context, ctx->request->client) = KRB5_NT_WELLKNOWN;
+        }
+    }
+    /*We will also handle anonymous if the input principal is the anonymous principal*/
     if (krb5_principal_compare_any_realm(context, ctx->request->client,
                                          krb5_anonymous_principal())) {
         ctx->request->kdc_options |= KDC_OPT_REQUEST_ANONYMOUS;

Modified: branches/anonymous/src/lib/krb5/krb/gic_opt.c
===================================================================
--- branches/anonymous/src/lib/krb5/krb/gic_opt.c	2009-12-23 21:10:52 UTC (rev 23510)
+++ branches/anonymous/src/lib/krb5/krb/gic_opt.c	2009-12-23 21:10:55 UTC (rev 23511)
@@ -53,6 +53,15 @@
 }
 
 void KRB5_CALLCONV
+krb5_get_init_creds_opt_set_anonymous (krb5_get_init_creds_opt *opt,
+                                       int anonymous)
+{
+    if (anonymous)
+        opt->flags |= KRB5_GET_INIT_CREDS_OPT_ANONYMOUS;
+    else opt->flags &= ~KRB5_GET_INIT_CREDS_OPT_ANONYMOUS;
+}
+
+void KRB5_CALLCONV
 krb5_get_init_creds_opt_set_etype_list(krb5_get_init_creds_opt *opt, krb5_enctype *etype_list, int etype_list_length)
 {
     opt->flags |= KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST;

Modified: branches/anonymous/src/lib/krb5/libkrb5.exports
===================================================================
--- branches/anonymous/src/lib/krb5/libkrb5.exports	2009-12-23 21:10:52 UTC (rev 23510)
+++ branches/anonymous/src/lib/krb5/libkrb5.exports	2009-12-23 21:10:55 UTC (rev 23511)
@@ -339,6 +339,7 @@
 krb5_get_init_creds_opt_get_pa
 krb5_get_init_creds_opt_init
 krb5_get_init_creds_opt_set_address_list
+krb5_get_init_creds_opt_set_anonymous
 krb5_get_init_creds_opt_set_canonicalize
 krb5_get_init_creds_opt_set_change_password_prompt
 krb5_get_init_creds_opt_set_etype_list




More information about the cvs-krb5 mailing list