diff options
author | Olga Kornievskaia <aglo@citi.umich.edu> | 2008-12-23 16:19:56 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-12-23 16:19:56 -0500 |
commit | 2efef7080f471d312a9c4feb3dc5ee038039c7ed (patch) | |
tree | cad946aa12f1780818d396c732d17ad9db642607 | |
parent | 8b1c7bf5b624c9bc91b41ae577b9fc5c21641705 (diff) |
rpc: add service field to new upcall
This patch extends the new upcall with a "service" field that currently
can have 2 values: "*" or "nfs". These values specify matching rules for
principals in the keytab file. The "*" means that gssd is allowed to use
"root", "nfs", or "host" keytab entries while the other option requires
"nfs".
Restricting gssd to use the "nfs" principal is needed for when the
server performs a callback to the client. The server in this case has
to authenticate itself as an "nfs" principal.
We also need "service" field to distiguish between two client-side cases
both currently using a uid of 0: the case of regular file access by the
root user, and the case of state-management calls (such as setclientid)
which should use a keytab for authentication. (And the upcall should
fail if an appropriate principal can't be found.)
Signed-off: Olga Kornievskaia <aglo@citi.umich.edu>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 1e8cced55ff..e630b38a604 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -369,7 +369,7 @@ static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg) | |||
369 | } | 369 | } |
370 | 370 | ||
371 | static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg, | 371 | static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg, |
372 | struct rpc_clnt *clnt) | 372 | struct rpc_clnt *clnt, int machine_cred) |
373 | { | 373 | { |
374 | char *p = gss_msg->databuf; | 374 | char *p = gss_msg->databuf; |
375 | int len = 0; | 375 | int len = 0; |
@@ -383,6 +383,15 @@ static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg, | |||
383 | p += len; | 383 | p += len; |
384 | gss_msg->msg.len += len; | 384 | gss_msg->msg.len += len; |
385 | } | 385 | } |
386 | if (machine_cred) { | ||
387 | len = sprintf(p, "service=* "); | ||
388 | p += len; | ||
389 | gss_msg->msg.len += len; | ||
390 | } else if (!strcmp(clnt->cl_program->name, "nfs4_cb")) { | ||
391 | len = sprintf(p, "service=nfs "); | ||
392 | p += len; | ||
393 | gss_msg->msg.len += len; | ||
394 | } | ||
386 | len = sprintf(p, "\n"); | 395 | len = sprintf(p, "\n"); |
387 | gss_msg->msg.len += len; | 396 | gss_msg->msg.len += len; |
388 | 397 | ||
@@ -391,16 +400,17 @@ static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg, | |||
391 | } | 400 | } |
392 | 401 | ||
393 | static void gss_encode_msg(struct gss_upcall_msg *gss_msg, | 402 | static void gss_encode_msg(struct gss_upcall_msg *gss_msg, |
394 | struct rpc_clnt *clnt) | 403 | struct rpc_clnt *clnt, int machine_cred) |
395 | { | 404 | { |
396 | if (pipe_version == 0) | 405 | if (pipe_version == 0) |
397 | gss_encode_v0_msg(gss_msg); | 406 | gss_encode_v0_msg(gss_msg); |
398 | else /* pipe_version == 1 */ | 407 | else /* pipe_version == 1 */ |
399 | gss_encode_v1_msg(gss_msg, clnt); | 408 | gss_encode_v1_msg(gss_msg, clnt, machine_cred); |
400 | } | 409 | } |
401 | 410 | ||
402 | static inline struct gss_upcall_msg * | 411 | static inline struct gss_upcall_msg * |
403 | gss_alloc_msg(struct gss_auth *gss_auth, uid_t uid, struct rpc_clnt *clnt) | 412 | gss_alloc_msg(struct gss_auth *gss_auth, uid_t uid, struct rpc_clnt *clnt, |
413 | int machine_cred) | ||
404 | { | 414 | { |
405 | struct gss_upcall_msg *gss_msg; | 415 | struct gss_upcall_msg *gss_msg; |
406 | int vers; | 416 | int vers; |
@@ -420,7 +430,7 @@ gss_alloc_msg(struct gss_auth *gss_auth, uid_t uid, struct rpc_clnt *clnt) | |||
420 | atomic_set(&gss_msg->count, 1); | 430 | atomic_set(&gss_msg->count, 1); |
421 | gss_msg->uid = uid; | 431 | gss_msg->uid = uid; |
422 | gss_msg->auth = gss_auth; | 432 | gss_msg->auth = gss_auth; |
423 | gss_encode_msg(gss_msg, clnt); | 433 | gss_encode_msg(gss_msg, clnt, machine_cred); |
424 | return gss_msg; | 434 | return gss_msg; |
425 | } | 435 | } |
426 | 436 | ||
@@ -432,11 +442,7 @@ gss_setup_upcall(struct rpc_clnt *clnt, struct gss_auth *gss_auth, struct rpc_cr | |||
432 | struct gss_upcall_msg *gss_new, *gss_msg; | 442 | struct gss_upcall_msg *gss_new, *gss_msg; |
433 | uid_t uid = cred->cr_uid; | 443 | uid_t uid = cred->cr_uid; |
434 | 444 | ||
435 | /* Special case: rpc.gssd assumes that uid == 0 implies machine creds */ | 445 | gss_new = gss_alloc_msg(gss_auth, uid, clnt, gss_cred->gc_machine_cred); |
436 | if (gss_cred->gc_machine_cred != 0) | ||
437 | uid = 0; | ||
438 | |||
439 | gss_new = gss_alloc_msg(gss_auth, uid, clnt); | ||
440 | if (IS_ERR(gss_new)) | 446 | if (IS_ERR(gss_new)) |
441 | return gss_new; | 447 | return gss_new; |
442 | gss_msg = gss_add_msg(gss_auth, gss_new); | 448 | gss_msg = gss_add_msg(gss_auth, gss_new); |