X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=utils%2Fsvcgssd%2Fsvcgssd_proc.c;h=8faddc1321ac3cded03e4ae9b63ae7912286a2b9;hb=e873a11144f5cbfa6b54a3b2eb3af131cbd5ebbd;hp=c2470c60f42604f6a8bf5880db1c3a520d6c5b3d;hpb=f1bfe0916c04d93de7a4fae5315fff6e4ccac23f;p=nfs-utils.git diff --git a/utils/svcgssd/svcgssd_proc.c b/utils/svcgssd/svcgssd_proc.c index c2470c6..8faddc1 100644 --- a/utils/svcgssd/svcgssd_proc.c +++ b/utils/svcgssd/svcgssd_proc.c @@ -44,6 +44,7 @@ #include #include #include +#include #include "svcgssd.h" #include "gss_util.h" @@ -63,6 +64,7 @@ extern char * mech2file(gss_OID mech); struct svc_cred { uid_t cr_uid; gid_t cr_gid; + int cr_ngroups; gid_t cr_groups[NGROUPS]; }; @@ -71,7 +73,7 @@ do_svc_downcall(gss_buffer_desc *out_handle, struct svc_cred *cred, gss_OID mech, gss_buffer_desc *context_token) { FILE *f; - int i, ngroups; + int i; char *fname = NULL; printerr(1, "doing downcall\n"); @@ -89,15 +91,8 @@ do_svc_downcall(gss_buffer_desc *out_handle, struct svc_cred *cred, qword_printint(f, 0x7fffffff); /*XXX need a better timeout */ qword_printint(f, cred->cr_uid); qword_printint(f, cred->cr_gid); - ngroups = NGROUPS; - for (i=0; i < NGROUPS; i++) { - if (cred->cr_groups[i] == NOGROUP) { - ngroups = i; - break; - } - } - qword_printint(f, ngroups); - for (i=0; i < ngroups; i++) + qword_printint(f, cred->cr_ngroups); + for (i=0; i < cred->cr_ngroups; i++) qword_printint(f, cred->cr_groups[i]); qword_print(f, fname); qword_printhex(f, context_token->value, context_token->length); @@ -167,17 +162,16 @@ send_response(FILE *f, gss_buffer_desc *in_handle, gss_buffer_desc *in_token, #define rpcsec_gsserr_credproblem 13 #define rpcsec_gsserr_ctxproblem 14 -/* XXX memory leaks everywhere: */ static int -get_ids(gss_name_t client_name, gss_OID *mech, struct svc_cred *cred) +get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred) { u_int32_t maj_stat, min_stat; gss_buffer_desc name; char *sname; int res = -1; - struct passwd *pw = NULL; + uid_t uid, gid; gss_OID name_type; - char *c; + char *secname; maj_stat = gss_display_name(&min_stat, client_name, &name, &name_type); if (maj_stat != GSS_S_COMPLETE) @@ -186,20 +180,21 @@ get_ids(gss_name_t client_name, gss_OID *mech, struct svc_cred *cred) goto out; memcpy(sname, name.value, name.length); printerr(1, "sname = %s\n", sname); - /* XXX: should use same mapping as idmapd? Or something; for now - * I'm just chopping off the domain. */ - /* XXX: note that idmapd also does this! It doesn't check the domain - * name. */ - if ((c = strchr(sname, '@')) != NULL) - *c = '\0'; - /* XXX? mapping unknown users (including machine creds) to nobody: */ - if ( !(pw = getpwnam(sname)) && !(pw = getpwnam("nobody")) ) - goto out; - cred->cr_uid = pw->pw_uid; - cred->cr_gid = pw->pw_gid; - /* XXX Read password file? Use initgroups? I dunno...*/ - cred->cr_groups[0] = NOGROUP; + + res = -EINVAL; + if ((secname = mech2file(mech)) == NULL) + goto out_free; + nfs4_init_name_mapping(NULL); /* XXX: should only do this once */ + res = nfs4_gss_princ_to_ids(secname, sname, &uid, &gid); + if (res < 0) + goto out_free; + cred->cr_uid = uid; + cred->cr_gid = gid; + /*XXX: want add_supplementary_groups(secname, sname, cred)? */ + cred->cr_ngroups = 0; res = 0; +out_free: + free(sname); out: if (res) printerr(0, "WARNING: get_uid failed\n"); @@ -315,7 +310,7 @@ handle_nullreq(FILE *f) { &null_token, &null_token); goto out_err; } - if (get_ids(client_name, &mech, &cred)) { + if (get_ids(client_name, mech, &cred)) { printerr(0, "WARNING: handle_nullreq: get_uid failed\n"); send_response(f, &in_handle, &in_tok, GSS_S_BAD_NAME /* XXX? */, 0, &null_token, &null_token);