]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Add an input ccache get_init_creds option
authorNalin Dahyabhai <nalin@dahyabhai.net>
Mon, 23 Jul 2012 19:02:37 +0000 (15:02 -0400)
committerGreg Hudson <ghudson@mit.edu>
Tue, 16 Oct 2012 23:22:21 +0000 (19:22 -0400)
Add a krb5_get_init_creds_opt_set_in_ccache() function.  An input
ccache may hold configuration data which the client libraries can
use to influence their decisions.

ticket: 7413 (new)

doc/appldev/refs/api/index.rst
src/clients/kinit/kinit.c
src/include/k5-int.h
src/include/krb5/krb5.hin
src/lib/krb5/krb/gic_opt.c
src/lib/krb5/libkrb5.exports
src/lib/krb5_32.def

index 26b7f8633147523d0ea9c711183b810ff150ef41..cf06d3fe9b620d70dff5c5a410e44827c929e78f 100644 (file)
@@ -47,6 +47,7 @@ Frequently used public interfaces
    krb5_get_init_creds_opt_set_fast_ccache_name.rst
    krb5_get_init_creds_opt_set_fast_flags.rst
    krb5_get_init_creds_opt_set_forwardable.rst
+   krb5_get_init_creds_opt_set_in_ccache.rst
    krb5_get_init_creds_opt_set_out_ccache.rst
    krb5_get_init_creds_opt_set_pa.rst
    krb5_get_init_creds_opt_set_preauth_list.rst
index a315173b6089d0edebcd528cdd4b9f501f55d881..ac204c1d07f5133f88c208a2fb51e3a593233c72 100644 (file)
@@ -116,7 +116,8 @@ struct k_opts
     char* principal_name;
     char* service_name;
     char* keytab_name;
-    char* k5_cache_name;
+    char* k5_in_cache_name;
+    char* k5_out_cache_name;
     char *armor_ccache;
 
     action_type action;
@@ -132,7 +133,7 @@ struct k_opts
 struct k5_data
 {
     krb5_context ctx;
-    krb5_ccache cc;
+    krb5_ccache in_cc, out_cc;
     krb5_principal me;
     char* name;
     krb5_boolean switch_to_cache;
@@ -286,8 +287,8 @@ parse_options(argc, argv, opts)
     int errflg = 0;
     int i;
 
-    while ((i = GETOPT(argc, argv, "r:fpFPn54aAVl:s:c:kit:T:RS:vX:CE"))
-           != -1) {
+    while ((i = GETOPT(argc, argv,
+                       "r:fpFPn54aAVl:s:c:kit:T:RS:vX:CEI:")) != -1) {
         switch (i) {
         case 'V':
             opts->verbose = 1;
@@ -376,12 +377,20 @@ parse_options(argc, argv, opts)
             opts->action = VALIDATE;
             break;
         case 'c':
-            if (opts->k5_cache_name)
+            if (opts->k5_out_cache_name)
             {
                 fprintf(stderr, _("Only one -c option allowed\n"));
                 errflg++;
             } else {
-                opts->k5_cache_name = optarg;
+                opts->k5_out_cache_name = optarg;
+            }
+            break;
+        case 'I':
+            if (opts->k5_in_cache_name) {
+                fprintf(stderr, _("Only one -I option allowed\n"));
+                errflg++;
+            } else {
+                opts->k5_in_cache_name = optarg;
             }
             break;
         case 'X':
@@ -467,16 +476,16 @@ k5_begin(opts, k5)
         }
     }
 
-    if (opts->k5_cache_name) {
-        code = krb5_cc_resolve(k5->ctx, opts->k5_cache_name, &k5->cc);
+    if (opts->k5_out_cache_name) {
+        code = krb5_cc_resolve(k5->ctx, opts->k5_out_cache_name, &k5->out_cc);
         if (code != 0) {
             com_err(progname, code, _("resolving ccache %s"),
-                    opts->k5_cache_name);
+                    opts->k5_out_cache_name);
             return 0;
         }
         if (opts->verbose) {
             fprintf(stderr, _("Using specified cache: %s\n"),
-                    opts->k5_cache_name);
+                    opts->k5_out_cache_name);
         }
     } else {
         if ((code = krb5_cc_default(k5->ctx, &defcache))) {
@@ -486,7 +495,7 @@ k5_begin(opts, k5)
         deftype = krb5_cc_get_type(k5->ctx, defcache);
         if (k5->me != NULL && krb5_cc_support_switch(k5->ctx, deftype)) {
             /* Use an existing cache for the specified principal if we can. */
-            code = krb5_cc_cache_match(k5->ctx, k5->me, &k5->cc);
+            code = krb5_cc_cache_match(k5->ctx, k5->me, &k5->out_cc);
             if (code != 0 && code != KRB5_CC_NOTFOUND) {
                 com_err(progname, code, _("while searching for ccache for %s"),
                         opts->principal_name);
@@ -494,7 +503,7 @@ k5_begin(opts, k5)
                 return 0;
             }
             if (code == KRB5_CC_NOTFOUND) {
-                code = krb5_cc_new_unique(k5->ctx, deftype, NULL, &k5->cc);
+                code = krb5_cc_new_unique(k5->ctx, deftype, NULL, &k5->out_cc);
                 if (code) {
                     com_err(progname, code, _("while generating new ccache"));
                     krb5_cc_close(k5->ctx, defcache);
@@ -502,22 +511,34 @@ k5_begin(opts, k5)
                 }
                 if (opts->verbose) {
                     fprintf(stderr, _("Using new cache: %s\n"),
-                            krb5_cc_get_name(k5->ctx, k5->cc));
+                            krb5_cc_get_name(k5->ctx, k5->out_cc));
                 }
             } else if (opts->verbose) {
                 fprintf(stderr, _("Using existing cache: %s\n"),
-                        krb5_cc_get_name(k5->ctx, k5->cc));
+                        krb5_cc_get_name(k5->ctx, k5->out_cc));
             }
             krb5_cc_close(k5->ctx, defcache);
             k5->switch_to_cache = 1;
         } else {
-            k5->cc = defcache;
+            k5->out_cc = defcache;
             if (opts->verbose) {
                 fprintf(stderr, _("Using default cache: %s\n"),
-                        krb5_cc_get_name(k5->ctx, k5->cc));
+                        krb5_cc_get_name(k5->ctx, k5->out_cc));
             }
         }
     }
