Beispiel #1
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);
}
Beispiel #2
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);
}
Beispiel #3
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));
}
Beispiel #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;
}
Beispiel #5
0
void opt_test_getset_bool(void **state)
{
    struct dp_option *opts = talloc_get_type(*state, struct dp_option);
    int ret;
    bool b;

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

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

    b = dp_opt_get_bool(opts, OPT_BOOL_TRUE);
    assert_false(b == true);
}
Beispiel #6
0
static void ipa_account_info_done(struct tevent_req *req)
{
    struct be_req *breq = tevent_req_callback_data(req, struct be_req);
    struct be_ctx *be_ctx = be_req_get_be_ctx(breq);
    struct ipa_id_ctx *ipa_ctx;
    struct be_acct_req *ar = talloc_get_type(be_req_get_data(breq),
                                             struct be_acct_req);
    const char *error_text;
    int ret, dp_error;

    ipa_ctx = talloc_get_type(be_ctx->bet_info[BET_ID].pvt_bet_data,
                              struct ipa_id_ctx);

    if ((ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_NETGROUP) {
        ret = ipa_id_get_netgroup_recv(req, &dp_error);
    } else {
        if (dp_opt_get_bool(ipa_ctx->ipa_options->basic, IPA_SERVER_MODE)) {
            ret = ipa_get_ad_acct_recv(req, &dp_error);
        } else {
            ret = ipa_get_subdom_acct_recv(req, &dp_error);
        }
    }
    talloc_zfree(req);

    error_text = ipa_account_info_error_text(ret, &dp_error,
                                             "Account info lookup failed");
    sdap_handler_done(breq, dp_error, ret, error_text);
}
Beispiel #7
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);
}
Beispiel #8
0
errno_t ad_dyndns_init(struct be_ctx *be_ctx,
                       struct ad_options *ad_opts)
{
    errno_t ret;

