struct ipa_sudo_conv * ipa_sudo_conv_init(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sdap_attr_map *map_rule, struct sdap_attr_map *map_cmdgroup, struct sdap_attr_map *map_cmd, struct sdap_attr_map *map_user, struct sdap_attr_map *map_group, struct sdap_attr_map *map_host, struct sdap_attr_map *map_hostgroup) { struct ipa_sudo_conv *conv; errno_t ret; conv = talloc_zero(mem_ctx, struct ipa_sudo_conv); if (conv == NULL) { return NULL; } conv->sysdb = sysdb; conv->map_rule = map_rule; conv->map_cmdgroup = map_cmdgroup; conv->map_cmd = map_cmd; conv->map_user = map_user; conv->map_group = map_group; conv->map_host = map_host; conv->map_hostgroup = map_hostgroup; ret = sss_hash_create(conv, 20, &conv->rules); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create hash table [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = sss_hash_create(conv, 20, &conv->cmdgroups); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create hash table [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = sss_hash_create(conv, 20, &conv->cmds); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create hash table [%d]: %s\n", ret, sss_strerror(ret)); goto done; } done: if (ret != EOK) { talloc_free(conv); return NULL; } return conv; }
void sbus_get_id_test_setup(void **state) { struct sbus_get_id_ctx *test_ctx; int ret; test_ctx = talloc(global_talloc_context, struct sbus_get_id_ctx); assert_non_null(test_ctx); test_ctx->conn = talloc(test_ctx, struct sbus_connection); assert_non_null(test_ctx->conn); test_ctx->conn->connection_type = SBUS_CONN_TYPE_SYSBUS; ret = sss_hash_create(test_ctx->conn, 32, &test_ctx->conn->clients); assert_int_equal(ret, EOK); test_ctx->stc = create_ev_test_ctx(test_ctx); assert_non_null(test_ctx->stc); *state = test_ctx; global_test_ctx = test_ctx; }
static errno_t process_ext_groups(TALLOC_CTX *mem_ctx, size_t reply_count, struct sysdb_attrs **reply, hash_table_t **_ext_group_hash) { int ret; hash_table_t *ext_group_hash = NULL; hash_key_t key; hash_value_t value; hash_table_t *m_hash = NULL; hash_key_t m_key; hash_value_t m_value; size_t g; size_t s; size_t m; TALLOC_CTX *tmp_ctx = NULL; const char **ext_sids; const char **mof; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); ret = ENOMEM; goto done; } ret = sss_hash_create(mem_ctx, reply_count, &ext_group_hash); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "sss_hash_create failed.\n"); goto done; } key.type = HASH_KEY_STRING; m_key.type = HASH_KEY_STRING; m_value.type = HASH_VALUE_PTR; m_value.ptr = NULL; for (g = 0; g < reply_count; g++) { ret = sysdb_attrs_get_string_array(reply[g], "ipaExternalMember", tmp_ctx, &ext_sids); if (ret == ENOENT) { /* no external members, try next external group. */ continue; } if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string_array failed.\n"); goto done; } ret = sysdb_attrs_get_string_array(reply[g], "memberOf", tmp_ctx, &mof); if (ret == ENOENT) { /* no IPA groups, try next external group. */ continue; } if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string_array failed.\n"); goto done; } for (s = 0; ext_sids[s] != NULL; s++) { /* hash_lookup does not modify key.str. */ key.str = discard_const(ext_sids[s]); ret = hash_lookup(ext_group_hash, &key, &value); if (ret == HASH_SUCCESS) { if (value.type != HASH_VALUE_PTR) { DEBUG(SSSDBG_OP_FAILURE, "Unexpected value type.\n"); ret = EINVAL; goto done; } for (m = 0; mof[m] != NULL; m++) { /* hash_enter does not modify m_key.str. */ m_key.str = discard_const(mof[m]); DEBUG(SSSDBG_TRACE_ALL, "Adding group [%s] to SID [%s].\n", m_key.str, key.str); ret = hash_enter(value.ptr, &m_key, &m_value); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed.\n"); goto done; } } } else if (ret == HASH_ERROR_KEY_NOT_FOUND) { ret = sss_hash_create(ext_group_hash, 5, &m_hash); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "sss_hash_create failed.\n"); goto done; } value.type = HASH_VALUE_PTR; value.ptr = m_hash; DEBUG(SSSDBG_TRACE_ALL, "Adding SID [%s] to external group hash.\n", key.str); ret = hash_enter(ext_group_hash, &key, &value); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed.\n"); goto done; } for (m = 0; mof[m] != NULL; m++) { /* hash_enter does not modify m_key.str. */ m_key.str = discard_const(mof[m]); DEBUG(SSSDBG_TRACE_ALL, "Adding group [%s] to SID [%s].\n", m_key.str, key.str); ret = hash_enter(m_hash, &m_key, &m_value); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed.\n"); goto done; } } } else { DEBUG(SSSDBG_OP_FAILURE, "hash_lookup failed.\n"); goto done; } } } ret = EOK; done: if (ret != EOK) { talloc_free(ext_group_hash); } else { *_ext_group_hash = ext_group_hash; } talloc_free(tmp_ctx); return ret; }
static errno_t find_ipa_ext_memberships(TALLOC_CTX *mem_ctx, const char *user_name, struct sss_domain_info *user_dom, hash_table_t *ext_group_hash, struct ldb_dn **_user_dn, char ***_groups) { int ret; TALLOC_CTX *tmp_ctx = NULL; struct ldb_result *result; char **groups = NULL; size_t c; const char *sid; hash_key_t key; hash_value_t value; hash_entry_t *entry; struct hash_iter_context_t *iter; hash_table_t *group_hash; size_t g_count; struct ldb_dn *user_dn = NULL; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } ret = sysdb_initgroups(tmp_ctx, user_dom, user_name, &result); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_initgroups failed.\n"); goto done; } if (result->count == 0) { DEBUG(SSSDBG_MINOR_FAILURE, "User [%s] not found in cache.\n", user_name); ret = EOK; goto done; } ret = sss_hash_create(tmp_ctx, 10, &group_hash); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "sss_hash_create failed.\n"); goto done; } key.type = HASH_KEY_STRING; /* The IPA external domains can have references to group and user SIDs. * This means that we not only want to look up the group SIDs but the SID * of the user (first element of result) as well. */ for (c = 0; c < result->count; c++) { sid = ldb_msg_find_attr_as_string(result->msgs[c], SYSDB_SID_STR, NULL); if (sid == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Group [%s] does not have a SID.\n", ldb_dn_get_linearized(result->msgs[c]->dn)); continue; } key.str = discard_const(sid); ret = hash_lookup(ext_group_hash, &key, &value); if (ret == HASH_ERROR_KEY_NOT_FOUND) { DEBUG(SSSDBG_TRACE_ALL, "SID [%s] not found in ext group hash.\n", sid); } else if (ret == HASH_SUCCESS) { iter = new_hash_iter_context(value.ptr); if (iter == NULL) { DEBUG(SSSDBG_OP_FAILURE, "new_hash_iter_context failed.\n"); ret = EINVAL; goto done; } while ((entry = iter->next(iter)) != NULL) { ret = hash_enter(group_hash, &entry->key, &entry->value); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "Failed to add group [%s].\n", entry->key.str); } } talloc_free(iter); } else { DEBUG(SSSDBG_OP_FAILURE, "hash_lookup failed for SID [%s].\n", sid); } } g_count = hash_count(group_hash); if (g_count == 0) { DEBUG(SSSDBG_TRACE_FUNC, "No external groupmemberships found.\n"); ret = EOK; goto done; } groups = talloc_zero_array(mem_ctx, char *, g_count + 1); if (groups == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n"); ret = ENOMEM; goto done; } iter = new_hash_iter_context(group_hash); if (iter == NULL) { DEBUG(SSSDBG_OP_FAILURE, "new_hash_iter_context failed.\n"); ret = EINVAL; goto done; } c = 0; while ((entry = iter->next(iter)) != NULL) { groups[c] = talloc_strdup(groups, entry->key.str); if (groups[c] == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } c++; } user_dn = ldb_dn_copy(mem_ctx, result->msgs[0]->dn); if (user_dn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_copy failed.\n"); ret = ENOMEM; goto done; } ret = EOK; done: *_user_dn = user_dn; *_groups = groups; talloc_free(tmp_ctx); return ret; }
static int pam_process_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct confdb_ctx *cdb) { struct resp_ctx *rctx; struct sss_cmd_table *pam_cmds; struct be_conn *iter; struct pam_ctx *pctx; int ret, max_retries; int id_timeout; int fd_limit; pam_cmds = get_pam_cmds(); ret = sss_process_init(mem_ctx, ev, cdb, pam_cmds, SSS_PAM_SOCKET_NAME, SSS_PAM_PRIV_SOCKET_NAME, CONFDB_PAM_CONF_ENTRY, SSS_PAM_SBUS_SERVICE_NAME, SSS_PAM_SBUS_SERVICE_VERSION, &monitor_pam_interface, "PAM", &pam_dp_interface, &rctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, ("sss_process_init() failed\n")); return ret; } pctx = talloc_zero(rctx, struct pam_ctx); if (!pctx) { ret = ENOMEM; goto done; } pctx->rctx = rctx; pctx->rctx->pvt_ctx = pctx; /* Enable automatic reconnection to the Data Provider */ /* FIXME: "retries" is too generic, either get it from a global config * or specify these retries are about the sbus connections to DP */ ret = confdb_get_int(pctx->rctx->cdb, CONFDB_PAM_CONF_ENTRY, CONFDB_SERVICE_RECON_RETRIES, 3, &max_retries); if (ret != EOK) { DEBUG(0, ("Failed to set up automatic reconnection\n")); goto done; } for (iter = pctx->rctx->be_conns; iter; iter = iter->next) { sbus_reconnect_init(iter->conn, max_retries, pam_dp_reconnect_init, iter); } /* Set up the negative cache */ ret = confdb_get_int(cdb, CONFDB_NSS_CONF_ENTRY, CONFDB_NSS_ENTRY_NEG_TIMEOUT, 15, &pctx->neg_timeout); if (ret != EOK) goto done; /* Set up the PAM identity timeout */ ret = confdb_get_int(cdb, CONFDB_PAM_CONF_ENTRY, CONFDB_PAM_ID_TIMEOUT, 5, &id_timeout); if (ret != EOK) goto done; pctx->id_timeout = (size_t)id_timeout; ret = sss_ncache_init(pctx, &pctx->ncache); if (ret != EOK) { DEBUG(0, ("fatal error initializing negative cache\n")); goto done; } ret = sss_ncache_prepopulate(pctx->ncache, cdb, pctx->rctx); if (ret != EOK) { goto done; } /* Create table for initgroup lookups */ ret = sss_hash_create(pctx, 10, &pctx->id_table); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, ("Could not create initgroups hash table: [%s]", strerror(ret))); goto done; } /* Set up file descriptor limits */ ret = confdb_get_int(pctx->rctx->cdb, CONFDB_PAM_CONF_ENTRY, CONFDB_SERVICE_FD_LIMIT, DEFAULT_PAM_FD_LIMIT, &fd_limit); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, ("Failed to set up file descriptor limit\n")); goto done; } responder_set_fd_limit(fd_limit); ret = EOK; done: if (ret != EOK) { talloc_free(rctx); } return ret; }