Пример #1
0
int common_ipa_init(struct be_ctx *bectx)
{
    const char *ipa_servers;
    const char *ipa_backup_servers;
    int ret;

    ret = ipa_get_options(bectx, bectx->cdb,
                          bectx->conf_path,
                          bectx->domain, &ipa_options);
    if (ret != EOK) {
        return ret;
    }

    ipa_servers = dp_opt_get_string(ipa_options->basic, IPA_SERVER);
    ipa_backup_servers = dp_opt_get_string(ipa_options->basic, IPA_BACKUP_SERVER);

    ret = ipa_service_init(ipa_options, bectx, ipa_servers,
                           ipa_backup_servers, ipa_options,
                           &ipa_options->service);
    if (ret != EOK) {
        DEBUG(SSSDBG_FATAL_FAILURE, "Failed to init IPA failover service!\n");
        return ret;
    }

    return EOK;
}
Пример #2
0
static void assert_defaults(struct dp_option *opts)
{
    char *s;
    struct dp_opt_blob b;
    int i;
    bool bo;

    s = dp_opt_get_string(opts, OPT_STRING_NODEFAULT);
    assert_null(s);

    s = dp_opt_get_string(opts, OPT_STRING_DEFAULT);
    assert_non_null(s);
    assert_string_equal(s, STRING_DEFAULT);

    b = dp_opt_get_blob(opts, OPT_BLOB_NODEFAULT);
    assert_null(b.data);
    assert_int_equal(b.length, 0);

    b = dp_opt_get_blob(opts, OPT_BLOB_DEFAULT);
    assert_non_null(b.data);
    assert_int_equal(b.length, strlen(BLOB_DEFAULT));
    assert_memory_equal(b.data, BLOB_DEFAULT, strlen(BLOB_DEFAULT));

    i = dp_opt_get_int(opts, OPT_INT_NODEFAULT);
    assert_int_equal(i, 0);

    i = dp_opt_get_int(opts, OPT_INT_DEFAULT);
    assert_int_equal(i, INT_DEFAULT);

    bo = dp_opt_get_bool(opts, OPT_BOOL_TRUE);
    assert_true(bo == true);

    bo = dp_opt_get_bool(opts, OPT_BOOL_FALSE);
    assert_true(bo == false);
}
Пример #3
0
void opt_test_get(void **state)
{
    int ret;
    struct sss_test_ctx *tctx;
    struct dp_option *opts;
    struct sss_test_conf_param params[] = {
        { "string_nodefault", "stringval2" },
        { "blob_nodefault", "blobval2" },
        { "int_nodefault", "456" },
        { "bool_true", "false" },
        { NULL, NULL },             /* Sentinel */
    };
    char *s;
    struct dp_opt_blob b;
    int i;
    bool bo;

    tctx = create_dom_test_ctx(global_talloc_context, TESTS_PATH, TEST_CONF_DB,
                               TEST_DOM_NAME, TEST_ID_PROVIDER, params);
    assert_non_null(tctx);

    ret = dp_get_options(global_talloc_context, tctx->confdb, tctx->conf_dom_path,
                         test_def_opts, OPT_NUM_OPTS, &opts);
    assert_int_equal(ret, EOK);

    /* Options that were not specified explicitly should only have the default
     * value, those that have been specified explicitly should carry that
     * value
     */
    s = dp_opt_get_string(opts, OPT_STRING_NODEFAULT);
    assert_non_null(s);
    assert_string_equal(s, "stringval2");

    s = dp_opt_get_string(opts, OPT_STRING_DEFAULT);
    assert_non_null(s);
    assert_string_equal(s, STRING_DEFAULT);

    b = dp_opt_get_blob(opts, OPT_BLOB_NODEFAULT);
    assert_non_null(b.data);
    assert_int_equal(b.length, strlen("blobval2"));
    assert_memory_equal(b.data, "blobval2", strlen("blobval2"));

    b = dp_opt_get_blob(opts, OPT_BLOB_DEFAULT);
    assert_non_null(b.data);
    assert_int_equal(b.length, strlen(BLOB_DEFAULT));
    assert_memory_equal(b.data, BLOB_DEFAULT, strlen(BLOB_DEFAULT));

    i = dp_opt_get_int(opts, OPT_INT_NODEFAULT);
    assert_int_equal(i, 456);

    i = dp_opt_get_int(opts, OPT_INT_DEFAULT);
    assert_int_equal(i, INT_DEFAULT);

    bo = dp_opt_get_bool(opts, OPT_BOOL_TRUE);
    assert_true(bo == false);

    bo = dp_opt_get_bool(opts, OPT_BOOL_FALSE);
    assert_true(bo == false);
}
Пример #4
0
int ldap_get_sudo_options(struct confdb_ctx *cdb,
                          const char *conf_path,
                          struct sdap_options *opts,
                          bool *use_host_filter,
                          bool *include_regexp,
                          bool *include_netgroups)
{
    const char *search_base;
    int ret;

    /* search base */
    search_base = dp_opt_get_string(opts->basic, SDAP_SEARCH_BASE);
    if (search_base != NULL) {
        /* set sudo search bases if they are not */
        if (dp_opt_get_string(opts->basic, SDAP_SUDO_SEARCH_BASE) == NULL) {
            ret = dp_opt_set_string(opts->basic, SDAP_SUDO_SEARCH_BASE,
                                    search_base);
            if (ret != EOK) {
                DEBUG(SSSDBG_OP_FAILURE, "Could not set SUDO search base"
                      "to default value\n");
                return ret;
            }

            DEBUG(SSSDBG_FUNC_DATA, "Option %s set to %s\n",
                  opts->basic[SDAP_SUDO_SEARCH_BASE].opt_name,
                  dp_opt_get_string(opts->basic, SDAP_SUDO_SEARCH_BASE));
        }
    } else {
        DEBUG(SSSDBG_TRACE_FUNC, "Search base not set, trying to discover it later "
              "connecting to the LDAP server.\n");
    }

    ret = sdap_parse_search_base(opts, opts->basic,
                                 SDAP_SUDO_SEARCH_BASE,
                                 &opts->sdom->sudo_search_bases);
    if (ret != EOK && ret != ENOENT) {
        DEBUG(SSSDBG_OP_FAILURE, "Could not parse SUDO search base\n");
        return ret;
    }

    /* attrs map */
    ret = sdap_get_map(opts, cdb, conf_path,
                       native_sudorule_map,
                       SDAP_OPTS_SUDO,
                       &opts->sudorule_map);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE, "Could not get SUDO attribute map\n");
        return ret;
    }

    /* host filter */
    *use_host_filter = dp_opt_get_bool(opts->basic, SDAP_SUDO_USE_HOST_FILTER);
    *include_netgroups = dp_opt_get_bool(opts->basic, SDAP_SUDO_INCLUDE_NETGROUPS);
    *include_regexp = dp_opt_get_bool(opts->basic, SDAP_SUDO_INCLUDE_REGEXP);

    return EOK;
}
Пример #5
0
void opt_test_copy_options(void **state)
{
    int ret;
    TALLOC_CTX *mem_ctx;
    struct dp_option *opts;
    char *s;
    struct dp_opt_blob b;
    int i;
    bool bo;

    mem_ctx = talloc_new(global_talloc_context);
    assert_non_null(mem_ctx);

    ret = dp_copy_options(mem_ctx, test_def_opts, OPT_NUM_OPTS, &opts);
    assert_int_equal(ret, EOK);
    assert_int_equal(ret, EOK);

    ret = dp_opt_set_string(opts, OPT_STRING_NODEFAULT, "str1");
    assert_int_equal(ret, EOK);

    b.data = discard_const_p(uint8_t, "blob1");
    b.length = strlen("blob1");
    ret = dp_opt_set_blob(opts, OPT_BLOB_NODEFAULT, b);
    assert_int_equal(ret, EOK);

    ret = dp_opt_set_int(opts, OPT_INT_NODEFAULT, 456);
    assert_int_equal(ret, EOK);

    ret = dp_opt_set_bool(opts, OPT_BOOL_TRUE, false);
    assert_int_equal(ret, EOK);

    /* Test that options set to an explicit value retain
     * the value and even options with default value
     * do not return the default unless explicitly set
     */
    s = dp_opt_get_string(opts, OPT_STRING_NODEFAULT);
    assert_string_equal(s, "str1");
    s = dp_opt_get_string(opts, OPT_STRING_DEFAULT);
    assert_null(s);

    b = dp_opt_get_blob(opts, OPT_BLOB_NODEFAULT);
    assert_non_null(b.data);
    assert_int_equal(b.length, strlen("blob1"));
    assert_memory_equal(b.data, "blob1", strlen("blob1"));
    b = dp_opt_get_blob(opts, OPT_BLOB_DEFAULT);
    assert_null(b.data);
    assert_int_equal(b.length, 0);

    i = dp_opt_get_int(opts, OPT_INT_NODEFAULT);
    assert_int_equal(i, 456);
    i = dp_opt_get_int(opts, OPT_INT_DEFAULT);
    assert_int_equal(i, 0);

    bo = dp_opt_get_bool(opts, OPT_BOOL_TRUE);
    assert_false(bo == true);
}
Пример #6
0
static errno_t krb5_init_kpasswd(struct krb5_ctx *ctx,
                                 struct be_ctx *be_ctx)
{
    const char *realm;
    const char *primary_servers;
    const char *backup_servers;
    const char *kdc_servers;
    bool use_kdcinfo;
    size_t n_lookahead_primary;
    size_t n_lookahead_backup;
    errno_t ret;

    realm = dp_opt_get_string(ctx->opts, KRB5_REALM);
    if (realm == NULL) {
        DEBUG(SSSDBG_FATAL_FAILURE, "Missing krb5_realm option!\n");
        return EINVAL;
    }

    kdc_servers = dp_opt_get_string(ctx->opts, KRB5_KDC);
    primary_servers = dp_opt_get_string(ctx->opts, KRB5_KPASSWD);
    backup_servers = dp_opt_get_string(ctx->opts, KRB5_BACKUP_KPASSWD);
    use_kdcinfo = dp_opt_get_bool(ctx->opts, KRB5_USE_KDCINFO);
    sss_krb5_parse_lookahead(dp_opt_get_string(ctx->opts, KRB5_KDCINFO_LOOKAHEAD),
                             &n_lookahead_primary, &n_lookahead_backup);


    if (primary_servers == NULL && backup_servers != NULL) {
        DEBUG(SSSDBG_CONF_SETTINGS, "kpasswd server wasn't specified but "
              "backup_servers kpasswd given. Using it as primary_servers\n");
        primary_servers = backup_servers;
        backup_servers = NULL;
    }

