diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/providers/krb5/krb5_child.c | 498 |
1 files changed, 210 insertions, 288 deletions
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c index 01da8402..9182f238 100644 --- a/src/providers/krb5/krb5_child.c +++ b/src/providers/krb5/krb5_child.c @@ -40,53 +40,16 @@ #define SSSD_KRB5_CHANGEPW_PRINCIPAL "kadmin/changepw" -struct krb5_child_ctx { - /* opts taken from kinit */ - /* in seconds */ - krb5_deltat starttime; - krb5_deltat lifetime; - krb5_deltat rlife; - - int forwardable; - int proxiable; - int addresses; - - int not_forwardable; - int not_proxiable; - int no_addresses; - - int verbose; - - char* principal_name; - char* service_name; - char* keytab_name; - char* k5_cache_name; - char* k4_cache_name; - - action_type action; - - char *kdcip; - char *realm; - char *ccache_dir; - char *ccname_template; - int auth_timeout; -}; - struct krb5_req { krb5_context ctx; krb5_principal princ; char* name; krb5_creds *creds; krb5_get_init_creds_opt *options; - pid_t child_pid; - int read_from_child_fd; - int write_to_child_fd; - struct be_req *req; struct pam_data *pd; - struct krb5_child_ctx *krb5_ctx; - errno_t (*child_req)(int fd, struct krb5_req *kr); + char *realm; char *ccname; char *keytab; bool validate; @@ -676,14 +639,14 @@ static struct response *prepare_response_message(struct krb5_req *kr, return resp; } -static errno_t sendresponse(int fd, krb5_error_code kerr, int pam_status, - struct krb5_req *kr) +static errno_t k5c_send_data(struct krb5_req *kr, int fd, + krb5_error_code kerr, int status) { struct response *resp; size_t written; int ret; - resp = prepare_response_message(kr, kerr, pam_status); + resp = prepare_response_message(kr, kerr, status); if (resp == NULL) { DEBUG(1, ("prepare_response_message failed.\n")); return ENOMEM; @@ -1063,7 +1026,7 @@ static int kerr_to_status(krb5_error_code kerr) return kerr_handle_error(kerr); } -static errno_t changepw_child(int fd, struct krb5_req *kr) +static errno_t changepw_child(struct krb5_req *kr, int *_status) { int ret; krb5_error_code kerr = 0; @@ -1203,15 +1166,11 @@ static errno_t changepw_child(int fd, struct krb5_req *kr) pam_status = kerr_to_status(kerr); done: - ret = sendresponse(fd, kerr, pam_status, kr); - if (ret != EOK) { - DEBUG(1, ("sendresponse failed.\n")); - } - - return ret; + *_status = pam_status; + return kerr; } -static errno_t tgt_req_child(int fd, struct krb5_req *kr) +static errno_t tgt_req_child(struct krb5_req *kr, int *_status) { int ret; krb5_error_code kerr = 0; @@ -1270,18 +1229,13 @@ static errno_t tgt_req_child(int fd, struct krb5_req *kr) pam_status = kerr_to_status(kerr); done: - ret = sendresponse(fd, kerr, pam_status, kr); - if (ret != EOK) { - DEBUG(1, ("sendresponse failed.\n")); - } - - return ret; + *_status = pam_status; + return kerr; } -static errno_t kuserok_child(int fd, struct krb5_req *kr) +static errno_t kuserok_child(struct krb5_req *kr, int *_status) { krb5_boolean access_allowed; - int status; int ret; krb5_error_code kerr; @@ -1295,7 +1249,7 @@ static errno_t kuserok_child(int fd, struct krb5_req *kr) "krb5_kuserok will most certainly fail.\n")); } - kerr = krb5_set_default_realm(kr->ctx, kr->krb5_ctx->realm); + kerr = krb5_set_default_realm(kr->ctx, kr->realm); if (kerr != 0) { DEBUG(1, ("krb5_set_default_realm failed, " "krb5_kuserok may fail.\n")); @@ -1305,17 +1259,11 @@ static errno_t kuserok_child(int fd, struct krb5_req *kr) DEBUG(SSSDBG_TRACE_LIBS, ("Access was %s\n", access_allowed ? "allowed" : "denied")); - status = access_allowed ? 0 : 1; - - ret = sendresponse(fd, 0, status, kr); - if (ret != EOK) { - DEBUG(1, ("sendresponse failed.\n")); - } - - return ret; + *_status = access_allowed ? 0 : 1; + return kerr; } -static errno_t renew_tgt_child(int fd, struct krb5_req *kr) +static errno_t renew_tgt_child(struct krb5_req *kr, int *_status) { int ret; int status = PAM_AUTHTOK_ERR; @@ -1396,15 +1344,11 @@ done: krb5_cc_close(kr->ctx, ccache); } - ret = sendresponse(fd, kerr, status, kr); - if (ret != EOK) { - DEBUG(1, ("sendresponse failed.\n")); - } - - return ret; + *_status = status; + return kerr; } -static errno_t create_empty_ccache(int fd, struct krb5_req *kr) +static errno_t create_empty_ccache(struct krb5_req *kr, int *_status) { int ret; int pam_status = PAM_SUCCESS; @@ -1418,11 +1362,7 @@ static errno_t create_empty_ccache(int fd, struct krb5_req *kr) pam_status = PAM_SYSTEM_ERR; } - ret = sendresponse(fd, ret, pam_status, kr); - if (ret != EOK) { - DEBUG(1, ("sendresponse failed.\n")); - } - + *_status = pam_status; return ret; } @@ -1458,19 +1398,27 @@ static errno_t unpack_authtok(TALLOC_CTX *mem_ctx, struct sss_auth_token *tok, return ret; } -static errno_t unpack_buffer(uint8_t *buf, size_t size, struct pam_data *pd, +static errno_t unpack_buffer(uint8_t *buf, size_t size, struct krb5_req *kr, uint32_t *offline) { size_t p = 0; uint32_t len; uint32_t validate; uint32_t different_realm; + struct pam_data *pd; errno_t ret; DEBUG(SSSDBG_TRACE_LIBS, ("total buffer size: [%d]\n", size)); if (!offline || !kr) return EINVAL; + pd = talloc_zero(kr, struct pam_data); + if (pd == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_zero failed.\n")); + return ENOMEM; + } + kr->pd = pd; + SAFEALIGN_COPY_UINT32_CHECK(&pd->cmd, buf + p, size, &p); SAFEALIGN_COPY_UINT32_CHECK(&kr->uid, buf + p, size, &p); SAFEALIGN_COPY_UINT32_CHECK(&kr->gid, buf + p, size, &p); @@ -1542,9 +1490,8 @@ static errno_t unpack_buffer(uint8_t *buf, size_t size, struct pam_data *pd, return EOK; } -static int krb5_cleanup(void *ptr) +static int krb5_cleanup(struct krb5_req *kr) { - struct krb5_req *kr = talloc_get_type(ptr, struct krb5_req); if (kr == NULL) return EOK; if (kr->options != NULL) { @@ -1562,9 +1509,6 @@ static int krb5_cleanup(void *ptr) if (kr->ctx != NULL) krb5_free_context(kr->ctx); - if (kr->krb5_ctx != NULL) { - memset(kr->krb5_ctx, 0, sizeof(struct krb5_child_ctx)); - } memset(kr, 0, sizeof(struct krb5_req)); return EOK; @@ -1616,10 +1560,11 @@ done: return krberr; } -static krb5_error_code check_fast_ccache(krb5_context ctx, const char *primary, +static krb5_error_code check_fast_ccache(TALLOC_CTX *mem_ctx, + krb5_context ctx, + const char *primary, const char *realm, const char *keytab_name, - TALLOC_CTX *mem_ctx, char **fast_ccname) { TALLOC_CTX *tmp_ctx = NULL; @@ -1716,120 +1661,159 @@ done: return kerr; } -static errno_t -set_child_debugging(krb5_context ctx) +static errno_t k5c_recv_data(struct krb5_req *kr, int fd, uint32_t *offline) +{ + uint8_t buf[IN_BUF_SIZE]; + ssize_t len; + errno_t ret; + + errno = 0; + len = sss_atomic_read_s(fd, buf, IN_BUF_SIZE); + if (len == -1) { + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, + ("read failed [%d][%s].\n", ret, strerror(ret))); + return ret; + } + + ret = unpack_buffer(buf, len, kr, offline); + if (ret != EOK) { + DEBUG(1, ("unpack_buffer failed.\n")); + } + + return ret; +} + +static int k5c_setup_fast(struct krb5_req *kr, char *lifetime_str, bool demand) { + krb5_principal fast_princ_struct; + krb5_data *realm_data; + char *fast_principal_realm; + char *fast_principal; krb5_error_code kerr; + char *tmp_str; - /* Set the global error context */ - krb5_error_ctx = ctx; + DEBUG(SSSDBG_CONF_SETTINGS, ("%s is set to [%s]\n", + SSSD_KRB5_LIFETIME, lifetime_str)); - if (debug_level & SSSDBG_TRACE_ALL) { - kerr = sss_child_set_krb5_tracing(ctx); + 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 (kerr) { - KRB5_CHILD_DEBUG(SSSDBG_MINOR_FAILURE, kerr); - return EIO; + DEBUG(1, ("krb5_parse_name failed.\n")); + return kerr; + } + kerr = sss_krb5_unparse_name_flags(kr->ctx, fast_princ_struct, + KRB5_PRINCIPAL_UNPARSE_NO_REALM, + &tmp_str); + if (kerr) { + DEBUG(1, ("sss_krb5_unparse_name_flags failed.\n")); + return kerr; + } + fast_principal = talloc_strdup(kr, tmp_str); + if (!fast_principal) { + DEBUG(1, ("talloc_strdup failed.\n")); + return KRB5KRB_ERR_GENERIC; + } + 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); + if (!fast_principal_realm) { + DEBUG(1, ("talloc_asprintf failed.\n")); + return ENOMEM; + } + } else { + fast_principal_realm = kr->realm; + fast_principal = NULL; + } + + kerr = check_fast_ccache(kr, kr->ctx, fast_principal, fast_principal_realm, + kr->keytab, &kr->fast_ccname); + if (kerr != 0) { + DEBUG(1, ("check_fast_ccache failed.\n")); + KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); + return kerr; + } + + kerr = sss_krb5_get_init_creds_opt_set_fast_ccache_name(kr->ctx, + kr->options, + kr->fast_ccname); + if (kerr != 0) { + DEBUG(1, ("sss_krb5_get_init_creds_opt_set_fast_ccache_name " + "failed.\n")); + KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); + return kerr; + } + + if (demand) { + kerr = sss_krb5_get_init_creds_opt_set_fast_flags(kr->ctx, + kr->options, + SSS_KRB5_FAST_REQUIRED); + if (kerr != 0) { + DEBUG(1, ("sss_krb5_get_init_creds_opt_set_fast_flags " + "failed.\n")); + KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); + return kerr; } } return EOK; } -static int krb5_child_setup(struct krb5_req *kr, uint32_t offline) +static int k5c_setup(struct krb5_req *kr, uint32_t offline) { - krb5_error_code kerr = 0; + krb5_error_code kerr; char *lifetime_str; char *use_fast_str; - char *tmp_str; - krb5_data *realm_data; - krb5_principal fast_princ_struct; - char *fast_principal = NULL; - const char *fast_principal_realm = NULL; krb5_deltat lifetime; - kr->krb5_ctx = talloc_zero(kr, struct krb5_child_ctx); - if (kr->krb5_ctx == NULL) { - DEBUG(1, ("talloc failed.\n")); - kerr = ENOMEM; - goto failed; - } - - kr->krb5_ctx->realm = getenv(SSSD_KRB5_REALM); - if (kr->krb5_ctx->realm == NULL) { + kr->realm = getenv(SSSD_KRB5_REALM); + if (kr->realm == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, ("Cannot read [%s] from environment.\n", SSSD_KRB5_REALM)); } - switch(kr->pd->cmd) { - case SSS_PAM_AUTHENTICATE: - /* If we are offline, we need to create an empty ccache file */ - if (offline) { - DEBUG(SSSDBG_TRACE_FUNC, ("Will perform offline auth\n")); - kr->child_req = create_empty_ccache; - } else { - DEBUG(SSSDBG_TRACE_FUNC, ("Will perform online auth\n")); - kr->child_req = tgt_req_child; - } - break; - case SSS_PAM_CHAUTHTOK: - case SSS_PAM_CHAUTHTOK_PRELIM: - DEBUG(SSSDBG_TRACE_FUNC, ("Will perform password change\n")); - kr->child_req = changepw_child; - break; - case SSS_PAM_ACCT_MGMT: - DEBUG(SSSDBG_TRACE_FUNC, ("Will perform account management\n")); - kr->child_req = kuserok_child; - break; - case SSS_CMD_RENEW: - if (!offline) { - DEBUG(SSSDBG_TRACE_FUNC, ("Will perform ticket renewal\n")); - kr->child_req = renew_tgt_child; - } else { - DEBUG(1, ("Cannot renew TGT while offline.\n")); - kerr = KRB5_KDC_UNREACH; - goto failed; - } - break; - default: - DEBUG(1, ("PAM command [%d] not supported.\n", kr->pd->cmd)); - kerr = EINVAL; - goto failed; - } - kerr = krb5_init_context(&kr->ctx); if (kerr != 0) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); - goto failed; + return kerr; } - kerr = set_child_debugging(kr->ctx); - if (kerr != EOK) { - DEBUG(SSSDBG_MINOR_FAILURE, ("Cannot set krb5_child debugging\n")); + /* Set the global error context */ + krb5_error_ctx = kr->ctx; + + if (debug_level & SSSDBG_TRACE_ALL) { + kerr = sss_child_set_krb5_tracing(kr->ctx); + if (kerr) { + KRB5_CHILD_DEBUG(SSSDBG_MINOR_FAILURE, kerr); + return EIO; + } } kerr = krb5_parse_name(kr->ctx, kr->upn, &kr->princ); if (kerr != 0) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); - goto failed; + return kerr; } kerr = krb5_unparse_name(kr->ctx, kr->princ, &kr->name); if (kerr != 0) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); - goto failed; + return kerr; } kr->creds = calloc(1, sizeof(krb5_creds)); if (kr->creds == NULL) { DEBUG(1, ("talloc_zero failed.\n")); - kerr = ENOMEM; - goto failed; + return ENOMEM; } kerr = sss_krb5_get_init_creds_opt_alloc(kr->ctx, &kr->options); if (kerr != 0) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); - goto failed; + return kerr; } #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_CHANGE_PASSWORD_PROMPT @@ -1839,7 +1823,7 @@ static int krb5_child_setup(struct krb5_req *kr, uint32_t offline) krb5_get_init_creds_opt_set_change_password_prompt(kr->options, 0); if (kerr != 0) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); - goto failed; + return kerr; } #endif @@ -1853,7 +1837,7 @@ static int krb5_child_setup(struct krb5_req *kr, uint32_t offline) DEBUG(1, ("krb5_string_to_deltat failed for [%s].\n", lifetime_str)); KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); - goto failed; + return kerr; } DEBUG(SSSDBG_CONF_SETTINGS, ("%s is set to [%s]\n", SSSD_KRB5_RENEWABLE_LIFETIME, lifetime_str)); @@ -1870,7 +1854,7 @@ static int krb5_child_setup(struct krb5_req *kr, uint32_t offline) DEBUG(1, ("krb5_string_to_deltat failed for [%s].\n", lifetime_str)); KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); - goto failed; + return kerr; } DEBUG(SSSDBG_CONF_SETTINGS, ("%s is set to [%s]\n", SSSD_KRB5_LIFETIME, lifetime_str)); @@ -1883,78 +1867,13 @@ static int krb5_child_setup(struct krb5_req *kr, uint32_t offline) 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")); - } else if (strcasecmp(use_fast_str, "try") == 0 || - strcasecmp(use_fast_str, "demand") == 0) { - - DEBUG(SSSDBG_CONF_SETTINGS, ("%s is set to [%s]\n", - SSSD_KRB5_LIFETIME, lifetime_str)); - tmp_str = getenv(SSSD_KRB5_FAST_PRINCIPAL); - if (!tmp_str) { - fast_principal = NULL; - fast_principal_realm = kr->krb5_ctx->realm; - } else { - DEBUG(SSSDBG_CONF_SETTINGS, ("%s is set to [%s]\n", - SSSD_KRB5_FAST_PRINCIPAL, lifetime_str)); - kerr = krb5_parse_name(kr->ctx, tmp_str, &fast_princ_struct); - if (kerr) { - DEBUG(1, ("krb5_parse_name failed.\n")); - goto failed; - } - kerr = sss_krb5_unparse_name_flags(kr->ctx, fast_princ_struct, - KRB5_PRINCIPAL_UNPARSE_NO_REALM, - &tmp_str); - if (kerr) { - DEBUG(1, ("sss_krb5_unparse_name_flags failed.\n")); - goto failed; - } - fast_principal = talloc_strdup(kr, tmp_str); - if (!fast_principal) { - DEBUG(1, ("talloc_strdup failed.\n")); - kerr = KRB5KRB_ERR_GENERIC; - goto failed; - } - 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); - if (!fast_principal_realm) { - DEBUG(1, ("talloc_asprintf failed.\n")); - goto failed; - } - } - - kerr = check_fast_ccache(kr->ctx, fast_principal, fast_principal_realm, kr->keytab, - kr, &kr->fast_ccname); - if (kerr != 0) { - DEBUG(1, ("check_fast_ccache failed.\n")); - KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); - goto failed; - } - - kerr = sss_krb5_get_init_creds_opt_set_fast_ccache_name(kr->ctx, - kr->options, - kr->fast_ccname); - if (kerr != 0) { - DEBUG(1, ("sss_krb5_get_init_creds_opt_set_fast_ccache_name " - "failed.\n")); - KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); - goto failed; - } - - if (strcasecmp(use_fast_str, "demand") == 0) { - kerr = sss_krb5_get_init_creds_opt_set_fast_flags(kr->ctx, - kr->options, - SSS_KRB5_FAST_REQUIRED); - if (kerr != 0) { - DEBUG(1, ("sss_krb5_get_init_creds_opt_set_fast_flags " - "failed.\n")); - KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); - goto failed; - } - } + } else if (strcasecmp(use_fast_str, "try") == 0) { + kerr = k5c_setup_fast(kr, lifetime_str, false); + } else if (strcasecmp(use_fast_str, "demand") == 0) { + kerr = k5c_setup_fast(kr, lifetime_str, true); } else { DEBUG(1, ("Unsupported value [%s] for krb5_use_fast.\n")); - kerr = EINVAL; - goto failed; + return EINVAL; } } @@ -1969,24 +1888,18 @@ static int krb5_child_setup(struct krb5_req *kr, uint32_t offline) * krb5_get_init_creds_opt_set_pa */ - return EOK; - -failed: - return kerr; } int main(int argc, const char *argv[]) { - uint8_t *buf = NULL; - int ret; - ssize_t len = 0; - struct pam_data *pd = NULL; struct krb5_req *kr = NULL; uint32_t offline; int opt; poptContext pc; int debug_fd = -1; + int status; + int ret; struct poptOption long_options[] = { POPT_AUTOHELP @@ -2019,10 +1932,16 @@ int main(int argc, const char *argv[]) DEBUG_INIT(debug_level); - debug_prg_name = talloc_asprintf(NULL, "[sssd[krb5_child[%d]]]", getpid()); + kr = talloc_zero(NULL, struct krb5_req); + if (kr == NULL) { + DEBUG(1, ("talloc failed.\n")); + exit(-1); + } + + debug_prg_name = talloc_asprintf(kr, "[sssd[krb5_child[%d]]]", getpid()); if (!debug_prg_name) { DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_asprintf failed.\n")); - goto fail; + goto done; } if (debug_fd != -1) { @@ -2034,65 +1953,68 @@ int main(int argc, const char *argv[]) DEBUG(SSSDBG_TRACE_FUNC, ("krb5_child started.\n")); - pd = talloc_zero(NULL, struct pam_data); - if (pd == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_zero failed.\n")); - talloc_free(discard_const(debug_prg_name)); - goto fail; - } - talloc_steal(pd, debug_prg_name); - - buf = talloc_size(pd, sizeof(uint8_t)*IN_BUF_SIZE); - if (buf == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, ("malloc failed.\n")); - goto fail; - } - - errno = 0; - len = sss_atomic_read_s(STDIN_FILENO, buf, IN_BUF_SIZE); - if (len == -1) { - ret = errno; - DEBUG(SSSDBG_CRIT_FAILURE, ("read failed [%d][%s].\n", ret, strerror(ret))); - goto fail; + ret = k5c_recv_data(kr, STDIN_FILENO, &offline); + if (ret != EOK) { + goto done; } close(STDIN_FILENO); - kr = talloc_zero(pd, struct krb5_req); - if (kr == NULL) { - DEBUG(1, ("talloc failed.\n")); - goto fail; - } - talloc_set_destructor((TALLOC_CTX *) kr, krb5_cleanup); - kr->pd = pd; - - ret = unpack_buffer(buf, len, pd, kr, &offline); + ret = k5c_setup(kr, offline); if (ret != EOK) { - DEBUG(1, ("unpack_buffer failed.\n")); - goto fail; + DEBUG(SSSDBG_CRIT_FAILURE, ("krb5_child_setup failed.\n")); + goto done; } - ret = krb5_child_setup(kr, offline); - if (ret != EOK) { - DEBUG(1, ("krb5_child_setup failed.\n")); - goto fail; + switch(kr->pd->cmd) { + case SSS_PAM_AUTHENTICATE: + /* If we are offline, we need to create an empty ccache file */ + if (offline) { + DEBUG(SSSDBG_TRACE_FUNC, ("Will perform offline auth\n")); + ret = create_empty_ccache(kr, &status); + } else { + DEBUG(SSSDBG_TRACE_FUNC, ("Will perform online auth\n")); + ret = tgt_req_child(kr, &status); + } + break; + case SSS_PAM_CHAUTHTOK: + case SSS_PAM_CHAUTHTOK_PRELIM: + DEBUG(SSSDBG_TRACE_FUNC, ("Will perform password change\n")); + ret = changepw_child(kr, &status); + break; + case SSS_PAM_ACCT_MGMT: + DEBUG(SSSDBG_TRACE_FUNC, ("Will perform account management\n")); + ret = kuserok_child(kr, &status); + break; + case SSS_CMD_RENEW: + if (!offline) { + DEBUG(SSSDBG_TRACE_FUNC, ("Will perform ticket renewal\n")); + ret = renew_tgt_child(kr, &status); + } else { + DEBUG(SSSDBG_CRIT_FAILURE, ("Cannot renew TGT while offline\n")); + ret = KRB5_KDC_UNREACH; + goto done; + } + break; + default: + DEBUG(1, ("PAM command [%d] not supported.\n", kr->pd->cmd)); + ret = EINVAL; + goto done; } - ret = kr->child_req(STDOUT_FILENO, kr); + ret = k5c_send_data(kr, STDOUT_FILENO, ret, status); if (ret != EOK) { - DEBUG(1, ("Child request failed.\n")); - goto fail; + DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to send reply\n")); } - DEBUG(SSSDBG_TRACE_FUNC, ("krb5_child completed successfully\n")); - close(STDOUT_FILENO); - talloc_free(pd); - - return 0; - -fail: - DEBUG(SSSDBG_CRIT_FAILURE, ("krb5_child failed!\n")); - close(STDOUT_FILENO); - talloc_free(pd); - exit(-1); +done: + krb5_cleanup(kr); + talloc_free(kr); + if (ret == EOK) { + DEBUG(SSSDBG_TRACE_FUNC, ("krb5_child completed successfully\n")); + exit(0); + } else { + DEBUG(SSSDBG_CRIT_FAILURE, ("krb5_child failed!\n")); + exit(-1); + } } |