]> git.decadent.org.uk Git - nfs-utils.git/commitdiff
gssd: process target= attribute in new upcall
authorOlga Kornievskaia <aglo@citi.umich.edu>
Mon, 16 Nov 2009 14:27:22 +0000 (09:27 -0500)
committerSteve Dickson <steved@redhat.com>
Mon, 16 Nov 2009 14:27:22 +0000 (09:27 -0500)
Add processing of the "target=" attribute in the new gssd upcall.
Information in this field is used to construct the gss service name
of the server for which gssd will create a context .

This, along with the next patch handling "service=", is needed
for callback security.

For Kerberos, the NFS client will use a service principal present
in its keytab during authentication of the SETCLIENT_ID operation.
When establishing the context for the callback, the gssd on the
NFS server will attempt to authenticate the callback against the
principal name used by the client.

Note: An NFS client machine must have a keytab for the callback
authentication to succeed.

Signed-off-by: Olga Kornievskaia <aglo@citi.umich.edu>
Signed-off-by: Kevin Coffman <kwc@citi.umich.edu>
Signed-off-by: Steve Dickson <steved@redhat.com>
utils/gssd/gssd_proc.c

index 5897ae6ac13074a09d019922ca7ddf2449e8fb0f..799a207c46b45de62a7e7139b6a3c059ad888e6d 100644 (file)
@@ -883,7 +883,7 @@ int create_auth_rpc_client(struct clnt_info *clp,
  * context on behalf of the kernel
  */
 static void
-process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd)
+process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname)
 {
        CLIENT                  *rpc_clnt = NULL;
        AUTH                    *auth = NULL;
@@ -896,6 +896,12 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd)
 
        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));
@@ -1060,7 +1066,7 @@ handle_krb5_upcall(struct clnt_info *clp)
                return;
        }
 
-       return process_krb5_upcall(clp, uid, clp->krb5_fd);
+       return process_krb5_upcall(clp, uid, clp->krb5_fd, NULL);
 }
 
 void
@@ -1085,6 +1091,7 @@ handle_gssd_upcall(struct clnt_info *clp)
        int                     lbuflen = 0;
        char                    *p;
        char                    *mech = NULL;
+       char                    *target = NULL;
 
        printerr(1, "handling gssd upcall (%s)\n", clp->dirname);
 
@@ -1128,9 +1135,21 @@ handle_gssd_upcall(struct clnt_info *clp)
                goto out;
        }
 
+       /* read target name */
+       if ((p = strstr(lbuf, "target=")) != NULL) {
+               target = malloc(lbuflen);
+               if (!target)
+                       goto out;
+               if (sscanf(p, "target=%s", target) != 1) {
+                       printerr(0, "WARNING: handle_gssd_upcall: "
+                                   "failed to parse target name "
+                                   "in upcall string '%s'\n", lbuf);
+                       goto out;
+               }
+       }
 
        if (strcmp(mech, "krb5") == 0)
-               process_krb5_upcall(clp, uid, clp->gssd_fd);
+               process_krb5_upcall(clp, uid, clp->gssd_fd, target);
        else if (strcmp(mech, "spkm3") == 0)
                process_spkm3_upcall(clp, uid, clp->gssd_fd);
        else
@@ -1140,6 +1159,7 @@ handle_gssd_upcall(struct clnt_info *clp)
 out:
        free(lbuf);
        free(mech);
+       free(target);
        return; 
 }