/* Test with `getcifsacl file` on client. */ int cifs_idmap_sid_to_str(void *handle, const struct cifs_sid *csid, char **name) { struct sssd_ctx *ctx = handle; enum idmap_error_code iderr; char *sid; enum sss_id_type id_type; int err; iderr = sss_idmap_bin_sid_to_sid(ctx->idmap, (const uint8_t *) csid, sizeof(*csid), &sid); if (iderr != IDMAP_SUCCESS) { ctx_set_error(ctx, idmap_error_string(iderr)); *name = NULL; return -1; } debug("sid: %s", sid); err = sss_nss_getnamebysid(sid, name, &id_type); if (err != 0) { ctx_set_error(ctx, strerror(err)); *name = NULL; return -err; } /* FIXME: Map Samba Unix SIDs? (sid->id and use getpwuid)? */ debug("name: %s", *name); return 0; }
/* Convert a SID to a domain and name */ wbcErr wbcLookupSid(const struct wbcDomainSid *sid, char **pdomain, char **pname, enum wbcSidType *pname_type) { char *str_sid; char *fq_name = NULL; enum sss_id_type type; int ret; char *p; wbcErr wbc_status; wbc_status = wbcSidToString(sid, &str_sid); if (!WBC_ERROR_IS_OK(wbc_status)) { return wbc_status; } ret = sss_nss_getnamebysid(str_sid, &fq_name, &type); wbcFreeMemory(str_sid); if (ret != 0) { return WBC_ERR_UNKNOWN_FAILURE; } if (pname_type != NULL) { ret = sss_id_type_to_wbcSidType(type, pname_type); if (ret != 0) { wbc_status = WBC_ERR_UNKNOWN_FAILURE; goto done; } } /* TODO: it would be nice to have an sss_nss_getnamebysid() call which * returns name and domain separately. */ p = strchr(fq_name, '@'); if (p == NULL) { wbc_status = WBC_ERR_UNKNOWN_FAILURE; goto done; } *p = '\0'; if (pname != NULL) { *pname = wbcStrDup(fq_name); if (*pname == NULL) { wbc_status = WBC_ERR_NO_MEMORY; goto done; } } if (pdomain != NULL) { *pdomain = wbcStrDup(p + 1); if (*pdomain == NULL) { wbcFreeMemory(*pname); wbc_status = WBC_ERR_NO_MEMORY; goto done; } } wbc_status = WBC_ERR_SUCCESS; done: free(fq_name); return wbc_status; }
int handle_request(struct ipa_extdom_ctx *ctx, struct extdom_req *req, struct extdom_res **res) { int ret; char *domain_name = NULL; char *sid_str = NULL; size_t buf_len; char *buf = NULL; long pw_max; long gr_max; struct pwd_grp pg_data; struct passwd *pwd_result = NULL; struct group *grp_result = NULL; enum sss_id_type id_type; char *fq_name = NULL; char *sep; pw_max = sysconf(_SC_GETPW_R_SIZE_MAX); gr_max = sysconf(_SC_GETGR_R_SIZE_MAX); if (pw_max == -1 && gr_max == -1) { buf_len = 16384; } else { buf_len = MAX(pw_max, gr_max); } buf = malloc(sizeof(char) * buf_len); if (buf == NULL) { return LDAP_OPERATIONS_ERROR; } switch (req->input_type) { case INP_POSIX_UID: if (req->request_type == REQ_SIMPLE) { ret = sss_nss_getsidbyid(req->data.posix_uid.uid, &sid_str, &id_type); } else { id_type = SSS_ID_TYPE_UID; ret = getpwuid_r(req->data.posix_uid.uid, &pg_data.data.pwd, buf, buf_len, &pwd_result); } domain_name = strdup(req->data.posix_uid.domain_name); break; case INP_POSIX_GID: if (req->request_type == REQ_SIMPLE) { ret = sss_nss_getsidbyid(req->data.posix_uid.uid, &sid_str, &id_type); } else { id_type = SSS_ID_TYPE_GID; ret = getgrgid_r(req->data.posix_gid.gid, &pg_data.data.grp, buf, buf_len, &grp_result); } domain_name = strdup(req->data.posix_gid.domain_name); break; case INP_SID: ret = sss_nss_getnamebysid(req->data.sid, &fq_name, &id_type); if (ret != 0) { ret = LDAP_OPERATIONS_ERROR; goto done; } sep = strrchr(fq_name, SSSD_DOMAIN_SEPARATOR); if (sep == NULL) { ret = LDAP_OPERATIONS_ERROR; goto done; } ret = asprintf(&domain_name, "%s", sep+1); if (ret == -1) { ret = LDAP_OPERATIONS_ERROR; domain_name = NULL; /* content is undefined according to asprintf(3) */ goto done; } switch(id_type) { case SSS_ID_TYPE_UID: case SSS_ID_TYPE_BOTH: ret = getpwnam_r(fq_name, &pg_data.data.pwd, buf, buf_len, &pwd_result); break; case SSS_ID_TYPE_GID: ret = getgrnam_r(fq_name, &pg_data.data.grp, buf, buf_len, &grp_result); break; default: ret = LDAP_OPERATIONS_ERROR; goto done; } break; case INP_NAME: ret = asprintf(&fq_name, "%s%c%s", req->data.name.object_name, SSSD_DOMAIN_SEPARATOR, req->data.name.domain_name); if (ret == -1) { ret = LDAP_OPERATIONS_ERROR; fq_name = NULL; /* content is undefined according to asprintf(3) */ goto done; } if (req->request_type == REQ_SIMPLE) { ret = sss_nss_getsidbyname(fq_name, &sid_str, &id_type); } else { id_type = SSS_ID_TYPE_UID; ret = getpwnam_r(fq_name, &pg_data.data.pwd, buf, buf_len, &pwd_result); if (ret == 0 && pwd_result == NULL) { /* no user entry found */ id_type = SSS_ID_TYPE_GID; ret = getgrnam_r(fq_name, &pg_data.data.grp, buf, buf_len, &grp_result); } } domain_name = strdup(req->data.name.domain_name); break; default: ret = LDAP_PROTOCOL_ERROR; goto done; } if (ret != 0) { ret = LDAP_OPERATIONS_ERROR; goto done; } else if (ret == 0 && pwd_result == NULL && grp_result == NULL && sid_str == NULL) { ret = LDAP_NO_SUCH_OBJECT; goto done; } if (domain_name == NULL) { ret = LDAP_OPERATIONS_ERROR; goto done; } ret = create_response(req, &pg_data, sid_str, id_type, domain_name, res); if (ret != 0) { ret = LDAP_OPERATIONS_ERROR; goto done; } ret = LDAP_SUCCESS; done: free(buf); free(fq_name); free(domain_name); free(sid_str); return ret; }