void nfsmapid_str_uid(struct mapid_arg *argp, size_t arg_size) { struct mapid_res result; struct passwd pwd; struct passwd *pwd_ptr; int pwd_rc; char *pwd_buf; char *user; char *domain; idmap_stat rc; if (argp->u_arg.len <= 0 || arg_size < MAPID_ARG_LEN(argp->u_arg.len)) { result.status = NFSMAPID_INVALID; result.u_res.uid = UID_NOBODY; goto done; } if (!extract_domain(argp->str, &user, &domain)) { unsigned long id; /* * Invalid "user@domain" string. Still, the user * part might be an encoded uid, so do a final check. * Remember, domain part of string was not set since * not a valid string. */ if (!validate_id_str(user)) { result.status = NFSMAPID_UNMAPPABLE; result.u_res.uid = UID_NOBODY; goto done; } errno = 0; id = strtoul(user, (char **)NULL, 10); /* * We don't accept ephemeral ids from the wire. */ if (errno || id > UID_MAX) { result.status = NFSMAPID_UNMAPPABLE; result.u_res.uid = UID_NOBODY; goto done; } result.u_res.uid = (uid_t)id; result.status = NFSMAPID_NUMSTR; goto done; } /* * String properly constructed. Now we check for domain and * group validity. */ if (!cur_domain_null() && !valid_domain(domain)) { /* * If the domain part of the string does not * match the NFS domain, try to map it using * idmap service. */ rc = idmap_getuidbywinname(user, domain, &result.u_res.uid); if (rc != IDMAP_SUCCESS) { result.status = NFSMAPID_BADDOMAIN; result.u_res.uid = UID_NOBODY; goto done; } result.status = NFSMAPID_OK; goto done; } if ((pwd_buf = malloc(pwd_buflen)) == NULL || (pwd_rc = getpwnam_r(user, &pwd, pwd_buf, pwd_buflen, &pwd_ptr)) != 0 || pwd_ptr == NULL) { if (pwd_buf == NULL || pwd_rc != 0) result.status = NFSMAPID_INTERNAL; else { /* * Not a valid user */ result.status = NFSMAPID_NOTFOUND; free(pwd_buf); } result.u_res.uid = UID_NOBODY; goto done; } /* * Valid user entry */ result.u_res.uid = pwd.pw_uid; result.status = NFSMAPID_OK; free(pwd_buf); done: (void) door_return((char *)&result, sizeof (struct mapid_res), NULL, 0); }
/* * Convert a group utf-8 string identifier into its local gid. */ int nfs_idmap_str_gid(utf8string *u8s, gid_t *gid) { struct mapid_arg *mapargp; struct mapid_res mapres; struct mapid_res *mapresp = &mapres; struct mapid_res *resp = mapresp; door_arg_t door_args; int doorfd; int error = 0; static int msg_done = 0; if (!u8s || !u8s->utf8string_val || !u8s->utf8string_len || (u8s->utf8string_val[0] == '\0')) { error = EINVAL; goto s2g_done; } if (bcmp(u8s->utf8string_val, "nobody", 6) == 0) { /* * If "nobody", just short circuit and bail */ *gid = GID_NOBODY; goto s2g_done; } if ((mapargp = malloc(MAPID_ARG_LEN(u8s->utf8string_len))) == NULL) { (void) fprintf(stderr, "Unable to malloc %d bytes\n", MAPID_ARG_LEN(u8s->utf8string_len)); error = ENOMEM; goto s2g_done; } mapargp->cmd = NFSMAPID_STR_GID; mapargp->u_arg.len = u8s->utf8string_len; (void) bcopy(u8s->utf8string_val, mapargp->str, mapargp->u_arg.len); mapargp->str[mapargp->u_arg.len] = '\0'; door_args.data_ptr = (char *)mapargp; door_args.data_size = MAPID_ARG_LEN(mapargp->u_arg.len); door_args.desc_ptr = NULL; door_args.desc_num = 0; door_args.rbuf = (char *)mapresp; door_args.rsize = sizeof (struct mapid_res); /* * call to the nfsmapid daemon */ if ((doorfd = nfs_idmap_doorget()) == -1) { if (!msg_done) { fprintf(stderr, "nfs_idmap_str_uid: Can't communicate" " with mapping daemon nfsmapid\n"); msg_done = 1; } error = ECOMM; free(mapargp); goto s2g_done; } if (door_call(doorfd, &door_args) == -1) { perror("door_call failed"); error = EINVAL; free(mapargp); goto s2g_done; } free(mapargp); resp = (struct mapid_res *)door_args.rbuf; switch (resp->status) { case NFSMAPID_OK: *gid = resp->u_res.gid; break; case NFSMAPID_NUMSTR: *gid = resp->u_res.gid; error = resp->status; goto out; default: case NFSMAPID_UNMAPPABLE: case NFSMAPID_INVALID: case NFSMAPID_INTERNAL: case NFSMAPID_BADDOMAIN: case NFSMAPID_BADID: case NFSMAPID_NOTFOUND: error = resp->status; goto s2g_done; } s2g_done: if (error) *gid = GID_NOBODY; out: if (resp != mapresp) munmap(door_args.rbuf, door_args.rsize); return (error); }
void nfsmapid_str_gid(struct mapid_arg *argp, size_t arg_size) { struct mapid_res result; struct group grp; struct group *grp_ptr; int grp_rc; char *grp_buf; char *group; char *domain; idmap_stat rc; if (argp->u_arg.len <= 0 || arg_size < MAPID_ARG_LEN(argp->u_arg.len)) { result.status = NFSMAPID_INVALID; result.u_res.gid = GID_NOBODY; goto done; } if (!extract_domain(argp->str, &group, &domain)) { unsigned long id; /* * Invalid "group@domain" string. Still, the * group part might be an encoded gid, so do a * final check. Remember, domain part of string * was not set since not a valid string. */ if (!validate_id_str(group)) { result.status = NFSMAPID_UNMAPPABLE; result.u_res.gid = GID_NOBODY; goto done; } errno = 0; id = strtoul(group, (char **)NULL, 10); /* * We don't accept ephemeral ids from the wire. */ if (errno || id > UID_MAX) { result.status = NFSMAPID_UNMAPPABLE; result.u_res.gid = GID_NOBODY; goto done; } result.u_res.gid = (gid_t)id; result.status = NFSMAPID_NUMSTR; goto done; } /* * String properly constructed. Now we check for domain and * group validity. */ if (!cur_domain_null() && !valid_domain(domain)) { /* * If the domain part of the string does not * match the NFS domain, try to map it using * idmap service. */ rc = idmap_getgidbywinname(group, domain, &result.u_res.gid); if (rc != IDMAP_SUCCESS) { result.status = NFSMAPID_BADDOMAIN; result.u_res.gid = GID_NOBODY; goto done; } result.status = NFSMAPID_OK; goto done; } if ((grp_buf = malloc(grp_buflen)) == NULL || (grp_rc = getgrnam_r(group, &grp, grp_buf, grp_buflen, &grp_ptr)) != 0 || grp_ptr == NULL) { if (grp_buf == NULL || grp_rc != 0) result.status = NFSMAPID_INTERNAL; else { /* * Not a valid group */ result.status = NFSMAPID_NOTFOUND; free(grp_buf); } result.u_res.gid = GID_NOBODY; goto done; } /* * Valid group entry */ result.status = NFSMAPID_OK; result.u_res.gid = grp.gr_gid; free(grp_buf); done: (void) door_return((char *)&result, sizeof (struct mapid_res), NULL, 0); }