    if (primary_servers == NULL && kdc_servers != NULL) {
        DEBUG(SSSDBG_FATAL_FAILURE, "Missing krb5_kpasswd option and KDC set "
              "explicitly, will use KDC for pasword change operations!\n");
        ctx->kpasswd_service = NULL;
    } else {
        ret = krb5_service_init(ctx, be_ctx, SSS_KRB5KPASSWD_FO_SRV,
                                primary_servers, backup_servers, realm,
                                use_kdcinfo,
                                n_lookahead_primary,
                                n_lookahead_backup,
                                &ctx->kpasswd_service);
        if (ret != EOK) {
            DEBUG(SSSDBG_FATAL_FAILURE,
                  "Failed to init KRB5KPASSWD failover service!\n");
            return ret;
        }
    }

    return EOK;
}
Пример #7
0
static void assert_nondefault_string_empty(struct dp_option *opts)
{
    char *s;

    s = dp_opt_get_string(opts, OPT_STRING_NODEFAULT);
    assert_null(s);
}
Пример #8
0
static void check_nondefault_string(struct dp_option *opts)
{
    char *s;

    s = dp_opt_get_string(opts, OPT_STRING_NODEFAULT);
    assert_non_null(s);
    assert_string_equal(s, "str1");
}
Пример #9
0
void opt_test_inherit(void **state)
{
    struct dp_option *opts = talloc_get_type(*state, struct dp_option);
    int ret;
    struct dp_option *opts_copy;
    const char *s;
    const char *sd_inherit_match[] = { "string_nodefault",
                                       "blob_nodefault",
                                       "int_nodefault",
                                       "bool_true",
                                       NULL };

    ret = dp_copy_defaults(opts, test_def_opts,
                           OPT_NUM_OPTS, &opts_copy);
    assert_int_equal(ret, EOK);
    assert_defaults(opts);

    dp_option_inherit(NULL, OPT_STRING_NODEFAULT,
                      opts, opts_copy);
    s = dp_opt_get_string(opts_copy, OPT_STRING_NODEFAULT);
    assert_null(s);

    /* string */
    assert_nondefault_string_empty(opts_copy);
    set_nondefault_string(opts);
    dp_option_inherit(discard_const(sd_inherit_match),
                      OPT_STRING_NODEFAULT,
                      opts, opts_copy);
    check_nondefault_string(opts_copy);

    /* blob */
    assert_nondefault_blob_empty(opts_copy);
    set_nondefault_blob(opts);
    dp_option_inherit(discard_const(sd_inherit_match),
                      OPT_BLOB_NODEFAULT,
                      opts, opts_copy);
    check_nondefault_blob(opts_copy);

    /* number */
    assert_nondefault_int_notset(opts_copy);
    set_nondefault_int(opts);
    dp_option_inherit(discard_const(sd_inherit_match),
                      OPT_INT_NODEFAULT,
                      opts, opts_copy);
    assert_nondefault_int_set(opts_copy);

    /* bool */
    assert_true(dp_opt_get_bool(opts_copy, OPT_BOOL_TRUE));

    ret = dp_opt_set_bool(opts, OPT_BOOL_TRUE, false);
    assert_int_equal(ret, EOK);

    dp_option_inherit(discard_const(sd_inherit_match),
                      OPT_BOOL_TRUE,
                      opts, opts_copy);

    assert_false(dp_opt_get_bool(opts_copy, OPT_BOOL_TRUE));
}
Пример #10
0
errno_t check_and_export_lifetime(struct dp_option *opts, const int opt_id,
                                  const char *env_name)
{
    int ret;
    char *str;
    krb5_deltat lifetime;
    bool free_str = false;

    str = dp_opt_get_string(opts, opt_id);
    if (str == NULL || *str == '\0') {
        DEBUG(5, ("No lifetime configured.\n"));
        return EOK;
    }

    if (isdigit(str[strlen(str)-1])) {
        str = talloc_asprintf(opts, "%ss", str);
        if (str == NULL) {
            DEBUG(1, ("talloc_asprintf failed\n"));
            return ENOMEM;
        }
        free_str = true;

        ret = dp_opt_set_string(opts, opt_id, str);
        if (ret != EOK) {
            DEBUG(1, ("dp_opt_set_string failed\n"));
            goto done;
        }
    }

    ret = krb5_string_to_deltat(str, &lifetime);
    if (ret != 0) {
        DEBUG(1, ("Invalid value [%s] for a lifetime.\n", str));
        ret = EINVAL;
        goto done;
    }

    ret = setenv(env_name, str, 1);
    if (ret != EOK) {
        ret = errno;
        DEBUG(2, ("setenv [%s] failed.\n", env_name));
        goto done;
    }

    ret = EOK;

done:
    if (free_str) {
        talloc_free(str);
    }

    return ret;
}
Пример #11
0
static errno_t krb5_init_kdc(struct krb5_ctx *ctx, struct be_ctx *be_ctx)
{
    const char *primary_servers;
    const char *backup_servers;
    const char *realm;
    bool use_kdcinfo;
    size_t n_lookahead_primary;
    size_t n_lookahead_backup;
    errno_t ret;

    realm = dp_opt_get_string(ctx->opts, KRB5_REALM);
    if (realm == NULL) {
        DEBUG(SSSDBG_FATAL_FAILURE, "Missing krb5_realm option!\n");
        return EINVAL;
    }

    primary_servers = dp_opt_get_string(ctx->opts, KRB5_KDC);
    backup_servers = dp_opt_get_string(ctx->opts, KRB5_BACKUP_KDC);

    use_kdcinfo = dp_opt_get_bool(ctx->opts, KRB5_USE_KDCINFO);
    sss_krb5_parse_lookahead(dp_opt_get_string(ctx->opts, KRB5_KDCINFO_LOOKAHEAD),
                             &n_lookahead_primary, &n_lookahead_backup);

    ret = krb5_service_init(ctx, be_ctx, SSS_KRB5KDC_FO_SRV,
                            primary_servers, backup_servers, realm,
                            use_kdcinfo,
                            n_lookahead_primary,
                            n_lookahead_backup,
                            &ctx->service);
    if (ret != EOK) {
        DEBUG(SSSDBG_FATAL_FAILURE, "Failed to init KRB5 failover service!\n");
        return ret;
    }

    return EOK;
}
Пример #12
0
errno_t krb5_try_kdcip(struct confdb_ctx *cdb, const char *conf_path,
                       struct dp_option *opts, int opt_id)
{
    char *krb5_servers = NULL;
    errno_t ret;

    krb5_servers = dp_opt_get_string(opts, opt_id);
    if (krb5_servers == NULL) {
        DEBUG(4, ("No KDC found in configuration, trying legacy option\n"));
        ret = confdb_get_string(cdb, NULL, conf_path,
                                "krb5_kdcip", NULL, &krb5_servers);
        if (ret != EOK) {
            DEBUG(1, ("confdb_get_string failed.\n"));
            return ret;
        }

        if (krb5_servers != NULL)
        {
            ret = dp_opt_set_string(opts, opt_id, krb5_servers);
            if (ret != EOK) {
                DEBUG(1, ("dp_opt_set_string failed.\n"));
                talloc_free(krb5_servers);
                return ret;
            }

            DEBUG(SSSDBG_CONF_SETTINGS,
                  ("Set krb5 server [%s] based on legacy krb5_kdcip option\n",
                   krb5_servers));
            DEBUG(SSSDBG_FATAL_FAILURE,
                  ("Your configuration uses the deprecated option "
                   "'krb5_kdcip' to specify the KDC. Please change the "
                   "configuration to use the 'krb5_server' option "
                   "instead.\n"));
            talloc_free(krb5_servers);
        }
    }

    return EOK;
}
Пример #13
0
static int hbac_get_host_info_step(struct hbac_ctx *hbac_ctx)
{
    struct be_ctx *be_ctx = be_req_get_be_ctx(hbac_ctx->be_req);
    const char *hostname;
    struct tevent_req *req;

    if (dp_opt_get_bool(hbac_ctx->ipa_options, IPA_HBAC_SUPPORT_SRCHOST)) {
        /* Support srchost
         * -> we don't want any particular host,
         *    we want all hosts
         */
        hostname = NULL;

        /* THIS FEATURE IS DEPRECATED */
        DEBUG(SSSDBG_MINOR_FAILURE, ("WARNING: Using deprecated option "
                    "ipa_hbac_support_srchost.\n"));
        sss_log(SSS_LOG_NOTICE, "WARNING: Using deprecated option "
                    "ipa_hbac_support_srchost.\n");
    } else {
        hostname = dp_opt_get_string(hbac_ctx->ipa_options, IPA_HOSTNAME);
    }

    req = ipa_host_info_send(hbac_ctx, be_ctx->ev,
                             sdap_id_op_handle(hbac_ctx->sdap_op),
                             hbac_ctx->sdap_ctx->opts,
                             hostname,
                             hbac_ctx->access_ctx->host_map,
                             hbac_ctx->access_ctx->hostgroup_map,
                             hbac_ctx->access_ctx->host_search_bases);
    if (req == NULL) {
        DEBUG(1, ("Could not get host info\n"));
        return ENOMEM;
    }
    tevent_req_set_callback(req, hbac_get_service_info_step, hbac_ctx);

    return EOK;
}
Пример #14
0
errno_t krb5_child_init(struct krb5_ctx *krb5_auth_ctx,
                        struct be_ctx *bectx)
{
    errno_t ret;
    FILE *debug_filep;
    time_t renew_intv = 0;
    krb5_deltat renew_interval_delta;
    char *renew_interval_str;

    if (dp_opt_get_bool(krb5_auth_ctx->opts, KRB5_STORE_PASSWORD_IF_OFFLINE)) {
        ret = init_delayed_online_authentication(krb5_auth_ctx, bectx,
                                                 bectx->ev);
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "init_delayed_online_authentication failed.\n");
            goto done;
        }
    }
    renew_interval_str = dp_opt_get_string(krb5_auth_ctx->opts,
                         KRB5_RENEW_INTERVAL);
    if (renew_interval_str != NULL) {
        ret = krb5_string_to_deltat(renew_interval_str, &renew_interval_delta);
        if (ret != EOK) {
            DEBUG(SSSDBG_MINOR_FAILURE,
                 "Reading krb5_renew_interval failed.\n");
            renew_interval_delta = 0;
        }
        renew_intv = renew_interval_delta;
    }

    if (renew_intv > 0) {
        ret = init_renew_tgt(krb5_auth_ctx, bectx, bectx->ev, renew_intv);
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, "init_renew_tgt failed.\n");
            goto done;
        }
    }

    ret = check_and_export_options(krb5_auth_ctx->opts, bectx->domain,
                                   krb5_auth_ctx);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, "check_and_export_opts failed.\n");
        goto done;
    }

    ret = krb5_install_offline_callback(bectx, krb5_auth_ctx);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, "krb5_install_offline_callback failed.\n");
        goto done;
    }

    ret = krb5_install_sigterm_handler(bectx->ev, krb5_auth_ctx);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, "krb5_install_sigterm_handler failed.\n");
        goto done;
    }

    if (debug_to_file != 0) {
        ret = open_debug_file_ex(KRB5_CHILD_LOG_FILE, &debug_filep, false);
        if (ret != EOK) {
            DEBUG(SSSDBG_FATAL_FAILURE, "Error setting up logging (%d) [%s]\n",
                    ret, strerror(ret));
            goto done;
        }

        krb5_auth_ctx->child_debug_fd = fileno(debug_filep);
        if (krb5_auth_ctx->child_debug_fd == -1) {
            DEBUG(SSSDBG_FATAL_FAILURE,
                  "fileno failed [%d][%s]\n", errno, strerror(errno));
            ret = errno;
            goto done;
        }
    }

