diff options
Diffstat (limited to 'fs/nfs/callback.c')
-rw-r--r-- | fs/nfs/callback.c | 109 |
1 files changed, 29 insertions, 80 deletions
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 199016528fcb..e3d294269058 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c | |||
@@ -135,33 +135,6 @@ out_err: | |||
135 | 135 | ||
136 | #if defined(CONFIG_NFS_V4_1) | 136 | #if defined(CONFIG_NFS_V4_1) |
137 | /* | 137 | /* |
138 | * * CB_SEQUENCE operations will fail until the callback sessionid is set. | ||
139 | * */ | ||
140 | int nfs4_set_callback_sessionid(struct nfs_client *clp) | ||
141 | { | ||
142 | struct svc_serv *serv = clp->cl_rpcclient->cl_xprt->bc_serv; | ||
143 | struct nfs4_sessionid *bc_sid; | ||
144 | |||
145 | if (!serv->sv_bc_xprt) | ||
146 | return -EINVAL; | ||
147 | |||
148 | /* on success freed in xprt_free */ | ||
149 | bc_sid = kmalloc(sizeof(struct nfs4_sessionid), GFP_KERNEL); | ||
150 | if (!bc_sid) | ||
151 | return -ENOMEM; | ||
152 | memcpy(bc_sid->data, &clp->cl_session->sess_id.data, | ||
153 | NFS4_MAX_SESSIONID_LEN); | ||
154 | spin_lock_bh(&serv->sv_cb_lock); | ||
155 | serv->sv_bc_xprt->xpt_bc_sid = bc_sid; | ||
156 | spin_unlock_bh(&serv->sv_cb_lock); | ||
157 | dprintk("%s set xpt_bc_sid=%u:%u:%u:%u for sv_bc_xprt %p\n", __func__, | ||
158 | ((u32 *)bc_sid->data)[0], ((u32 *)bc_sid->data)[1], | ||
159 | ((u32 *)bc_sid->data)[2], ((u32 *)bc_sid->data)[3], | ||
160 | serv->sv_bc_xprt); | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | /* | ||
165 | * The callback service for NFSv4.1 callbacks | 138 | * The callback service for NFSv4.1 callbacks |
166 | */ | 139 | */ |
167 | static int | 140 | static int |
@@ -266,10 +239,6 @@ static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt, | |||
266 | struct nfs_callback_data *cb_info) | 239 | struct nfs_callback_data *cb_info) |
267 | { | 240 | { |
268 | } | 241 | } |
269 | int nfs4_set_callback_sessionid(struct nfs_client *clp) | ||
270 | { | ||
271 | return 0; | ||
272 | } | ||
273 | #endif /* CONFIG_NFS_V4_1 */ | 242 | #endif /* CONFIG_NFS_V4_1 */ |
274 | 243 | ||
275 | /* | 244 | /* |
@@ -359,78 +328,58 @@ void nfs_callback_down(int minorversion) | |||
359 | mutex_unlock(&nfs_callback_mutex); | 328 | mutex_unlock(&nfs_callback_mutex); |
360 | } | 329 | } |
361 | 330 | ||
362 | static int check_gss_callback_principal(struct nfs_client *clp, | 331 | /* Boolean check of RPC_AUTH_GSS principal */ |
363 | struct svc_rqst *rqstp) | 332 | int |
333 | check_gss_callback_principal(struct nfs_client *clp, struct svc_rqst *rqstp) | ||
364 | { | 334 | { |
365 | struct rpc_clnt *r = clp->cl_rpcclient; | 335 | struct rpc_clnt *r = clp->cl_rpcclient; |
366 | char *p = svc_gss_principal(rqstp); | 336 | char *p = svc_gss_principal(rqstp); |
367 | 337 | ||
338 | if (rqstp->rq_authop->flavour != RPC_AUTH_GSS) | ||
339 | return 1; | ||
340 | |||
368 | /* No RPC_AUTH_GSS on NFSv4.1 back channel yet */ | 341 | /* No RPC_AUTH_GSS on NFSv4.1 back channel yet */ |
369 | if (clp->cl_minorversion != 0) | 342 | if (clp->cl_minorversion != 0) |
370 | return SVC_DROP; | 343 | return 0; |
371 | /* | 344 | /* |
372 | * It might just be a normal user principal, in which case | 345 | * It might just be a normal user principal, in which case |
373 | * userspace won't bother to tell us the name at all. | 346 | * userspace won't bother to tell us the name at all. |
374 | */ | 347 | */ |
375 | if (p == NULL) | 348 | if (p == NULL) |
376 | return SVC_DENIED; | 349 | return 0; |
377 | 350 | ||
378 | /* Expect a GSS_C_NT_HOSTBASED_NAME like "nfs@serverhostname" */ | 351 | /* Expect a GSS_C_NT_HOSTBASED_NAME like "nfs@serverhostname" */ |
379 | 352 | ||
380 | if (memcmp(p, "nfs@", 4) != 0) | 353 | if (memcmp(p, "nfs@", 4) != 0) |
381 | return SVC_DENIED; | 354 | return 0; |
382 | p += 4; | 355 | p += 4; |
383 | if (strcmp(p, r->cl_server) != 0) | 356 | if (strcmp(p, r->cl_server) != 0) |
384 | return SVC_DENIED; | 357 | return 0; |
385 | return SVC_OK; | 358 | return 1; |
386 | } | 359 | } |
387 | 360 | ||
388 | /* pg_authenticate method helper */ | 361 | /* |
389 | static struct nfs_client *nfs_cb_find_client(struct svc_rqst *rqstp) | 362 | * pg_authenticate method for nfsv4 callback threads. |
390 | { | 363 | * |
391 | struct nfs4_sessionid *sessionid = bc_xprt_sid(rqstp); | 364 | * The authflavor has been negotiated, so an incorrect flavor is a server |
392 | int is_cb_compound = rqstp->rq_proc == CB_COMPOUND ? 1 : 0; | 365 | * bug. Drop packets with incorrect authflavor. |
393 | 366 | * | |
394 | dprintk("--> %s rq_proc %d\n", __func__, rqstp->rq_proc); | 367 | * All other checking done after NFS decoding where the nfs_client can be |
395 | if (svc_is_backchannel(rqstp)) | 368 | * found in nfs4_callback_compound |
396 | /* Sessionid (usually) set after CB_NULL ping */ | 369 | */ |
397 | return nfs4_find_client_sessionid(svc_addr(rqstp), sessionid, | ||
398 | is_cb_compound); | ||
399 | else | ||
400 | /* No callback identifier in pg_authenticate */ | ||
401 | return nfs4_find_client_no_ident(svc_addr(rqstp)); | ||
402 | } | ||
403 | |||
404 | /* pg_authenticate method for nfsv4 callback threads. */ | ||
405 | static int nfs_callback_authenticate(struct svc_rqst *rqstp) | 370 | static int nfs_callback_authenticate(struct svc_rqst *rqstp) |
406 | { | 371 | { |
407 | struct nfs_client *clp; | ||
408 | RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); | ||
409 | int ret = SVC_OK; | ||
410 | |||
411 | /* Don't talk to strangers */ | ||
412 | clp = nfs_cb_find_client(rqstp); | ||
413 | if (clp == NULL) | ||
414 | return SVC_DROP; | ||
415 | |||
416 | dprintk("%s: %s NFSv4 callback!\n", __func__, | ||
417 | svc_print_addr(rqstp, buf, sizeof(buf))); | ||
418 | |||
419 | switch (rqstp->rq_authop->flavour) { | 372 | switch (rqstp->rq_authop->flavour) { |
420 | case RPC_AUTH_NULL: | 373 | case RPC_AUTH_NULL: |
421 | if (rqstp->rq_proc != CB_NULL) | 374 | if (rqstp->rq_proc != CB_NULL) |
422 | ret = SVC_DENIED; | 375 | return SVC_DROP; |
423 | break; | 376 | break; |
424 | case RPC_AUTH_UNIX: | 377 | case RPC_AUTH_GSS: |
425 | break; | 378 | /* No RPC_AUTH_GSS support yet in NFSv4.1 */ |
426 | case RPC_AUTH_GSS: | 379 | if (svc_is_backchannel(rqstp)) |
427 | ret = check_gss_callback_principal(clp, rqstp); | 380 | return SVC_DROP; |
428 | break; | ||
429 | default: | ||
430 | ret = SVC_DENIED; | ||
431 | } | 381 | } |
432 | nfs_put_client(clp); | 382 | return SVC_OK; |
433 | return ret; | ||
434 | } | 383 | } |
435 | 384 | ||
436 | /* | 385 | /* |