Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 5
0
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;
}