done:
    return ret;
}
Пример #15
0
static void ipa_hbac_check(struct tevent_req *req)
{
    struct be_req *be_req;
    struct be_ctx *be_ctx;
    struct pam_data *pd;
    struct hbac_ctx *hbac_ctx = NULL;
    const char *deny_method;
    struct ipa_access_ctx *ipa_access_ctx;
    int ret;

    be_req = tevent_req_callback_data(req, struct be_req);
    be_ctx = be_req_get_be_ctx(be_req);
    pd = talloc_get_type(be_req_get_data(be_req), struct pam_data);

    ret = sdap_access_recv(req);
    talloc_zfree(req);

    switch(ret) {
    case EOK:
        /* Account wasn't locked. Continue below
         * to HBAC processing.
         */
        break;
    case ERR_ACCESS_DENIED:
        /* Account was locked. Return permission denied
         * here.
         */
        pd->pam_status = PAM_PERM_DENIED;
        be_req_terminate(be_req, DP_ERR_OK, pd->pam_status, NULL);
        return;
    case ERR_ACCOUNT_EXPIRED:
        pd->pam_status = PAM_ACCT_EXPIRED;
        be_req_terminate(be_req, DP_ERR_OK, pd->pam_status, NULL);
        return;
    default:
        /* We got an unexpected error. Return it as-is */
        pd->pam_status = PAM_SYSTEM_ERR;
        be_req_terminate(be_req, DP_ERR_FATAL, pd->pam_status,
                         sss_strerror(ret));
        return;
    }

    hbac_ctx = talloc_zero(be_req, struct hbac_ctx);
    if (hbac_ctx == NULL) {
        DEBUG(1, ("talloc failed.\n"));
        ret = ENOMEM;
        goto fail;
    }

    hbac_ctx->be_req = be_req;
    hbac_ctx->pd = pd;
    ipa_access_ctx = talloc_get_type(be_ctx->bet_info[BET_ACCESS].pvt_bet_data,
                                     struct ipa_access_ctx);
    hbac_ctx->access_ctx = ipa_access_ctx;
    hbac_ctx->sdap_ctx = ipa_access_ctx->sdap_ctx;
    hbac_ctx->ipa_options = ipa_access_ctx->ipa_options;
    hbac_ctx->tr_ctx = ipa_access_ctx->tr_ctx;
    hbac_ctx->search_bases = ipa_access_ctx->hbac_search_bases;
    if (hbac_ctx->search_bases == NULL) {
        DEBUG(1, ("No HBAC search base found.\n"));
        ret = EINVAL;
        goto fail;
    }

    deny_method = dp_opt_get_string(hbac_ctx->ipa_options,
                                    IPA_HBAC_DENY_METHOD);
    if (strcasecmp(deny_method, "IGNORE") == 0) {
        hbac_ctx->get_deny_rules = false;
    } else {
        hbac_ctx->get_deny_rules = true;
    }

    ret = hbac_retry(hbac_ctx);
    if (ret != EOK) {
        goto fail;
    }

    return;

fail:
    if (hbac_ctx) {
        /* Return an proper error */
        ipa_access_reply(hbac_ctx, PAM_SYSTEM_ERR);
    } else {
        be_req_terminate(be_req, DP_ERR_FATAL, PAM_SYSTEM_ERR, NULL);
    }
}
Пример #16
0
errno_t krb5_child_init(struct krb5_ctx *krb5_auth_ctx,
                        struct be_ctx *bectx)
{
    errno_t ret;
    time_t renew_intv = 0;
    krb5_deltat renew_interval_delta;
    char *renew_interval_str;

    if (dp_opt_get_bool(krb5_auth_ctx->opts, KRB5_STORE_PASSWORD_IF_OFFLINE)) {
        ret = init_delayed_online_authentication(krb5_auth_ctx, bectx,
                                                 bectx->ev);
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "init_delayed_online_authentication failed.\n");
            goto done;
        }
    }
    renew_interval_str = dp_opt_get_string(krb5_auth_ctx->opts,
                         KRB5_RENEW_INTERVAL);
    if (renew_interval_str != NULL) {
        ret = krb5_string_to_deltat(renew_interval_str, &renew_interval_delta);
        if (ret != EOK) {
            DEBUG(SSSDBG_MINOR_FAILURE,
                 "Reading krb5_renew_interval failed.\n");
            renew_interval_delta = 0;
        }
        renew_intv = renew_interval_delta;
    }

    if (renew_intv > 0) {
        ret = init_renew_tgt(krb5_auth_ctx, bectx, bectx->ev, renew_intv);
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, "init_renew_tgt failed.\n");
            goto done;
        }
    }

    ret = check_and_export_options(krb5_auth_ctx->opts, bectx->domain,
                                   krb5_auth_ctx);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, "check_and_export_opts failed.\n");
        goto done;
    }

    ret = krb5_install_offline_callback(bectx, krb5_auth_ctx);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, "krb5_install_offline_callback failed.\n");
        goto done;
    }

    ret = krb5_install_sigterm_handler(bectx->ev, krb5_auth_ctx);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, "krb5_install_sigterm_handler failed.\n");
        goto done;
    }

    krb5_auth_ctx->child_debug_fd = -1; /* -1 means not initialized */
    ret = child_debug_init(KRB5_CHILD_LOG_FILE,
                           &krb5_auth_ctx->child_debug_fd);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE, "Could not set krb5_child debugging!\n");
        goto done;
    }

    ret = parse_krb5_map_user(krb5_auth_ctx,
                              dp_opt_get_cstring(krb5_auth_ctx->opts,
                                                 KRB5_MAP_USER),
                              bectx->domain->name,
                              &krb5_auth_ctx->name_to_primary);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE, "parse_krb5_map_user failed: %s:[%d]\n",
              sss_strerror(ret), ret);
        goto done;
    }

    ret = EOK;

done:
    return ret;
}
Пример #17
0
int ldap_get_options(TALLOC_CTX *memctx,
                     struct sss_domain_info *dom,
                     struct confdb_ctx *cdb,
                     const char *conf_path,
                     struct data_provider *dp,
                     struct sdap_options **_opts)
{
    struct sdap_attr_map *default_attr_map;
    struct sdap_attr_map *default_user_map;
    struct sdap_attr_map *default_group_map;
    struct sdap_attr_map *default_netgroup_map;
    struct sdap_attr_map *default_host_map;
    struct sdap_attr_map *default_service_map;
    struct sdap_options *opts;
    char *schema;
    char *pwmodify;
    const char *search_base;
    const char *pwd_policy;
    int ret;
    int account_cache_expiration;
    int offline_credentials_expiration;
    const char *ldap_deref;
    int ldap_deref_val;
    int o;
    const char *authtok_type;
    struct dp_opt_blob authtok_blob;
    char *cleartext;
    const int search_base_options[] = { SDAP_USER_SEARCH_BASE,
                                        SDAP_GROUP_SEARCH_BASE,
                                        SDAP_NETGROUP_SEARCH_BASE,
                                        SDAP_HOST_SEARCH_BASE,
                                        SDAP_SERVICE_SEARCH_BASE,
                                        -1 };

    opts = talloc_zero(memctx, struct sdap_options);
    if (!opts) return ENOMEM;
    opts->dp = dp;

    ret = sdap_domain_add(opts, dom, NULL);
    if (ret != EOK) {
        goto done;
    }

    ret = dp_get_options(opts, cdb, conf_path,
                         default_basic_opts,
                         SDAP_OPTS_BASIC,
                         &opts->basic);
    if (ret != EOK) {
        goto done;
    }

    /* Handle search bases */
    search_base = dp_opt_get_string(opts->basic, SDAP_SEARCH_BASE);
    if (search_base != NULL) {
        /* set user/group/netgroup search bases if they are not */
        for (o = 0; search_base_options[o] != -1; o++) {
            if (NULL == dp_opt_get_string(opts->basic, search_base_options[o])) {
                ret = dp_opt_set_string(opts->basic, search_base_options[o],
                                        search_base);
                if (ret != EOK) {
                    goto done;
                }
                DEBUG(SSSDBG_TRACE_FUNC, "Option %s set to %s\n",
                          opts->basic[search_base_options[o]].opt_name,
                          dp_opt_get_string(opts->basic,
                                            search_base_options[o]));
            }
        }
    } else {
        DEBUG(SSSDBG_FUNC_DATA,
              "Search base not set, trying to discover it later when "
                  "connecting to the LDAP server.\n");
    }

    /* Default search */
    ret = sdap_parse_search_base(opts, opts->basic,
                                 SDAP_SEARCH_BASE,
                                 &opts->sdom->search_bases);
    if (ret != EOK && ret != ENOENT) goto done;

    /* User search */
    ret = sdap_parse_search_base(opts, opts->basic,
                                 SDAP_USER_SEARCH_BASE,
                                 &opts->sdom->user_search_bases);
    if (ret != EOK && ret != ENOENT) goto done;

    /* Group search base */
    ret = sdap_parse_search_base(opts, opts->basic,
                                 SDAP_GROUP_SEARCH_BASE,
                                 &opts->sdom->group_search_bases);
    if (ret != EOK && ret != ENOENT) goto done;

    /* Netgroup search */
    ret = sdap_parse_search_base(opts, opts->basic,
                                 SDAP_NETGROUP_SEARCH_BASE,
                                 &opts->sdom->netgroup_search_bases);
    if (ret != EOK && ret != ENOENT) goto done;

    /* Netgroup search */
    ret = sdap_parse_search_base(opts, opts->basic,
                                 SDAP_HOST_SEARCH_BASE,
                                 &opts->sdom->host_search_bases);
    if (ret != EOK && ret != ENOENT) goto done;

    /* Service search */
    ret = sdap_parse_search_base(opts, opts->basic,
                                 SDAP_SERVICE_SEARCH_BASE,
                                 &opts->sdom->service_search_bases);
    if (ret != EOK && ret != ENOENT) goto done;

