aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2008-03-12 12:12:16 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-03-14 13:42:32 -0400
commitaf093835774931de898a9baf7b4041fa0d100f77 (patch)
treef7617eb4556ead8615f6c26d8b02fcec8f64c6b3
parent25337fdc85951dfeac944f16cb565904c619077a (diff)
SUNRPC: Fix RPCAUTH_LOOKUP_ROOTCREDS
The current RPCAUTH_LOOKUP_ROOTCREDS flag only works for AUTH_SYS authentication, and then only as a special case in the code. This patch removes the auth_sys special casing, and replaces it with generic code. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--include/linux/sunrpc/auth.h4
-rw-r--r--net/sunrpc/auth.c35
-rw-r--r--net/sunrpc/auth_unix.c56
-rw-r--r--net/sunrpc/sched.c4
4 files changed, 49 insertions, 50 deletions
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
index 84d5f3a05b16..012566a6257b 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -89,7 +89,6 @@ struct rpc_auth {
89 89
90/* Flags for rpcauth_lookupcred() */ 90/* Flags for rpcauth_lookupcred() */
91#define RPCAUTH_LOOKUP_NEW 0x01 /* Accept an uninitialised cred */ 91#define RPCAUTH_LOOKUP_NEW 0x01 /* Accept an uninitialised cred */
92#define RPCAUTH_LOOKUP_ROOTCREDS 0x02 /* This really ought to go! */
93 92
94/* 93/*
95 * Client authentication ops 94 * Client authentication ops
@@ -136,7 +135,8 @@ void rpcauth_release(struct rpc_auth *);
136struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int); 135struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int);
137void rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *); 136void rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *);
138struct rpc_cred * rpcauth_lookupcred(struct rpc_auth *, int); 137struct rpc_cred * rpcauth_lookupcred(struct rpc_auth *, int);
139struct rpc_cred * rpcauth_bindcred(struct rpc_task *); 138void rpcauth_bindcred(struct rpc_task *);
139void rpcauth_bind_root_cred(struct rpc_task *);
140void rpcauth_holdcred(struct rpc_task *); 140void rpcauth_holdcred(struct rpc_task *);
141void put_rpccred(struct rpc_cred *); 141void put_rpccred(struct rpc_cred *);
142void rpcauth_unbindcred(struct rpc_task *); 142void rpcauth_unbindcred(struct rpc_task *);
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index b38f6ee2f5e2..b0f2b2ee7cc0 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -285,9 +285,6 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
285 285
286 nr = hash_long(acred->uid, RPC_CREDCACHE_HASHBITS); 286 nr = hash_long(acred->uid, RPC_CREDCACHE_HASHBITS);
287 287
288 if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS))
289 nr = acred->uid & RPC_CREDCACHE_MASK;
290
291 rcu_read_lock(); 288 rcu_read_lock();
292 hlist_for_each_entry_rcu(entry, pos, &cache->hashtable[nr], cr_hash) { 289 hlist_for_each_entry_rcu(entry, pos, &cache->hashtable[nr], cr_hash) {
293 if (!entry->cr_ops->crmatch(acred, entry, flags)) 290 if (!entry->cr_ops->crmatch(acred, entry, flags))
@@ -378,30 +375,38 @@ rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred,
378} 375}
379EXPORT_SYMBOL_GPL(rpcauth_init_cred); 376EXPORT_SYMBOL_GPL(rpcauth_init_cred);
380 377
381struct rpc_cred * 378void
382rpcauth_bindcred(struct rpc_task *task) 379rpcauth_bind_root_cred(struct rpc_task *task)
383{ 380{
384 struct rpc_auth *auth = task->tk_client->cl_auth; 381 struct rpc_auth *auth = task->tk_client->cl_auth;
385 struct auth_cred acred = { 382 struct auth_cred acred = {
386 .uid = current->fsuid, 383 .uid = 0,
387 .gid = current->fsgid, 384 .gid = 0,
388 .group_info = current->group_info,
389 }; 385 };
390 struct rpc_cred *ret; 386 struct rpc_cred *ret;
391 int flags = 0;
392 387
393 dprintk("RPC: %5u looking up %s cred\n", 388 dprintk("RPC: %5u looking up %s cred\n",
394 task->tk_pid, task->tk_client->cl_auth->au_ops->au_name); 389 task->tk_pid, task->tk_client->cl_auth->au_ops->au_name);
395 get_group_info(acred.group_info); 390 ret = auth->au_ops->lookup_cred(auth, &acred, 0);
396 if (task->tk_flags & RPC_TASK_ROOTCREDS) 391 if (!IS_ERR(ret))
397 flags |= RPCAUTH_LOOKUP_ROOTCREDS; 392 task->tk_msg.rpc_cred = ret;
398 ret = auth->au_ops->lookup_cred(auth, &acred, flags); 393 else
394 task->tk_status = PTR_ERR(ret);
395}
396
397void
398rpcauth_bindcred(struct rpc_task *task)
399{
400 struct rpc_auth *auth = task->tk_client->cl_auth;
401 struct rpc_cred *ret;
402
403 dprintk("RPC: %5u looking up %s cred\n",
404 task->tk_pid, auth->au_ops->au_name);
405 ret = rpcauth_lookupcred(auth, 0);
399 if (!IS_ERR(ret)) 406 if (!IS_ERR(ret))
400 task->tk_msg.rpc_cred = ret; 407 task->tk_msg.rpc_cred = ret;
401 else 408 else
402 task->tk_status = PTR_ERR(ret); 409 task->tk_status = PTR_ERR(ret);
403 put_group_info(acred.group_info);
404 return ret;
405} 410}
406 411
407void 412void
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index 5ed91e5bcee4..b763710d3dbd 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -60,7 +60,8 @@ static struct rpc_cred *
60unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) 60unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
61{ 61{
62 struct unx_cred *cred; 62 struct unx_cred *cred;
63 int i; 63 unsigned int groups = 0;
64 unsigned int i;
64 65
65 dprintk("RPC: allocating UNIX cred for uid %d gid %d\n", 66 dprintk("RPC: allocating UNIX cred for uid %d gid %d\n",
66 acred->uid, acred->gid); 67 acred->uid, acred->gid);
@@ -70,21 +71,17 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
70 71
71 rpcauth_init_cred(&cred->uc_base, acred, auth, &unix_credops); 72 rpcauth_init_cred(&cred->uc_base, acred, auth, &unix_credops);
72 cred->uc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE; 73 cred->uc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE;
73 if (flags & RPCAUTH_LOOKUP_ROOTCREDS) { 74
74 cred->uc_uid = 0; 75 if (acred->group_info != NULL)
75 cred->uc_gid = 0; 76 groups = acred->group_info->ngroups;
76 cred->uc_gids[0] = NOGROUP; 77 if (groups > NFS_NGROUPS)
77 } else { 78 groups = NFS_NGROUPS;
78 int groups = acred->group_info->ngroups; 79
79 if (groups > NFS_NGROUPS) 80 cred->uc_gid = acred->gid;
80 groups = NFS_NGROUPS; 81 for (i = 0; i < groups; i++)
81 82 cred->uc_gids[i] = GROUP_AT(acred->group_info, i);
82 cred->uc_gid = acred->gid; 83 if (i < NFS_NGROUPS)
83 for (i = 0; i < groups; i++) 84 cred->uc_gids[i] = NOGROUP;
84 cred->uc_gids[i] = GROUP_AT(acred->group_info, i);
85 if (i < NFS_NGROUPS)
86 cred->uc_gids[i] = NOGROUP;
87 }
88 85
89 return &cred->uc_base; 86 return &cred->uc_base;
90} 87}
@@ -118,26 +115,21 @@ static int
118unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags) 115unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
119{ 116{
120 struct unx_cred *cred = container_of(rcred, struct unx_cred, uc_base); 117 struct unx_cred *cred = container_of(rcred, struct unx_cred, uc_base);
121 int i; 118 unsigned int groups = 0;
119 unsigned int i;
122 120
123 if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS)) {
124 int groups;
125 121
126 if (cred->uc_uid != acred->uid 122 if (cred->uc_uid != acred->uid || cred->uc_gid != acred->gid)
127 || cred->uc_gid != acred->gid) 123 return 0;
128 return 0;
129 124
125 if (acred->group_info != NULL)
130 groups = acred->group_info->ngroups; 126 groups = acred->group_info->ngroups;
131 if (groups > NFS_NGROUPS) 127 if (groups > NFS_NGROUPS)
132 groups = NFS_NGROUPS; 128 groups = NFS_NGROUPS;
133 for (i = 0; i < groups ; i++) 129 for (i = 0; i < groups ; i++)
134 if (cred->uc_gids[i] != GROUP_AT(acred->group_info, i)) 130 if (cred->uc_gids[i] != GROUP_AT(acred->group_info, i))
135 return 0; 131 return 0;
136 return 1; 132 return 1;
137 }
138 return (cred->uc_uid == 0
139 && cred->uc_gid == 0
140 && cred->uc_gids[0] == (gid_t) NOGROUP);
141} 133}
142 134
143/* 135/*
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index cae219c8caeb..7db956f6e018 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -821,8 +821,10 @@ static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *ta
821 /* Bind the user cred */ 821 /* Bind the user cred */
822 if (task->tk_msg.rpc_cred != NULL) 822 if (task->tk_msg.rpc_cred != NULL)
823 rpcauth_holdcred(task); 823 rpcauth_holdcred(task);
824 else 824 else if (!(task_setup_data->flags & RPC_TASK_ROOTCREDS))
825 rpcauth_bindcred(task); 825 rpcauth_bindcred(task);
826 else
827 rpcauth_bind_root_cred(task);
826 if (task->tk_action == NULL) 828 if (task->tk_action == NULL)
827 rpc_call_start(task); 829 rpc_call_start(task);
828 } 830 }