+    if (opts->k5_in_cache_name) {
+        code = krb5_cc_resolve(k5->ctx, opts->k5_in_cache_name, &k5->in_cc);
+        if (code != 0) {
+            com_err(progname, code, _("resolving ccache %s"),
+                    opts->k5_in_cache_name);
+            return 0;
+        }
+        if (opts->verbose) {
+            fprintf(stderr, _("Using specified input cache: %s\n"),
+                    opts->k5_in_cache_name);
+        }
+    }
 
     if (!k5->me) {
         /* No principal name specified */
@@ -563,7 +584,7 @@ k5_begin(opts, k5)
                 }
             } else {
                 /* Get default principal from cache if one exists */
-                code = krb5_cc_get_principal(k5->ctx, k5->cc,
+                code = krb5_cc_get_principal(k5->ctx, k5->out_cc,
                                              &k5->me);
                 if (code) {
                     char *name = get_name_from_os();
@@ -603,8 +624,10 @@ k5_end(k5)
         krb5_free_unparsed_name(k5->ctx, k5->name);
     if (k5->me)
         krb5_free_principal(k5->ctx, k5->me);
-    if (k5->cc)
-        krb5_cc_close(k5->ctx, k5->cc);
+    if (k5->in_cc)
+        krb5_cc_close(k5->ctx, k5->in_cc);
+    if (k5->out_cc)
+        krb5_cc_close(k5->ctx, k5->out_cc);
     if (k5->ctx)
         krb5_free_context(k5->ctx);
     errctx = NULL;
@@ -727,7 +750,14 @@ k5_kinit(opts, k5)
                     opts->pa_opts[i].value);
         }
     }
-    code = krb5_get_init_creds_opt_set_out_ccache(k5->ctx, options, k5->cc);
+    if (k5->in_cc) {
+        code = krb5_get_init_creds_opt_set_in_ccache(k5->ctx, options,
+                                                     k5->in_cc);
+        if (code)
+            goto cleanup;
+    }
+    code = krb5_get_init_creds_opt_set_out_ccache(k5->ctx, options,
+                                                  k5->out_cc);
     if (code)
         goto cleanup;
 
@@ -747,11 +777,11 @@ k5_kinit(opts, k5)
                                           options);
         break;
     case VALIDATE:
