#include <string.h>
#include <fcntl.h>
#include <errno.h>
+#include <nfsidmap.h>
#include "svcgssd.h"
#include "gss_util.h"
struct svc_cred {
uid_t cr_uid;
gid_t cr_gid;
+ int cr_ngroups;
gid_t cr_groups[NGROUPS];
};
gss_OID mech, gss_buffer_desc *context_token)
{
FILE *f;
- int i, ngroups;
+ int i;
char *fname = NULL;
printerr(1, "doing downcall\n");
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);
#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)
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");
&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);