    pwd_policy = dp_opt_get_string(opts->basic, SDAP_PWD_POLICY);
    if (pwd_policy == NULL) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Missing password policy, this may not happen.\n");
        ret = EINVAL;
        goto done;
    }
    if (strcasecmp(pwd_policy, PWD_POL_OPT_NONE) != 0 &&
        strcasecmp(pwd_policy, PWD_POL_OPT_SHADOW) != 0 &&
        strcasecmp(pwd_policy, PWD_POL_OPT_MIT) != 0) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Unsupported password policy [%s].\n", pwd_policy);
        ret = EINVAL;
        goto done;
    }

    /* account_cache_expiration must be >= than offline_credentials_expiration */
    ret = confdb_get_int(cdb, CONFDB_PAM_CONF_ENTRY,
                         CONFDB_PAM_CRED_TIMEOUT, 0,
                         &offline_credentials_expiration);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Cannot get value of %s from confdb \n",
                  CONFDB_PAM_CRED_TIMEOUT);
        goto done;
    }

    account_cache_expiration = dp_opt_get_int(opts->basic,
                                              SDAP_ACCOUNT_CACHE_EXPIRATION);

    /* account cache_expiration must not be smaller than
     * offline_credentials_expiration to prevent deleting entries that
     * still contain credentials valid for offline login.
     *
     * offline_credentials_expiration == 0 is a special case that says
     * that the cached credentials are valid forever. Therefore, the cached
     * entries must not be purged from cache.
     */
    if (!offline_credentials_expiration && account_cache_expiration) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Conflicting values for options %s (unlimited) "
                  "and %s (%d)\n",
                  opts->basic[SDAP_ACCOUNT_CACHE_EXPIRATION].opt_name,
                  CONFDB_PAM_CRED_TIMEOUT,
                  offline_credentials_expiration);
        ret = EINVAL;
        goto done;
    }
    if (offline_credentials_expiration && account_cache_expiration &&
        offline_credentials_expiration > account_cache_expiration) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Value of %s (now %d) must be larger "
                  "than value of %s (now %d)\n",
                  opts->basic[SDAP_ACCOUNT_CACHE_EXPIRATION].opt_name,
                  account_cache_expiration,
                  CONFDB_PAM_CRED_TIMEOUT,
                  offline_credentials_expiration);
        ret = EINVAL;
        goto done;
    }

    ldap_deref = dp_opt_get_string(opts->basic, SDAP_DEREF);
    if (ldap_deref != NULL) {
        ret = deref_string_to_val(ldap_deref, &ldap_deref_val);
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, "Failed to verify ldap_deref option.\n");
            goto done;
        }
    }

#ifndef HAVE_LDAP_CONNCB
    bool ldap_referrals;

    ldap_referrals = dp_opt_get_bool(opts->basic, SDAP_REFERRALS);
    if (ldap_referrals) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "LDAP referrals are not supported, because the LDAP library "
                  "is too old, see sssd-ldap(5) for details.\n");
        ret = dp_opt_set_bool(opts->basic, SDAP_REFERRALS, false);
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, "dp_opt_set_string failed.\n");
            goto done;
        }
    }
#endif

    /* schema type */
    schema = dp_opt_get_string(opts->basic, SDAP_SCHEMA);
    if (strcasecmp(schema, "rfc2307") == 0) {
        opts->schema_type = SDAP_SCHEMA_RFC2307;
        default_attr_map = generic_attr_map;
        default_user_map = rfc2307_user_map;
        default_group_map = rfc2307_group_map;
        default_netgroup_map = netgroup_map;
        default_host_map = host_map;
        default_service_map = service_map;
    } else
    if (strcasecmp(schema, "rfc2307bis") == 0) {
        opts->schema_type = SDAP_SCHEMA_RFC2307BIS;
        default_attr_map = generic_attr_map;
        default_user_map = rfc2307bis_user_map;
        default_group_map = rfc2307bis_group_map;
        default_netgroup_map = netgroup_map;
        default_host_map = host_map;
        default_service_map = service_map;
    } else
    if (strcasecmp(schema, "IPA") == 0) {
        opts->schema_type = SDAP_SCHEMA_IPA_V1;
        default_attr_map = gen_ipa_attr_map;
        default_user_map = rfc2307bis_user_map;
        default_group_map = rfc2307bis_group_map;
        default_netgroup_map = netgroup_map;
        default_host_map = host_map;
        default_service_map = service_map;
    } else
    if (strcasecmp(schema, "AD") == 0) {
        opts->schema_type = SDAP_SCHEMA_AD;
        default_attr_map = gen_ad_attr_map;
        default_user_map = gen_ad2008r2_user_map;
        default_group_map = gen_ad2008r2_group_map;
        default_netgroup_map = netgroup_map;
        default_host_map = host_map;
        default_service_map = service_map;
    } else {
        DEBUG(SSSDBG_FATAL_FAILURE, "Unrecognized schema type: %s\n", schema);
        ret = EINVAL;
        goto done;
    }

    /* pwmodify mode */
    pwmodify = dp_opt_get_string(opts->basic, SDAP_PWMODIFY_MODE);
    if (strcasecmp(pwmodify, "exop") == 0) {
        opts->pwmodify_mode = SDAP_PWMODIFY_EXOP;
    } else if (strcasecmp(pwmodify, "ldap_modify") == 0) {
        opts->pwmodify_mode = SDAP_PWMODIFY_LDAP;
    } else {
        DEBUG(SSSDBG_FATAL_FAILURE, "Unrecognized pwmodify mode: %s\n", pwmodify);
        ret = EINVAL;
        goto done;
    }

    ret = sdap_get_map(opts, cdb, conf_path,
                       default_attr_map,
                       SDAP_AT_GENERAL,
                       &opts->gen_map);
    if (ret != EOK) {
        goto done;
    }

    ret = sdap_get_map(opts, cdb, conf_path,
                       default_user_map,
                       SDAP_OPTS_USER,
                       &opts->user_map);
    if (ret != EOK) {
        goto done;
    }

    ret = sdap_extend_map_with_list(opts, opts, SDAP_USER_EXTRA_ATTRS,
                                    opts->user_map, SDAP_OPTS_USER,
                                    &opts->user_map, &opts->user_map_cnt);
    if (ret != EOK) {
        goto done;
    }

    ret = sdap_get_map(opts, cdb, conf_path,
                       default_group_map,
                       SDAP_OPTS_GROUP,
                       &opts->group_map);
    if (ret != EOK) {
        goto done;
    }

    ret = sdap_get_map(opts, cdb, conf_path,
                       default_netgroup_map,
                       SDAP_OPTS_NETGROUP,
                       &opts->netgroup_map);
    if (ret != EOK) {
        goto done;
    }

    ret = sdap_get_map(opts, cdb, conf_path,
                       default_host_map,
                       SDAP_OPTS_HOST,
                       &opts->host_map);
    if (ret != EOK) {
        goto done;
    }

    ret = sdap_get_map(opts, cdb, conf_path,
                       default_service_map,
                       SDAP_OPTS_SERVICES,
                       &opts->service_map);
    if (ret != EOK) {
        goto done;
    }

    /* If there is no KDC, try the deprecated krb5_kdcip option, too */
    /* FIXME - this can be removed in a future version */
    ret = krb5_try_kdcip(cdb, conf_path, opts->basic, SDAP_KRB5_KDC);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, "sss_krb5_try_kdcip failed.\n");
        goto done;
    }

    authtok_type = dp_opt_get_string(opts->basic, SDAP_DEFAULT_AUTHTOK_TYPE);
    if (authtok_type != NULL &&
        strcasecmp(authtok_type,"obfuscated_password") == 0) {
        DEBUG(SSSDBG_TRACE_ALL, "Found obfuscated password, "
                  "trying to convert to cleartext.\n");

        authtok_blob = dp_opt_get_blob(opts->basic, SDAP_DEFAULT_AUTHTOK);
        if (authtok_blob.data == NULL || authtok_blob.length == 0) {
            DEBUG(SSSDBG_CRIT_FAILURE, "Missing obfuscated password string.\n");
            ret = EINVAL;
            goto done;
        }

        ret = sss_password_decrypt(memctx, (char *) authtok_blob.data,
                                   &cleartext);
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, "Cannot convert the obfuscated "
                      "password back to cleartext\n");
            goto done;
        }

        authtok_blob.data = (uint8_t *) cleartext;
        authtok_blob.length = strlen(cleartext);
        ret = dp_opt_set_blob(opts->basic, SDAP_DEFAULT_AUTHTOK, authtok_blob);
        talloc_free(cleartext);
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, "dp_opt_set_string failed.\n");
            goto done;
        }

        ret = dp_opt_set_string(opts->basic, SDAP_DEFAULT_AUTHTOK_TYPE,
                                "password");
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, "dp_opt_set_string failed.\n");
            goto done;
        }
    }

    ret = EOK;
    *_opts = opts;

