diff options
Diffstat (limited to 'net/sunrpc/auth.c')
-rw-r--r-- | net/sunrpc/auth.c | 75 |
1 files changed, 74 insertions, 1 deletions
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index f5294047df77..ed2fdd210c0b 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c | |||
@@ -82,7 +82,7 @@ MODULE_PARM_DESC(auth_hashtable_size, "RPC credential cache hashtable size"); | |||
82 | 82 | ||
83 | static u32 | 83 | static u32 |
84 | pseudoflavor_to_flavor(u32 flavor) { | 84 | pseudoflavor_to_flavor(u32 flavor) { |
85 | if (flavor >= RPC_AUTH_MAXFLAVOR) | 85 | if (flavor > RPC_AUTH_MAXFLAVOR) |
86 | return RPC_AUTH_GSS; | 86 | return RPC_AUTH_GSS; |
87 | return flavor; | 87 | return flavor; |
88 | } | 88 | } |
@@ -124,6 +124,79 @@ rpcauth_unregister(const struct rpc_authops *ops) | |||
124 | EXPORT_SYMBOL_GPL(rpcauth_unregister); | 124 | EXPORT_SYMBOL_GPL(rpcauth_unregister); |
125 | 125 | ||
126 | /** | 126 | /** |
127 | * rpcauth_get_pseudoflavor - check if security flavor is supported | ||
128 | * @flavor: a security flavor | ||
129 | * @info: a GSS mech OID, quality of protection, and service value | ||
130 | * | ||
131 | * Verifies that an appropriate kernel module is available or already loaded. | ||
132 | * Returns an equivalent pseudoflavor, or RPC_AUTH_MAXFLAVOR if "flavor" is | ||
133 | * not supported locally. | ||
134 | */ | ||
135 | rpc_authflavor_t | ||
136 | rpcauth_get_pseudoflavor(rpc_authflavor_t flavor, struct rpcsec_gss_info *info) | ||
137 | { | ||
138 | const struct rpc_authops *ops; | ||
139 | rpc_authflavor_t pseudoflavor; | ||
140 | |||
141 | ops = auth_flavors[flavor]; | ||
142 | if (ops == NULL) | ||
143 | request_module("rpc-auth-%u", flavor); | ||
144 | spin_lock(&rpc_authflavor_lock); | ||
145 | ops = auth_flavors[flavor]; | ||
146 | if (ops == NULL || !try_module_get(ops->owner)) { | ||
147 | spin_unlock(&rpc_authflavor_lock); | ||
148 | return RPC_AUTH_MAXFLAVOR; | ||
149 | } | ||
150 | spin_unlock(&rpc_authflavor_lock); | ||
151 | |||
152 | pseudoflavor = flavor; | ||
153 | if (ops->info2flavor != NULL) | ||
154 | pseudoflavor = ops->info2flavor(info); | ||
155 | |||
156 | module_put(ops->owner); | ||
157 | return pseudoflavor; | ||
158 | } | ||
159 | EXPORT_SYMBOL_GPL(rpcauth_get_pseudoflavor); | ||
160 | |||
161 | /** | ||
162 | * rpcauth_get_gssinfo - find GSS tuple matching a GSS pseudoflavor | ||
163 | * @pseudoflavor: GSS pseudoflavor to match | ||
164 | * @info: rpcsec_gss_info structure to fill in | ||
165 | * | ||
166 | * Returns zero and fills in "info" if pseudoflavor matches a | ||
167 | * supported mechanism. | ||
168 | */ | ||
169 | int | ||
170 | rpcauth_get_gssinfo(rpc_authflavor_t pseudoflavor, struct rpcsec_gss_info *info) | ||
171 | { | ||
172 | rpc_authflavor_t flavor = pseudoflavor_to_flavor(pseudoflavor); | ||
173 | const struct rpc_authops *ops; | ||
174 | int result; | ||
175 | |||
176 | if (flavor >= RPC_AUTH_MAXFLAVOR) | ||
177 | return -EINVAL; | ||
178 | |||
179 | ops = auth_flavors[flavor]; | ||
180 | if (ops == NULL) | ||
181 | request_module("rpc-auth-%u", flavor); | ||
182 | spin_lock(&rpc_authflavor_lock); | ||
183 | ops = auth_flavors[flavor]; | ||
184 | if (ops == NULL || !try_module_get(ops->owner)) { | ||
185 | spin_unlock(&rpc_authflavor_lock); | ||
186 | return -ENOENT; | ||
187 | } | ||
188 | spin_unlock(&rpc_authflavor_lock); | ||
189 | |||
190 | result = -ENOENT; | ||
191 | if (ops->flavor2info != NULL) | ||
192 | result = ops->flavor2info(pseudoflavor, info); | ||
193 | |||
194 | module_put(ops->owner); | ||
195 | return result; | ||
196 | } | ||
197 | EXPORT_SYMBOL_GPL(rpcauth_get_gssinfo); | ||
198 | |||
199 | /** | ||
127 | * rpcauth_list_flavors - discover registered flavors and pseudoflavors | 200 | * rpcauth_list_flavors - discover registered flavors and pseudoflavors |
128 | * @array: array to fill in | 201 | * @array: array to fill in |
129 | * @size: size of "array" | 202 | * @size: size of "array" |