aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/sunrpc/auth.h5
-rw-r--r--net/sunrpc/auth.c17
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c25
-rw-r--r--net/sunrpc/auth_unix.c6
4 files changed, 37 insertions, 16 deletions
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
index b68c11a2d6dd..bfc5fb279539 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -50,6 +50,7 @@ struct rpc_cred {
50}; 50};
51#define RPCAUTH_CRED_LOCKED 0x0001 51#define RPCAUTH_CRED_LOCKED 0x0001
52#define RPCAUTH_CRED_UPTODATE 0x0002 52#define RPCAUTH_CRED_UPTODATE 0x0002
53#define RPCAUTH_CRED_NEW 0x0004
53 54
54#define RPCAUTH_CRED_MAGIC 0x0f4aa4f0 55#define RPCAUTH_CRED_MAGIC 0x0f4aa4f0
55 56
@@ -87,6 +88,10 @@ struct rpc_auth {
87 * uid/gid, fs[ug]id, gids) 88 * uid/gid, fs[ug]id, gids)
88 */ 89 */
89 90
91/* Flags for rpcauth_lookupcred() */
92#define RPCAUTH_LOOKUP_NEW 0x01 /* Accept an uninitialised cred */
93#define RPCAUTH_LOOKUP_ROOTCREDS 0x02 /* This really ought to go! */
94
90/* 95/*
91 * Client authentication ops 96 * Client authentication ops
92 */ 97 */
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index 9ac1b8c26c01..1ca89c36da7a 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -184,7 +184,7 @@ rpcauth_gc_credcache(struct rpc_auth *auth, struct hlist_head *free)
184 */ 184 */
185struct rpc_cred * 185struct rpc_cred *
186rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, 186rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
187 int taskflags) 187 int flags)
188{ 188{
189 struct rpc_cred_cache *cache = auth->au_credcache; 189 struct rpc_cred_cache *cache = auth->au_credcache;
190 HLIST_HEAD(free); 190 HLIST_HEAD(free);
@@ -193,7 +193,7 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
193 *cred = NULL; 193 *cred = NULL;
194 int nr = 0; 194 int nr = 0;
195 195
196 if (!(taskflags & RPC_TASK_ROOTCREDS)) 196 if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS))
197 nr = acred->uid & RPC_CREDCACHE_MASK; 197 nr = acred->uid & RPC_CREDCACHE_MASK;
198retry: 198retry:
199 spin_lock(&rpc_credcache_lock); 199 spin_lock(&rpc_credcache_lock);
@@ -202,7 +202,7 @@ retry:
202 hlist_for_each_safe(pos, next, &cache->hashtable[nr]) { 202 hlist_for_each_safe(pos, next, &cache->hashtable[nr]) {
203 struct rpc_cred *entry; 203 struct rpc_cred *entry;
204 entry = hlist_entry(pos, struct rpc_cred, cr_hash); 204 entry = hlist_entry(pos, struct rpc_cred, cr_hash);
205 if (entry->cr_ops->crmatch(acred, entry, taskflags)) { 205 if (entry->cr_ops->crmatch(acred, entry, flags)) {
206 hlist_del(&entry->cr_hash); 206 hlist_del(&entry->cr_hash);
207 cred = entry; 207 cred = entry;
208 break; 208 break;
@@ -224,7 +224,7 @@ retry:
224 rpcauth_destroy_credlist(&free); 224 rpcauth_destroy_credlist(&free);
225 225
226 if (!cred) { 226 if (!cred) {
227 new = auth->au_ops->crcreate(auth, acred, taskflags); 227 new = auth->au_ops->crcreate(auth, acred, flags);
228 if (!IS_ERR(new)) { 228 if (!IS_ERR(new)) {
229#ifdef RPC_DEBUG 229#ifdef RPC_DEBUG
230 new->cr_magic = RPCAUTH_CRED_MAGIC; 230 new->cr_magic = RPCAUTH_CRED_MAGIC;
@@ -238,7 +238,7 @@ retry:
238} 238}
239 239
240struct rpc_cred * 240struct rpc_cred *
241rpcauth_lookupcred(struct rpc_auth *auth, int taskflags) 241rpcauth_lookupcred(struct rpc_auth *auth, int flags)
242{ 242{
243 struct auth_cred acred = { 243 struct auth_cred acred = {
244 .uid = current->fsuid, 244 .uid = current->fsuid,
@@ -250,7 +250,7 @@ rpcauth_lookupcred(struct rpc_auth *auth, int taskflags)
250 dprintk("RPC: looking up %s cred\n", 250 dprintk("RPC: looking up %s cred\n",
251 auth->au_ops->au_name); 251 auth->au_ops->au_name);
252 get_group_info(acred.group_info); 252 get_group_info(acred.group_info);
253 ret = auth->au_ops->lookup_cred(auth, &acred, taskflags); 253 ret = auth->au_ops->lookup_cred(auth, &acred, flags);
254 put_group_info(acred.group_info); 254 put_group_info(acred.group_info);
255 return ret; 255 return ret;
256} 256}
@@ -265,11 +265,14 @@ rpcauth_bindcred(struct rpc_task *task)
265 .group_info = current->group_info, 265 .group_info = current->group_info,
266 }; 266 };
267 struct rpc_cred *ret; 267 struct rpc_cred *ret;
268 int flags = 0;
268 269
269 dprintk("RPC: %4d looking up %s cred\n", 270 dprintk("RPC: %4d looking up %s cred\n",
270 task->tk_pid, task->tk_auth->au_ops->au_name); 271 task->tk_pid, task->tk_auth->au_ops->au_name);
271 get_group_info(acred.group_info); 272 get_group_info(acred.group_info);
272 ret = auth->au_ops->lookup_cred(auth, &acred, task->tk_flags); 273 if (task->tk_flags & RPC_TASK_ROOTCREDS)
274 flags |= RPCAUTH_LOOKUP_ROOTCREDS;
275 ret = auth->au_ops->lookup_cred(auth, &acred, flags);
273 if (!IS_ERR(ret)) 276 if (!IS_ERR(ret))
274 task->tk_msg.rpc_cred = ret; 277 task->tk_msg.rpc_cred = ret;
275 else 278 else
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 8d782282ec19..03affcbf6292 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -158,6 +158,7 @@ gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx)
158 old = gss_cred->gc_ctx; 158 old = gss_cred->gc_ctx;
159 gss_cred->gc_ctx = ctx; 159 gss_cred->gc_ctx = ctx;
160 cred->cr_flags |= RPCAUTH_CRED_UPTODATE; 160 cred->cr_flags |= RPCAUTH_CRED_UPTODATE;
161 cred->cr_flags &= ~RPCAUTH_CRED_NEW;
161 write_unlock(&gss_ctx_lock); 162 write_unlock(&gss_ctx_lock);
162 if (old) 163 if (old)
163 gss_put_ctx(old); 164 gss_put_ctx(old);
@@ -580,7 +581,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
580 } else { 581 } else {
581 struct auth_cred acred = { .uid = uid }; 582 struct auth_cred acred = { .uid = uid };
582 spin_unlock(&gss_auth->lock); 583 spin_unlock(&gss_auth->lock);
583 cred = rpcauth_lookup_credcache(clnt->cl_auth, &acred, 0); 584 cred = rpcauth_lookup_credcache(clnt->cl_auth, &acred, RPCAUTH_LOOKUP_NEW);
584 if (IS_ERR(cred)) { 585 if (IS_ERR(cred)) {
585 err = PTR_ERR(cred); 586 err = PTR_ERR(cred);
586 goto err_put_ctx; 587 goto err_put_ctx;
@@ -758,13 +759,13 @@ gss_destroy_cred(struct rpc_cred *rc)
758 * Lookup RPCSEC_GSS cred for the current process 759 * Lookup RPCSEC_GSS cred for the current process
759 */ 760 */
760static struct rpc_cred * 761static struct rpc_cred *
761gss_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int taskflags) 762gss_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
762{ 763{
763 return rpcauth_lookup_credcache(auth, acred, taskflags); 764 return rpcauth_lookup_credcache(auth, acred, flags);
764} 765}
765 766
766static struct rpc_cred * 767static struct rpc_cred *
767gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int taskflags) 768gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
768{ 769{
769 struct gss_auth *gss_auth = container_of(auth, struct gss_auth, rpc_auth); 770 struct gss_auth *gss_auth = container_of(auth, struct gss_auth, rpc_auth);
770 struct gss_cred *cred = NULL; 771 struct gss_cred *cred = NULL;
@@ -785,13 +786,17 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int taskflags)
785 */ 786 */
786 cred->gc_flags = 0; 787 cred->gc_flags = 0;
787 cred->gc_base.cr_ops = &gss_credops; 788 cred->gc_base.cr_ops = &gss_credops;
789 cred->gc_base.cr_flags = RPCAUTH_CRED_NEW;
788 cred->gc_service = gss_auth->service; 790 cred->gc_service = gss_auth->service;
791 /* Is the caller prepared to initialise the credential? */
792 if (flags & RPCAUTH_LOOKUP_NEW)
793 goto out;
789 do { 794 do {
790 err = gss_create_upcall(gss_auth, cred); 795 err = gss_create_upcall(gss_auth, cred);
791 } while (err == -EAGAIN); 796 } while (err == -EAGAIN);
792 if (err < 0) 797 if (err < 0)
793 goto out_err; 798 goto out_err;
794 799out:
795 return &cred->gc_base; 800 return &cred->gc_base;
796 801
797out_err: 802out_err:
@@ -801,13 +806,21 @@ out_err:
801} 806}
802 807
803static int 808static int
804gss_match(struct auth_cred *acred, struct rpc_cred *rc, int taskflags) 809gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags)
805{ 810{
806 struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base); 811 struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base);
807 812
813 /*
814 * If the searchflags have set RPCAUTH_LOOKUP_NEW, then
815 * we don't really care if the credential has expired or not,
816 * since the caller should be prepared to reinitialise it.
817 */
818 if ((flags & RPCAUTH_LOOKUP_NEW) && (rc->cr_flags & RPCAUTH_CRED_NEW))
819 goto out;
808 /* Don't match with creds that have expired. */ 820 /* Don't match with creds that have expired. */
809 if (gss_cred->gc_ctx && time_after(jiffies, gss_cred->gc_ctx->gc_expiry)) 821 if (gss_cred->gc_ctx && time_after(jiffies, gss_cred->gc_ctx->gc_expiry))
810 return 0; 822 return 0;
823out:
811 return (rc->cr_uid == acred->uid); 824 return (rc->cr_uid == acred->uid);
812} 825}
813 826
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index 1b3ed4fd1987..df14b6bfbf10 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -75,7 +75,7 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
75 75
76 atomic_set(&cred->uc_count, 1); 76 atomic_set(&cred->uc_count, 1);
77 cred->uc_flags = RPCAUTH_CRED_UPTODATE; 77 cred->uc_flags = RPCAUTH_CRED_UPTODATE;
78 if (flags & RPC_TASK_ROOTCREDS) { 78 if (flags & RPCAUTH_LOOKUP_ROOTCREDS) {
79 cred->uc_uid = 0; 79 cred->uc_uid = 0;
80 cred->uc_gid = 0; 80 cred->uc_gid = 0;
81 cred->uc_gids[0] = NOGROUP; 81 cred->uc_gids[0] = NOGROUP;
@@ -108,12 +108,12 @@ unx_destroy_cred(struct rpc_cred *cred)
108 * request root creds (e.g. for NFS swapping). 108 * request root creds (e.g. for NFS swapping).
109 */ 109 */
110static int 110static int
111unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int taskflags) 111unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
112{ 112{
113 struct unx_cred *cred = (struct unx_cred *) rcred; 113 struct unx_cred *cred = (struct unx_cred *) rcred;
114 int i; 114 int i;
115 115
116 if (!(taskflags & RPC_TASK_ROOTCREDS)) { 116 if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS)) {
117 int groups; 117 int groups;
118 118
119 if (cred->uc_uid != acred->uid 119 if (cred->uc_uid != acred->uid