-        code = krb5_get_validated_creds(k5->ctx, &my_creds, k5->me, k5->cc,
+        code = krb5_get_validated_creds(k5->ctx, &my_creds, k5->me, k5->out_cc,
                                         opts->service_name);
         break;
     case RENEW:
-        code = krb5_get_renewed_creds(k5->ctx, &my_creds, k5->me, k5->cc,
+        code = krb5_get_renewed_creds(k5->ctx, &my_creds, k5->me, k5->out_cc,
                                       opts->service_name);
         break;
     }
@@ -780,17 +810,17 @@ k5_kinit(opts, k5)
     }
 
     if ((opts->action != INIT_PW) && (opts->action != INIT_KT)) {
-        code = krb5_cc_initialize(k5->ctx, k5->cc, opts->canonicalize ?
+        code = krb5_cc_initialize(k5->ctx, k5->out_cc, opts->canonicalize ?
                                   my_creds.client : k5->me);
         if (code) {
             com_err(progname, code, _("when initializing cache %s"),
-                    opts->k5_cache_name?opts->k5_cache_name:"");
+                    opts->k5_out_cache_name?opts->k5_out_cache_name:"");
             goto cleanup;
         }
         if (opts->verbose)
             fprintf(stderr, _("Initialized cache\n"));
 
-        code = krb5_cc_store_cred(k5->ctx, k5->cc, &my_creds);
+        code = krb5_cc_store_cred(k5->ctx, k5->out_cc, &my_creds);
         if (code) {
             com_err(progname, code, _("while storing credentials"));
             goto cleanup;
@@ -801,7 +831,7 @@ k5_kinit(opts, k5)
     notix = 0;
 
     if (k5->switch_to_cache) {
-        code = krb5_cc_switch(k5->ctx, k5->cc);
+        code = krb5_cc_switch(k5->ctx, k5->out_cc);
         if (code) {
             com_err(progname, code, _("while switching to new ccache"));
             goto cleanup;
index 57a6277a83c521d2d2eb055e59d8c7b29e7535ad..169d6d395828fcb9be48d5349fd7601cccdc905d 100644 (file)
@@ -1029,6 +1029,7 @@ typedef struct _krb5_gic_opt_private {
     int num_preauth_data;
     krb5_gic_opt_pa_data *preauth_data;
     char * fast_ccache_name;
+    krb5_ccache in_ccache;
     krb5_ccache out_ccache;
     krb5_flags fast_flags;
     krb5_expire_callback_func expire_cb;
index 3deb7a7800bb4de48d32fe9f76a75a0569de22b7..e515e8a01dd3ecbe324af0845c5bcc3c02a9666e 100644 (file)
@@ -6819,6 +6819,25 @@ krb5_get_init_creds_opt_set_fast_ccache(krb5_context context,
                                         krb5_get_init_creds_opt *opt,
                                         krb5_ccache ccache);
 
+/**
+ * Set an input credential cache in initial credential options.
+ *
+ * @param [in] context          Library context
+ * @param [in] opt              Options
+ * @param [in] ccache           Credential cache handle
+ *
+ * If an input credential cache is set, then the krb5_get_init_creds family of
+ * APIs will read settings from it.  Setting an input ccache is desirable when
+ * the application wishes to perform authentication in the same way (using the
+ * same preauthentication mechanisms, and making the same non-security-
+ * sensitive choices) as the previous authentication attempt, which stored
+ * information in the passed-in ccache.
+ */
+krb5_error_code KRB5_CALLCONV
+krb5_get_init_creds_opt_set_in_ccache(krb5_context context,
+                                      krb5_get_init_creds_opt *opt,
+                                      krb5_ccache ccache);
+
 /**
  * Set an output credential cache in initial credential options.
  *
index 2580abdbe2539666ffc1be967e1eeeb2ee125d46..5b0fc83bbf16589abcb04f0551fc27ec155466e6 100644 (file)
@@ -453,6 +453,21 @@ krb5_get_init_creds_opt_set_fast_ccache(krb5_context context,
     return retval;
 }
 
+krb5_error_code KRB5_CALLCONV
+krb5_get_init_creds_opt_set_in_ccache(krb5_context context,
+                                      krb5_get_init_creds_opt *opt,
+                                      krb5_ccache ccache)
+{
+    krb5_error_code retval = 0;
+    krb5_gic_opt_ext *opte;
+
+    retval = krb5int_gic_opt_to_opte(context, opt, &opte, 0,
+                                     "krb5_get_init_creds_opt_set_in_ccache");
+    if (retval)
+        return retval;
+    opte->opt_private->in_ccache = ccache;
+    return 0;
+}
 
 krb5_error_code KRB5_CALLCONV
 krb5_get_init_creds_opt_set_out_ccache(krb5_context context,
index c1acbce7f0f0c662a144942e0f679bddedd5bb0b..2fbf5d4c82822ae6c4b7d09e1bddc3df3262cfd6 100644 (file)
@@ -369,6 +369,7 @@ krb5_get_init_creds_opt_set_fast_ccache
 krb5_get_init_creds_opt_set_fast_ccache_name
 krb5_get_init_creds_opt_set_fast_flags
 krb5_get_init_creds_opt_set_forwardable
+krb5_get_init_creds_opt_set_in_ccache
 krb5_get_init_creds_opt_set_out_ccache
 krb5_get_init_creds_opt_set_pa
 krb5_get_init_creds_opt_set_preauth_list
index c31ba0f96b1dfb91378b88b1cb8e457ccdaf8118..c60da004ca7def66529142a8a3a819f2badf4b1b 100644 (file)
@@ -443,3 +443,4 @@ EXPORTS
        krb5_responder_otp_set_answer                   @414
        krb5_responder_otp_challenge_free               @415
        krb5_cc_move                                    @416
+       krb5_get_init_creds_opt_set_in_ccache           @417