SUNRPC: Fix machine creds in generic_create_cred and generic_match
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Mon, 23 Jan 2012 17:49:36 +0000 (12:49 -0500)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Mon, 23 Jan 2012 22:03:46 +0000 (14:03 -0800)
- generic_create_cred needs to copy the '.principal' field.
- generic_match needs to ignore the groups and match on the '.principal'
  field.

This fixes an Oops that was introduced by commit 68c9715 (SUNRPC:
Clean up the RPCSEC_GSS service ticket requests)

Reported-by: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Tested-by: J. Bruce Fields <bfields@redhat.com>
net/sunrpc/auth_generic.c

index 1426ec3d0a531ecd4ec0b227c5f7aa22843a1750..75762f346975ed6e2be6d639ed7a3e1d83ede077 100644 (file)
@@ -92,6 +92,7 @@ generic_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
        if (gcred->acred.group_info != NULL)
                get_group_info(gcred->acred.group_info);
        gcred->acred.machine_cred = acred->machine_cred;
+       gcred->acred.principal = acred->principal;
 
        dprintk("RPC:       allocated %s cred %p for uid %d gid %d\n",
                        gcred->acred.machine_cred ? "machine" : "generic",
@@ -123,6 +124,17 @@ generic_destroy_cred(struct rpc_cred *cred)
        call_rcu(&cred->cr_rcu, generic_free_cred_callback);
 }
 
+static int
+machine_cred_match(struct auth_cred *acred, struct generic_cred *gcred, int flags)
+{
+       if (!gcred->acred.machine_cred ||
+           gcred->acred.principal != acred->principal ||
+           gcred->acred.uid != acred->uid ||
+           gcred->acred.gid != acred->gid)
+               return 0;
+       return 1;
+}
+
 /*
  * Match credentials against current process creds.
  */
@@ -132,9 +144,12 @@ generic_match(struct auth_cred *acred, struct rpc_cred *cred, int flags)
        struct generic_cred *gcred = container_of(cred, struct generic_cred, gc_base);
        int i;
 
+       if (acred->machine_cred)
+               return machine_cred_match(acred, gcred, flags);
+
        if (gcred->acred.uid != acred->uid ||
            gcred->acred.gid != acred->gid ||
-           gcred->acred.machine_cred != acred->machine_cred)
+           gcred->acred.machine_cred != 0)
                goto out_nomatch;
 
        /* Optimisation in the case where pointers are identical... */