    /* nsupdate is available. Dynamic updates
     * are supported
     */
    ret = ad_get_dyndns_options(be_ctx, ad_opts);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, ("Could not set AD options\n"));
        return ret;
    }

    if (dp_opt_get_bool(ad_opts->dyndns_ctx->opts,
                        DP_OPT_DYNDNS_UPDATE) == false) {
        DEBUG(SSSDBG_CONF_SETTINGS, ("Dynamic DNS updates not set\n"));
        return EOK;
    }

    DEBUG(SSSDBG_CONF_SETTINGS,
          ("Dynamic DNS updates are on. Checking for nsupdate..\n"));
    ret = be_nsupdate_check();
    if (ret == ENOENT) {
        DEBUG(SSSDBG_MINOR_FAILURE,
              ("DNS updates requested but nsupdate not available\n"));
        return EOK;
    } else if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE, ("Could not check for nsupdate\n"));
        return ret;
    }

    ad_opts->be_res = be_ctx->be_res;
    if (ad_opts->be_res == NULL) {
        DEBUG(SSSDBG_OP_FAILURE, ("Resolver must be initialized in order "
              "to use the AD dynamic DNS updates\n"));
        return EINVAL;
    }

    ret = be_nsupdate_init_timer(ad_opts->dyndns_ctx, be_ctx->ev,
                                 ad_dyndns_timer, ad_opts);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, ("Could not set up periodic update\n"));
        return ret;
    }

    ret = be_add_online_cb(be_ctx, be_ctx,
                           ad_dyndns_update,
                           ad_opts, NULL);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, ("Could not set up online callback\n"));
        return ret;
    }

    return EOK;
}
Beispiel #9
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;
}
Beispiel #10
0
void ipa_account_info_handler(struct be_req *breq)
{
    struct be_ctx *be_ctx = be_req_get_be_ctx(breq);
    struct ipa_id_ctx *ipa_ctx;
    struct sdap_id_ctx *ctx;
    struct be_acct_req *ar;
    struct tevent_req *req = NULL;

    ipa_ctx = talloc_get_type(be_ctx->bet_info[BET_ID].pvt_bet_data,
                              struct ipa_id_ctx);
    ctx = ipa_ctx->sdap_id_ctx;

    if (be_is_offline(ctx->be)) {
        return sdap_handler_done(breq, DP_ERR_OFFLINE, EAGAIN, "Offline");
    }

    ar = talloc_get_type(be_req_get_data(breq), struct be_acct_req);

    if (strcasecmp(ar->domain, be_ctx->domain->name) != 0) {
        /* if domain names do not match, this is a subdomain case
         * subdomain lookups are handled differently on the server
         * and the client
         */
        if (dp_opt_get_bool(ipa_ctx->ipa_options->basic, IPA_SERVER_MODE)) {
            req = ipa_get_ad_acct_send(breq, be_ctx->ev, ipa_ctx, breq, ar);
        } else {
            req = ipa_get_subdom_acct_send(breq, be_ctx->ev, ctx, ar);
        }
    } else if ((ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_NETGROUP) {
        /* netgroups are handled by a separate request function */
        if (ar->filter_type != BE_FILTER_NAME) {
            return sdap_handler_done(breq, DP_ERR_FATAL,
                                     EINVAL, "Invalid filter type");
        }
        req = ipa_id_get_netgroup_send(breq, be_ctx->ev,
                                       ipa_ctx, ar->filter_value);
    } else {
        /* any account request is handled by sdap,
         * any invalid request is caught there. */
        return sdap_handle_account_info(breq, ctx, ctx->conn);
    }

    if (!req) {
        return sdap_handler_done(breq, DP_ERR_FATAL,
                                 ENOMEM, "Out of memory");
    }
    tevent_req_set_callback(req, ipa_account_info_done, breq);
}
Beispiel #11
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;
}
Beispiel #12
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;
}
Beispiel #13
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;
}
Beispiel #14
0
/* FIXME: support storing additional attributes */
int sdap_save_user(TALLOC_CTX *memctx,
                   struct sdap_options *opts,
                   struct sss_domain_info *dom,
                   struct sysdb_attrs *attrs,
                   char **_usn_value,
                   time_t now)
{
    struct ldb_message_element *el;
    int ret;
    const char *user_name = NULL;
    const char *fullname = NULL;
    const char *pwd;
    const char *gecos;
    const char *homedir;
    const char *shell;
    const char *orig_dn = NULL;
    uid_t uid;
    gid_t gid;
    struct sysdb_attrs *user_attrs;
    char *upn = NULL;
    size_t i;
    int cache_timeout;
    char *usn_value = NULL;
    char **missing = NULL;
    TALLOC_CTX *tmpctx = NULL;
    bool use_id_mapping;
    char *sid_str;
    char *dom_sid_str = NULL;
    struct sss_domain_info *subdomain;

    DEBUG(SSSDBG_TRACE_FUNC, "Save user\n");

    tmpctx = talloc_new(NULL);
    if (!tmpctx) {
        ret = ENOMEM;
        goto done;
    }

    user_attrs = sysdb_new_attrs(tmpctx);
    if (user_attrs == NULL) {
        ret = ENOMEM;
        goto done;
    }

    /* Always store SID string if available */
    ret = sdap_attrs_get_sid_str(tmpctx, opts->idmap_ctx, attrs,
                                opts->user_map[SDAP_AT_USER_OBJECTSID].sys_name,
                                &sid_str);
    if (ret == EOK) {
        ret = sysdb_attrs_add_string(user_attrs, SYSDB_SID_STR, sid_str);
        if (ret != EOK) {
            DEBUG(SSSDBG_MINOR_FAILURE, "Could not add SID string: [%s]\n",
                                         sss_strerror(ret));
            goto done;
        }
    } else if (ret == ENOENT) {
        DEBUG(SSSDBG_TRACE_ALL, "objectSID: not available for user\n");
        sid_str = NULL;
    } else {
        DEBUG(SSSDBG_MINOR_FAILURE, "Could not identify objectSID: [%s]\n",
                                     sss_strerror(ret));
        sid_str = NULL;
    }

    /* Always store UUID if available */
    ret = sysdb_handle_original_uuid(opts->user_map[SDAP_AT_USER_UUID].def_name,
                                     attrs,
                                     opts->user_map[SDAP_AT_USER_UUID].sys_name,
                                     user_attrs, SYSDB_UUID);
    if (ret != EOK) {
        DEBUG((ret == ENOENT) ? SSSDBG_TRACE_ALL : SSSDBG_MINOR_FAILURE,
              "Failed to retrieve UUID [%d][%s].\n", ret, sss_strerror(ret));
    }

    /* If this object has a SID available, we will determine the correct
     * domain by its SID. */
    if (sid_str != NULL) {
        subdomain = find_domain_by_sid(get_domains_head(dom), sid_str);
        if (subdomain) {
            dom = subdomain;
        } else {
            DEBUG(SSSDBG_TRACE_FUNC, "SID %s does not belong to any known "
                                      "domain\n", sid_str);
        }
    }

    ret = sdap_get_user_primary_name(memctx, opts, attrs, dom, &user_name);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE, "Failed to get user name\n");
        goto done;
    }
    DEBUG(SSSDBG_TRACE_FUNC, "Processing user %s\n", user_name);

    if (opts->schema_type == SDAP_SCHEMA_AD) {
        ret = sysdb_attrs_get_string(attrs,
                    opts->user_map[SDAP_AT_USER_FULLNAME].sys_name, &fullname);
        if (ret == EOK) {
            ret = sysdb_attrs_add_string(user_attrs, SYSDB_FULLNAME, fullname);
            if (ret != EOK) {
                goto done;
            }
        } else if (ret != ENOENT) {
            goto done;
        }
    }

    ret = sysdb_attrs_get_el(attrs,
                             opts->user_map[SDAP_AT_USER_PWD].sys_name, &el);
    if (ret) goto done;
    if (el->num_values == 0) pwd = NULL;
    else pwd = (const char *)el->values[0].data;

    ret = sysdb_attrs_get_el(attrs,
                             opts->user_map[SDAP_AT_USER_GECOS].sys_name, &el);
    if (ret) goto done;
    if (el->num_values == 0) gecos = NULL;
    else gecos = (const char *)el->values[0].data;

    if (!gecos) {
        /* Fall back to the user's full name */
        ret = sysdb_attrs_get_el(
                attrs,
                opts->user_map[SDAP_AT_USER_FULLNAME].sys_name, &el);
        if (ret) goto done;
        if (el->num_values > 0) gecos = (const char *)el->values[0].data;
    }

    ret = sysdb_attrs_get_el(attrs,
                             opts->user_map[SDAP_AT_USER_HOME].sys_name, &el);
    if (ret) goto done;
    if (el->num_values == 0) homedir = NULL;
    else homedir = (const char *)el->values[0].data;

    ret = sysdb_attrs_get_el(attrs,
                             opts->user_map[SDAP_AT_USER_SHELL].sys_name, &el);
    if (ret) goto done;
    if (el->num_values == 0) shell = NULL;
    else shell = (const char *)el->values[0].data;

    use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(opts->idmap_ctx,
                                                               dom->name,
                                                               sid_str);

    /* Retrieve or map the UID as appropriate */
    if (use_id_mapping) {

        if (sid_str == NULL) {
            DEBUG(SSSDBG_MINOR_FAILURE, "SID not available, cannot map a " \
                                         "unix ID to user [%s].\n", user_name);
            ret = ENOENT;
            goto done;
        }

        DEBUG(SSSDBG_TRACE_LIBS,
              "Mapping user [%s] objectSID [%s] to unix ID\n", user_name, sid_str);

        /* Convert the SID into a UNIX user ID */
        ret = sdap_idmap_sid_to_unix(opts->idmap_ctx, sid_str, &uid);
        if (ret == ENOTSUP) {
            DEBUG(SSSDBG_TRACE_FUNC, "Skipping built-in object.\n");
            ret = EOK;
            goto done;
        } else if (ret != EOK) {
            goto done;
        }

        /* Store the UID in the ldap_attrs so it doesn't get
         * treated as a missing attribute from LDAP and removed.
         */
        ret = sdap_replace_id(attrs, SYSDB_UIDNUM, uid);
        if (ret) {
            DEBUG(SSSDBG_OP_FAILURE, "Cannot set the id-mapped UID\n");
            goto done;
        }
    } else {
        ret = sysdb_attrs_get_uint32_t(attrs,
                                       opts->user_map[SDAP_AT_USER_UID].sys_name,
                                       &uid);
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "no uid provided for [%s] in domain [%s].\n",
                   user_name, dom->name);
            ret = EINVAL;
            goto done;
        }
    }
    /* check that the uid is valid for this domain */
    if (OUT_OF_ID_RANGE(uid, dom->id_min, dom->id_max)) {
            DEBUG(SSSDBG_OP_FAILURE,
                  "User [%s] filtered out! (uid out of range)\n",
                      user_name);
        ret = EINVAL;
        goto done;
    }

    if (use_id_mapping) {
        ret = sdap_get_idmap_primary_gid(opts, attrs, sid_str, dom_sid_str,
                                         &gid);
        if (ret) {
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "Cannot get the GID for [%s] in domain [%s].\n",
                   user_name, dom->name);
            goto done;
        }

        if (IS_SUBDOMAIN(dom)) {
            /* For subdomain users, only create the private group as
             * the subdomain is an MPG domain.
             * But we have to save the GID of the original primary group
             * becasuse otherwise this information might be lost because
             * typically (Unix and AD) the user is not listed in his primary
             * group as a member.
             */
            ret = sysdb_attrs_add_uint32(user_attrs, SYSDB_PRIMARY_GROUP_GIDNUM,
                                         (uint32_t) gid);
            if (ret != EOK) {
                DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_uint32 failed.\n");
                goto done;
            }

            gid = 0;
        }

        /* Store the GID in the ldap_attrs so it doesn't get
        * treated as a missing attribute from LDAP and removed.
        */
        ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, gid);
        if (ret != EOK) goto done;
    } else {
        ret = sysdb_attrs_get_uint32_t(attrs,
                                       opts->user_map[SDAP_AT_USER_GID].sys_name,
                                       &gid);
        if (ret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "no gid provided for [%s] in domain [%s].\n",
                  user_name, dom->name);
            ret = EINVAL;
            goto done;
        }
    }

    /* check that the gid is valid for this domain */
    if (IS_SUBDOMAIN(dom) == false &&
            OUT_OF_ID_RANGE(gid, dom->id_min, dom->id_max)) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "User [%s] filtered out! (primary gid out of range)\n",
               user_name);
        ret = EINVAL;
        goto done;
    }

    ret = sysdb_attrs_get_el(attrs, SYSDB_ORIG_DN, &el);
    if (ret) {
        goto done;
    }
    if (!el || el->num_values == 0) {
        DEBUG(SSSDBG_MINOR_FAILURE,
              "originalDN is not available for [%s].\n", user_name);
    } else {
        orig_dn = (const char *) el->values[0].data;
        DEBUG(SSSDBG_TRACE_INTERNAL, "Adding originalDN [%s] to attributes "
                "of [%s].\n", orig_dn, user_name);

        ret = sysdb_attrs_add_string(user_attrs, SYSDB_ORIG_DN, orig_dn);
        if (ret) {
            goto done;
        }
    }

    ret = sysdb_attrs_get_el(attrs, SYSDB_MEMBEROF, &el);
    if (ret) {
        goto done;
    }
    if (el->num_values == 0) {
        DEBUG(SSSDBG_TRACE_FUNC,
              "Original memberOf is not available for [%s].\n", user_name);
    } else {
        DEBUG(SSSDBG_TRACE_FUNC,
              "Adding original memberOf attributes to [%s].\n", user_name);
        for (i = 0; i < el->num_values; i++) {
            ret = sysdb_attrs_add_string(user_attrs, SYSDB_ORIG_MEMBEROF,
                    (const char *) el->values[i].data);
            if (ret) {
                goto done;
            }
        }
    }

    ret = sdap_attrs_add_string(attrs,
                            opts->user_map[SDAP_AT_USER_MODSTAMP].sys_name,
                            "original mod-Timestamp",
                            user_name, user_attrs);
    if (ret != EOK) {
        goto done;
    }

    ret = sysdb_attrs_get_el(attrs,
                      opts->user_map[SDAP_AT_USER_USN].sys_name, &el);
    if (ret) {
        goto done;
    }
    if (el->num_values == 0) {
        DEBUG(SSSDBG_TRACE_FUNC,
              "Original USN value is not available for [%s].\n", user_name);
    } else {
        ret = sysdb_attrs_add_string(user_attrs,
                          opts->user_map[SDAP_AT_USER_USN].sys_name,
                          (const char*)el->values[0].data);
        if (ret) {
            goto done;
        }
        usn_value = talloc_strdup(tmpctx, (const char*)el->values[0].data);
        if (!usn_value) {
            ret = ENOMEM;
            goto done;
        }
    }

    ret = sysdb_attrs_get_el(attrs,
                             opts->user_map[SDAP_AT_USER_PRINC].sys_name, &el);
    if (ret) {
        goto done;
    }
    if (el->num_values == 0) {
        DEBUG(SSSDBG_TRACE_FUNC,
              "User principal is not available for [%s].\n", user_name);
    } else {
        upn = talloc_strdup(user_attrs, (const char*) el->values[0].data);
        if (!upn) {
            ret = ENOMEM;
            goto done;
        }
        if (dp_opt_get_bool(opts->basic, SDAP_FORCE_UPPER_CASE_REALM)) {
            make_realm_upper_case(upn);
        }
        DEBUG(SSSDBG_TRACE_FUNC,
              "Adding user principal [%s] to attributes of [%s].\n",
               upn, user_name);
        ret = sysdb_attrs_add_string(user_attrs, SYSDB_UPN, upn);
        if (ret) {
            goto done;
        }
    }

    for (i = SDAP_FIRST_EXTRA_USER_AT; i < opts->user_map_cnt; i++) {
        ret = sdap_attrs_add_list(attrs, opts->user_map[i].sys_name,
                                  NULL, user_name, user_attrs);
        if (ret) {
            goto done;
        }
    }

    cache_timeout = dom->user_timeout;

    ret = sdap_save_all_names(user_name, attrs, dom, user_attrs);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Failed to save user names\n");
        goto done;
    }

    /* Make sure that any attributes we requested from LDAP that we
     * did not receive are also removed from the sysdb
     */
    ret = list_missing_attrs(user_attrs, opts->user_map, opts->user_map_cnt,
                             attrs, &missing);
    if (ret != EOK) {
        goto done;
    }

    DEBUG(SSSDBG_TRACE_FUNC, "Storing info for user %s\n", user_name);

    ret = sysdb_store_user(dom, user_name, pwd, uid, gid,
                           gecos, homedir, shell, orig_dn,
                           user_attrs, missing, cache_timeout, now);
    if (ret) goto done;

    if (_usn_value) {
        *_usn_value = talloc_steal(memctx, usn_value);
    }

    talloc_steal(memctx, user_attrs);
    ret = EOK;

