/* * Find the name@domain string from either a user or group id */ int name_lookup(char *id, key_serial_t key, int type) { char name[IDMAP_NAMESZ]; char domain[NFS4_MAX_DOMAIN_LEN]; uid_t uid; gid_t gid; int rc; rc = nfs4_get_default_domain(NULL, domain, NFS4_MAX_DOMAIN_LEN); if (rc != 0) { xlog_errno(rc, "name_lookup: nfs4_get_default_domain failed: %m"); rc = -1; goto out; } if (type == USER) { uid = atoi(id); rc = nfs4_uid_to_name(uid, domain, name, IDMAP_NAMESZ); } else { gid = atoi(id); rc = nfs4_gid_to_name(gid, domain, name, IDMAP_NAMESZ); } if (rc < 0) xlog_errno(rc, "name_lookup: %s: failed: %m", (type == USER ? "nfs4_uid_to_name" : "nfs4_gid_to_name")); if (rc == 0) { rc = keyctl_instantiate(key, &name, strlen(name), 0); if (rc < 0) xlog_err("name_lookup: keyctl_instantiate failed: %m"); } out: return rc; }
/** * * gid2name: convert a gid to a name. * * convert a uid to a name. * * @param name [OUT] the name of the user * @param gid [IN] the input gid * * return 1 if successful, 0 otherwise * */ int gid2name(char *name, gid_t * pgid) { #ifndef _USE_NFSIDMAP struct group g; #ifndef _SOLARIS struct group *pg = NULL; #endif static char buff[NFS4_MAX_DOMAIN_LEN]; /* Working area for getgrnam_r */ #endif #ifdef _USE_NFSIDMAP int rc; if(gnamemap_get(*pgid, name) == ID_MAPPER_SUCCESS) { LogFullDebug(COMPONENT_IDMAPPER, "gid2name: unamemap_get gid %d returned %s", *pgid, name); return 1; } else { if(!nfsidmap_set_conf()) { LogCrit(COMPONENT_IDMAPPER, "gid2name: nfsidmap_set_conf failed"); return 0; } rc = nfs4_gid_to_name(*pgid, idmap_domain, name, NFS4_MAX_DOMAIN_LEN); if(rc != 0) { LogDebug(COMPONENT_IDMAPPER, "gid2name: nfs4_gid_to_name %d returned %d (%s)", *pgid, -rc, strerror(-rc)); return 0; } LogFullDebug(COMPONENT_IDMAPPER, "gid2name: nfs4_gid_to_name gid %d returned %s", *pgid, name); if(gidmap_add(name, *pgid) != ID_MAPPER_SUCCESS) { LogCrit(COMPONENT_IDMAPPER, "gid2name: gidmap_add %s %d failed", name, *pgid); return 0; } } return 1; #else if(gnamemap_get(*pgid, name) == ID_MAPPER_SUCCESS) { LogFullDebug(COMPONENT_IDMAPPER, "gid2name: gnamemap_get gid %d returned %s", *pgid, name); return 1; } else { #ifdef _SOLARIS if(getgrgid_r(*pgid, &g, buff, NFS4_MAX_DOMAIN_LEN) != 0) #else if((getgrgid_r(*pgid, &g, buff, NFS4_MAX_DOMAIN_LEN, &pg) != 0) || (pg == NULL)) #endif /* _SOLARIS */ { LogFullDebug(COMPONENT_IDMAPPER, "gid2name: getgrgid_r %d failed", *pgid); return 0; } strncpy(name, g.gr_name, NFS4_MAX_DOMAIN_LEN); LogFullDebug(COMPONENT_IDMAPPER, "gid2name: getgrgid_r gid %d returned %s", *pgid, name); if(gidmap_add(name, *pgid) != ID_MAPPER_SUCCESS) { LogCrit(COMPONENT_IDMAPPER, "gid2name: gidmap_add %s %d failed", name, *pgid); return 0; } } return 1; #endif /* _USE_NFSIDMAP */ } /* gid2name */
static bool xdr_encode_nfs4_princ(XDR *xdrs, uint32_t id, bool group) { const struct gsh_buffdesc *found; uint32_t not_a_size_t; bool success = false; PTHREAD_RWLOCK_rdlock(group ? &idmapper_group_lock : &idmapper_user_lock); if (group) success = idmapper_lookup_by_gid(id, &found); else success = idmapper_lookup_by_uid(id, &found, NULL); if (likely(success)) { not_a_size_t = found->len; /* Fully qualified owners are always stored in the hash table, no matter what our lookup method. */ success = inline_xdr_bytes(xdrs, (char **)&found->addr, ¬_a_size_t, UINT32_MAX); PTHREAD_RWLOCK_unlock(group ? &idmapper_group_lock : &idmapper_user_lock); return success; } else { PTHREAD_RWLOCK_unlock(group ? &idmapper_group_lock : &idmapper_user_lock); int rc; int size; bool looked_up = false; char *namebuff = NULL; struct gsh_buffdesc new_name; if (nfs_param.nfsv4_param.use_getpwnam) { if (group) size = sysconf(_SC_GETGR_R_SIZE_MAX); else size = sysconf(_SC_GETPW_R_SIZE_MAX); if (size == -1) size = PWENT_BEST_GUESS_LEN; new_name.len = size; size += owner_domain.len + 2; } else { size = NFS4_MAX_DOMAIN_LEN + 2; } namebuff = alloca(size); new_name.addr = namebuff; if (nfs_param.nfsv4_param.use_getpwnam) { char *cursor; bool nulled; if (group) { struct group g; struct group *gres; rc = getgrgid_r(id, &g, namebuff, new_name.len, &gres); nulled = (gres == NULL); } else { struct passwd p; struct passwd *pres; rc = getpwuid_r(id, &p, namebuff, new_name.len, &pres); nulled = (pres == NULL); } if ((rc == 0) && !nulled) { new_name.len = strlen(namebuff); cursor = namebuff + new_name.len; *(cursor++) = '@'; ++new_name.len; memcpy(cursor, owner_domain.addr, owner_domain.len); new_name.len += owner_domain.len; looked_up = true; } else { LogInfo(COMPONENT_IDMAPPER, "%s failed with code %d.", (group ? "getgrgid_r" : "getpwuid_r"), rc); } } else { #ifdef USE_NFSIDMAP if (group) { rc = nfs4_gid_to_name(id, owner_domain.addr, namebuff, NFS4_MAX_DOMAIN_LEN + 1); } else { rc = nfs4_uid_to_name(id, owner_domain.addr, namebuff, NFS4_MAX_DOMAIN_LEN + 1); } if (rc == 0) { new_name.len = strlen(namebuff); looked_up = true; } else { LogInfo(COMPONENT_IDMAPPER, "%s failed with code %d.", (group ? "nfs4_gid_to_name" : "nfs4_uid_to_name"), rc); } #else /* USE_NFSIDMAP */ looked_up = false; #endif /* !USE_NFSIDMAP */ } if (!looked_up) { if (nfs_param.nfsv4_param.allow_numeric_owners) { LogInfo(COMPONENT_IDMAPPER, "Lookup for %d failed, using numeric %s", id, (group ? "group" : "owner")); /* 2**32 is 10 digits long in decimal */ sprintf(namebuff, "%u", id); new_name.len = strlen(namebuff); } else { LogInfo(COMPONENT_IDMAPPER, "Lookup for %d failed, using nobody.", id); memcpy(new_name.addr, "nobody", 6); new_name.len = 6; } } /* Add to the cache and encode the result. */ PTHREAD_RWLOCK_wrlock(group ? &idmapper_group_lock : &idmapper_user_lock); if (group) success = idmapper_add_group(&new_name, id); else success = idmapper_add_user(&new_name, id, NULL, false); PTHREAD_RWLOCK_unlock(group ? &idmapper_group_lock : &idmapper_user_lock); if (unlikely(!success)) { LogMajor(COMPONENT_IDMAPPER, "%s failed.", group ? "idmapper_add_group" : "idmaper_add_user"); } not_a_size_t = new_name.len; return inline_xdr_bytes(xdrs, (char **)&new_name.addr, ¬_a_size_t, UINT32_MAX); } }