Exemplo n.º 1
0
errno_t krb5_install_sigterm_handler(struct tevent_context *ev,
                                     struct krb5_ctx *krb5_ctx)
{
    const char *krb5_realm;
    char *sig_realm;
    struct tevent_signal *sige;

    BlockSignals(false, SIGTERM);

    krb5_realm = dp_opt_get_cstring(krb5_ctx->opts, KRB5_REALM);
    if (krb5_realm == NULL) {
        DEBUG(1, ("Missing krb5_realm option!\n"));
        return EINVAL;
    }

    sig_realm = talloc_strdup(krb5_ctx, krb5_realm);
    if (sig_realm == NULL) {
        DEBUG(1, ("talloc_strdup failed!\n"));
        return ENOMEM;
    }

    sige = tevent_add_signal(ev, krb5_ctx, SIGTERM, SA_SIGINFO, krb5_finalize,
                             sig_realm);
    if (sige == NULL) {
        DEBUG(1, ("tevent_add_signal failed.\n"));
        talloc_free(sig_realm);
        return ENOMEM;
    }
    talloc_steal(sige, sig_realm);

    return EOK;
}
Exemplo n.º 2
0
char *get_enterprise_principal_string_filter(TALLOC_CTX *mem_ctx,
                                             const char *attr_name,
                                             const char *princ,
                                             struct dp_option *sdap_basic_opts)
{
    const char *realm;
    char *p;

    if (attr_name == NULL || princ == NULL || sdap_basic_opts == NULL) {
        return NULL;
    }

    realm = dp_opt_get_cstring(sdap_basic_opts, SDAP_KRB5_REALM);
    if (realm == NULL) {
        return NULL;
    }

    p = strchr(princ, '@');
    if (p == NULL) {
        return NULL;
    }

    return talloc_asprintf(mem_ctx, "(%s=%.*s\\\\@%s@%s)", attr_name,
                                                           (int) (p - princ),
                                                           princ,
                                                           p + 1, realm);
}
Exemplo n.º 3
0
static errno_t krb5_auth_prepare_ccache_name(struct krb5child_req *kr,
                                             struct ldb_message *user_msg,
                                             struct be_ctx *be_ctx)
{
    const char *ccname_template;

    ccname_template = dp_opt_get_cstring(kr->krb5_ctx->opts, KRB5_CCNAME_TMPL);

    kr->ccname = expand_ccname_template(kr, kr, ccname_template,
                                        kr->krb5_ctx->illegal_path_re, true,
                                        be_ctx->domain->case_sensitive);
    if (kr->ccname == NULL) {
        DEBUG(SSSDBG_CRIT_FAILURE, "expand_ccname_template failed.\n");
        return ENOMEM;
    }

    kr->old_ccname = ldb_msg_find_attr_as_string(user_msg,
                                                 SYSDB_CCACHE_FILE, NULL);
    if (kr->old_ccname == NULL) {
        DEBUG(SSSDBG_TRACE_LIBS,
                "No ccache file for user [%s] found.\n", kr->pd->user);
    }

    return EOK;
}
Exemplo n.º 4
0
errno_t krb5_install_offline_callback(struct be_ctx *be_ctx,
                                      struct krb5_ctx *krb5_ctx)
{
    int ret;
    struct remove_info_files_ctx *ctx;
    const char *krb5_realm;

    if (krb5_ctx->service == NULL || krb5_ctx->service->name == NULL) {
        DEBUG(1, ("Missing KDC service name!\n"));
        return EINVAL;
    }

    ctx = talloc_zero(krb5_ctx, struct remove_info_files_ctx);
    if (ctx == NULL) {
        DEBUG(1, ("talloc_zfree failed.\n"));
        return ENOMEM;
    }

    krb5_realm = dp_opt_get_cstring(krb5_ctx->opts, KRB5_REALM);
    if (krb5_realm == NULL) {
        DEBUG(1, ("Missing krb5_realm option!\n"));
        ret = EINVAL;
        goto done;
    }

