From af093835774931de898a9baf7b4041fa0d100f77 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 12 Mar 2008 12:12:16 -0400 Subject: 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 --- net/sunrpc/auth_unix.c | 56 ++++++++++++++++++++++---------------------------- 1 file changed, 24 insertions(+), 32 deletions(-) (limited to 'net/sunrpc/auth_unix.c') diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c index 5ed91e5bcee..b763710d3db 100644 --- a/net/sunrpc/auth_unix.c +++ b/net/sunrpc/auth_unix.c @@ -60,7 +60,8 @@ static struct rpc_cred * unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) { struct unx_cred *cred; - int i; + unsigned int groups = 0; + unsigned int i; dprintk("RPC: allocating UNIX cred for uid %d gid %d\n", acred->uid, acred->gid); @@ -70,21 +71,17 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) rpcauth_init_cred(&cred->uc_base, acred, auth, &unix_credops); cred->uc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE; - if (flags & RPCAUTH_LOOKUP_ROOTCREDS) { - cred->uc_uid = 0; - cred->uc_gid = 0; - cred->uc_gids[0] = NOGROUP; - } else { - int groups = acred->group_info->ngroups; - if (groups > NFS_NGROUPS) - groups = NFS_NGROUPS; - - cred->uc_gid = acred->gid; - for (i = 0; i < groups; i++) - cred->uc_gids[i] = GROUP_AT(acred->group_info, i); - if (i < NFS_NGROUPS) - cred->uc_gids[i] = NOGROUP; - } + + if (acred->group_info != NULL) + groups = acred->group_info->ngroups; + if (groups > NFS_NGROUPS) + groups = NFS_NGROUPS; + + cred->uc_gid = acred->gid; + for (i = 0; i < groups; i++) + cred->uc_gids[i] = GROUP_AT(acred->group_info, i); + if (i < NFS_NGROUPS) + cred->uc_gids[i] = NOGROUP; return &cred->uc_base; } @@ -118,26 +115,21 @@ static int unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags) { struct unx_cred *cred = container_of(rcred, struct unx_cred, uc_base); - int i; + unsigned int groups = 0; + unsigned int i; - if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS)) { - int groups; - if (cred->uc_uid != acred->uid - || cred->uc_gid != acred->gid) - return 0; + if (cred->uc_uid != acred->uid || cred->uc_gid != acred->gid) + return 0; + if (acred->group_info != NULL) groups = acred->group_info->ngroups; - if (groups > NFS_NGROUPS) - groups = NFS_NGROUPS; - for (i = 0; i < groups ; i++) - if (cred->uc_gids[i] != GROUP_AT(acred->group_info, i)) - return 0; - return 1; - } - return (cred->uc_uid == 0 - && cred->uc_gid == 0 - && cred->uc_gids[0] == (gid_t) NOGROUP); + if (groups > NFS_NGROUPS) + groups = NFS_NGROUPS; + for (i = 0; i < groups ; i++) + if (cred->uc_gids[i] != GROUP_AT(acred->group_info, i)) + return 0; + return 1; } /* -- cgit v1.2.3-70-g09d2 From 5c691044ecbca04dd558fca4c754121689fe1b34 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 12 Mar 2008 16:21:07 -0400 Subject: SUNRPC: Add an rpc_credop callback for binding a credential to an rpc_task We need the ability to treat 'generic' creds specially, since they want to bind instances of the auth cred instead of binding themselves. Signed-off-by: Trond Myklebust --- include/linux/sunrpc/auth.h | 2 ++ net/sunrpc/auth.c | 5 +++-- net/sunrpc/auth_generic.c | 15 +++++++++++++++ net/sunrpc/auth_gss/auth_gss.c | 2 ++ net/sunrpc/auth_null.c | 1 + net/sunrpc/auth_unix.c | 1 + 6 files changed, 24 insertions(+), 2 deletions(-) (limited to 'net/sunrpc/auth_unix.c') diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h index 70644ed6799..e93cd8aa3eb 100644 --- a/include/linux/sunrpc/auth.h +++ b/include/linux/sunrpc/auth.h @@ -112,6 +112,7 @@ struct rpc_credops { void (*crdestroy)(struct rpc_cred *); int (*crmatch)(struct auth_cred *, struct rpc_cred *, int); + void (*crbind)(struct rpc_task *, struct rpc_cred *); __be32 * (*crmarshal)(struct rpc_task *, __be32 *); int (*crrefresh)(struct rpc_task *); __be32 * (*crvalidate)(struct rpc_task *, __be32 *); @@ -139,6 +140,7 @@ struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred * void rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *); struct rpc_cred * rpcauth_lookupcred(struct rpc_auth *, int); void rpcauth_bindcred(struct rpc_task *, struct rpc_cred *, int); +void rpcauth_generic_bind_cred(struct rpc_task *, struct rpc_cred *); void put_rpccred(struct rpc_cred *); void rpcauth_unbindcred(struct rpc_task *); __be32 * rpcauth_marshcred(struct rpc_task *, __be32 *); diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 012f2a32063..d65dd794010 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c @@ -375,13 +375,14 @@ rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred, } EXPORT_SYMBOL_GPL(rpcauth_init_cred); -static void +void rpcauth_generic_bind_cred(struct rpc_task *task, struct rpc_cred *cred) { task->tk_msg.rpc_cred = get_rpccred(cred); dprintk("RPC: %5u holding %s cred %p\n", task->tk_pid, cred->cr_auth->au_ops->au_name, cred); } +EXPORT_SYMBOL_GPL(rpcauth_generic_bind_cred); static void rpcauth_bind_root_cred(struct rpc_task *task) @@ -421,7 +422,7 @@ void rpcauth_bindcred(struct rpc_task *task, struct rpc_cred *cred, int flags) { if (cred != NULL) - rpcauth_generic_bind_cred(task, cred); + cred->cr_ops->crbind(task, cred); else if (flags & RPC_TASK_ROOTCREDS) rpcauth_bind_root_cred(task); else diff --git a/net/sunrpc/auth_generic.c b/net/sunrpc/auth_generic.c index 6f129b1b20a..6a3f77c9e4d 100644 --- a/net/sunrpc/auth_generic.c +++ b/net/sunrpc/auth_generic.c @@ -35,6 +35,20 @@ struct rpc_cred *rpc_lookup_cred(void) } EXPORT_SYMBOL_GPL(rpc_lookup_cred); +static void +generic_bind_cred(struct rpc_task *task, struct rpc_cred *cred) +{ + struct rpc_auth *auth = task->tk_client->cl_auth; + struct auth_cred *acred = &container_of(cred, struct generic_cred, gc_base)->acred; + struct rpc_cred *ret; + + ret = auth->au_ops->lookup_cred(auth, acred, 0); + if (!IS_ERR(ret)) + task->tk_msg.rpc_cred = ret; + else + task->tk_status = PTR_ERR(ret); +} + /* * Lookup generic creds for current process */ @@ -138,5 +152,6 @@ static struct rpc_auth generic_auth = { static const struct rpc_credops generic_credops = { .cr_name = "Generic cred", .crdestroy = generic_destroy_cred, + .crbind = generic_bind_cred, .crmatch = generic_match, }; diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index ef638496180..d34f6dfc751 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -1300,6 +1300,7 @@ static const struct rpc_credops gss_credops = { .cr_name = "AUTH_GSS", .crdestroy = gss_destroy_cred, .cr_init = gss_cred_init, + .crbind = rpcauth_generic_bind_cred, .crmatch = gss_match, .crmarshal = gss_marshal, .crrefresh = gss_refresh, @@ -1311,6 +1312,7 @@ static const struct rpc_credops gss_credops = { static const struct rpc_credops gss_nullops = { .cr_name = "AUTH_GSS", .crdestroy = gss_destroy_cred, + .crbind = rpcauth_generic_bind_cred, .crmatch = gss_match, .crmarshal = gss_marshal, .crrefresh = gss_refresh_null, diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c index 537d0e8589d..3c26c18df0d 100644 --- a/net/sunrpc/auth_null.c +++ b/net/sunrpc/auth_null.c @@ -125,6 +125,7 @@ static const struct rpc_credops null_credops = { .cr_name = "AUTH_NULL", .crdestroy = nul_destroy_cred, + .crbind = rpcauth_generic_bind_cred, .crmatch = nul_match, .crmarshal = nul_marshal, .crrefresh = nul_refresh, diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c index b763710d3db..04e936a56fb 100644 --- a/net/sunrpc/auth_unix.c +++ b/net/sunrpc/auth_unix.c @@ -237,6 +237,7 @@ static const struct rpc_credops unix_credops = { .cr_name = "AUTH_UNIX", .crdestroy = unx_destroy_cred, + .crbind = rpcauth_generic_bind_cred, .crmatch = unx_match, .crmarshal = unx_marshal, .crrefresh = unx_refresh, -- cgit v1.2.3-70-g09d2 From 78ea323be6380a9313e87fe241809e912e8ae401 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 7 Apr 2008 20:49:28 -0400 Subject: NFSv4: Don't use cred->cr_ops->cr_name in nfs4_proc_setclientid() With the recent change to generic creds, we can no longer use cred->cr_ops->cr_name to distinguish between RPCSEC_GSS principals and AUTH_SYS/AUTH_NULL identities. Replace it with the rpc_authops->au_name instead... Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 2 +- include/linux/sunrpc/auth.h | 2 -- net/sunrpc/auth_generic.c | 2 -- net/sunrpc/auth_gss/auth_gss.c | 2 -- net/sunrpc/auth_null.c | 2 -- net/sunrpc/auth_unix.c | 2 -- 6 files changed, 1 insertion(+), 11 deletions(-) (limited to 'net/sunrpc/auth_unix.c') diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index a1069325b87..dbc09271af0 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2885,7 +2885,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short po RPC_DISPLAY_ADDR), rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_PROTO), - cred->cr_ops->cr_name, + clp->cl_rpcclient->cl_auth->au_ops->au_name, clp->cl_id_uniquifier); setclientid.sc_netid_len = scnprintf(setclientid.sc_netid, sizeof(setclientid.sc_netid), diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h index e93cd8aa3eb..a19c3af933c 100644 --- a/include/linux/sunrpc/auth.h +++ b/include/linux/sunrpc/auth.h @@ -96,9 +96,7 @@ struct rpc_auth { struct rpc_authops { struct module *owner; rpc_authflavor_t au_flavor; /* flavor (RPC_AUTH_*) */ -#ifdef RPC_DEBUG char * au_name; -#endif struct rpc_auth * (*create)(struct rpc_clnt *, rpc_authflavor_t); void (*destroy)(struct rpc_auth *); diff --git a/net/sunrpc/auth_generic.c b/net/sunrpc/auth_generic.c index 6a3f77c9e4d..b6f124c8507 100644 --- a/net/sunrpc/auth_generic.c +++ b/net/sunrpc/auth_generic.c @@ -136,9 +136,7 @@ static struct rpc_cred_cache generic_cred_cache = { static const struct rpc_authops generic_auth_ops = { .owner = THIS_MODULE, -#ifdef RPC_DEBUG .au_name = "Generic", -#endif .lookup_cred = generic_lookup_cred, .crcreate = generic_create_cred, }; diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 55948cd5ea5..7567eb95823 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -1287,9 +1287,7 @@ out: static const struct rpc_authops authgss_ops = { .owner = THIS_MODULE, .au_flavor = RPC_AUTH_GSS, -#ifdef RPC_DEBUG .au_name = "RPCSEC_GSS", -#endif .create = gss_create, .destroy = gss_destroy, .lookup_cred = gss_lookup_cred, diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c index 3c26c18df0d..c70dd7f5258 100644 --- a/net/sunrpc/auth_null.c +++ b/net/sunrpc/auth_null.c @@ -104,9 +104,7 @@ nul_validate(struct rpc_task *task, __be32 *p) const struct rpc_authops authnull_ops = { .owner = THIS_MODULE, .au_flavor = RPC_AUTH_NULL, -#ifdef RPC_DEBUG .au_name = "NULL", -#endif .create = nul_create, .destroy = nul_destroy, .lookup_cred = nul_lookup_cred, diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c index 04e936a56fb..44920b90bdc 100644 --- a/net/sunrpc/auth_unix.c +++ b/net/sunrpc/auth_unix.c @@ -210,9 +210,7 @@ void __init rpc_init_authunix(void) const struct rpc_authops authunix_ops = { .owner = THIS_MODULE, .au_flavor = RPC_AUTH_UNIX, -#ifdef RPC_DEBUG .au_name = "UNIX", -#endif .create = unx_create, .destroy = unx_destroy, .lookup_cred = unx_lookup_cred, -- cgit v1.2.3-70-g09d2