diff options
Diffstat (limited to 'src/providers')
-rw-r--r-- | src/providers/krb5/krb5_auth.h | 9 | ||||
-rw-r--r-- | src/providers/krb5/krb5_child.c | 129 | ||||
-rw-r--r-- | src/providers/krb5/krb5_child_handler.c | 134 | ||||
-rw-r--r-- | src/providers/krb5/krb5_common.c | 97 | ||||
-rw-r--r-- | src/providers/krb5/krb5_common.h | 30 | ||||
-rw-r--r-- | src/providers/krb5/krb5_init.c | 2 | ||||
-rw-r--r-- | src/providers/krb5/krb5_init_shared.c | 6 |
7 files changed, 276 insertions, 131 deletions
diff --git a/src/providers/krb5/krb5_auth.h b/src/providers/krb5/krb5_auth.h index 11bb59583..75ad916e7 100644 --- a/src/providers/krb5/krb5_auth.h +++ b/src/providers/krb5/krb5_auth.h @@ -38,6 +38,15 @@ #define ILLEGAL_PATH_PATTERN "//|/\\./|/\\.\\./" +#define CHILD_OPT_FAST_CCACHE_UID "fast-ccache-uid" +#define CHILD_OPT_FAST_CCACHE_GID "fast-ccache-gid" +#define CHILD_OPT_REALM "realm" +#define CHILD_OPT_LIFETIME "lifetime" +#define CHILD_OPT_RENEWABLE_LIFETIME "renewable-lifetime" +#define CHILD_OPT_USE_FAST "use-fast" +#define CHILD_OPT_FAST_PRINCIPAL "fast-principal" +#define CHILD_OPT_CANONICALIZE "canonicalize" + struct krb5child_req { struct pam_data *pd; struct krb5_ctx *krb5_ctx; diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c index df94bc4c4..be31ddbc4 100644 --- a/src/providers/krb5/krb5_child.c +++ b/src/providers/krb5/krb5_child.c @@ -48,6 +48,15 @@ enum k5c_fast_opt { K5C_FAST_DEMAND, }; +struct cli_opts { + char *realm; + char *lifetime; + char *rtime; + char *use_fast_str; + char *fast_principal; + bool canonicalize; +}; + struct krb5_req { krb5_context ctx; krb5_principal princ; @@ -81,73 +90,68 @@ struct krb5_req { uid_t fast_uid; gid_t fast_gid; + + struct cli_opts *cli_opts; }; static krb5_context krb5_error_ctx; #define KRB5_CHILD_DEBUG(level, error) KRB5_DEBUG(level, krb5_error_ctx, error) -static krb5_error_code set_lifetime_options(krb5_get_init_creds_opt *options) +static krb5_error_code set_lifetime_options(struct cli_opts *cli_opts, + krb5_get_init_creds_opt *options) { - char *lifetime_str; krb5_error_code kerr; krb5_deltat lifetime; - lifetime_str = getenv(SSSD_KRB5_RENEWABLE_LIFETIME); - if (lifetime_str == NULL) { - DEBUG(SSSDBG_CONF_SETTINGS, "Cannot read [%s] from environment.\n", - SSSD_KRB5_RENEWABLE_LIFETIME); + if (cli_opts->rtime == NULL) { + DEBUG(SSSDBG_CONF_SETTINGS, + "No specific renewable lifetime requested.\n"); /* Unset option flag to make sure defaults from krb5.conf are used. */ options->flags &= ~(KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE); } else { - kerr = krb5_string_to_deltat(lifetime_str, &lifetime); + kerr = krb5_string_to_deltat(cli_opts->rtime, &lifetime); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, - "krb5_string_to_deltat failed for [%s].\n", - lifetime_str); + "krb5_string_to_deltat failed for [%s].\n", cli_opts->rtime); KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); return kerr; } - DEBUG(SSSDBG_CONF_SETTINGS, "%s is set to [%s]\n", - SSSD_KRB5_RENEWABLE_LIFETIME, lifetime_str); + DEBUG(SSSDBG_CONF_SETTINGS, "Renewable lifetime is set to [%s]\n", + cli_opts->rtime); krb5_get_init_creds_opt_set_renew_life(options, lifetime); } - lifetime_str = getenv(SSSD_KRB5_LIFETIME); - if (lifetime_str == NULL) { - DEBUG(SSSDBG_CONF_SETTINGS, "Cannot read [%s] from environment.\n", - SSSD_KRB5_LIFETIME); + if (cli_opts->lifetime == NULL) { + DEBUG(SSSDBG_CONF_SETTINGS, "No specific lifetime requested.\n"); /* Unset option flag to make sure defaults from krb5.conf are used. */ options->flags &= ~(KRB5_GET_INIT_CREDS_OPT_TKT_LIFE); } else { - kerr = krb5_string_to_deltat(lifetime_str, &lifetime); + kerr = krb5_string_to_deltat(cli_opts->lifetime, &lifetime); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_string_to_deltat failed for [%s].\n", - lifetime_str); + cli_opts->lifetime); KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); return kerr; } - DEBUG(SSSDBG_CONF_SETTINGS, - "%s is set to [%s]\n", SSSD_KRB5_LIFETIME, lifetime_str); + DEBUG(SSSDBG_CONF_SETTINGS, "Lifetime is set to [%s]\n", + cli_opts->lifetime); krb5_get_init_creds_opt_set_tkt_life(options, lifetime); } return 0; } -static void set_canonicalize_option(krb5_get_init_creds_opt *opts) +static void set_canonicalize_option(struct cli_opts *cli_opts, + krb5_get_init_creds_opt *opts) { int canonicalize = 0; - char *tmp_str; - tmp_str = getenv(SSSD_KRB5_CANONICALIZE); - if (tmp_str != NULL && strcasecmp(tmp_str, "true") == 0) { - canonicalize = 1; - } - DEBUG(SSSDBG_CONF_SETTINGS, "%s is set to [%s]\n", - SSSD_KRB5_CANONICALIZE, tmp_str ? tmp_str : "not set"); + canonicalize = cli_opts->canonicalize ? 1 : 0; + DEBUG(SSSDBG_CONF_SETTINGS, "Canonicalization is set to [%s]\n", + cli_opts->canonicalize ? "true" : "false"); sss_krb5_get_init_creds_opt_set_canonicalize(opts, canonicalize); } @@ -160,18 +164,19 @@ static void set_changepw_options(krb5_get_init_creds_opt *options) krb5_get_init_creds_opt_set_tkt_life(options, 5*60); } -static void revert_changepw_options(krb5_get_init_creds_opt *options) +static void revert_changepw_options(struct cli_opts *cli_opts, + krb5_get_init_creds_opt *options) { krb5_error_code kerr; - set_canonicalize_option(options); + set_canonicalize_option(cli_opts, options); /* Currently we do not set forwardable and proxiable explicitly, the flags * must be removed so that libkrb5 can take the defaults from krb5.conf */ options->flags &= ~(KRB5_GET_INIT_CREDS_OPT_FORWARDABLE); options->flags &= ~(KRB5_GET_INIT_CREDS_OPT_PROXIABLE); - kerr = set_lifetime_options(options); + kerr = set_lifetime_options(cli_opts, options); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "set_lifetime_options failed.\n"); } @@ -1218,6 +1223,7 @@ done: } static krb5_error_code get_and_save_tgt_with_keytab(krb5_context ctx, + struct cli_opts *cli_opts, krb5_principal princ, krb5_keytab keytab, char *ccname) @@ -1232,7 +1238,7 @@ static krb5_error_code get_and_save_tgt_with_keytab(krb5_context ctx, krb5_get_init_creds_opt_set_address_list(&options, NULL); krb5_get_init_creds_opt_set_forwardable(&options, 0); krb5_get_init_creds_opt_set_proxiable(&options, 0); - set_canonicalize_option(&options); + set_canonicalize_option(cli_opts, &options); kerr = krb5_get_init_creds_keytab(ctx, &creds, princ, keytab, 0, NULL, &options); @@ -1582,7 +1588,7 @@ static errno_t changepw_child(struct krb5_req *kr, bool prelim) /* We changed some of the gic options for the password change, now we have * to change them back to get a fresh TGT. */ - revert_changepw_options(kr->options); + revert_changepw_options(kr->cli_opts, kr->options); ret = sss_authtok_set_password(kr->pd->authtok, newpassword, 0); if (ret != EOK) { @@ -2053,6 +2059,7 @@ static krb5_error_code check_fast_ccache(TALLOC_CTX *mem_ctx, krb5_context ctx, uid_t fast_uid, gid_t fast_gid, + struct cli_opts *cli_opts, const char *primary, const char *realm, const char *keytab_name, @@ -2149,7 +2156,7 @@ static krb5_error_code check_fast_ccache(TALLOC_CTX *mem_ctx, DEBUG(SSSDBG_TRACE_INTERNAL, "Running as [%"SPRIuid"][%"SPRIgid"].\n", geteuid(), getegid()); - kerr = get_and_save_tgt_with_keytab(ctx, client_princ, + kerr = get_and_save_tgt_with_keytab(ctx, cli_opts, client_princ, keytab, ccname); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, @@ -2255,14 +2262,14 @@ static int k5c_setup_fast(struct krb5_req *kr, bool demand) char *fast_principal_realm; char *fast_principal; krb5_error_code kerr; - char *tmp_str; + char *tmp_str = NULL; char *new_ccname; - tmp_str = getenv(SSSD_KRB5_FAST_PRINCIPAL); - if (tmp_str) { - DEBUG(SSSDBG_CONF_SETTINGS, "%s is set to [%s]\n", - SSSD_KRB5_FAST_PRINCIPAL, tmp_str); - kerr = krb5_parse_name(kr->ctx, tmp_str, &fast_princ_struct); + if (kr->cli_opts->fast_principal) { + DEBUG(SSSDBG_CONF_SETTINGS, "Fast principal is set to [%s]\n", + kr->cli_opts->fast_principal); + kerr = krb5_parse_name(kr->ctx, kr->cli_opts->fast_principal, + &fast_princ_struct); if (kerr) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_parse_name failed.\n"); return kerr; @@ -2281,7 +2288,8 @@ static int k5c_setup_fast(struct krb5_req *kr, bool demand) } free(tmp_str); realm_data = krb5_princ_realm(kr->ctx, fast_princ_struct); - fast_principal_realm = talloc_asprintf(kr, "%.*s", realm_data->length, realm_data->data); + fast_principal_realm = talloc_asprintf(kr, "%.*s", realm_data->length, + realm_data->data); if (!fast_principal_realm) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); return ENOMEM; @@ -2292,6 +2300,7 @@ static int k5c_setup_fast(struct krb5_req *kr, bool demand) } kerr = check_fast_ccache(kr, kr->ctx, kr->fast_uid, kr->fast_gid, + kr->cli_opts, fast_principal, fast_principal_realm, kr->keytab, &kr->fast_ccname); if (kerr != 0) { @@ -2336,12 +2345,11 @@ static int k5c_setup_fast(struct krb5_req *kr, bool demand) return EOK; } -static errno_t check_use_fast(enum k5c_fast_opt *_fast_val) +static errno_t check_use_fast(const char *use_fast_str, + enum k5c_fast_opt *_fast_val) { - char *use_fast_str; enum k5c_fast_opt fast_val; - use_fast_str = getenv(SSSD_KRB5_USE_FAST); if (use_fast_str == NULL || strcasecmp(use_fast_str, "never") == 0) { DEBUG(SSSDBG_CONF_SETTINGS, "Not using FAST.\n"); fast_val = K5C_FAST_NEVER; @@ -2560,14 +2568,14 @@ static int k5c_setup(struct krb5_req *kr, uint32_t offline) krb5_get_init_creds_opt_set_change_password_prompt(kr->options, 0); #endif - kerr = set_lifetime_options(kr->options); + kerr = set_lifetime_options(kr->cli_opts, kr->options); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "set_lifetime_options failed.\n"); return kerr; } if (!offline) { - set_canonicalize_option(kr->options); + set_canonicalize_option(kr->cli_opts, kr->options); } /* TODO: set options, e.g. @@ -2591,10 +2599,9 @@ static krb5_error_code privileged_krb5_setup(struct krb5_req *kr, int ret; char *mem_keytab; - kr->realm = getenv(SSSD_KRB5_REALM); + kr->realm = kr->cli_opts->realm; if (kr->realm == NULL) { - DEBUG(SSSDBG_MINOR_FAILURE, - "Cannot read [%s] from environment.\n", SSSD_KRB5_REALM); + DEBUG(SSSDBG_MINOR_FAILURE, "Realm not available.\n"); } kerr = krb5_init_context(&kr->ctx); @@ -2609,7 +2616,7 @@ static krb5_error_code privileged_krb5_setup(struct krb5_req *kr, return kerr; } - ret = check_use_fast(&kr->fast_val); + ret = check_use_fast(kr->cli_opts->use_fast_str, &kr->fast_val); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "check_use_fast failed.\n"); return ret; @@ -2691,6 +2698,7 @@ int main(int argc, const char *argv[]) krb5_error_code kerr; uid_t fast_uid; gid_t fast_gid; + struct cli_opts cli_opts = { 0 }; struct poptOption long_options[] = { POPT_AUTOHELP @@ -2705,19 +2713,37 @@ int main(int argc, const char *argv[]) {"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, &debug_to_stderr, 0, _("Send the debug output to stderr directly."), NULL }, - {"fast-ccache-uid", 0, POPT_ARG_INT, &fast_uid, 0, + {CHILD_OPT_FAST_CCACHE_UID, 0, POPT_ARG_INT, &fast_uid, 0, _("The user to create FAST ccache as"), NULL}, - {"fast-ccache-gid", 0, POPT_ARG_INT, &fast_gid, 0, + {CHILD_OPT_FAST_CCACHE_GID, 0, POPT_ARG_INT, &fast_gid, 0, _("The group to create FAST ccache as"), NULL}, + {CHILD_OPT_REALM, 0, POPT_ARG_STRING, &cli_opts.realm, 0, + _("Kerberos realm to use"), NULL}, + {CHILD_OPT_LIFETIME, 0, POPT_ARG_STRING, &cli_opts.lifetime, 0, + _("Requested lifetime of the ticket"), NULL}, + {CHILD_OPT_RENEWABLE_LIFETIME, 0, POPT_ARG_STRING, &cli_opts.rtime, 0, + _("Requested renewable lifetime of the ticket"), NULL}, + {CHILD_OPT_USE_FAST, 0, POPT_ARG_STRING, &cli_opts.use_fast_str, 0, + _("FAST options ('never', 'try', 'demand')"), NULL}, + {CHILD_OPT_FAST_PRINCIPAL, 0, POPT_ARG_STRING, + &cli_opts.fast_principal, 0, + _("Specifies the server principal to use for FAST"), NULL}, + {CHILD_OPT_CANONICALIZE, 0, POPT_ARG_NONE, NULL, 'C', + _("Requests canonicalization of the principal name"), NULL}, POPT_TABLEEND }; /* Set debug level to invalid value so we can decide if -d 0 was used. */ debug_level = SSSDBG_INVALID; + cli_opts.canonicalize = false; + pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { + case 'C': + cli_opts.canonicalize = true; + break; default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); @@ -2757,6 +2783,7 @@ int main(int argc, const char *argv[]) kr->fast_uid = fast_uid; kr->fast_gid = fast_gid; + kr->cli_opts = &cli_opts; ret = k5c_recv_data(kr, STDIN_FILENO, &offline); if (ret != EOK) { diff --git a/src/providers/krb5/krb5_child_handler.c b/src/providers/krb5/krb5_child_handler.c index 1eec7261f..69636e0bc 100644 --- a/src/providers/krb5/krb5_child_handler.c +++ b/src/providers/krb5/krb5_child_handler.c @@ -273,21 +273,140 @@ static errno_t activate_child_timeout_handler(struct tevent_req *req, return EOK; } +errno_t set_extra_args(TALLOC_CTX *mem_ctx, struct krb5_ctx *krb5_ctx, + const char ***krb5_child_extra_args) +{ + const char **extra_args; + size_t c = 0; + int ret; + + if (krb5_ctx == NULL || krb5_child_extra_args == NULL) { + return EINVAL; + } + + extra_args = talloc_zero_array(mem_ctx, const char *, 9); + if (extra_args == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_array failed.\n"); + return ENOMEM; + } + + extra_args[c] = talloc_asprintf(extra_args, + "--"CHILD_OPT_FAST_CCACHE_UID"=%"SPRIuid, + getuid()); + if (extra_args[c] == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); + ret = ENOMEM; + goto done; + } + c++; + + extra_args[c] = talloc_asprintf(extra_args, + "--"CHILD_OPT_FAST_CCACHE_GID"=%"SPRIgid, + getgid()); + if (extra_args[c] == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); + ret = ENOMEM; + goto done; + } + c++; + + if (krb5_ctx->realm != NULL) { + extra_args[c] = talloc_asprintf(extra_args, "--"CHILD_OPT_REALM"=%s", + krb5_ctx->realm); + if (extra_args[c] == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); + ret = ENOMEM; + goto done; + } + c++; + } + + if (krb5_ctx->lifetime_str != NULL) { + extra_args[c] = talloc_asprintf(extra_args, "--"CHILD_OPT_LIFETIME"=%s", + krb5_ctx->lifetime_str); + if (extra_args[c] == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); + ret = ENOMEM; + goto done; + } + c++; + } + + if (krb5_ctx->rlife_str != NULL) { + extra_args[c] = talloc_asprintf(extra_args, + "--"CHILD_OPT_RENEWABLE_LIFETIME"=%s", + krb5_ctx->rlife_str); + if (extra_args[c] == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); + ret = ENOMEM; + goto done; + } + c++; + } + + if (krb5_ctx->use_fast_str != NULL) { + extra_args[c] = talloc_asprintf(extra_args, "--"CHILD_OPT_USE_FAST"=%s", + krb5_ctx->use_fast_str); + if (extra_args[c] == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); + ret = ENOMEM; + goto done; + } + c++; + + if (krb5_ctx->fast_principal != NULL) { + extra_args[c] = talloc_asprintf(extra_args, + "--"CHILD_OPT_FAST_PRINCIPAL"=%s", + krb5_ctx->fast_principal); + if (extra_args[c] == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); + ret = ENOMEM; + goto done; + } + c++; + } + } + + if (krb5_ctx->canonicalize) { + extra_args[c] = talloc_strdup(extra_args, + "--" CHILD_OPT_CANONICALIZE); + if (extra_args[c] == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); + ret = ENOMEM; + goto done; + } + c++; + } + + extra_args[c] = NULL; + + *krb5_child_extra_args = extra_args; + + ret = EOK; + +done: + + if (ret != EOK) { + talloc_free(extra_args); + } + + return ret; +} + static errno_t fork_child(struct tevent_req *req) { int pipefd_to_child[2] = PIPE_INIT; int pipefd_from_child[2] = PIPE_INIT; pid_t pid; errno_t ret; + const char **krb5_child_extra_args; struct handle_child_state *state = tevent_req_data(req, struct handle_child_state); - const char *k5c_extra_args[3]; - k5c_extra_args[0] = talloc_asprintf(state, "--fast-ccache-uid=%"SPRIuid, getuid()); - k5c_extra_args[1] = talloc_asprintf(state, "--fast-ccache-gid=%"SPRIgid, getgid()); - k5c_extra_args[2] = NULL; - if (k5c_extra_args[0] == NULL || k5c_extra_args[1] == NULL) { - return ENOMEM; + ret = set_extra_args(state, state->kr->krb5_ctx, &krb5_child_extra_args); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "set_extra_args failed.\n"); + goto fail; } ret = pipe(pipefd_from_child); @@ -311,7 +430,8 @@ static errno_t fork_child(struct tevent_req *req) exec_child_ex(state, pipefd_to_child, pipefd_from_child, KRB5_CHILD, state->kr->krb5_ctx->child_debug_fd, - k5c_extra_args, false, STDIN_FILENO, STDOUT_FILENO); + krb5_child_extra_args, false, + STDIN_FILENO, STDOUT_FILENO); /* We should never get here */ DEBUG(SSSDBG_CRIT_FAILURE, "BUG: Could not exec KRB5 child\n"); diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c index 208a003e0..6c39b3584 100644 --- a/src/providers/krb5/krb5_common.c +++ b/src/providers/krb5/krb5_common.c @@ -38,31 +38,38 @@ #include <profile.h> #endif -errno_t check_and_export_lifetime(struct dp_option *opts, const int opt_id, - const char *env_name) +static errno_t check_lifetime(TALLOC_CTX *mem_ctx, struct dp_option *opts, + const int opt_id, char **lifetime_str) { int ret; - char *str; + char *str = NULL; krb5_deltat lifetime; - bool free_str = false; str = dp_opt_get_string(opts, opt_id); if (str == NULL || *str == '\0') { DEBUG(SSSDBG_FUNC_DATA, "No lifetime configured.\n"); + *lifetime_str = NULL; return EOK; } if (isdigit(str[strlen(str)-1])) { - str = talloc_asprintf(opts, "%ss", str); + str = talloc_asprintf(mem_ctx, "%ss", str); if (str == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed\n"); - return ENOMEM; + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); + ret = ENOMEM; + goto done; } - free_str = true; ret = dp_opt_set_string(opts, opt_id, str); if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "dp_opt_set_string failed\n"); + DEBUG(SSSDBG_CRIT_FAILURE, "dp_opt_set_string failed.\n"); + goto done; + } + } else { + str = talloc_strdup(mem_ctx, str); + if (str == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n"); + ret = ENOMEM; goto done; } } @@ -74,17 +81,12 @@ errno_t check_and_export_lifetime(struct dp_option *opts, const int opt_id, goto done; } - ret = setenv(env_name, str, 1); - if (ret != EOK) { - ret = errno; - DEBUG(SSSDBG_OP_FAILURE, "setenv [%s] failed.\n", env_name); - goto done; - } + *lifetime_str = str; ret = EOK; done: - if (free_str) { + if (ret != EOK) { talloc_free(str); } @@ -157,18 +159,20 @@ static void sss_check_cc_template(const char *cc_template) } } -errno_t check_and_export_options(struct dp_option *opts, - struct sss_domain_info *dom, - struct krb5_ctx *krb5_ctx) +errno_t sss_krb5_check_options(struct dp_option *opts, + struct sss_domain_info *dom, + struct krb5_ctx *krb5_ctx) { TALLOC_CTX *tmp_ctx = NULL; int ret; const char *realm; const char *dummy; - char *use_fast_str; - char *fast_principal; char *ccname; + if (opts == NULL || dom == NULL || krb5_ctx == NULL) { + return EINVAL; + } + tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { ret = ENOMEM; @@ -185,15 +189,14 @@ errno_t check_and_export_options(struct dp_option *opts, realm = dom->name; } - ret = setenv(SSSD_KRB5_REALM, realm, 1); - if (ret != EOK) { + krb5_ctx->realm = talloc_strdup(krb5_ctx, realm); + if (krb5_ctx->realm == NULL) { DEBUG(SSSDBG_OP_FAILURE, - "setenv %s failed, authentication might fail.\n", - SSSD_KRB5_REALM); + "Failed to set realm, krb5_child might not work as expected.\n"); } - ret = check_and_export_lifetime(opts, KRB5_RENEWABLE_LIFETIME, - SSSD_KRB5_RENEWABLE_LIFETIME); + ret = check_lifetime(krb5_ctx, opts, KRB5_RENEWABLE_LIFETIME, + &krb5_ctx->rlife_str); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to check value of krb5_renewable_lifetime. [%d][%s]\n", @@ -201,8 +204,8 @@ errno_t check_and_export_options(struct dp_option *opts, goto done; } - ret = check_and_export_lifetime(opts, KRB5_LIFETIME, - SSSD_KRB5_LIFETIME); + ret = check_lifetime(krb5_ctx, opts, KRB5_LIFETIME, + &krb5_ctx->lifetime_str); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to check value of krb5_lifetime. [%d][%s]\n", @@ -210,30 +213,17 @@ errno_t check_and_export_options(struct dp_option *opts, goto done; } - - 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); + krb5_ctx->use_fast_str = dp_opt_get_cstring(opts, KRB5_USE_FAST); + if (krb5_ctx->use_fast_str != NULL) { + ret = check_fast(krb5_ctx->use_fast_str, &krb5_ctx->use_fast); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "check_fast failed.\n"); goto done; } if (krb5_ctx->use_fast) { - ret = setenv(SSSD_KRB5_USE_FAST, use_fast_str, 1); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, - "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(SSSDBG_OP_FAILURE, - "setenv [%s] failed.\n", SSSD_KRB5_FAST_PRINCIPAL); - } - } - } + krb5_ctx->fast_principal = dp_opt_get_cstring(opts, + KRB5_FAST_PRINCIPAL); } } @@ -241,15 +231,10 @@ errno_t check_and_export_options(struct dp_option *opts, * enterprise principal in an AS request but requires the canonicalize * flags to be set. To be on the safe side we always enable * canonicalization if enterprise principals are used. */ + krb5_ctx->canonicalize = false; if (dp_opt_get_bool(opts, KRB5_CANONICALIZE) || dp_opt_get_bool(opts, KRB5_USE_ENTERPRISE_PRINCIPAL)) { - ret = setenv(SSSD_KRB5_CANONICALIZE, "true", 1); - } else { - ret = setenv(SSSD_KRB5_CANONICALIZE, "false", 1); - } - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, - "setenv [%s] failed.\n", SSSD_KRB5_CANONICALIZE); + krb5_ctx->canonicalize = true; } dummy = dp_opt_get_cstring(opts, KRB5_KDC); @@ -370,8 +355,8 @@ errno_t krb5_try_kdcip(struct confdb_ctx *cdb, const char *conf_path, return EOK; } -errno_t krb5_get_options(TALLOC_CTX *memctx, struct confdb_ctx *cdb, - const char *conf_path, struct dp_option **_opts) +errno_t sss_krb5_get_options(TALLOC_CTX *memctx, struct confdb_ctx *cdb, + const char *conf_path, struct dp_option **_opts) { int ret; struct dp_option *opts; diff --git a/src/providers/krb5/krb5_common.h b/src/providers/krb5/krb5_common.h index 3bd5ed1c8..bc35c5df6 100644 --- a/src/providers/krb5/krb5_common.h +++ b/src/providers/krb5/krb5_common.h @@ -33,14 +33,6 @@ #include "util/util.h" #include "util/sss_krb5.h" -#define SSSD_KRB5_KDC "SSSD_KRB5_KDC" -#define SSSD_KRB5_REALM "SSSD_KRB5_REALM" -#define SSSD_KRB5_RENEWABLE_LIFETIME "SSSD_KRB5_RENEWABLE_LIFETIME" -#define SSSD_KRB5_LIFETIME "SSSD_KRB5_LIFETIME" -#define SSSD_KRB5_USE_FAST "SSSD_KRB5_USE_FAST" -#define SSSD_KRB5_FAST_PRINCIPAL "SSSD_KRB5_FAST_PRINCIPAL" -#define SSSD_KRB5_CANONICALIZE "SSSD_KRB5_CANONICALIZE" - #define KDCINFO_TMPL PUBCONF_PATH"/kdcinfo.%s" #define KPASSWDINFO_TMPL PUBCONF_PATH"/kpasswdinfo.%s" @@ -100,7 +92,9 @@ struct krb5_ctx { /* in seconds */ krb5_deltat starttime; krb5_deltat lifetime; + char *lifetime_str; krb5_deltat rlife; + char *rlife_str; int forwardable; int proxiable; @@ -136,6 +130,13 @@ struct krb5_ctx { enum krb5_config_type config_type; struct map_id_name_to_krb_primary *name_to_primary; + + char *realm; + + const char *use_fast_str; + const char *fast_principal; + + bool canonicalize; }; struct remove_info_files_ctx { @@ -145,15 +146,15 @@ struct remove_info_files_ctx { const char *kpasswd_service_name; }; -errno_t check_and_export_options(struct dp_option *opts, - struct sss_domain_info *dom, - struct krb5_ctx *krb5_ctx); +errno_t sss_krb5_check_options(struct dp_option *opts, + struct sss_domain_info *dom, + struct krb5_ctx *krb5_ctx); errno_t krb5_try_kdcip(struct confdb_ctx *cdb, const char *conf_path, struct dp_option *opts, int opt_id); -errno_t krb5_get_options(TALLOC_CTX *memctx, struct confdb_ctx *cdb, - const char *conf_path, struct dp_option **_opts); +errno_t sss_krb5_get_options(TALLOC_CTX *memctx, struct confdb_ctx *cdb, + const char *conf_path, struct dp_option **_opts); errno_t write_krb5info_file(const char *realm, const char *kdc, const char *service); @@ -221,4 +222,7 @@ krb5_error_code copy_keytab_into_memory(TALLOC_CTX *mem_ctx, krb5_context kctx, const char *inp_keytab_file, char **_mem_name, krb5_keytab *_mem_keytab); + +errno_t set_extra_args(TALLOC_CTX *mem_ctx, struct krb5_ctx *krb5_ctx, + const char ***krb5_child_extra_args); #endif /* __KRB5_COMMON_H__ */ diff --git a/src/providers/krb5/krb5_init.c b/src/providers/krb5/krb5_init.c index d356491e5..12c8dfcc4 100644 --- a/src/providers/krb5/krb5_init.c +++ b/src/providers/krb5/krb5_init.c @@ -136,7 +136,7 @@ errno_t sssm_krb5_init(TALLOC_CTX *mem_ctx, return ENOMEM; } - ret = krb5_get_options(ctx, be_ctx->cdb, be_ctx->conf_path, &ctx->opts); + ret = sss_krb5_get_options(ctx, be_ctx->cdb, be_ctx->conf_path, &ctx->opts); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get krb5 options [%d]: %s\n", ret, sss_strerror(ret)); diff --git a/src/providers/krb5/krb5_init_shared.c b/src/providers/krb5/krb5_init_shared.c index c8fd8593a..3901b7272 100644 --- a/src/providers/krb5/krb5_init_shared.c +++ b/src/providers/krb5/krb5_init_shared.c @@ -64,10 +64,10 @@ errno_t krb5_child_init(struct krb5_ctx *krb5_auth_ctx, } } - ret = check_and_export_options(krb5_auth_ctx->opts, bectx->domain, - krb5_auth_ctx); + ret = sss_krb5_check_options(krb5_auth_ctx->opts, bectx->domain, + krb5_auth_ctx); if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "check_and_export_opts failed.\n"); + DEBUG(SSSDBG_CRIT_FAILURE, "sss_krb5_check_options failed.\n"); goto done; } |