    ctx->realm = talloc_strdup(ctx, krb5_realm);
    if (ctx->realm == NULL) {
        DEBUG(1, ("talloc_strdup failed!\n"));
        ret = ENOMEM;
        goto done;
    }

    ctx->be_ctx = be_ctx;
    ctx->kdc_service_name = krb5_ctx->service->name;
    if (krb5_ctx->kpasswd_service == NULL) {
        ctx->kpasswd_service_name =NULL;
    } else {
        ctx->kpasswd_service_name = krb5_ctx->kpasswd_service->name;
    }

    ret = be_add_offline_cb(ctx, be_ctx, remove_krb5_info_files_callback, ctx,
                            NULL);
    if (ret != EOK) {
        DEBUG(1, ("be_add_offline_cb failed.\n"));
        goto done;
    }

    ret = EOK;

done:
    if (ret != EOK) {
        talloc_zfree(ctx);
    }

    return ret;
}
Exemplo n.º 5
0
static errno_t ad_get_enabled_domains(TALLOC_CTX *mem_ctx,
                                      struct ad_id_ctx *ad_id_ctx,
                                      const char *ad_domain,
                                      const char ***_ad_enabled_domains)
{
    int ret;
    const char *str;
    const char *option_name;
    const char **domains = NULL;
    int count;
    bool is_ad_in_domains;
    TALLOC_CTX *tmp_ctx = NULL;

    tmp_ctx = talloc_new(NULL);
    if (tmp_ctx == NULL) {
        return ENOMEM;
    }

    str = dp_opt_get_cstring(ad_id_ctx->ad_options->basic, AD_ENABLED_DOMAINS);
    if (str == NULL) {
        *_ad_enabled_domains = NULL;
        ret = EOK;
        goto done;
    }

    count = 0;
    ret = split_on_separator(tmp_ctx, str, ',', true, true,
                             discard_const_p(char **, &domains), &count);
    if (ret != EOK) {
        option_name = ad_id_ctx->ad_options->basic[AD_ENABLED_DOMAINS].opt_name;
        DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse option [%s], [%i] [%s]!\n",
                                   option_name, ret, sss_strerror(ret));
        ret = EINVAL;
        goto done;
    }

    is_ad_in_domains = false;
    for (int i = 0; i < count; i++) {
        is_ad_in_domains += strcmp(ad_domain, domains[i]) == 0 ? true : false;
    }

    if (is_ad_in_domains == false) {
        domains = talloc_realloc(tmp_ctx, domains, const char*, count + 2);
        if (domains == NULL) {
            ret = ENOMEM;
            goto done;
        }

        domains[count] = talloc_strdup(domains, ad_domain);
        if (domains[count] == NULL) {
            ret = ENOMEM;
            goto done;
        }

        domains[count + 1] = NULL;
    } else {
Exemplo n.º 6
0
static errno_t krb5_auth_prepare_ccache_name(struct krb5child_req *kr,
                                             struct ldb_message *user_msg,
                                             struct be_ctx *be_ctx)
{
    const char *ccname_template;

    switch (kr->dom->type) {
    case DOM_TYPE_POSIX:
        ccname_template = dp_opt_get_cstring(kr->krb5_ctx->opts, KRB5_CCNAME_TMPL);

        kr->ccname = expand_ccname_template(kr, kr, ccname_template,
                                            kr->krb5_ctx->illegal_path_re, true,
                                            be_ctx->domain->case_sensitive);
        if (kr->ccname == NULL) {
            DEBUG(SSSDBG_CRIT_FAILURE, "expand_ccname_template failed.\n");
            return ENOMEM;
        }

        kr->old_ccname = ldb_msg_find_attr_as_string(user_msg,
                                                    SYSDB_CCACHE_FILE, NULL);
        if (kr->old_ccname == NULL) {
            DEBUG(SSSDBG_TRACE_LIBS,
                    "No ccache file for user [%s] found.\n", kr->pd->user);
        }
        break;
    case DOM_TYPE_APPLICATION:
        DEBUG(SSSDBG_TRACE_FUNC,
               "Domain type application, will use in-memory ccache\n");
        /* We don't care about using cryptographic randomness, just
         * a non-predictable ccname, so using rand() here is fine
         */
        kr->ccname = talloc_asprintf(kr,
                                     NON_POSIX_CCNAME_FMT,
                                     rand() % UINT_MAX);
        if (kr->ccname == NULL) {
            DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
            return ENOMEM;
        }

        break;
    default:
        DEBUG(SSSDBG_FATAL_FAILURE, "Unsupported domain type\n");
        return EINVAL;
    }

    return EOK;
}
Exemplo n.º 7
0
errno_t krb5_get_simple_upn(TALLOC_CTX *mem_ctx, struct krb5_ctx *krb5_ctx,
                            const char *username, const char **_upn)
{
    const char *realm;
    char *upn;

    realm = dp_opt_get_cstring(krb5_ctx->opts, KRB5_REALM);
    if (realm == NULL) {
        DEBUG(1, ("Missing Kerberos realm.\n"));
        return ENOENT;
    }

    /* NOTE: this is a hack, works only in some environments */
    upn = talloc_asprintf(mem_ctx, "%s@%s",  username, realm);
    if (upn == NULL) {
        DEBUG(1, ("talloc_asprintf failed.\n"));
        return ENOMEM;
    }

    DEBUG(9, ("Using simple UPN [%s].\n", upn));

    *_upn = upn;
    return EOK;
}
Exemplo n.º 8
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;
}
Exemplo n.º 9
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;
}
Exemplo n.º 10
0
static void hbac_get_rule_info_step(struct tevent_req *req)
{
    errno_t ret;
    size_t i;
    const char *ipa_hostname;
    const char *hostname;
    struct hbac_ctx *hbac_ctx =
            tevent_req_callback_data(req, struct hbac_ctx);
    struct be_ctx *be_ctx = be_req_get_be_ctx(hbac_ctx->be_req);

    ret = ipa_hbac_service_info_recv(req, hbac_ctx,
                                     &hbac_ctx->service_count,
                                     &hbac_ctx->services,
                                     &hbac_ctx->servicegroup_count,
                                     &hbac_ctx->servicegroups);
    talloc_zfree(req);
    if (!hbac_check_step_result(hbac_ctx, ret)) {
        return;
    }

    /* Get the ipa_host attrs */
    hbac_ctx->ipa_host = NULL;
    ipa_hostname = dp_opt_get_cstring(hbac_ctx->ipa_options, IPA_HOSTNAME);
    if (ipa_hostname == NULL) {
        DEBUG(1, ("Missing ipa_hostname, this should never happen.\n"));
        goto fail;
    }

    for (i = 0; i < hbac_ctx->host_count; i++) {
        ret = sysdb_attrs_get_string(hbac_ctx->hosts[i],
                                     SYSDB_FQDN,
                                     &hostname);
        if (ret != EOK) {
            DEBUG(1, ("Could not locate IPA host\n"));
            goto fail;
        }

        if (strcasecmp(hostname, ipa_hostname) == 0) {
            hbac_ctx->ipa_host = hbac_ctx->hosts[i];
            break;
        }
    }
    if (hbac_ctx->ipa_host == NULL) {
        DEBUG(1, ("Could not locate IPA host\n"));
        goto fail;
    }


    /* Get the list of applicable rules */
    req = ipa_hbac_rule_info_send(hbac_ctx,
                                  hbac_ctx->get_deny_rules,
                                  be_ctx->ev,
                                  sdap_id_op_handle(hbac_ctx->sdap_op),
                                  hbac_ctx->sdap_ctx->opts,
                                  hbac_ctx->search_bases,
                                  hbac_ctx->ipa_host);
    if (req == NULL) {
        DEBUG(1, ("Could not get rules\n"));
        goto fail;
    }

    tevent_req_set_callback(req, hbac_sysdb_save, hbac_ctx);
    return;

fail:
    ipa_access_reply(hbac_ctx, PAM_SYSTEM_ERR);
}