done:
    if (ret != EOK) {
        talloc_zfree(opts);
    }
    return ret;
}
Пример #18
0
errno_t setup_tls_config(struct dp_option *basic_opts)
{
    int ret;
    int ldap_opt_x_tls_require_cert;
    const char *tls_opt;
    tls_opt = dp_opt_get_string(basic_opts, SDAP_TLS_REQCERT);
    if (tls_opt) {
        if (strcasecmp(tls_opt, "never") == 0) {
            ldap_opt_x_tls_require_cert = LDAP_OPT_X_TLS_NEVER;
        }
        else if (strcasecmp(tls_opt, "allow") == 0) {
            ldap_opt_x_tls_require_cert = LDAP_OPT_X_TLS_ALLOW;
        }
        else if (strcasecmp(tls_opt, "try") == 0) {
            ldap_opt_x_tls_require_cert = LDAP_OPT_X_TLS_TRY;
        }
        else if (strcasecmp(tls_opt, "demand") == 0) {
            ldap_opt_x_tls_require_cert = LDAP_OPT_X_TLS_DEMAND;
        }
        else if (strcasecmp(tls_opt, "hard") == 0) {
            ldap_opt_x_tls_require_cert = LDAP_OPT_X_TLS_HARD;
        }
        else {
            DEBUG(1, ("Unknown value for tls_reqcert.\n"));
            return EINVAL;
        }
        /* LDAP_OPT_X_TLS_REQUIRE_CERT has to be set as a global option,
         * because the SSL/TLS context is initialized from this value. */
        ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,
                              &ldap_opt_x_tls_require_cert);
        if (ret != LDAP_OPT_SUCCESS) {
            DEBUG(1, ("ldap_set_option failed: %s\n", sss_ldap_err2string(ret)));
            return EIO;
        }
    }

    tls_opt = dp_opt_get_string(basic_opts, SDAP_TLS_CACERT);
    if (tls_opt) {
        ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, tls_opt);
        if (ret != LDAP_OPT_SUCCESS) {
            DEBUG(1, ("ldap_set_option failed: %s\n", sss_ldap_err2string(ret)));
            return EIO;
        }
    }

    tls_opt = dp_opt_get_string(basic_opts, SDAP_TLS_CACERTDIR);
    if (tls_opt) {
        ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTDIR, tls_opt);
        if (ret != LDAP_OPT_SUCCESS) {
            DEBUG(1, ("ldap_set_option failed: %s\n", sss_ldap_err2string(ret)));
            return EIO;
        }
    }

    tls_opt = dp_opt_get_string(basic_opts, SDAP_TLS_CERT);
    if (tls_opt) {
        ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CERTFILE, tls_opt);
        if (ret != LDAP_OPT_SUCCESS) {
            DEBUG(1, ("ldap_set_option failed: %s\n", sss_ldap_err2string(ret)));
            return EIO;
        }
    }

    tls_opt = dp_opt_get_string(basic_opts, SDAP_TLS_KEY);
    if (tls_opt) {
        ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_KEYFILE, tls_opt);
        if (ret != LDAP_OPT_SUCCESS) {
            DEBUG(1, ("ldap_set_option failed: %s\n", sss_ldap_err2string(ret)));
            return EIO;
        }
    }

    tls_opt = dp_opt_get_string(basic_opts, SDAP_TLS_CIPHER_SUITE);
    if (tls_opt) {
        ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CIPHER_SUITE, tls_opt);
        if (ret != LDAP_OPT_SUCCESS) {
            DEBUG(1, ("ldap_set_option failed: %s\n", sss_ldap_err2string(ret)));
            return EIO;
        }
    }

    return EOK;
}
Пример #19
0
int sssm_ldap_id_init(struct be_ctx *bectx,
                      struct bet_ops **ops,
                      void **pvt_data)
{
    struct sdap_id_ctx *ctx = NULL;
    const char *urls;
    const char *backup_urls;
    const char *dns_service_name;
    const char *sasl_mech;
    struct sdap_service *sdap_service;
    struct sdap_options *opts = NULL;
    int ret;

    /* If we're already set up, just return that */
    if(bectx->bet_info[BET_ID].mod_name &&
       strcmp("ldap", bectx->bet_info[BET_ID].mod_name) == 0) {
        DEBUG(8, ("Re-using sdap_id_ctx for this provider\n"));
        *ops = bectx->bet_info[BET_ID].bet_ops;
        *pvt_data = bectx->bet_info[BET_ID].pvt_bet_data;
        return EOK;
    }

    ret = ldap_get_options(bectx, bectx->domain, bectx->cdb,
                           bectx->conf_path, &opts);
    if (ret != EOK) {
        goto done;
    }

    dns_service_name = dp_opt_get_string(opts->basic,
                                         SDAP_DNS_SERVICE_NAME);
    DEBUG(SSSDBG_CONF_SETTINGS,
          ("Service name for discovery set to %s\n", dns_service_name));

    urls = dp_opt_get_string(opts->basic, SDAP_URI);
    backup_urls = dp_opt_get_string(opts->basic, SDAP_BACKUP_URI);

    ret = sdap_service_init(bectx, bectx, "LDAP",
                            dns_service_name, urls, backup_urls,
                            &sdap_service);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE, ("Failed to initialize failover service!\n"));
        goto done;
    }

    ctx = sdap_id_ctx_new(bectx, bectx, sdap_service);
    if (!ctx) {
        ret = ENOMEM;
        goto done;
    }
    ctx->opts = talloc_steal(ctx, opts);

    sasl_mech = dp_opt_get_string(ctx->opts->basic, SDAP_SASL_MECH);
    if (sasl_mech && strcasecmp(sasl_mech, "GSSAPI") == 0) {
        if (dp_opt_get_bool(ctx->opts->basic, SDAP_KRB5_KINIT)) {
            ret = sdap_gssapi_init(ctx, ctx->opts->basic,
                                   ctx->be, ctx->conn->service,
                                   &ctx->krb5_service);
            if (ret !=  EOK) {
                DEBUG(1, ("sdap_gssapi_init failed [%d][%s].\n",
                            ret, strerror(ret)));
                goto done;
            }
        }
    }

    ret = setup_tls_config(ctx->opts->basic);
    if (ret != EOK) {
        DEBUG(1, ("setup_tls_config failed [%d][%s].\n",
                  ret, strerror(ret)));
        goto done;
    }

    /* Set up the ID mapping object */
    ret = sdap_idmap_init(ctx, ctx, &ctx->opts->idmap_ctx);
    if (ret != EOK) goto done;

    ret = ldap_id_setup_tasks(ctx);
    if (ret != EOK) {
        goto done;
    }

    ret = sdap_setup_child();
    if (ret != EOK) {
        DEBUG(1, ("setup_child failed [%d][%s].\n",
                  ret, strerror(ret)));
        goto done;
    }

    /* setup SRV lookup plugin */
    ret = be_fo_set_dns_srv_lookup_plugin(bectx, NULL);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to set SRV lookup plugin "
                                    "[%d]: %s\n", ret, strerror(ret)));
        goto done;
    }

    /* setup periodical refresh of expired records */
    ret = be_refresh_add_cb(bectx->refresh_ctx, BE_REFRESH_TYPE_NETGROUPS,
                            sdap_refresh_netgroups_send,
                            sdap_refresh_netgroups_recv,
                            ctx);
    if (ret != EOK && ret != EEXIST) {
        DEBUG(SSSDBG_MINOR_FAILURE, ("Periodical refresh of netgroups "
              "will not work [%d]: %s\n", ret, strerror(ret)));
    }

    *ops = &sdap_id_ops;
    *pvt_data = ctx;
    ret = EOK;

