Use newly added keytab functions
authorKevin Coffman <kwc@citi.umich.edu>
Fri, 30 Mar 2007 22:32:14 +0000 (18:32 -0400)
committerNeil Brown <neilb@suse.de>
Fri, 30 Mar 2007 23:08:02 +0000 (09:08 +1000)
Use the new functions added in the previous patch.

Obtain machine credentials in a pre-determined order

Look for appropriate machine credentials in the following order:
     root/<fqdn>@REALM
     nfs/<fqdn>@REALM
     host/<fqdn>@REALM
     root/<any-name>@REALM
     nfs/<any-name>@REALM
     host/<any-name>@REALM

The first matching credential will be used.

Also, the machine credentials to be used are now determined
"on-demand" rather than at gssd startup.  This allows keytab
additions to be noticed and used without requiring a restart of gssd.

Signed-off-by: Kevin Coffman <kwc@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@suse.de>
utils/gssd/gssd.c
utils/gssd/gssd.man
utils/gssd/gssd_proc.c
utils/gssd/krb5_util.c
utils/gssd/krb5_util.h

index 747637c..b6c4ee4 100644 (file)
@@ -165,10 +165,6 @@ main(int argc, char *argv[])
        signal(SIGTERM, sig_die);
        signal(SIGHUP, sig_hup);
 
-       /* Process keytab file and get machine credentials */
-       if (root_uses_machine_creds)
-               gssd_refresh_krb5_machine_creds();
-
        gssd_run();
        printerr(0, "gssd_run returned!\n");
        abort();
index f2ecd69..8da10b2 100644 (file)
@@ -45,14 +45,25 @@ to use the keys found in
 .I keytab
 to obtain "machine credentials".
 The default value is "/etc/krb5.keytab".
+.IP
 Previous versions of
 .B rpc.gssd
 used only "nfs/*" keys found within the keytab.
-Now, the first keytab entry for each distinct Kerberos realm
-within the keytab is used.  This means that an NFS client
-no longer needs an "nfs/hostname" principal and keytab entry,
-but can instead use a "host/hostname" (or any other) keytab
-entry that is available.
+To be more consistent with other implementations, we now look for
+specific keytab entries.  The search order for keytabs to be used
+for "machine credentials" is now:
+.br
+  root/<hostname>@<REALM>
+.br
+  nfs/<hostname>@<REALM>
+.br
+  host/<hostname>@<REALM>
+.br
+  root/<anyname>@<REALM>
+.br
+  nfs/<anyname>@<REALM>
+.br
+  host/<anyname>@<REALM>
 .TP
 .B -p path
 Tells
index eff740c..48880b6 100644 (file)
@@ -700,14 +700,16 @@ handle_krb5_upcall(struct clnt_info *clp)
                if (uid == 0 && root_uses_machine_creds == 1) {
                        int success = 0;
 
+                       gssd_refresh_krb5_machine_credential(clp->servername,
+                                                            NULL);
                        /*
                         * Get a list of credential cache names and try each
                         * of them until one works or we've tried them all
                         */
                        if (gssd_get_krb5_machine_cred_list(&credlist)) {
-                               printerr(0, "WARNING: Failed to obtain machine "
-                                        "credentials for connection to "
-                                        "server %s\n", clp->servername);
+                               printerr(0, "ERROR: No credentials found "
+                                        "for connection to server %s\n",
+                                        clp->servername);
                                        goto out_return_error;
                        }
                        for (ccname = credlist; ccname && *ccname; ccname++) {
index 20396e0..dee2639 100644 (file)
@@ -358,8 +358,8 @@ gssd_get_single_krb5_cred(krb5_context context,
        printerr(0, "WARNING: Using (debug) short machine cred lifetime!\n");
        krb5_get_init_creds_opt_set_tkt_life(&options, 5*60);
 #endif
-        if ((code = krb5_get_init_creds_keytab(context, &my_creds, ple->princ,
-                                         kt, 0, NULL, &options))) {
+       if ((code = krb5_get_init_creds_keytab(context, &my_creds, ple->princ,
+                                              kt, 0, NULL, &options))) {
                char *pname;
                if ((krb5_unparse_name(context, ple->princ, &pname))) {
                        pname = NULL;
@@ -1146,18 +1146,19 @@ gssd_get_krb5_machine_cred_list(char ***list)
        retval = -1;
        *list = (char **) NULL;
 
-       /* Refresh machine credentials */
-       if ((retval = gssd_refresh_krb5_machine_creds())) {
-               goto out;
-       }
-
        if ((l = (char **) malloc(listsize * sizeof(char *))) == NULL) {
                retval = ENOMEM;
                goto out;
        }
 
+       /* Need to serialize list if we ever become multi-threaded! */
+
        for (ple = gssd_k5_kt_princ_list; ple; ple = ple->next) {
                if (ple->ccname) {
+                       /* Make sure cred is up-to-date before returning it */
+                       retval = gssd_refresh_krb5_machine_credential(NULL, ple);
+                       if (retval)
+                               continue;
                        if (i + 1 > listsize) {
                                listsize += listinc;
                                l = (char **)
index 625d53c..ce7cb57 100644 (file)
@@ -5,7 +5,8 @@
 
 /*
  * List of principals from our keytab that we
- * may try to get credentials for
+ * will try to use to obtain credentials
+ * (known as a principal list entry (ple))
  */
 struct gssd_k5_kt_princ {
        struct gssd_k5_kt_princ *next;