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; }
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); }
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; }
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; }
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 {
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; }
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; }
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; }
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; }
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); }