done:
    if (ret != EOK) {
        talloc_free(opts);
        talloc_free(ctx);
    }
    return ret;
}
Пример #20
0
int sssm_ldap_id_init(struct be_ctx *bectx,
                      struct bet_ops **ops,
                      void **pvt_data)
{
    struct sdap_id_ctx *ctx;
    const char *urls;
    const char *dns_service_name;
    const char *sasl_mech;
    int ret;

    /* If we're already set up, just return that */
    if(bectx->bet_info[BET_ID].mod_name &&
       strcmp("ldap", bectx->bet_info[BET_ID].mod_name) == 0) {
        DEBUG(8, ("Re-using sdap_id_ctx for this provider\n"));
        *ops = bectx->bet_info[BET_ID].bet_ops;
        *pvt_data = bectx->bet_info[BET_ID].pvt_bet_data;
        return EOK;
    }

    ctx = talloc_zero(bectx, struct sdap_id_ctx);
    if (!ctx) return ENOMEM;

    ctx->be = bectx;

    ret = ldap_get_options(ctx, bectx->cdb,
                           bectx->conf_path, &ctx->opts);
    if (ret != EOK) {
        goto done;
    }

    dns_service_name = dp_opt_get_string(ctx->opts->basic,
                                         SDAP_DNS_SERVICE_NAME);
    DEBUG(7, ("Service name for discovery set to %s\n", dns_service_name));

    urls = dp_opt_get_string(ctx->opts->basic, SDAP_URI);
    if (!urls) {
        DEBUG(1, ("Missing ldap_uri, will use service discovery\n"));
    }

    ret = sdap_service_init(ctx, ctx->be, "LDAP",
                            dns_service_name, urls, &ctx->service);
    if (ret != EOK) {
        DEBUG(1, ("Failed to initialize failover service!\n"));
        goto done;
    }

    sasl_mech = dp_opt_get_string(ctx->opts->basic, SDAP_SASL_MECH);
    if (sasl_mech && strcasecmp(sasl_mech, "GSSAPI") == 0) {
        if (dp_opt_get_bool(ctx->opts->basic, SDAP_KRB5_KINIT)) {
            ret = sdap_gssapi_init(ctx, ctx->opts->basic,
                                   ctx->be, ctx->service,
                                   &ctx->krb5_service);
            if (ret !=  EOK) {
                DEBUG(1, ("sdap_gssapi_init failed [%d][%s].\n",
                            ret, strerror(ret)));
                goto done;
            }
        }
    }

    ret = setup_tls_config(ctx->opts->basic);
    if (ret != EOK) {
        DEBUG(1, ("setup_tls_config failed [%d][%s].\n",
                  ret, strerror(ret)));
        goto done;
    }

    ret = sdap_id_conn_cache_create(ctx, ctx, &ctx->conn_cache);
    if (ret != EOK) {
        goto done;
    }

    ret = sdap_id_setup_tasks(ctx);
    if (ret != EOK) {
        goto done;
    }

    ret = setup_child(ctx);
    if (ret != EOK) {
        DEBUG(1, ("setup_child failed [%d][%s].\n",
                  ret, strerror(ret)));
        goto done;
    }

    *ops = &sdap_id_ops;
    *pvt_data = ctx;
    ret = EOK;

done:
    if (ret != EOK) {
        talloc_free(ctx);
    }
    return ret;
}
Пример #21
0
int sssm_ipa_id_init(struct be_ctx *bectx,
                     struct bet_ops **ops,
                     void **pvt_data)
{
    struct ipa_id_ctx *ipa_ctx;
    struct sdap_id_ctx *sdap_ctx;
    const char *hostname;
    const char *ipa_domain;
    const char *ipa_servers;
    struct ipa_srv_plugin_ctx *srv_ctx;
    bool server_mode;
    int ret;

    if (!ipa_options) {
        ret = common_ipa_init(bectx);
        if (ret != EOK) {
            return ret;
        }
    }

    if (ipa_options->id_ctx) {
        /* already initialized */
        *ops = &ipa_id_ops;
        *pvt_data = ipa_options->id_ctx;
        return EOK;
    }

    ipa_ctx = talloc_zero(ipa_options, struct ipa_id_ctx);
    if (!ipa_ctx) {
        return ENOMEM;
    }
    ipa_options->id_ctx = ipa_ctx;
    ipa_ctx->ipa_options = ipa_options;

    sdap_ctx = sdap_id_ctx_new(ipa_options, bectx, ipa_options->service->sdap);
    if (sdap_ctx == NULL) {
        return ENOMEM;
    }
    ipa_ctx->sdap_id_ctx = sdap_ctx;

    ret = ipa_get_id_options(ipa_options, bectx->cdb,
                             bectx->conf_path,
                             &sdap_ctx->opts);
    if (ret != EOK) {
        goto done;
    }

    ret = ipa_get_dyndns_options(bectx, ipa_options);
    if (ret != EOK) {
        goto done;
    }

    if (dp_opt_get_bool(ipa_options->dyndns_ctx->opts, DP_OPT_DYNDNS_UPDATE)) {
        /* Perform automatic DNS updates when the
         * IP address changes.
         * Register a callback for successful LDAP
         * reconnections. This is the easiest way to
         * identify that we have gone online.
         */

        DEBUG(SSSDBG_CONF_SETTINGS,
              "Dynamic DNS updates are on. Checking for nsupdate..\n");
        ret = be_nsupdate_check();
        if (ret == EOK) {
            /* nsupdate is available. Dynamic updates
             * are supported
             */
            ret = ipa_dyndns_init(sdap_ctx->be, ipa_options);
            if (ret != EOK) {
                DEBUG(SSSDBG_CRIT_FAILURE,
                      "Failure setting up automatic DNS update\n");
                /* We will continue without DNS updating */
            }
        }
    }

    ret = setup_tls_config(sdap_ctx->opts->basic);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, "setup_tls_config failed [%d][%s].\n",
                  ret, strerror(ret));
        goto done;
    }


    /* Set up the ID mapping object */
    ret = ipa_idmap_init(sdap_ctx, sdap_ctx, &sdap_ctx->opts->idmap_ctx);
    if (ret != EOK) {
        DEBUG(SSSDBG_FATAL_FAILURE,
              "Could not initialize ID mapping. In case ID mapping properties "
              "changed on the server, please remove the SSSD database\n");
        goto done;
    }


    ret = ldap_id_setup_tasks(sdap_ctx);
    if (ret != EOK) {
        goto done;
    }

    ret = sdap_setup_child();
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, "setup_child failed [%d][%s].\n",
                  ret, strerror(ret));
        goto done;
    }

    /* setup SRV lookup plugin */
    hostname = dp_opt_get_string(ipa_options->basic, IPA_HOSTNAME);
    server_mode = dp_opt_get_bool(ipa_options->basic, IPA_SERVER_MODE);

    if (server_mode == true) {
        ipa_ctx->view_name = talloc_strdup(ipa_ctx, SYSDB_DEFAULT_VIEW_NAME);
        if (ipa_ctx->view_name == NULL) {
            DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
            ret = ENOMEM;
            goto done;
        }

        ret = sysdb_update_view_name(bectx->domain->sysdb, ipa_ctx->view_name);
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "Cannot add/update view name to sysdb.\n");
            goto done;
        }

        ipa_servers = dp_opt_get_string(ipa_options->basic, IPA_SERVER);
        if (srv_in_server_list(ipa_servers) == true
                || dp_opt_get_bool(ipa_options->basic,
                                   IPA_ENABLE_DNS_SITES) == true) {
            DEBUG(SSSDBG_MINOR_FAILURE, "SRV resolution or IPA sites enabled "
                  "on the IPA server. Site discovery of trusted AD servers "
                  "might not work\n");

            /* If SRV discovery is enabled on the server and
             * dns_discovery_domain is set explicitly, then
             * the current failover code would use the dns_discovery
             * domain to try to find AD servers and fail
             */
            if (dp_opt_get_string(bectx->be_res->opts,
                                  DP_RES_OPT_DNS_DOMAIN)) {
                sss_log(SSS_LOG_ERR, ("SRV discovery is enabled on the IPA "
                        "server while using custom dns_discovery_domain. "
                        "DNS discovery of trusted AD domain will likely fail. "
                        "It is recommended not to use SRV discovery or the "
                        "dns_discovery_domain option for the IPA domain while "
                        "running on the server itself\n"));
                DEBUG(SSSDBG_CRIT_FAILURE, "SRV discovery is enabled on IPA "
                      "server while using custom dns_discovery_domain. "
                      "DNS discovery of trusted AD domain will likely fail. "
                      "It is recommended not to use SRV discovery or the "
                      "dns_discovery_domain option for the IPA domain while "
                      "running on the server itself\n");
            }

            ret = be_fo_set_dns_srv_lookup_plugin(bectx, hostname);
            if (ret != EOK) {
                DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set SRV lookup plugin "
                                            "[%d]: %s\n", ret, strerror(ret));
                goto done;
            }
        } else {
            /* In server mode we need to ignore the dns_discovery_domain if set
             * and only discover servers based on AD domains
             */
            ret = dp_opt_set_string(bectx->be_res->opts, DP_RES_OPT_DNS_DOMAIN,
                                    NULL);
            if (ret != EOK) {
                DEBUG(SSSDBG_MINOR_FAILURE, "Could not reset the "
                    "dns_discovery_domain, trusted AD domains discovery "
                    "might fail. Please remove dns_discovery_domain "
                    "from the config file and restart the SSSD\n");
            } else {
                DEBUG(SSSDBG_CONF_SETTINGS, "The value of dns_discovery_domain "
                      "will be ignored in ipa_server_mode\n");
            }
        }
    } else {
        ret = sysdb_get_view_name(ipa_ctx, bectx->domain->sysdb,
                                  &ipa_ctx->view_name);
        if (ret != EOK) {
            if (ret == ENOENT) {
                DEBUG(SSSDBG_CRIT_FAILURE,
                      "Cannot find view name in the cache. " \
                      "Will do online lookup later.\n");
            } else {
                DEBUG(SSSDBG_OP_FAILURE, "sysdb_get_view_name failed.\n");
                goto done;
            }
        }

        if (dp_opt_get_bool(ipa_options->basic, IPA_ENABLE_DNS_SITES)) {
            /* use IPA plugin */
            ipa_domain = dp_opt_get_string(ipa_options->basic, IPA_DOMAIN);
            srv_ctx = ipa_srv_plugin_ctx_init(bectx, bectx->be_res->resolv,
                                              hostname, ipa_domain);
            if (srv_ctx == NULL) {
                DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n");
                ret = ENOMEM;
                goto done;
            }

            be_fo_set_srv_lookup_plugin(bectx, ipa_srv_plugin_send,
                                        ipa_srv_plugin_recv, srv_ctx, "IPA");
        } else {
            /* fall back to standard plugin on clients. */
            ret = be_fo_set_dns_srv_lookup_plugin(bectx, hostname);
            if (ret != EOK) {
                DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set SRV lookup plugin "
                                            "[%d]: %s\n", ret, strerror(ret));
                goto done;
            }
        }
    }

    /* setup periodical refresh of expired records */
    ret = sdap_refresh_init(bectx->refresh_ctx, sdap_ctx);
    if (ret != EOK && ret != EEXIST) {
        DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh "
              "will not work [%d]: %s\n", ret, strerror(ret));
    }

    ipa_ctx->sdap_id_ctx->opts->ext_ctx = ipa_create_ext_members_ctx(
                                                    ipa_ctx->sdap_id_ctx->opts,
                                                    ipa_ctx);
    if (ipa_ctx->sdap_id_ctx->opts->ext_ctx == NULL) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Unable to set SRV the extrernal group ctx\n");
        ret = ENOMEM;
        goto done;
    }

    *ops = &ipa_id_ops;
    *pvt_data = ipa_ctx;
    ret = EOK;

done:
    if (ret != EOK) {
        talloc_zfree(ipa_options->id_ctx);
    }
    return ret;
}
Пример #22
0
int ldap_get_autofs_options(TALLOC_CTX *memctx,
                            struct confdb_ctx *cdb,
                            const char *conf_path,
                            struct sdap_options *opts)
{
    const char *search_base;
    struct sdap_attr_map *default_entry_map;
    struct sdap_attr_map *default_mobject_map;
    int ret;

    /* search base */
    search_base = dp_opt_get_string(opts->basic, SDAP_SEARCH_BASE);
    if (search_base != NULL) {
        /* set autofs search bases if they are not */
        if (dp_opt_get_string(opts->basic, SDAP_AUTOFS_SEARCH_BASE) == NULL) {
            ret = dp_opt_set_string(opts->basic, SDAP_AUTOFS_SEARCH_BASE,
                                    search_base);
            if (ret != EOK) {
                DEBUG(SSSDBG_OP_FAILURE, "Could not set autofs search base"
                      "to default value\n");
                return ret;
            }

            DEBUG(SSSDBG_FUNC_DATA, "Option %s set to %s\n",
                  opts->basic[SDAP_AUTOFS_SEARCH_BASE].opt_name,
                  dp_opt_get_string(opts->basic, SDAP_AUTOFS_SEARCH_BASE));
        }
    } else {
        DEBUG(SSSDBG_TRACE_FUNC, "Search base not set, trying to discover it later "
              "connecting to the LDAP server.\n");
    }

    if (opts->schema_type == SDAP_SCHEMA_RFC2307 &&
            ldap_rfc2307_autofs_defaults(cdb, conf_path) == true) {
        DEBUG(SSSDBG_IMPORTANT_INFO,
              "Your configuration uses the autofs provider "
              "with schema set to rfc2307 and default attribute mappings. "
              "The default map has changed in this release, please make "
              "sure the configuration matches the server attributes.\n");
        sss_log(SSS_LOG_NOTICE,
                _("Your configuration uses the autofs provider "
                  "with schema set to rfc2307 and default attribute mappings. "
                  "The default map has changed in this release, please make "
                  "sure the configuration matches the server attributes.\n"));
    }

    ret = sdap_parse_search_base(opts, opts->basic,
                                 SDAP_AUTOFS_SEARCH_BASE,
                                 &opts->sdom->autofs_search_bases);
    if (ret != EOK && ret != ENOENT) {
        DEBUG(SSSDBG_OP_FAILURE, "Could not parse autofs search base\n");
        return ret;
    }

    /* attribute maps */
    switch (opts->schema_type) {
        case SDAP_SCHEMA_RFC2307:
            default_mobject_map = rfc2307_autofs_mobject_map;
            default_entry_map = rfc2307_autofs_entry_map;
            break;
        case SDAP_SCHEMA_RFC2307BIS:
        case SDAP_SCHEMA_IPA_V1:
        case SDAP_SCHEMA_AD:
            default_mobject_map = rfc2307bis_autofs_mobject_map;
            default_entry_map = rfc2307bis_autofs_entry_map;
            break;
        default:
            DEBUG(SSSDBG_CRIT_FAILURE, "Unknown LDAP schema!\n");
            return EINVAL;
    }

    ret = sdap_get_map(opts, cdb, conf_path,
                       default_mobject_map,
                       SDAP_OPTS_AUTOFS_MAP,
                       &opts->autofs_mobject_map);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE,
              "Could not get autofs map object attribute map\n");
        return ret;
    }

    ret = sdap_get_map(opts, cdb, conf_path,
                       default_entry_map,
                       SDAP_OPTS_AUTOFS_ENTRY,
                       &opts->autofs_entry_map);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE,
              "Could not get autofs entry object attribute map\n");
        return ret;
    }

    return EOK;
}
Пример #23
0
static errno_t
ipa_ad_ctx_new(struct be_ctx *be_ctx,
               struct ipa_id_ctx *id_ctx,
               struct sss_domain_info *subdom,
               struct ad_id_ctx **_ad_id_ctx)
{
    struct ad_options *ad_options;
    struct ad_id_ctx *ad_id_ctx;
    const char *gc_service_name;
    const char *service_name;
    struct ad_srv_plugin_ctx *srv_ctx;
    const char *ad_domain;
    const char *ad_site_override;
    struct sdap_domain *sdom;
    errno_t ret;
    const char *extra_attrs;

    ad_domain = subdom->name;
    DEBUG(SSSDBG_TRACE_LIBS, "Setting up AD subdomain %s\n", subdom->name);

    ad_options = ipa_ad_options_new(id_ctx, subdom);
    if (ad_options == NULL) {
        DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD options\n");
        talloc_free(ad_options);
        return ENOMEM;
    }