done:
    if (ret) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Failed to save user [%s]\n",
               user_name ? user_name : "Unknown");
    }
    talloc_free(tmpctx);
    return ret;
}
Beispiel #15
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;
}
Beispiel #16
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;
}
Beispiel #17
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;
}
Beispiel #18
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;
}
Beispiel #19
0
int sssm_ipa_auth_init(struct be_ctx *bectx,
                       struct bet_ops **ops,
                       void **pvt_data)
{
    struct ipa_auth_ctx *ipa_auth_ctx;
    struct ipa_id_ctx *id_ctx;
    struct krb5_ctx *krb5_auth_ctx;
    struct sdap_auth_ctx *sdap_auth_ctx;
    struct bet_ops *id_ops;
    int ret;

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

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

    ipa_auth_ctx = talloc_zero(ipa_options, struct ipa_auth_ctx);
    if (!ipa_auth_ctx) {
        return ENOMEM;
    }
    ipa_options->auth_ctx = ipa_auth_ctx;

    ret = sssm_ipa_id_init(bectx, &id_ops, (void **) &id_ctx);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, "sssm_ipa_id_init failed.\n");
        goto done;
    }
    ipa_auth_ctx->sdap_id_ctx = id_ctx->sdap_id_ctx;

    ret = dp_copy_options(ipa_auth_ctx, ipa_options->basic,
                          IPA_OPTS_BASIC, &ipa_auth_ctx->ipa_options);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, "dp_copy_options failed.\n");
        goto done;
    }

    krb5_auth_ctx = talloc_zero(ipa_auth_ctx, struct krb5_ctx);
    if (!krb5_auth_ctx) {
        ret = ENOMEM;
        goto done;
    }
    krb5_auth_ctx->service = ipa_options->service->krb5_service;

    if (dp_opt_get_bool(id_ctx->ipa_options->basic,
                        IPA_SERVER_MODE) == true) {
        krb5_auth_ctx->config_type = K5C_IPA_SERVER;
    } else {
        krb5_auth_ctx->config_type = K5C_IPA_CLIENT;
    }
    ipa_options->auth_ctx->krb5_auth_ctx = krb5_auth_ctx;

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

    sdap_auth_ctx = talloc_zero(ipa_auth_ctx, struct sdap_auth_ctx);
    if (!sdap_auth_ctx) {
        ret = ENOMEM;
        goto done;
    }
    sdap_auth_ctx->be =  bectx;
    sdap_auth_ctx->service = ipa_options->service->sdap;

    if (ipa_options->id == NULL) {
        ret = EINVAL;
        goto done;
    }
    sdap_auth_ctx->opts = ipa_options->id;

    ipa_options->auth_ctx->sdap_auth_ctx = sdap_auth_ctx;

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

    /* Initialize features needed by the krb5_child */
    ret = krb5_child_init(krb5_auth_ctx, bectx);
    if (ret != EOK) {
        DEBUG(SSSDBG_FATAL_FAILURE,
              "Could not initialize krb5_child settings: [%s]\n",
               strerror(ret));
        goto done;
    }

    ret = create_ipa_preauth_indicator();
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Failed to create preauth indicator file, special password "
              "prompting might not be available.\n");
        sss_log(SSSDBG_CRIT_FAILURE,
                "Failed to create preauth indicator file, special password "
                "prompting might not be available.\n");
    }

    *ops = &ipa_auth_ops;
    *pvt_data = ipa_auth_ctx;
    ret = EOK;

