diff -u --recursive --new-file linux-2.5.32-file/fs/nfs/dir.c linux-2.5.32-rpccred/fs/nfs/dir.c --- linux-2.5.32-file/fs/nfs/dir.c Thu Aug 1 22:34:55 2002 +++ linux-2.5.32-rpccred/fs/nfs/dir.c Mon Sep 2 12:32:53 2002 @@ -1212,6 +1212,7 @@ nfs_permission(struct inode *inode, int mask) { struct nfs_access_cache *cache = &NFS_I(inode)->cache_access; + struct vfs_cred *vfscred; struct rpc_cred *cred; int mode = inode->i_mode; int res; @@ -1240,7 +1241,9 @@ if (!NFS_PROTO(inode)->access) goto out_notsup; - cred = rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0); + vfscred = get_current_vfscred(); + cred = rpcauth_lookupcred(vfscred, NFS_CLIENT(inode)->cl_auth, 0); + put_vfscred(vfscred); if (cache->cred == cred && time_before(jiffies, cache->jiffies + NFS_ATTRTIMEO(inode))) { if (!(res = cache->err)) { diff -u --recursive --new-file linux-2.5.32-file/fs/nfs/inode.c linux-2.5.32-rpccred/fs/nfs/inode.c --- linux-2.5.32-file/fs/nfs/inode.c Thu Aug 29 22:27:25 2002 +++ linux-2.5.32-rpccred/fs/nfs/inode.c Mon Sep 2 12:33:24 2002 @@ -877,7 +877,7 @@ goto out; } auth = NFS_CLIENT(inode)->cl_auth; - cred = rpcauth_lookupcred(auth, 0); + cred = rpcauth_lookupcred(filp->f_cred, auth, 0); filp->private_data = cred; if (filp->f_mode & FMODE_WRITE) nfs_set_mmcred(inode, cred); diff -u --recursive --new-file linux-2.5.32-file/fs/nfs/unlink.c linux-2.5.32-rpccred/fs/nfs/unlink.c --- linux-2.5.32-file/fs/nfs/unlink.c Tue Mar 12 21:03:56 2002 +++ linux-2.5.32-rpccred/fs/nfs/unlink.c Mon Sep 2 12:34:12 2002 @@ -160,6 +160,7 @@ struct dentry *dir = dentry->d_parent; struct nfs_unlinkdata *data; struct rpc_task *task; + struct vfs_cred *vfscred; struct rpc_clnt *clnt = NFS_CLIENT(dir->d_inode); int status = -ENOMEM; @@ -182,7 +183,9 @@ task->tk_release = nfs_async_unlink_release; dentry->d_flags |= DCACHE_NFSFS_RENAMED; - data->cred = rpcauth_lookupcred(clnt->cl_auth, 0); + vfscred = get_current_vfscred(); + data->cred = rpcauth_lookupcred(vfscred, clnt->cl_auth, 0); + put_vfscred(vfscred); rpc_sleep_on(&nfs_delete_queue, task, NULL, NULL); status = 0; diff -u --recursive --new-file linux-2.5.32-file/include/linux/sunrpc/auth.h linux-2.5.32-rpccred/include/linux/sunrpc/auth.h --- linux-2.5.32-file/include/linux/sunrpc/auth.h Tue Feb 5 08:44:27 2002 +++ linux-2.5.32-rpccred/include/linux/sunrpc/auth.h Mon Sep 2 13:33:05 2002 @@ -63,6 +63,8 @@ * uid/gid, fs[ug]id, gids) */ +struct vfs_cred; + /* * Client authentication ops */ @@ -74,13 +76,13 @@ struct rpc_auth * (*create)(struct rpc_clnt *); void (*destroy)(struct rpc_auth *); - struct rpc_cred * (*crcreate)(int); + struct rpc_cred * (*crcreate)(struct vfs_cred *, int); }; struct rpc_credops { void (*crdestroy)(struct rpc_cred *); - int (*crmatch)(struct rpc_cred *, int); + int (*crmatch)(struct vfs_cred *, struct rpc_cred *, int); u32 * (*crmarshal)(struct rpc_task *, u32 *, int); int (*crrefresh)(struct rpc_task *); u32 * (*crvalidate)(struct rpc_task *, u32 *); @@ -96,13 +98,11 @@ int rpcauth_unregister(struct rpc_authops *); struct rpc_auth * rpcauth_create(unsigned int, struct rpc_clnt *); void rpcauth_destroy(struct rpc_auth *); -struct rpc_cred * rpcauth_lookupcred(struct rpc_auth *, int); +struct rpc_cred * rpcauth_lookupcred(struct vfs_cred *, struct rpc_auth *, int); struct rpc_cred * rpcauth_bindcred(struct rpc_task *); void rpcauth_holdcred(struct rpc_task *); void put_rpccred(struct rpc_cred *); void rpcauth_unbindcred(struct rpc_task *); -int rpcauth_matchcred(struct rpc_auth *, - struct rpc_cred *, int); u32 * rpcauth_marshcred(struct rpc_task *, u32 *); u32 * rpcauth_checkverf(struct rpc_task *, u32 *); int rpcauth_refreshcred(struct rpc_task *); diff -u --recursive --new-file linux-2.5.32-file/net/sunrpc/auth.c linux-2.5.32-rpccred/net/sunrpc/auth.c --- linux-2.5.32-file/net/sunrpc/auth.c Tue Feb 5 08:45:49 2002 +++ linux-2.5.32-rpccred/net/sunrpc/auth.c Mon Sep 2 12:30:16 2002 @@ -189,13 +189,13 @@ * Look up a process' credentials in the authentication cache */ static struct rpc_cred * -rpcauth_lookup_credcache(struct rpc_auth *auth, int taskflags) +rpcauth_lookup_credcache(struct vfs_cred *vfscred, struct rpc_auth *auth, int taskflags) { struct rpc_cred **q, *cred = NULL; int nr = 0; if (!(taskflags & RPC_TASK_ROOTCREDS)) - nr = current->uid & RPC_CREDCACHE_MASK; + nr = vfscred->uid & RPC_CREDCACHE_MASK; if (time_before(auth->au_nextgc, jiffies)) rpcauth_gc_credcache(auth); @@ -204,7 +204,7 @@ q = &auth->au_credcache[nr]; while ((cred = *q) != NULL) { if (!(cred->cr_flags & RPCAUTH_CRED_DEAD) && - cred->cr_ops->crmatch(cred, taskflags)) { + cred->cr_ops->crmatch(vfscred, cred, taskflags)) { *q = cred->cr_next; break; } @@ -213,7 +213,7 @@ spin_unlock(&rpc_credcache_lock); if (!cred) { - cred = auth->au_ops->crcreate(taskflags); + cred = auth->au_ops->crcreate(vfscred, taskflags); #ifdef RPC_DEBUG if (cred) cred->cr_magic = RPCAUTH_CRED_MAGIC; @@ -250,34 +250,29 @@ } struct rpc_cred * -rpcauth_lookupcred(struct rpc_auth *auth, int taskflags) +rpcauth_lookupcred(struct vfs_cred *vfscred, struct rpc_auth *auth, int taskflags) { dprintk("RPC: looking up %s cred\n", auth->au_ops->au_name); - return rpcauth_lookup_credcache(auth, taskflags); + return rpcauth_lookup_credcache(vfscred, auth, taskflags); } struct rpc_cred * rpcauth_bindcred(struct rpc_task *task) { + struct vfs_cred *vfscred; struct rpc_auth *auth = task->tk_auth; dprintk("RPC: %4d looking up %s cred\n", task->tk_pid, task->tk_auth->au_ops->au_name); - task->tk_msg.rpc_cred = rpcauth_lookup_credcache(auth, task->tk_flags); + vfscred = get_current_vfscred(); + task->tk_msg.rpc_cred = rpcauth_lookup_credcache(vfscred, auth, task->tk_flags); + put_vfscred(vfscred); if (task->tk_msg.rpc_cred == 0) task->tk_status = -ENOMEM; return task->tk_msg.rpc_cred; } -int -rpcauth_matchcred(struct rpc_auth *auth, struct rpc_cred *cred, int taskflags) -{ - dprintk("RPC: matching %s cred %d\n", - auth->au_ops->au_name, taskflags); - return cred->cr_ops->crmatch(cred, taskflags); -} - void rpcauth_holdcred(struct rpc_task *task) { diff -u --recursive --new-file linux-2.5.32-file/net/sunrpc/auth_null.c linux-2.5.32-rpccred/net/sunrpc/auth_null.c --- linux-2.5.32-file/net/sunrpc/auth_null.c Tue Feb 5 16:23:07 2002 +++ linux-2.5.32-rpccred/net/sunrpc/auth_null.c Mon Sep 2 12:37:33 2002 @@ -48,7 +48,7 @@ * Create NULL creds for current process */ static struct rpc_cred * -nul_create_cred(int flags) +nul_create_cred(struct vfs_cred *vfscred, int flags) { struct rpc_cred *cred; @@ -75,7 +75,7 @@ * Match cred handle against current process */ static int -nul_match(struct rpc_cred *cred, int taskflags) +nul_match(struct vfs_cred *vfscred, struct rpc_cred *cred, int taskflags) { return 1; } diff -u --recursive --new-file linux-2.5.32-file/net/sunrpc/auth_unix.c linux-2.5.32-rpccred/net/sunrpc/auth_unix.c --- linux-2.5.32-file/net/sunrpc/auth_unix.c Mon Sep 2 12:47:04 2002 +++ linux-2.5.32-rpccred/net/sunrpc/auth_unix.c Mon Sep 2 16:26:55 2002 @@ -16,14 +16,17 @@ #define NFS_NGROUPS 16 struct unx_cred { struct rpc_cred uc_base; - uid_t uc_fsuid; - gid_t uc_gid, uc_fsgid; - gid_t uc_gids[NFS_NGROUPS]; + struct vfs_cred * uc_vfscred; + gid_t uc_gid; }; #define uc_uid uc_base.cr_uid #define uc_count uc_base.cr_count #define uc_flags uc_base.cr_flags #define uc_expire uc_base.cr_expire +#define uc_fsuid uc_vfscred->uid +#define uc_fsgid uc_vfscred->gid +#define uc_ngids uc_vfscred->ngroups +#define uc_gids uc_vfscred->groups #define UNX_CRED_EXPIRE (60 * HZ) @@ -62,10 +65,9 @@ } static struct rpc_cred * -unx_create_cred(int flags) +unx_create_cred(struct vfs_cred *vfscred, int flags) { struct unx_cred *cred; - int i; dprintk("RPC: allocating UNIX cred for uid %d gid %d\n", current->uid, current->gid); @@ -75,49 +77,18 @@ atomic_set(&cred->uc_count, 0); cred->uc_flags = RPCAUTH_CRED_UPTODATE; - if (flags & RPC_TASK_ROOTCREDS) { - cred->uc_uid = cred->uc_fsuid = 0; - cred->uc_gid = cred->uc_fsgid = 0; - cred->uc_gids[0] = NOGROUP; - } else { - cred->uc_uid = current->uid; - cred->uc_gid = current->gid; - cred->uc_fsuid = current->vfscred->uid; - cred->uc_fsgid = current->vfscred->gid; - i = getgroups(NFS_NGROUPS, cred->uc_gids); - if (i < NFS_NGROUPS) - cred->uc_gids[i] = NOGROUP; - } + cred->uc_uid = current->uid; + cred->uc_gid = current->gid; + cred->uc_vfscred = get_vfscred(vfscred); cred->uc_base.cr_ops = &unix_credops; return (struct rpc_cred *) cred; } -struct rpc_cred * -authunix_fake_cred(struct rpc_task *task, uid_t uid, gid_t gid) -{ - struct unx_cred *cred; - - dprintk("RPC: allocating fake UNIX cred for uid %d gid %d\n", - uid, gid); - - if (!(cred = (struct unx_cred *) rpc_malloc(task, sizeof(*cred)))) - return NULL; - - atomic_set(&cred->uc_count, 1); - cred->uc_flags = RPCAUTH_CRED_DEAD|RPCAUTH_CRED_UPTODATE; - cred->uc_uid = uid; - cred->uc_gid = gid; - cred->uc_fsuid = uid; - cred->uc_fsgid = gid; - cred->uc_gids[0] = (gid_t) NOGROUP; - - return task->tk_msg.rpc_cred = (struct rpc_cred *) cred; -} - static void unx_destroy_cred(struct rpc_cred *cred) { + put_vfscred(((struct unx_cred*)cred)->uc_vfscred); rpc_free(cred); } @@ -127,19 +98,11 @@ * request root creds (e.g. for NFS swapping). */ static int -unx_match(struct rpc_cred *rcred, int taskflags) +unx_match(struct vfs_cred *vfscred, struct rpc_cred *rcred, int taskflags) { struct unx_cred *cred = (struct unx_cred *) rcred; - struct vfs_cred *vfscred; int groups; - if ((taskflags & RPC_TASK_ROOTCREDS)) { - return (cred->uc_uid == 0 && cred->uc_fsuid == 0 - && cred->uc_gid == 0 && cred->uc_fsgid == 0 - && cred->uc_gids[0] == (gid_t) NOGROUP); - } - - vfscred = get_current_vfscred(); if (cred->uc_uid != current->uid || cred->uc_gid != current->gid || cred->uc_fsuid != vfscred->uid @@ -147,13 +110,12 @@ goto out_mismatch; groups = vfscred->ngroups; + if (groups != cred->uc_ngids) + goto out_mismatch; if (groups > NFS_NGROUPS) groups = NFS_NGROUPS; if (memcmp(cred->uc_gids, vfscred->groups, groups*sizeof(gid_t))) goto out_mismatch; - if (groups < NFS_NGROUPS && cred->uc_gids[groups] != NOGROUP) - goto out_mismatch; - put_vfscred(vfscred); return 1; out_mismatch: return 0; @@ -169,7 +131,7 @@ struct rpc_clnt *clnt = task->tk_client; struct unx_cred *cred = (struct unx_cred *) task->tk_msg.rpc_cred; u32 *base, *hold; - int i, n; + int i, n, ngrp; *p++ = htonl(RPC_AUTH_UNIX); base = p++; @@ -192,8 +154,13 @@ *p++ = htonl((u32) cred->uc_fsgid); } hold = p++; - for (i = 0; i < 16 && cred->uc_gids[i] != (gid_t) NOGROUP; i++) + ngrp = cred->uc_ngids; + if (ngrp > NFS_NGROUPS) + ngrp = NFS_NGROUPS; + for (i = 0; i < ngrp; i++) *p++ = htonl((u32) cred->uc_gids[i]); + if (ngrp < NFS_NGROUPS) + *p++ = htonl(NOGROUP); *hold = htonl(p - hold - 1); /* gid array length */ *base = htonl((p - base - 1) << 2); /* cred length */ diff -u --recursive --new-file linux-2.5.32-file/net/sunrpc/sunrpc_syms.c linux-2.5.32-rpccred/net/sunrpc/sunrpc_syms.c --- linux-2.5.32-file/net/sunrpc/sunrpc_syms.c Fri Jul 26 02:05:29 2002 +++ linux-2.5.32-rpccred/net/sunrpc/sunrpc_syms.c Mon Sep 2 15:35:09 2002 @@ -65,7 +65,6 @@ EXPORT_SYMBOL(rpcauth_insert_credcache); EXPORT_SYMBOL(rpcauth_lookupcred); EXPORT_SYMBOL(rpcauth_bindcred); -EXPORT_SYMBOL(rpcauth_matchcred); EXPORT_SYMBOL(put_rpccred); /* RPC server stuff */