diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-03-12 12:12:16 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-03-14 13:42:32 -0400 |
commit | af093835774931de898a9baf7b4041fa0d100f77 (patch) | |
tree | f7617eb4556ead8615f6c26d8b02fcec8f64c6b3 | |
parent | 25337fdc85951dfeac944f16cb565904c619077a (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.h | 4 | ||||
-rw-r--r-- | net/sunrpc/auth.c | 35 | ||||
-rw-r--r-- | net/sunrpc/auth_unix.c | 56 | ||||
-rw-r--r-- | net/sunrpc/sched.c | 4 |
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 *); | |||
136 | struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int); | 135 | struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int); |
137 | void rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *); | 136 | void rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *); |
138 | struct rpc_cred * rpcauth_lookupcred(struct rpc_auth *, int); | 137 | struct rpc_cred * rpcauth_lookupcred(struct rpc_auth *, int); |
139 | struct rpc_cred * rpcauth_bindcred(struct rpc_task *); | 138 | void rpcauth_bindcred(struct rpc_task *); |
139 | void rpcauth_bind_root_cred(struct rpc_task *); | ||
140 | void rpcauth_holdcred(struct rpc_task *); | 140 | void rpcauth_holdcred(struct rpc_task *); |
141 | void put_rpccred(struct rpc_cred *); | 141 | void put_rpccred(struct rpc_cred *); |
142 | void rpcauth_unbindcred(struct rpc_task *); | 142 | void 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 | } |
379 | EXPORT_SYMBOL_GPL(rpcauth_init_cred); | 376 | EXPORT_SYMBOL_GPL(rpcauth_init_cred); |
380 | 377 | ||
381 | struct rpc_cred * | 378 | void |
382 | rpcauth_bindcred(struct rpc_task *task) | 379 | rpcauth_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 | |||
397 | void | ||
398 | rpcauth_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 | ||
407 | void | 412 | void |
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 * | |||
60 | unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) | 60 | unx_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 | |||
118 | unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags) | 115 | unx_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 | } |