/** * Find the corresponding UID for a user from a remote domain based on the * domain SID of the remote domain and the RID of the user. */ errno_t domsid_rid_to_uid(struct pac_ctx *pac_ctx, struct sysdb_ctx *sysdb, const char *domain_name, struct dom_sid2 *domsid, uint32_t rid, uid_t *uid) { enum idmap_error_code err; char *sid_str = NULL; char *dom_sid_str = NULL; uint32_t id; int ret; err = sss_idmap_smb_sid_to_sid(pac_ctx->idmap_ctx, domsid, &dom_sid_str); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, ("sss_idmap_smb_sid_to_sid failed.\n")); ret = EFAULT; goto done; } sid_str = talloc_asprintf(NULL, "%s-%lu", dom_sid_str, (unsigned long) rid); if (sid_str == NULL) { DEBUG(SSSDBG_OP_FAILURE, ("dom_sid_and_rid_string failed.\n")); return ENOMEM; } err = sss_idmap_sid_to_unix(pac_ctx->idmap_ctx, sid_str, &id); if (err == IDMAP_NO_DOMAIN) { ret = add_idmap_domain(pac_ctx->idmap_ctx, sysdb, domain_name, dom_sid_str); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, ("add_idmap_domain failed.\n")); goto done; } err = sss_idmap_sid_to_unix(pac_ctx->idmap_ctx, sid_str, &id); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, ("sss_idmap_sid_to_unix failed " "even in the second attempt.\n")); ret = ENOENT; goto done; } } else if (err != IDMAP_SUCCESS && err != IDMAP_NO_DOMAIN) { DEBUG(SSSDBG_OP_FAILURE, ("sss_idmap_sid_to_unix failed.\n")); ret = EFAULT; goto done; } *uid = (uid_t) id; ret = EOK; done: talloc_free(dom_sid_str); talloc_free(sid_str); return ret; }
static errno_t add_sids_from_rid_array_to_hash_table(struct dom_sid *dom_sid, struct samr_RidWithAttributeArray *groups, struct sss_idmap_ctx *idmap_ctx, hash_table_t *sid_table) { enum idmap_error_code err; char *dom_sid_str = NULL; size_t dom_sid_str_len; char *sid_str = NULL; char *rid_start; hash_key_t key; hash_value_t value; int ret; size_t c; TALLOC_CTX *tmp_ctx = NULL; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } key.type = HASH_KEY_STRING; value.type = HASH_VALUE_ULONG; err = sss_idmap_smb_sid_to_sid(idmap_ctx, dom_sid, &dom_sid_str); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "sss_idmap_smb_sid_to_sid failed.\n"); ret = EFAULT; goto done; } dom_sid_str_len = strlen(dom_sid_str); sid_str = talloc_zero_size(tmp_ctx, dom_sid_str_len + 12); if (sid_str == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_size failed.\n"); ret = ENOMEM; goto done; } rid_start = sid_str + dom_sid_str_len; memcpy(sid_str, dom_sid_str, dom_sid_str_len); for (c = 0; c < groups->count; c++) { memset(rid_start, '\0', 12); ret = snprintf(rid_start, 12, "-%lu", (unsigned long) groups->rids[c].rid); if (ret < 0 || ret > 12) { DEBUG(SSSDBG_OP_FAILURE, "snprintf failed.\n"); ret = EIO; goto done; } key.str = sid_str; value.ul = 0; ret = hash_enter(sid_table, &key, &value); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed [%d][%s].\n", ret, hash_error_string(ret)); ret = EIO; goto done; } } ret = EOK; done: sss_idmap_free_sid(idmap_ctx, dom_sid_str); talloc_free(tmp_ctx); return ret; }