/* * Translate the sid string ("S-1-...") to the user@domain name, if * possible. */ static PyObject * py_sid_to_name(PyObject *self, PyObject *args) { int isuser, err, flag = IDMAP_REQ_FLG_USE_CACHE; char *name, *sid; idmap_stat stat; uid_t pid; PyObject *ret; if (!PyArg_ParseTuple(args, "si", &sid, &isuser)) return (NULL); err = sid_to_id(sid, isuser, &pid); if (err) { PyErr_SetString(PyExc_KeyError, sid); return (NULL); } if (isuser) stat = idmap_getwinnamebyuid(pid, flag, &name, NULL); else stat = idmap_getwinnamebygid(pid, flag, &name, NULL); if (stat < 0) { PyErr_SetString(PyExc_KeyError, sid); return (NULL); } if (name == NULL) { PyErr_SetString(PyExc_KeyError, sid); return (NULL); } ret = PyString_FromString(name); free(name); return (ret); }
static int getsidname(uid_t who, boolean_t user, char **sidp, boolean_t noresolve) { idmap_get_handle_t *get_hdl = NULL; idmap_stat status; idmap_rid_t rid; int error = IDMAP_ERR_NORESULT; int len; char *domain = NULL; *sidp = NULL; /* * First try and get windows name */ if (!noresolve) { if (user) error = idmap_getwinnamebyuid(who, IDMAP_REQ_FLG_USE_CACHE, sidp, NULL); else error = idmap_getwinnamebygid(who, IDMAP_REQ_FLG_USE_CACHE, sidp, NULL); } if (error != IDMAP_SUCCESS) { if (idmap_get_create(&get_hdl) == IDMAP_SUCCESS) { if (user) error = idmap_get_sidbyuid(get_hdl, who, IDMAP_REQ_FLG_USE_CACHE, &domain, &rid, &status); else error = idmap_get_sidbygid(get_hdl, who, IDMAP_REQ_FLG_USE_CACHE, &domain, &rid, &status); if (error == IDMAP_SUCCESS && idmap_get_mappings(get_hdl) == 0) { if (status == IDMAP_SUCCESS) { len = snprintf(NULL, 0, "%s-%d", domain, rid); if (*sidp = malloc(len + 1)) { (void) snprintf(*sidp, len + 1, "%s-%d", domain, rid); } } } } if (get_hdl) idmap_get_destroy(get_hdl); } free(domain); return (*sidp ? 0 : 1); }
/* ARGSUSED1 */ void nfsmapid_uid_str(struct mapid_arg *argp, size_t arg_size) { struct mapid_res result; struct mapid_res *resp; struct passwd pwd; struct passwd *pwd_ptr; char *pwd_buf = NULL; char *idmap_buf = NULL; uid_t uid = argp->u_arg.uid; size_t uid_str_len; char *pw_str; size_t pw_str_len; char *at_str; size_t at_str_len; char dom_str[DNAMEMAX]; size_t dom_str_len; idmap_stat rc; if (uid == (uid_t)-1) { /* * Sentinel uid is not a valid id */ resp = &result; resp->status = NFSMAPID_BADID; resp->u_res.len = 0; goto done; } /* * Make local copy of domain for further manipuation * NOTE: mapid_get_domain() returns a ptr to TSD. */ if (cur_domain_null()) { dom_str_len = 0; dom_str[0] = '\0'; } else { dom_str_len = strlcpy(dom_str, mapid_get_domain(), DNAMEMAX); } /* * If uid is ephemeral then resolve it using idmap service */ if (uid > UID_MAX) { rc = idmap_getwinnamebyuid(uid, &idmap_buf, NULL); if (rc != IDMAP_SUCCESS) { /* * We don't put stringified ephemeral uids on * the wire. */ resp = &result; resp->status = NFSMAPID_UNMAPPABLE; resp->u_res.len = 0; goto done; } /* * idmap_buf is already in the desired form i.e. name@domain */ pw_str = idmap_buf; pw_str_len = strlen(pw_str); at_str_len = dom_str_len = 0; at_str = ""; dom_str[0] = '\0'; goto gen_result; } /* * Handling non-ephemeral uids * * We want to encode the uid into a literal string... : * * - upon failure to allocate space from the heap * - if there is no current domain configured * - if there is no such uid in the passwd DB's */ if ((pwd_buf = malloc(pwd_buflen)) == NULL || dom_str_len == 0 || getpwuid_r(uid, &pwd, pwd_buf, pwd_buflen, &pwd_ptr) != 0 || pwd_ptr == NULL) { /* * If we could not allocate from the heap, try * allocating from the stack as a last resort. */ if (pwd_buf == NULL && (pwd_buf = alloca(MAPID_RES_LEN(UID_MAX_STR_LEN))) == NULL) { resp = &result; resp->status = NFSMAPID_INTERNAL; resp->u_res.len = 0; goto done; } /* * Constructing literal string without '@' so that * we'll know that it's not a user, but rather a * uid encoded string. */ pw_str = pwd_buf; (void) sprintf(pw_str, "%u", uid); pw_str_len = strlen(pw_str); at_str_len = dom_str_len = 0; at_str = ""; dom_str[0] = '\0'; } else { /* * Otherwise, we construct the "user@domain" string if * it's not already in that form. */ pw_str = pwd.pw_name; pw_str_len = strlen(pw_str); if (strchr(pw_str, '@') == NULL) { at_str = "@"; at_str_len = 1; } else { at_str_len = dom_str_len = 0; at_str = ""; dom_str[0] = '\0'; } } gen_result: uid_str_len = pw_str_len + at_str_len + dom_str_len; if ((resp = alloca(MAPID_RES_LEN(uid_str_len))) == NULL) { resp = &result; resp->status = NFSMAPID_INTERNAL; resp->u_res.len = 0; goto done; } /* LINTED format argument to sprintf */ (void) sprintf(resp->str, "%s%s%s", pw_str, at_str, dom_str); resp->u_res.len = uid_str_len; if (pwd_buf) free(pwd_buf); if (idmap_buf) idmap_free(idmap_buf); resp->status = NFSMAPID_OK; done: /* * There is a chance that the door_return will fail because the * resulting string is too large, try to indicate that if possible */ if (door_return((char *)resp, MAPID_RES_LEN(resp->u_res.len), NULL, 0) == -1) { resp->status = NFSMAPID_INTERNAL; resp->u_res.len = 0; (void) door_return((char *)&result, sizeof (struct mapid_res), NULL, 0); } }