    extra_attrs = dp_opt_get_string(id_ctx->sdap_id_ctx->opts->basic,
                            SDAP_USER_EXTRA_ATTRS);
    if (extra_attrs != NULL) {
        DEBUG(SSSDBG_TRACE_ALL,
              "Setting extra attrs for subdomain [%s] to [%s].\n", ad_domain,
                                                                   extra_attrs);

        ret = dp_opt_set_string(ad_options->id->basic, SDAP_USER_EXTRA_ATTRS,
                                extra_attrs);
        if (ret != EOK) {
            DEBUG(SSSDBG_OP_FAILURE, "dp_opt_get_string failed.\n");
            talloc_free(ad_options);
            return ret;
        }

        ret = sdap_extend_map_with_list(ad_options->id, ad_options->id,
                                        SDAP_USER_EXTRA_ATTRS,
                                        ad_options->id->user_map,
                                        SDAP_OPTS_USER,
                                        &ad_options->id->user_map,
                                        &ad_options->id->user_map_cnt);
        if (ret != EOK) {
            DEBUG(SSSDBG_OP_FAILURE, "sdap_extend_map_with_list failed.\n");
            talloc_free(ad_options);
            return ret;
        }
    } else {
        DEBUG(SSSDBG_TRACE_ALL, "No extra attrs set.\n");
    }

    gc_service_name = talloc_asprintf(ad_options, "sd_gc_%s", subdom->forest);
    if (gc_service_name == NULL) {
        talloc_free(ad_options);
        return ENOMEM;
    }

    service_name = talloc_asprintf(ad_options, "sd_%s", subdom->name);
    if (service_name == NULL) {
        talloc_free(ad_options);
        return ENOMEM;
    }

    /* Set KRB5 realm to same as the one of IPA when IPA
     * is able to attach PAC. For testing, use hardcoded. */
    ret = ad_failover_init(ad_options, be_ctx, NULL, NULL,
                           id_ctx->server_mode->realm,
                           service_name, gc_service_name,
                           subdom->name, &ad_options->service);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD failover\n");
        talloc_free(ad_options);
        return ret;
    }

    ad_id_ctx = ad_id_ctx_init(ad_options, be_ctx);
    if (ad_id_ctx == NULL) {
        talloc_free(ad_options);
        return ENOMEM;
    }
    ad_id_ctx->sdap_id_ctx->opts = ad_options->id;
    ad_options->id_ctx = ad_id_ctx;

    ad_site_override = dp_opt_get_string(ad_options->basic, AD_SITE);

    /* use AD plugin */
    srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx->be_res,
                                     default_host_dbs,
                                     ad_id_ctx->ad_options->id,
                                     id_ctx->server_mode->hostname,
                                     ad_domain,
                                     ad_site_override);
    if (srv_ctx == NULL) {
        DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n");
        return ENOMEM;
    }
    be_fo_set_srv_lookup_plugin(be_ctx, ad_srv_plugin_send,
                                ad_srv_plugin_recv, srv_ctx, "AD");

    ret = sdap_domain_subdom_add(ad_id_ctx->sdap_id_ctx,
                                 ad_id_ctx->sdap_id_ctx->opts->sdom,
                                 subdom->parent);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize sdap domain\n");
        talloc_free(ad_options);
        return ret;
    }

    sdom = sdap_domain_get(ad_id_ctx->sdap_id_ctx->opts, subdom);
    if (sdom == NULL) {
        return EFAULT;
    }

    sdap_inherit_options(subdom->parent->sd_inherit,
                         id_ctx->sdap_id_ctx->opts,
                         ad_id_ctx->sdap_id_ctx->opts);

    ret = sdap_id_setup_tasks(be_ctx,
                              ad_id_ctx->sdap_id_ctx,
                              sdom,
                              ldap_enumeration_send,
                              ldap_enumeration_recv,
                              ad_id_ctx->sdap_id_ctx);
    if (ret != EOK) {
        talloc_free(ad_options);
        return ret;
    }

    sdom->pvt = ad_id_ctx;

    /* Set up the ID mapping object */
    ad_id_ctx->sdap_id_ctx->opts->idmap_ctx =
        id_ctx->sdap_id_ctx->opts->idmap_ctx;

    *_ad_id_ctx = ad_id_ctx;
    return EOK;
}
Пример #24
0
errno_t check_and_export_options(struct dp_option *opts,
                                 struct sss_domain_info *dom,
                                 struct krb5_ctx *krb5_ctx)
{
    int ret;
    const char *realm;
    const char *dummy;
    char *use_fast_str;
    char *fast_principal;
    enum sss_krb5_cc_type cc_be;

    realm = dp_opt_get_cstring(opts, KRB5_REALM);
    if (realm == NULL) {
        ret = dp_opt_set_string(opts, KRB5_REALM, dom->name);
        if (ret != EOK) {
            DEBUG(1, ("dp_opt_set_string failed.\n"));
            return ret;
        }
        realm = dom->name;
    }

    ret = setenv(SSSD_KRB5_REALM, realm, 1);
    if (ret != EOK) {
        DEBUG(2, ("setenv %s failed, authentication might fail.\n",
                  SSSD_KRB5_REALM));
    }

    ret = check_and_export_lifetime(opts, KRB5_RENEWABLE_LIFETIME,
                                    SSSD_KRB5_RENEWABLE_LIFETIME);
    if (ret != EOK) {
        DEBUG(1, ("Failed to check value of krb5_renewable_lifetime. [%d][%s]\n",
                  ret, strerror(ret)));
        return ret;
    }

    ret = check_and_export_lifetime(opts, KRB5_LIFETIME,
                                    SSSD_KRB5_LIFETIME);
    if (ret != EOK) {
        DEBUG(1, ("Failed to check value of krb5_lifetime. [%d][%s]\n",
                  ret, strerror(ret)));
        return ret;
    }


    use_fast_str = dp_opt_get_string(opts, KRB5_USE_FAST);
    if (use_fast_str != NULL) {
        ret = check_fast(use_fast_str, &krb5_ctx->use_fast);
        if (ret != EOK) {
            DEBUG(1, ("check_fast failed.\n"));
            return ret;
        }

        if (krb5_ctx->use_fast) {
            ret = setenv(SSSD_KRB5_USE_FAST, use_fast_str, 1);
            if (ret != EOK) {
                DEBUG(2, ("setenv [%s] failed.\n", SSSD_KRB5_USE_FAST));
            } else {
                fast_principal = dp_opt_get_string(opts, KRB5_FAST_PRINCIPAL);
                if (fast_principal != NULL) {
                    ret = setenv(SSSD_KRB5_FAST_PRINCIPAL, fast_principal, 1);
                    if (ret != EOK) {
                        DEBUG(2, ("setenv [%s] failed.\n", SSSD_KRB5_FAST_PRINCIPAL));
                    }
                }
            }
        }
    }

    if (dp_opt_get_bool(opts, KRB5_CANONICALIZE)) {
        ret = setenv(SSSD_KRB5_CANONICALIZE, "true", 1);
    } else {
        ret = setenv(SSSD_KRB5_CANONICALIZE, "false", 1);
    }
    if (ret != EOK) {
        DEBUG(2, ("setenv [%s] failed.\n", SSSD_KRB5_CANONICALIZE));
    }

    dummy = dp_opt_get_cstring(opts, KRB5_KDC);
    if (dummy == NULL) {
        DEBUG(SSSDBG_CONF_SETTINGS, ("No KDC explicitly configured, using defaults.\n"));
    }

    dummy = dp_opt_get_cstring(opts, KRB5_KPASSWD);
    if (dummy == NULL) {
        DEBUG(SSSDBG_CONF_SETTINGS, ("No kpasswd server explicitly configured, "
                                     "using the KDC or defaults.\n"));
    }

    dummy = dp_opt_get_cstring(opts, KRB5_CCNAME_TMPL);
    if (dummy == NULL) {
        DEBUG(1, ("Missing credential cache name template.\n"));
        return EINVAL;
    }

    cc_be = sss_krb5_get_type(dummy);
    switch (cc_be) {
    case SSS_KRB5_TYPE_FILE:
        DEBUG(SSSDBG_CONF_SETTINGS, ("ccache is of type FILE\n"));
        krb5_ctx->cc_be = &file_cc;
        if (dummy[0] != '/') {
            /* FILE:/path/to/cc */
            break;
        }

        DEBUG(SSSDBG_CONF_SETTINGS, ("The ccname template was "
              "missing an explicit type, but is an absolute "
              "path specifier. Assuming FILE:\n"));

        dummy = talloc_asprintf(opts, "FILE:%s", dummy);
        if (!dummy) return ENOMEM;

        ret = dp_opt_set_string(opts, KRB5_CCNAME_TMPL, dummy);
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, ("dp_opt_set_string failed.\n"));
            return ret;
        }
        break;

#ifdef HAVE_KRB5_DIRCACHE
    case SSS_KRB5_TYPE_DIR:
        DEBUG(SSSDBG_CONF_SETTINGS, ("ccache is of type DIR\n"));
        krb5_ctx->cc_be = &dir_cc;
        break;
#endif

    default:
        DEBUG(SSSDBG_OP_FAILURE, ("Unknown ccname database\n"));
        return EINVAL;
        break;
    }

    return EOK;
}
Пример #25
0
int ipa_get_options(TALLOC_CTX *memctx,
                    struct confdb_ctx *cdb,
                    const char *conf_path,
                    struct sss_domain_info *dom,
                    struct ipa_options **_opts)
{
    struct ipa_options *opts;
    char *domain;
    char *server;
    char *realm;
    char *ipa_hostname;
    int ret;
    char hostname[HOST_NAME_MAX + 1];

    opts = talloc_zero(memctx, struct ipa_options);
    if (!opts) return ENOMEM;

    ret = dp_get_options(opts, cdb, conf_path,
                         ipa_basic_opts,
                         IPA_OPTS_BASIC,
                         &opts->basic);
    if (ret != EOK) {
        goto done;
    }

    domain = dp_opt_get_string(opts->basic, IPA_DOMAIN);
    if (!domain) {
        ret = dp_opt_set_string(opts->basic, IPA_DOMAIN, dom->name);
        if (ret != EOK) {
            goto done;
        }
        domain = dom->name;
    }

    server = dp_opt_get_string(opts->basic, IPA_SERVER);
    if (!server) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "No ipa server set, will use service discovery!\n");
    }

    ipa_hostname = dp_opt_get_string(opts->basic, IPA_HOSTNAME);
    if (ipa_hostname == NULL) {
        ret = gethostname(hostname, HOST_NAME_MAX);
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, "gethostname failed [%d][%s].\n", errno,
                      strerror(errno));
            ret = errno;
            goto done;
        }
        hostname[HOST_NAME_MAX] = '\0';
        DEBUG(SSSDBG_TRACE_ALL, "Setting ipa_hostname to [%s].\n", hostname);
        ret = dp_opt_set_string(opts->basic, IPA_HOSTNAME, hostname);
        if (ret != EOK) {
            goto done;
        }
    }

    /* First check whether the realm has been manually specified */
    realm = dp_opt_get_string(opts->basic, IPA_KRB5_REALM);
    if (!realm) {
        /* No explicit krb5_realm, use the IPA domain, transform to upper-case */
        realm = get_uppercase_realm(opts, domain);
        if (!realm) {
            ret = ENOMEM;
            goto done;
        }

        ret = dp_opt_set_string(opts->basic, IPA_KRB5_REALM,
                                realm);
        if (ret != EOK) {
            goto done;
        }
    }

    ret = EOK;
    *_opts = opts;