done:
    if (ret != EOK) {
        talloc_zfree(ipa_options->auth_ctx);
    }
    return ret;
}
Beispiel #20
0
/* FIXME: support storing additional attributes */
int sdap_save_user(TALLOC_CTX *memctx,
                   struct sysdb_ctx *ctx,
                   struct sdap_options *opts,
                   struct sss_domain_info *dom,
                   struct sysdb_attrs *attrs,
                   bool is_initgr,
                   char **_usn_value,
                   time_t now)
{
    struct ldb_message_element *el;
    int ret;
    const char *name = NULL;
    const char *fullname = NULL;
    const char *pwd;
    const char *gecos;
    const char *homedir;
    const char *shell;
    const char *orig_dn = NULL;
    uid_t uid;
    gid_t gid, primary_gid;
    struct sysdb_attrs *user_attrs;
    char *upn = NULL;
    size_t i;
    int cache_timeout;
    char *usn_value = NULL;
    char **missing = NULL;
    TALLOC_CTX *tmpctx = NULL;
    bool use_id_mapping = dp_opt_get_bool(opts->basic, SDAP_ID_MAPPING);
    char *sid_str;
    char *dom_sid_str = NULL;
    char *group_sid_str;

    DEBUG(9, ("Save user\n"));

    tmpctx = talloc_new(NULL);
    if (!tmpctx) {
        ret = ENOMEM;
        goto done;
    }

    user_attrs = sysdb_new_attrs(tmpctx);
    if (user_attrs == NULL) {
        ret = ENOMEM;
        goto done;
    }

    ret = sysdb_attrs_primary_name(ctx, attrs,
                                   opts->user_map[SDAP_AT_USER_NAME].name,
                                   &name);
    if (ret != EOK) {
        DEBUG(1, ("Failed to save the user - entry has no name attribute\n"));
        goto done;
    }

    if (opts->schema_type == SDAP_SCHEMA_AD) {
        ret = sysdb_attrs_get_string(attrs,
                    opts->user_map[SDAP_AT_USER_FULLNAME].sys_name, &fullname);
        if (ret == EOK) {
            ret = sysdb_attrs_add_string(user_attrs, SYSDB_FULLNAME, fullname);
            if (ret != EOK) {
                goto done;
            }
        } else if (ret != ENOENT) {
            goto done;
        }
    }

    ret = sysdb_attrs_get_el(attrs,
                             opts->user_map[SDAP_AT_USER_PWD].sys_name, &el);
    if (ret) goto done;
    if (el->num_values == 0) pwd = NULL;
    else pwd = (const char *)el->values[0].data;

    ret = sysdb_attrs_get_el(attrs,
                             opts->user_map[SDAP_AT_USER_GECOS].sys_name, &el);
    if (ret) goto done;
    if (el->num_values == 0) gecos = NULL;
    else gecos = (const char *)el->values[0].data;

    if (!gecos) {
        /* Fall back to the user's full name */
        ret = sysdb_attrs_get_el(
                attrs,
                opts->user_map[SDAP_AT_USER_FULLNAME].sys_name, &el);
        if (ret) goto done;
        if (el->num_values > 0) gecos = (const char *)el->values[0].data;
    }

    ret = sysdb_attrs_get_el(attrs,
                             opts->user_map[SDAP_AT_USER_HOME].sys_name, &el);
    if (ret) goto done;
    if (el->num_values == 0) homedir = NULL;
    else homedir = (const char *)el->values[0].data;

    ret = sysdb_attrs_get_el(attrs,
                             opts->user_map[SDAP_AT_USER_SHELL].sys_name, &el);
    if (ret) goto done;
    if (el->num_values == 0) shell = NULL;
    else shell = (const char *)el->values[0].data;

    /* Retrieve or map the UID as appropriate */
    if (use_id_mapping) {
        DEBUG(SSSDBG_TRACE_LIBS,
              ("Mapping user [%s] objectSID to unix ID\n", name));

        ret = sdap_attrs_get_sid_str(
                tmpctx, opts->idmap_ctx, attrs,
                opts->user_map[SDAP_AT_USER_OBJECTSID].sys_name,
                &sid_str);
        if (ret != EOK) goto done;

        /* Add string representation to the cache for easier
         * debugging
         */
        ret = sysdb_attrs_add_string(user_attrs, SYSDB_SID_STR, sid_str);
        if (ret != EOK) goto done;

        /* Convert the SID into a UNIX user ID */
        ret = sdap_idmap_sid_to_unix(opts->idmap_ctx, sid_str, &uid);
        if (ret == ENOTSUP) {
            DEBUG(SSSDBG_TRACE_FUNC, ("Skipping built-in object.\n"));
            ret = EOK;
            goto done;
        } else if (ret != EOK) {
            goto done;
        }

        /* Store the UID in the ldap_attrs so it doesn't get
         * treated as a missing attribute from LDAP and removed.
         */
        ret = sdap_replace_id(attrs, SYSDB_UIDNUM, uid);
        if (ret) {
            DEBUG(SSSDBG_OP_FAILURE, ("Cannot set the id-mapped UID\n"));
            goto done;
        }
    } else {
        ret = sysdb_attrs_get_uint32_t(attrs,
                                       opts->user_map[SDAP_AT_USER_UID].sys_name,
                                       &uid);
        if (ret != EOK) {
            DEBUG(1, ("no uid provided for [%s] in domain [%s].\n",
                      name, dom->name));
            ret = EINVAL;
            goto done;
        }
    }
    /* check that the uid is valid for this domain */
    if (OUT_OF_ID_RANGE(uid, dom->id_min, dom->id_max)) {
            DEBUG(2, ("User [%s] filtered out! (uid out of range)\n",
                      name));
        ret = EINVAL;
        goto done;
    }

    if (use_id_mapping) {
        ret = sysdb_attrs_get_uint32_t(
                attrs,
                opts->user_map[SDAP_AT_USER_PRIMARY_GROUP].sys_name,
                &primary_gid);
        if (ret != EOK) {
            DEBUG(SSSDBG_MINOR_FAILURE,
                  ("no primary group ID provided for [%s] in domain [%s].\n",
                   name, dom->name));
            ret = EINVAL;
            goto done;
        }

        /* The primary group ID is just the RID part of the objectSID
         * of the group. Generate the GID by adding this to the domain
         * SID value.
         */

        /* First, get the domain SID if we didn't do so above */
        if (!dom_sid_str) {
            ret = sdap_idmap_get_dom_sid_from_object(tmpctx, sid_str,
                                                     &dom_sid_str);
            if (ret != EOK) {
                DEBUG(SSSDBG_MINOR_FAILURE,
                      ("Could not parse domain SID from [%s]\n", sid_str));
                goto done;
            }
        }

        /* Add the RID to the end */
        group_sid_str = talloc_asprintf(tmpctx, "%s-%lu",
                                        dom_sid_str,
                                        (unsigned long)primary_gid);
        if (!group_sid_str) {
            ret = ENOMEM;
            goto done;
        }

        /* Convert the SID into a UNIX group ID */
        ret = sdap_idmap_sid_to_unix(opts->idmap_ctx, group_sid_str, &gid);
        if (ret != EOK) goto done;

        /* Store the GID in the ldap_attrs so it doesn't get
         * treated as a missing attribute from LDAP and removed.
         */
        ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, gid);
        if (ret != EOK) goto done;
    } else {
        ret = sysdb_attrs_get_uint32_t(attrs,
                                       opts->user_map[SDAP_AT_USER_GID].sys_name,
                                       &gid);
        if (ret != EOK) {
            DEBUG(1, ("no gid provided for [%s] in domain [%s].\n",
                      name, dom->name));
            ret = EINVAL;
            goto done;
        }
    }

    /* check that the gid is valid for this domain */
    if (OUT_OF_ID_RANGE(gid, dom->id_min, dom->id_max)) {
            DEBUG(2, ("User [%s] filtered out! (primary gid out of range)\n",
                      name));
        ret = EINVAL;
        goto done;
    }

    ret = sysdb_attrs_get_el(attrs, SYSDB_ORIG_DN, &el);
    if (ret) {
        goto done;
    }
    if (!el || el->num_values == 0) {
        DEBUG(SSSDBG_MINOR_FAILURE,
              ("originalDN is not available for [%s].\n", name));
    } else {
        orig_dn = (const char *) el->values[0].data;
        DEBUG(SSSDBG_TRACE_INTERNAL, ("Adding originalDN [%s] to attributes "
                "of [%s].\n", orig_dn, name));

        ret = sysdb_attrs_add_string(user_attrs, SYSDB_ORIG_DN, orig_dn);
        if (ret) {
            goto done;
        }
    }

    ret = sysdb_attrs_get_el(attrs, SYSDB_MEMBEROF, &el);
    if (ret) {
        goto done;
    }
    if (el->num_values == 0) {
        DEBUG(7, ("Original memberOf is not available for [%s].\n",
                    name));
    } else {
        DEBUG(7, ("Adding original memberOf attributes to [%s].\n",
                    name));
        for (i = 0; i < el->num_values; i++) {
            ret = sysdb_attrs_add_string(user_attrs, SYSDB_ORIG_MEMBEROF,
                    (const char *) el->values[i].data);
            if (ret) {
                goto done;
            }
        }
    }

    ret = sdap_attrs_add_string(attrs,
                            opts->user_map[SDAP_AT_USER_MODSTAMP].sys_name,
                            "original mod-Timestamp",
                            name, user_attrs);
    if (ret != EOK) {
        goto done;
    }

    ret = sysdb_attrs_get_el(attrs,
                      opts->user_map[SDAP_AT_USER_USN].sys_name, &el);
    if (ret) {
        goto done;
    }
    if (el->num_values == 0) {
        DEBUG(7, ("Original USN value is not available for [%s].\n",
                  name));
    } else {
        ret = sysdb_attrs_add_string(user_attrs,
                          opts->user_map[SDAP_AT_USER_USN].sys_name,
                          (const char*)el->values[0].data);
        if (ret) {
            goto done;
        }
        usn_value = talloc_strdup(tmpctx, (const char*)el->values[0].data);
        if (!usn_value) {
            ret = ENOMEM;
            goto done;
        }
    }

    ret = sysdb_attrs_get_el(attrs,
                             opts->user_map[SDAP_AT_USER_PRINC].sys_name, &el);
    if (ret) {
        goto done;
    }
    if (el->num_values == 0) {
        DEBUG(7, ("User principal is not available for [%s].\n", name));
    } else {
        upn = talloc_strdup(user_attrs, (const char*) el->values[0].data);
        if (!upn) {
            ret = ENOMEM;
            goto done;
        }
        if (dp_opt_get_bool(opts->basic, SDAP_FORCE_UPPER_CASE_REALM)) {
            make_realm_upper_case(upn);
        }
        DEBUG(7, ("Adding user principal [%s] to attributes of [%s].\n",
                  upn, name));
        ret = sysdb_attrs_add_string(user_attrs, SYSDB_UPN, upn);
        if (ret) {
            goto done;
        }
    }

    for (i = SDAP_FIRST_EXTRA_USER_AT; i < SDAP_OPTS_USER; i++) {
        ret = sdap_attrs_add_list(attrs, opts->user_map[i].sys_name,
                                  NULL, name, user_attrs);
        if (ret) {
            goto done;
        }
    }

    cache_timeout = dom->user_timeout;

    if (is_initgr) {
        ret = sysdb_attrs_add_time_t(user_attrs, SYSDB_INITGR_EXPIRE,
                                     (cache_timeout ?
                                      (time(NULL) + cache_timeout) : 0));
        if (ret) {
            goto done;
        }
    }

    ret = sdap_save_all_names(name, attrs, !dom->case_sensitive, user_attrs);
    if (ret != EOK) {
        DEBUG(1, ("Failed to save user names\n"));
        goto done;
    }

    /* Make sure that any attributes we requested from LDAP that we
     * did not receive are also removed from the sysdb
     */
    ret = list_missing_attrs(user_attrs, opts->user_map, SDAP_OPTS_USER,
                             attrs, &missing);
    if (ret != EOK) {
        goto done;
    }

    DEBUG(6, ("Storing info for user %s\n", name));

    ret = sysdb_store_user(ctx, dom, name, pwd, uid, gid,
                           gecos, homedir, shell, orig_dn,
                           user_attrs, missing, cache_timeout, now);
    if (ret) goto done;

    if (_usn_value) {
        *_usn_value = talloc_steal(memctx, usn_value);
    }

    talloc_steal(memctx, user_attrs);
    ret = EOK;

