static int do_svc_downcall(gss_buffer_desc *out_handle, struct svc_cred *cred, gss_OID mech, gss_buffer_desc *context_token, int32_t endtime, char *client_name) { FILE *f; int i; char *fname = NULL; int err; printerr(1, "doing downcall\n"); if ((fname = mech2file(mech)) == NULL) goto out_err; f = fopen(SVCGSSD_CONTEXT_CHANNEL, "w"); if (f == NULL) { printerr(0, "WARNING: unable to open downcall channel " "%s: %s\n", SVCGSSD_CONTEXT_CHANNEL, strerror(errno)); goto out_err; } qword_printhex(f, out_handle->value, out_handle->length); /* XXX are types OK for the rest of this? */ /* For context cache, use the actual context endtime */ qword_printint(f, endtime); qword_printint(f, cred->cr_uid); qword_printint(f, cred->cr_gid); qword_printint(f, cred->cr_ngroups); printerr(2, "mech: %s, hndl len: %d, ctx len %d, timeout: %d (%d from now), " "clnt: %s, uid: %d, gid: %d, num aux grps: %d:\n", fname, out_handle->length, context_token->length, endtime, endtime - time(0), client_name ? client_name : "<null>", cred->cr_uid, cred->cr_gid, cred->cr_ngroups); for (i=0; i < cred->cr_ngroups; i++) { qword_printint(f, cred->cr_groups[i]); printerr(2, " (%4d) %d\n", i+1, cred->cr_groups[i]); } qword_print(f, fname); qword_printhex(f, context_token->value, context_token->length); if (client_name) qword_print(f, client_name); err = qword_eol(f); if (err) { printerr(1, "WARNING: error writing to downcall channel " "%s: %s\n", SVCGSSD_CONTEXT_CHANNEL, strerror(errno)); } fclose(f); return err; out_err: printerr(1, "WARNING: downcall failed\n"); return -1; }
static int 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; uid_t uid, gid; gss_OID name_type = GSS_C_NO_OID; char *secname; maj_stat = gss_display_name(&min_stat, client_name, &name, &name_type); if (maj_stat != GSS_S_COMPLETE) { pgsserr("get_ids: gss_display_name", maj_stat, min_stat, mech); goto out; } if (name.length >= 0xffff || /* be certain name.length+1 doesn't overflow */ !(sname = calloc(name.length + 1, 1))) { printerr(0, "WARNING: get_ids: error allocating %d bytes " "for sname\n", name.length + 1); gss_release_buffer(&min_stat, &name); goto out; } memcpy(sname, name.value, name.length); printerr(1, "sname = %s\n", sname); gss_release_buffer(&min_stat, &name); res = -EINVAL; if ((secname = mech2file(mech)) == NULL) { printerr(0, "WARNING: get_ids: error mapping mech to " "file for name '%s'\n", sname); 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) { /* * -ENOENT means there was no mapping, any other error * value means there was an error trying to do the * mapping. * If there was no mapping, we send down the value -1 * to indicate that the anonuid/anongid for the export * should be used. */ if (res == -ENOENT) { cred->cr_uid = -1; cred->cr_gid = -1; cred->cr_ngroups = 0; res = 0; goto out_free; } printerr(1, "WARNING: get_ids: failed to map name '%s' " "to uid/gid: %s\n", sname, strerror(-res)); goto out_free; } cred->cr_uid = uid; cred->cr_gid = gid; add_supplementary_groups(secname, sname, cred); res = 0; out_free: free(sname); out: return res; }