]> git.decadent.org.uk Git - nfs-utils.git/commitdiff
gssd: Handle the target name correctly
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Wed, 28 Nov 2012 19:30:07 +0000 (14:30 -0500)
committerSteve Dickson <steved@redhat.com>
Wed, 28 Nov 2012 19:48:01 +0000 (14:48 -0500)
The target name contains a hostname in the realm that we are
authenticating
to. Since we may be authenticating to a different realm than the default
realm for the server, we should not assume that the target name and host
name point to the same string.
In fact, the kernel NFS client will always use its own hostname as the
target name, since it is always authenticating to its own default realm.
On the other hand, the NFS server's callback channel will pass the
hostname
of the NFS client that it is authenticating too (Section 3.4, RFC3530).

This patch fixes the handling of the target name in process_krb5_upcall,
and ensures that it gets passed to find_keytab_entry().

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
utils/gssd/gssd_proc.c
utils/gssd/krb5_util.c
utils/gssd/krb5_util.h

index aa5bbb9d4c8b25bed6f170eddb7939a1af574b16..2fba7de00039f7e264a38c6ac2d2a2ed4cfcf84d 100644 (file)
@@ -951,12 +951,6 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname,
 
        printerr(1, "handling krb5 upcall (%s)\n", clp->dirname);
 
-       if (tgtname) {
-               if (clp->servicename) {
-                       free(clp->servicename);
-                       clp->servicename = strdup(tgtname);
-               }
-       }
        token.length = 0;
        token.value = NULL;
        memset(&pd, 0, sizeof(struct authgss_private_data));
@@ -1005,7 +999,8 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname,
                        int success = 0;
                        do {
                                gssd_refresh_krb5_machine_credential(clp->servername,
-                                                                    NULL, service);
+                                                                    NULL, service,
+                                                                    tgtname);
                                /*
                                 * Get a list of credential cache names and try each
                                 * of them until one works or we've tried them all
index 60ba594babd4acca780fa7b03e7581ceebb2e331..aeb8f70bbcfbe6200cba6c907a5c781409860726 100644 (file)
@@ -774,12 +774,16 @@ gssd_search_krb5_keytab(krb5_context context, krb5_keytab kt,
 }
 
 /*
- * Find a keytab entry to use for a given target hostname.
+ * Find a keytab entry to use for a given target realm.
  * Tries to find the most appropriate keytab to use given the
  * name of the host we are trying to connect with.
+ *
+ * Note: the tgtname contains a hostname in the realm that we
+ * are authenticating to. It may, or may not be the same as
+ * the server hostname.
  */
 static int
-find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname,
+find_keytab_entry(krb5_context context, krb5_keytab kt, const char *tgtname,
                  krb5_keytab_entry *kte, const char **svcnames)
 {
        krb5_error_code code;
@@ -795,7 +799,7 @@ find_keytab_entry(krb5_context context, krb5_keytab kt, const char *hostname,
 
 
        /* Get full target hostname */
-       retval = get_full_hostname(hostname, targethostname,
+       retval = get_full_hostname(tgtname, targethostname,
                                   sizeof(targethostname));
        if (retval)
                goto out;
@@ -1128,7 +1132,7 @@ gssd_get_krb5_machine_cred_list(char ***list)
                if (ple->ccname) {
                        /* Make sure cred is up-to-date before returning it */
                        retval = gssd_refresh_krb5_machine_credential(NULL, ple,
-                               NULL);
+                               NULL, NULL);
                        if (retval)
                                continue;
                        if (i + 1 > listsize) {
@@ -1219,7 +1223,8 @@ gssd_destroy_krb5_machine_creds(void)
 int
 gssd_refresh_krb5_machine_credential(char *hostname,
                                     struct gssd_k5_kt_princ *ple, 
-                                        char *service)
+                                        char *service,
+                                        char *tgtname)
 {
        krb5_error_code code = 0;
        krb5_context context;
@@ -1258,7 +1263,10 @@ gssd_refresh_krb5_machine_credential(char *hostname,
        if (ple == NULL) {
                krb5_keytab_entry kte;
 
-               code = find_keytab_entry(context, kt, hostname, &kte, svcnames);
+               if (tgtname == NULL)
+                       tgtname = hostname;
+
+               code = find_keytab_entry(context, kt, tgtname, &kte, svcnames);
                if (code) {
                        printerr(0, "ERROR: %s: no usable keytab entry found "
                                 "in keytab %s for connection with host %s\n",
index cd6e107326923449375f0a93e81b0a5cf8d0a342..9f41625858fe136a63f08d757b4140508729423e 100644 (file)
@@ -31,7 +31,8 @@ void gssd_setup_krb5_machine_gss_ccache(char *servername);
 void gssd_destroy_krb5_machine_creds(void);
 int  gssd_refresh_krb5_machine_credential(char *hostname,
                                          struct gssd_k5_kt_princ *ple, 
-                                         char *service);
+                                         char *service,
+                                         char *tgtname);
 char *gssd_k5_err_msg(krb5_context context, krb5_error_code code);
 void gssd_k5_get_default_realm(char **def_realm);