done:
    if (ret) {
        DEBUG(2, ("Failed to save user [%s]\n",
                  name ? name : "Unknown"));
    }
    talloc_free(tmpctx);
    return ret;
}
Beispiel #21
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;
}
Beispiel #22
0
errno_t
sdap_idmap_add_domain(struct sdap_idmap_ctx *idmap_ctx,
                      const char *dom_name,
                      const char *dom_sid,
                      id_t slice)
{
    errno_t ret;
    struct sss_idmap_range range;
    enum idmap_error_code err;
    id_t idmap_upper;
    bool external_mapping = true;

    ret = sss_idmap_ctx_get_upper(idmap_ctx->map, &idmap_upper);
    if (ret != IDMAP_SUCCESS) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Failed to get upper bound of available ID range.\n");
        ret = EIO;
        goto done;
    }

    if (dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic, SDAP_ID_MAPPING)) {
        external_mapping = false;
        ret = sss_idmap_calculate_range(idmap_ctx->map, dom_sid, &slice, &range);
        if (ret != IDMAP_SUCCESS) {
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "Failed to calculate range for domain [%s]: [%d]\n", dom_name,
                   ret);
            ret = EIO;
            goto done;
        }
        DEBUG(SSSDBG_TRACE_LIBS,
              "Adding domain [%s] as slice [%"SPRIid"]\n", dom_sid, slice);

        if (range.max > idmap_upper) {
            /* This should never happen */
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "BUG: Range maximum exceeds the global maximum: "
                   "%u > %"SPRIid"\n", range.max, idmap_upper);
            ret = EINVAL;
            goto done;
        }
    } else {
        ret = sdap_idmap_get_configured_external_range(idmap_ctx, &range);
        if (ret != EOK) {
            DEBUG(SSSDBG_OP_FAILURE,
                  "sdap_idmap_get_configured_external_range failed.\n");
            return ret;
        }
    }

    /* Add this domain to the map */
    err = sss_idmap_add_domain_ex(idmap_ctx->map, dom_name, dom_sid, &range,
                                  NULL, 0, external_mapping);
    if (err != IDMAP_SUCCESS) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Could not add domain [%s] to the map: [%d]\n",
               dom_name, err);
        ret = EIO;
        goto done;
    }

    /* If algorithmic mapping is used add this domain to the SYSDB cache so it
     * will survive reboot */
    if (!external_mapping) {
        ret = sysdb_idmap_store_mapping(idmap_ctx->id_ctx->be->domain,
                                        dom_name, dom_sid,
                                        slice);
        if (ret != EOK) {
            DEBUG(SSSDBG_OP_FAILURE, "sysdb_idmap_store_mapping failed.\n");
            goto done;
        }
    }

