diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2012-07-11 16:31:08 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-07-16 15:12:15 -0400 |
commit | 6a1a1e34dc55f17e7bd260809207442dbb7a0296 (patch) | |
tree | 3a2ce5b9d3c8edc80f6486efc1f9b34cee559f8f /net/sunrpc | |
parent | 56d08fef2369d5ca9ad2e1fc697f5379fd8af751 (diff) |
SUNRPC: Add rpcauth_list_flavors()
The gss_mech_list_pseudoflavors() function provides a list of
currently registered GSS pseudoflavors. This list does not include
any non-GSS flavors that have been registered with the RPC client.
nfs4_find_root_sec() currently adds these extra flavors by hand.
Instead, nfs4_find_root_sec() should be looking at the set of flavors
that have been explicitly registered via rpcauth_register(). And,
other areas of code will soon need the same kind of list that
contains all flavors the kernel currently knows about (see below).
Rather than cloning the open-coded logic in nfs4_find_root_sec() to
those new places, introduce a generic RPC function that generates a
full list of registered auth flavors and pseudoflavors.
A new rpc_authops method is added that lists a flavor's
pseudoflavors, if it has any. I encountered an interesting module
loader loop when I tried to get the RPC client to invoke
gss_mech_list_pseudoflavors() by name.
This patch is a pre-requisite for server trunking discovery, and a
pre-requisite for fixing up the in-kernel mount client to do better
automatic security flavor selection.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/auth.c | 54 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 1 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/gss_mech_switch.c | 18 |
3 files changed, 69 insertions, 4 deletions
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 727e506cacda..b5c067bccc45 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
14 | #include <linux/hash.h> | 14 | #include <linux/hash.h> |
15 | #include <linux/sunrpc/clnt.h> | 15 | #include <linux/sunrpc/clnt.h> |
16 | #include <linux/sunrpc/gss_api.h> | ||
16 | #include <linux/spinlock.h> | 17 | #include <linux/spinlock.h> |
17 | 18 | ||
18 | #ifdef RPC_DEBUG | 19 | #ifdef RPC_DEBUG |
@@ -122,6 +123,59 @@ rpcauth_unregister(const struct rpc_authops *ops) | |||
122 | } | 123 | } |
123 | EXPORT_SYMBOL_GPL(rpcauth_unregister); | 124 | EXPORT_SYMBOL_GPL(rpcauth_unregister); |
124 | 125 | ||
126 | /** | ||
127 | * rpcauth_list_flavors - discover registered flavors and pseudoflavors | ||
128 | * @array: array to fill in | ||
129 | * @size: size of "array" | ||
130 | * | ||
131 | * Returns the number of array items filled in, or a negative errno. | ||
132 | * | ||
133 | * The returned array is not sorted by any policy. Callers should not | ||
134 | * rely on the order of the items in the returned array. | ||
135 | */ | ||
136 | int | ||
137 | rpcauth_list_flavors(rpc_authflavor_t *array, int size) | ||
138 | { | ||
139 | rpc_authflavor_t flavor; | ||
140 | int result = 0; | ||
141 | |||
142 | spin_lock(&rpc_authflavor_lock); | ||
143 | for (flavor = 0; flavor < RPC_AUTH_MAXFLAVOR; flavor++) { | ||
144 | const struct rpc_authops *ops = auth_flavors[flavor]; | ||
145 | rpc_authflavor_t pseudos[4]; | ||
146 | int i, len; | ||
147 | |||
148 | if (result >= size) { | ||
149 | result = -ENOMEM; | ||
150 | break; | ||
151 | } | ||
152 | |||
153 | if (ops == NULL) | ||
154 | continue; | ||
155 | if (ops->list_pseudoflavors == NULL) { | ||
156 | array[result++] = ops->au_flavor; | ||
157 | continue; | ||
158 | } | ||
159 | len = ops->list_pseudoflavors(pseudos, ARRAY_SIZE(pseudos)); | ||
160 | if (len < 0) { | ||
161 | result = len; | ||
162 | break; | ||
163 | } | ||
164 | for (i = 0; i < len; i++) { | ||
165 | if (result >= size) { | ||
166 | result = -ENOMEM; | ||
167 | break; | ||
168 | } | ||
169 | array[result++] = pseudos[i]; | ||
170 | } | ||
171 | } | ||
172 | spin_unlock(&rpc_authflavor_lock); | ||
173 | |||
174 | dprintk("RPC: %s returns %d\n", __func__, result); | ||
175 | return result; | ||
176 | } | ||
177 | EXPORT_SYMBOL_GPL(rpcauth_list_flavors); | ||
178 | |||
125 | struct rpc_auth * | 179 | struct rpc_auth * |
126 | rpcauth_create(rpc_authflavor_t pseudoflavor, struct rpc_clnt *clnt) | 180 | rpcauth_create(rpc_authflavor_t pseudoflavor, struct rpc_clnt *clnt) |
127 | { | 181 | { |
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index d3ad81f8da5b..34c522021004 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -1619,6 +1619,7 @@ static const struct rpc_authops authgss_ops = { | |||
1619 | .crcreate = gss_create_cred, | 1619 | .crcreate = gss_create_cred, |
1620 | .pipes_create = gss_pipes_dentries_create, | 1620 | .pipes_create = gss_pipes_dentries_create, |
1621 | .pipes_destroy = gss_pipes_dentries_destroy, | 1621 | .pipes_destroy = gss_pipes_dentries_destroy, |
1622 | .list_pseudoflavors = gss_mech_list_pseudoflavors, | ||
1622 | }; | 1623 | }; |
1623 | 1624 | ||
1624 | static const struct rpc_credops gss_credops = { | 1625 | static const struct rpc_credops gss_credops = { |
diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c index 782bfe1b6465..6ac5dfcd2928 100644 --- a/net/sunrpc/auth_gss/gss_mech_switch.c +++ b/net/sunrpc/auth_gss/gss_mech_switch.c | |||
@@ -239,14 +239,26 @@ gss_mech_get_by_pseudoflavor(u32 pseudoflavor) | |||
239 | 239 | ||
240 | EXPORT_SYMBOL_GPL(gss_mech_get_by_pseudoflavor); | 240 | EXPORT_SYMBOL_GPL(gss_mech_get_by_pseudoflavor); |
241 | 241 | ||
242 | int gss_mech_list_pseudoflavors(rpc_authflavor_t *array_ptr) | 242 | /** |
243 | * gss_mech_list_pseudoflavors - Discover registered GSS pseudoflavors | ||
244 | * @array: array to fill in | ||
245 | * @size: size of "array" | ||
246 | * | ||
247 | * Returns the number of array items filled in, or a negative errno. | ||
248 | * | ||
249 | * The returned array is not sorted by any policy. Callers should not | ||
250 | * rely on the order of the items in the returned array. | ||
251 | */ | ||
252 | int gss_mech_list_pseudoflavors(rpc_authflavor_t *array_ptr, int size) | ||
243 | { | 253 | { |
244 | struct gss_api_mech *pos = NULL; | 254 | struct gss_api_mech *pos = NULL; |
245 | int j, i = 0; | 255 | int j, i = 0; |
246 | 256 | ||
247 | spin_lock(®istered_mechs_lock); | 257 | spin_lock(®istered_mechs_lock); |
248 | list_for_each_entry(pos, ®istered_mechs, gm_list) { | 258 | list_for_each_entry(pos, ®istered_mechs, gm_list) { |
249 | for (j=0; j < pos->gm_pf_num; j++) { | 259 | for (j = 0; j < pos->gm_pf_num; j++) { |
260 | if (i >= size) | ||
261 | return -ENOMEM; | ||
250 | array_ptr[i++] = pos->gm_pfs[j].pseudoflavor; | 262 | array_ptr[i++] = pos->gm_pfs[j].pseudoflavor; |
251 | } | 263 | } |
252 | } | 264 | } |
@@ -254,8 +266,6 @@ int gss_mech_list_pseudoflavors(rpc_authflavor_t *array_ptr) | |||
254 | return i; | 266 | return i; |
255 | } | 267 | } |
256 | 268 | ||
257 | EXPORT_SYMBOL_GPL(gss_mech_list_pseudoflavors); | ||
258 | |||
259 | u32 | 269 | u32 |
260 | gss_svc_to_pseudoflavor(struct gss_api_mech *gm, u32 service) | 270 | gss_svc_to_pseudoflavor(struct gss_api_mech *gm, u32 service) |
261 | { | 271 | { |