aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/callback.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/callback.c')
-rw-r--r--fs/nfs/callback.c36
1 files changed, 31 insertions, 5 deletions
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index c2e9cfd9e5a4..3e634f2a1083 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -16,6 +16,7 @@
16#include <linux/mutex.h> 16#include <linux/mutex.h>
17#include <linux/freezer.h> 17#include <linux/freezer.h>
18#include <linux/kthread.h> 18#include <linux/kthread.h>
19#include <linux/sunrpc/svcauth_gss.h>
19 20
20#include <net/inet_sock.h> 21#include <net/inet_sock.h>
21 22
@@ -182,10 +183,34 @@ void nfs_callback_down(void)
182 mutex_unlock(&nfs_callback_mutex); 183 mutex_unlock(&nfs_callback_mutex);
183} 184}
184 185
186static int check_gss_callback_principal(struct nfs_client *clp,
187 struct svc_rqst *rqstp)
188{
189 struct rpc_clnt *r = clp->cl_rpcclient;
190 char *p = svc_gss_principal(rqstp);
191
192 /*
193 * It might just be a normal user principal, in which case
194 * userspace won't bother to tell us the name at all.
195 */
196 if (p == NULL)
197 return SVC_DENIED;
198
199 /* Expect a GSS_C_NT_HOSTBASED_NAME like "nfs@serverhostname" */
200
201 if (memcmp(p, "nfs@", 4) != 0)
202 return SVC_DENIED;
203 p += 4;
204 if (strcmp(p, r->cl_server) != 0)
205 return SVC_DENIED;
206 return SVC_OK;
207}
208
185static int nfs_callback_authenticate(struct svc_rqst *rqstp) 209static int nfs_callback_authenticate(struct svc_rqst *rqstp)
186{ 210{
187 struct nfs_client *clp; 211 struct nfs_client *clp;
188 RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); 212 RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]);
213 int ret = SVC_OK;
189 214
190 /* Don't talk to strangers */ 215 /* Don't talk to strangers */
191 clp = nfs_find_client(svc_addr(rqstp), 4); 216 clp = nfs_find_client(svc_addr(rqstp), 4);
@@ -194,21 +219,22 @@ static int nfs_callback_authenticate(struct svc_rqst *rqstp)
194 219
195 dprintk("%s: %s NFSv4 callback!\n", __func__, 220 dprintk("%s: %s NFSv4 callback!\n", __func__,
196 svc_print_addr(rqstp, buf, sizeof(buf))); 221 svc_print_addr(rqstp, buf, sizeof(buf)));
197 nfs_put_client(clp);
198 222
199 switch (rqstp->rq_authop->flavour) { 223 switch (rqstp->rq_authop->flavour) {
200 case RPC_AUTH_NULL: 224 case RPC_AUTH_NULL:
201 if (rqstp->rq_proc != CB_NULL) 225 if (rqstp->rq_proc != CB_NULL)
202 return SVC_DENIED; 226 ret = SVC_DENIED;
203 break; 227 break;
204 case RPC_AUTH_UNIX: 228 case RPC_AUTH_UNIX:
205 break; 229 break;
206 case RPC_AUTH_GSS: 230 case RPC_AUTH_GSS:
207 /* FIXME: RPCSEC_GSS handling? */ 231 ret = check_gss_callback_principal(clp, rqstp);
232 break;
208 default: 233 default:
209 return SVC_DENIED; 234 ret = SVC_DENIED;
210 } 235 }
211 return SVC_OK; 236 nfs_put_client(clp);
237 return ret;
212} 238}
213 239
214/* 240/*