done:
    return ret;
}
Beispiel #23
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;
}
Beispiel #24
0
bool sdap_idmap_domain_has_algorithmic_mapping(struct sdap_idmap_ctx *ctx,
                                               const char *dom_name,
                                               const char *dom_sid)
{
    enum idmap_error_code err;
    bool has_algorithmic_mapping;
    char *new_dom_sid;
    int ret;
    TALLOC_CTX *tmp_ctx = NULL;

    if (dp_opt_get_bool(ctx->id_ctx->opts->basic, SDAP_ID_MAPPING)
        && 0 == strcmp("ldap", ctx->id_ctx->be->bet_info[BET_ID].mod_name)) {
        return true;
    }

    err = sss_idmap_domain_has_algorithmic_mapping(ctx->map, dom_sid,
                                                   &has_algorithmic_mapping);
    switch (err){
    case IDMAP_SUCCESS:
        return has_algorithmic_mapping;
    case IDMAP_SID_INVALID: /* FALLTHROUGH */
    case IDMAP_SID_UNKNOWN: /* FALLTHROUGH */
    case IDMAP_NO_DOMAIN:   /* FALLTHROUGH */
        /* continue with idmap_domain_by_name */
        break;
    default:
        return false;
    }

    err = sss_idmap_domain_by_name_has_algorithmic_mapping(ctx->map,
                                                  dom_name,
                                                  &has_algorithmic_mapping);
    if (err == IDMAP_SUCCESS) {
        return has_algorithmic_mapping;
    } else if (err != IDMAP_NAME_UNKNOWN && err != IDMAP_NO_DOMAIN) {
        return false;
    }

    /* This is the first time we've seen this domain
     * Create a new domain for it. We'll use the dom-sid
     * as the domain name for now, since we don't have
     * any way to get the real name.
     */

    if (is_domain_sid(dom_sid)) {
        new_dom_sid = discard_const(dom_sid);
    } else {
        tmp_ctx = talloc_new(NULL);
        if (tmp_ctx == NULL) {
            DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
            return false;
        }

        ret = sdap_idmap_get_dom_sid_from_object(tmp_ctx, dom_sid,
                                                 &new_dom_sid);
        if (ret != EOK) {
            DEBUG(SSSDBG_MINOR_FAILURE,
                  "Could not parse domain SID from [%s]\n", dom_sid);
            talloc_free(tmp_ctx);
            return false;
        }
    }

    ret = ctx->find_new_domain(ctx, dom_name, new_dom_sid);
    talloc_free(tmp_ctx);
    if (ret != EOK) {
        DEBUG(SSSDBG_MINOR_FAILURE,
              "Could not add new domain for sid [%s]\n", dom_sid);
        return false;
    }

    err = sss_idmap_domain_has_algorithmic_mapping(ctx->map, dom_sid,
                                                   &has_algorithmic_mapping);
    if (err == IDMAP_SUCCESS) {
        return has_algorithmic_mapping;
    }

    return false;
}
Beispiel #25
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;
}