done:
    if (ret != EOK) {
        talloc_zfree(opts);
    }
    return ret;
}
Пример #26
0
errno_t
sdap_idmap_init(TALLOC_CTX *mem_ctx,
                struct sdap_id_ctx *id_ctx,
                struct sdap_idmap_ctx **_idmap_ctx)
{
    errno_t ret;
    TALLOC_CTX *tmp_ctx;
    enum idmap_error_code err;
    size_t i;
    struct ldb_result *res;
    const char *dom_name;
    const char *sid_str;
    id_t slice_num;
    id_t idmap_lower;
    id_t idmap_upper;
    id_t rangesize;
    bool autorid_mode;
    struct sdap_idmap_ctx *idmap_ctx = NULL;

    tmp_ctx = talloc_new(NULL);
    if (!tmp_ctx) return ENOMEM;

    idmap_ctx = talloc_zero(tmp_ctx, struct sdap_idmap_ctx);
    if (!idmap_ctx) {
        ret = ENOMEM;
        goto done;
    }
    idmap_ctx->id_ctx = id_ctx;
    idmap_ctx->find_new_domain = sdap_idmap_find_new_domain;

    idmap_lower = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic,
                                 SDAP_IDMAP_LOWER);
    idmap_upper = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic,
                                 SDAP_IDMAP_UPPER);
    rangesize = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic,
                               SDAP_IDMAP_RANGESIZE);
    autorid_mode = dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic,
                                   SDAP_IDMAP_AUTORID_COMPAT);

    /* Validate that the values make sense */
    if (rangesize <= 0
            || idmap_upper <= idmap_lower
            || (idmap_upper-idmap_lower) < rangesize)
    {
        DEBUG(SSSDBG_FATAL_FAILURE,
              "Invalid settings for range selection: "
               "[%"SPRIid"][%"SPRIid"][%"SPRIid"]\n",
               idmap_lower, idmap_upper, rangesize);
        ret = EINVAL;
        goto done;
    }

    if (((idmap_upper - idmap_lower) % rangesize) != 0) {
        DEBUG(SSSDBG_CONF_SETTINGS,
              "Range size does not divide evenly. Uppermost range will "
               "not be used\n");
    }

    /* Initialize the map */
    err = sss_idmap_init(sss_idmap_talloc, idmap_ctx,
                         sss_idmap_talloc_free,
                         &idmap_ctx->map);
    if (err != IDMAP_SUCCESS) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Could not initialize the ID map: [%s]\n",
               idmap_error_string(err));
        if (err == IDMAP_OUT_OF_MEMORY) {
            ret = ENOMEM;
        } else {
            ret = EINVAL;
        }
        goto done;
    }

    err = sss_idmap_ctx_set_autorid(idmap_ctx->map, autorid_mode);
    err |= sss_idmap_ctx_set_lower(idmap_ctx->map, idmap_lower);
    err |= sss_idmap_ctx_set_upper(idmap_ctx->map, idmap_upper);
    err |= sss_idmap_ctx_set_rangesize(idmap_ctx->map, rangesize);
    if (err != IDMAP_SUCCESS) {
        /* This should never happen */
        DEBUG(SSSDBG_CRIT_FAILURE, "sss_idmap_ctx corrupted\n");
        return EIO;
    }


    /* Setup range for externally managed IDs, i.e. IDs are read from the
     * ldap_user_uid_number and ldap_group_gid_number attributes. */
    if (!dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic, SDAP_ID_MAPPING)) {
        ret = sdap_idmap_add_configured_external_range(idmap_ctx);
        if (ret != EOK) {
            DEBUG(SSSDBG_OP_FAILURE,
                  "sdap_idmap_add_configured_external_range failed.\n");
            goto done;
        }
    }

    /* Read in any existing mappings from the cache */
    ret = sysdb_idmap_get_mappings(tmp_ctx, id_ctx->be->domain, &res);
    if (ret != EOK && ret != ENOENT) {
        DEBUG(SSSDBG_FATAL_FAILURE,
              "Could not read ID mappings from the cache: [%s]\n",
               strerror(ret));
        goto done;
    }

    if (ret == EOK && res->count > 0) {
        DEBUG(SSSDBG_CONF_SETTINGS,
              "Initializing [%d] domains for ID-mapping\n", res->count);

        for (i = 0; i < res->count; i++) {
            dom_name = ldb_msg_find_attr_as_string(res->msgs[i],
                                                   SYSDB_NAME,
                                                   NULL);
            if (!dom_name) {
                /* This should never happen */
                ret = EINVAL;
                goto done;
            }

            sid_str = ldb_msg_find_attr_as_string(res->msgs[i],
                                                  SYSDB_IDMAP_SID_ATTR,
                                                  NULL);
            if (!sid_str) {
                /* This should never happen */
                ret = EINVAL;
                goto done;
            }

            slice_num = ldb_msg_find_attr_as_int(res->msgs[i],
                                                 SYSDB_IDMAP_SLICE_ATTR,
                                                 -1);
            if (slice_num == -1) {
                /* This should never happen */
                ret = EINVAL;
                goto done;
            }

            ret = sdap_idmap_add_domain(idmap_ctx, dom_name,
                                        sid_str, slice_num);
            if (ret != EOK) {
                DEBUG(SSSDBG_CRIT_FAILURE,
                      "Could not add domain [%s][%s][%"SPRIid"] "
                       "to ID map: [%s]\n",
                       dom_name, sid_str, slice_num, strerror(ret));
                goto done;
            }
        }
    } else {
        /* This is the first time we're setting up id-mapping
         * Store the default domain as slice 0
         */
        dom_name = dp_opt_get_string(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_DEFAULT_DOMAIN);
        if (!dom_name) {
            /* If it's not explicitly specified, use the SSSD domain name */
            dom_name = idmap_ctx->id_ctx->be->domain->name;
            ret = dp_opt_set_string(idmap_ctx->id_ctx->opts->basic,
                                    SDAP_IDMAP_DEFAULT_DOMAIN,
                                    dom_name);
            if (ret != EOK) goto done;
        }

        sid_str = dp_opt_get_string(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_DEFAULT_DOMAIN_SID);
        if (sid_str) {
            /* Set the default domain as slice 0 */
            ret = sdap_idmap_add_domain(idmap_ctx, dom_name,
                                        sid_str, 0);
            if (ret != EOK) {
                DEBUG(SSSDBG_CRIT_FAILURE,
                      "Could not add domain [%s][%s][%u] to ID map: [%s]\n",
                       dom_name, sid_str, 0, strerror(ret));
                goto done;
            }
        } else {
            if (dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_AUTORID_COMPAT)) {
                /* In autorid compatibility mode, we MUST have a slice 0 */
                DEBUG(SSSDBG_CRIT_FAILURE,
                      "WARNING: Autorid compatibility mode selected, "
                       "but %s is not set. UID/GID values may differ "
                       "between clients.\n",
                       idmap_ctx->id_ctx->opts->basic[SDAP_IDMAP_DEFAULT_DOMAIN_SID].opt_name);
            }
            /* Otherwise, we'll just fall back to hash values as they are seen */
        }
    }

    *_idmap_ctx = talloc_steal(mem_ctx, idmap_ctx);
    ret = EOK;

done:
    talloc_free(tmp_ctx);
    return ret;
}
Пример #27
0
static errno_t
find_password_expiration_attributes(TALLOC_CTX *mem_ctx,
                                    const struct ldb_message *msg,
                                    struct dp_option *opts,
                                    enum pwexpire *type, void **data)
{
    const char *mark;
    const char *val;
    struct spwd *spwd;
    const char *pwd_policy;
    int ret;

    *type = PWEXPIRE_NONE;
    *data = NULL;

    pwd_policy = dp_opt_get_string(opts, SDAP_PWD_POLICY);
    if (pwd_policy == NULL) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Missing password policy.\n");
        return EINVAL;
    }

    if (strcasecmp(pwd_policy, PWD_POL_OPT_NONE) == 0) {
        DEBUG(SSSDBG_TRACE_ALL, "No password policy requested.\n");
        return EOK;
    } else if (strcasecmp(pwd_policy, PWD_POL_OPT_MIT) == 0) {
        mark = ldb_msg_find_attr_as_string(msg, SYSDB_KRBPW_LASTCHANGE, NULL);
        if (mark != NULL) {
            DEBUG(SSSDBG_TRACE_ALL,
                  "Found Kerberos password expiration attributes.\n");
            val = ldb_msg_find_attr_as_string(msg, SYSDB_KRBPW_EXPIRATION,
                                              NULL);
            if (val != NULL) {
                *data = talloc_strdup(mem_ctx, val);
                if (*data == NULL) {
                    DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n");
                    return ENOMEM;
                }
                *type = PWEXPIRE_KERBEROS;

                return EOK;
            }
        } else {
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "No Kerberos password expiration attributes found, "
                      "but MIT Kerberos password policy was requested. "
                      "Access will be denied.\n");
            return EACCES;
        }
    } else if (strcasecmp(pwd_policy, PWD_POL_OPT_SHADOW) == 0) {
        mark = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_LASTCHANGE, NULL);
        if (mark != NULL) {
            DEBUG(SSSDBG_TRACE_ALL,
                  "Found shadow password expiration attributes.\n");
            spwd = talloc_zero(mem_ctx, struct spwd);
            if (spwd == NULL) {
                DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n");
                return ENOMEM;
            }

            val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_LASTCHANGE, NULL);
            ret = string_to_shadowpw_days(val, &spwd->sp_lstchg);
            if (ret != EOK) goto shadow_fail;

            val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_MIN, NULL);
            ret = string_to_shadowpw_days(val, &spwd->sp_min);
            if (ret != EOK) goto shadow_fail;

            val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_MAX, NULL);
            ret = string_to_shadowpw_days(val, &spwd->sp_max);
            if (ret != EOK) goto shadow_fail;

            val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_WARNING, NULL);
            ret = string_to_shadowpw_days(val, &spwd->sp_warn);
            if (ret != EOK) goto shadow_fail;

            val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_INACTIVE, NULL);
            ret = string_to_shadowpw_days(val, &spwd->sp_inact);
            if (ret != EOK) goto shadow_fail;

            val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_EXPIRE, NULL);
            ret = string_to_shadowpw_days(val, &spwd->sp_expire);
            if (ret != EOK) goto shadow_fail;

            *data = spwd;
            *type = PWEXPIRE_SHADOW;

            return EOK;
        } else {