krb5_child.c revision f7e97d8b7b72f376a7c75dbe184634f38db35567
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht Kerberos 5 Backend Module -- tgt_req and changepw child
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht Sumit Bose <sbose@redhat.com>
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht Copyright (C) 2009-2010 Red Hat
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht This program is free software; you can redistribute it and/or modify
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht it under the terms of the GNU General Public License as published by
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht the Free Software Foundation; either version 3 of the License, or
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht (at your option) any later version.
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht This program is distributed in the hope that it will be useful,
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht but WITHOUT ANY WARRANTY; without even the implied warranty of
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht GNU General Public License for more details.
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht You should have received a copy of the GNU General Public License
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht along with this program. If not, see <http://www.gnu.org/licenses/>.
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht#define SSSD_KRB5_CHANGEPW_PRINCIPAL "kadmin/changepw"
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht /* opts taken from kinit */
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht /* in seconds */
8600e22385bce13c5d1048f7b955f9394a5d94d6Simon Ulbricht errno_t (*child_req)(int fd, struct krb5_req *kr);
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht#define KRB5_CHILD_DEBUG(level, error) KRB5_DEBUG(level, krb5_error_ctx, error)
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbrichtstatic krb5_error_code get_changepw_options(krb5_context ctx,
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht kerr = sss_krb5_get_init_creds_opt_alloc(ctx, &options);
8600e22385bce13c5d1048f7b955f9394a5d94d6Simon Ulbricht sss_krb5_get_init_creds_opt_set_canonicalize(options, 0);
5b93337fb97e848522fcc277e384f694595bc42cSimon Ulbricht krb5_get_init_creds_opt_set_forwardable(options, 0);
5b93337fb97e848522fcc277e384f694595bc42cSimon Ulbricht krb5_get_init_creds_opt_set_proxiable(options, 0);
5b93337fb97e848522fcc277e384f694595bc42cSimon Ulbricht krb5_get_init_creds_opt_set_renew_life(options, 0);
5b93337fb97e848522fcc277e384f694595bc42cSimon Ulbricht krb5_get_init_creds_opt_set_tkt_life(options, 5*60);
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbrichtstatic errno_t sss_send_pac(krb5_authdata **pac_authdata)
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht ret = sss_pac_make_request(SSS_PAC_ADD_PAC_USER, &sss_data,
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht if (ret != NSS_STATUS_SUCCESS || errnop != 0) {
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht DEBUG(SSSDBG_OP_FAILURE, ("sss_pac_make_request failed [%d][%d].\n",
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbrichtstatic void sss_krb5_expire_callback_func(krb5_context context, void *data,
04641e4ea004e422b32d3e6359f68a3326b4aa8bSimon Ulbricht struct krb5_req *kr = talloc_get_type(data, struct krb5_req);
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht DEBUG(1, ("Time to expire out of range.\n"));
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht DEBUG(SSSDBG_TRACE_INTERNAL, ("exp_time: [%d]\n", exp_time));
804459c3af78eeee3fd3c940c74594febd030dacSimon Ulbricht ret = pam_add_response(kr->pd, SSS_PAM_USER_INFO, 2 * sizeof(uint32_t),
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbrichtstatic krb5_error_code sss_krb5_prompter(krb5_context context, void *data,
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht struct krb5_req *kr = talloc_get_type(data, struct krb5_req);
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht DEBUG(1, ("Cannot handle password prompts.\n"));
5917663ca76c8f8b60b767f7fb959f1d1609576bSimon Ulbricht DEBUG(5, ("Prompter called with empty banner, nothing to do.\n"));
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht DEBUG(SSSDBG_FUNC_DATA, ("Prompter called with [%s].\n", banner));
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht ret = pam_add_response(kr->pd, SSS_PAM_TEXT_MSG, strlen(banner)+1,
55be4caff6a01e4c32ec47ee27fe00b67dfd3db5Simon Ulbrichtstatic krb5_error_code create_empty_cred(krb5_context ctx, krb5_principal princ,
5b93337fb97e848522fcc277e384f694595bc42cSimon Ulbricht kerr = krb5_copy_principal(ctx, princ, &cred->client);
55be4caff6a01e4c32ec47ee27fe00b67dfd3db5Simon Ulbricht kerr = krb5_build_principal_ext(ctx, &cred->server,
5917663ca76c8f8b60b767f7fb959f1d1609576bSimon Ulbricht DEBUG(1, ("krb5_build_principal_ext failed.\n"));
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht DEBUG(SSSDBG_TRACE_INTERNAL, ("Created empty krb5_creds.\n"));
96a17035df49356b70d7ac14bd9f4d52a5f0308dSimon Ulbrichtstore_creds_in_ccache(krb5_context ctx, krb5_principal princ,
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht kerr = create_empty_cred(ctx, princ, &l_cred);
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht#endif /* HAVE_KRB5_DIRCACHE */
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbrichtstatic krb5_error_code create_ccache_file(krb5_context ctx,
e3d7fd1b63d824960b1c17b6c7009d52d7528c1eChristian Maeder DEBUG(SSSDBG_FUNC_DATA, ("Creating ccache at [%s]\n", ccname));
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht DEBUG(1, ("Ccache filename is not an absolute path.\n"));
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht tmp_ccname = talloc_strndup(tmp_ctx, cc_file_name,
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht tmp_ccname = talloc_asprintf_append(tmp_ccname, "/.krb5cc_dummy_XXXXXX");
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht ("mkstemp failed [%d][%s].\n", kerr, strerror(kerr)));
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht kerr = krb5_cc_resolve(ctx, tmp_ccname, &tmp_cc);
7577ca4229962db6f297853d160c2e0214bd2034Simon Ulbricht kerr = store_creds_in_ccache(ctx, princ, tmp_cc, creds);
7577ca4229962db6f297853d160c2e0214bd2034Simon Ulbricht if (ccname_len >= 6 && strcmp(cc_file_name + (ccname_len - 6), "XXXXXX") == 0) {
da4b55f4795a4b585f513eaceb67cda10485febfChristian Maeder ("mkstemp failed [%d][%s].\n", kerr, strerror(kerr)));
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht DEBUG(1, ("rename failed [%d][%s].\n", kerr, strerror(kerr)));
c3b1c9fa0aa53167405eb9a004137fb5e327fd4fSimon Ulbricht DEBUG(SSSDBG_TRACE_LIBS, ("Created ccache file: [%s]\n", ccname));
return kerr;
#ifdef HAVE_KRB5_DIRCACHE
static errno_t
errno = 0;
return EIO;
return EACCES;
return EACCES;
return ret;
return EOK;
static krb5_error_code
const char *dirname;
return EIO;
goto done;
if (kerr != 0) {
goto done;
if (kerr) {
goto done;
if (kerr != 0) {
goto done;
if (kerr != 0) {
goto done;
return EIO;
if (kerr != 0) {
goto done;
done:
return kerr;
static krb5_error_code
switch (cctype) {
case SSS_KRB5_TYPE_FILE:
#ifdef HAVE_KRB5_DIRCACHE
case SSS_KRB5_TYPE_DIR:
return EINVAL;
size_t p = 0;
return ENOMEM;
return EOK;
int pam_status)
int ret;
return NULL;
if (kerr == 0) {
return NULL;
return NULL;
return NULL;
return NULL;
return resp;
int ret;
return ENOMEM;
errno = 0;
return ret;
return EOK;
return EOK;
int ret;
unsigned int upn_len = 0;
goto done;
if (kerr != 0) {
goto done;
goto done;
done:
return ret;
bool realm_entry_found = false;
if (kerr != 0) {
return kerr;
if (kerr != 0) {
return kerr;
if (kerr != 0) {
goto done;
if (kerr != 0) {
realm_entry_found = true;
if (!realm_entry_found) {
if (kerr != 0) {
goto done;
goto done;
if (kerr != 0) {
goto done;
if (kerr == 0) {
principal));
goto done;
if (kerr != 0) {
kerr = 0;
goto done;
if (kerr != 0) {
kerr = 0;
done:
return kerr;
int canonicalize = 0;
char *tmp_str;
char *ccname)
&options);
if (kerr != 0) {
return kerr;
if (kerr != 0) {
goto done;
kerr = 0;
done:
return kerr;
const char *password)
int ret;
const char *realm_name;
int realm_length;
kr);
if (kerr != 0) {
if (kerr != 0) {
return kerr;
if (kerr != 0) {
return kerr;
return ret;
if (kerr != 0) {
goto done;
kerr = 0;
done:
return kerr;
int pam_status;
switch (kerr) {
case KRB5_LIBOS_CANTREADPWD:
case KRB5_KDC_UNREACH:
case KRB5KDC_ERR_KEY_EXP:
case KRB5_PREAUTH_FAILED:
return pam_status;
if (kerr == 0) {
return PAM_SUCCESS;
int ret;
const char *realm_name;
int realm_length;
goto done;
if (kerr != 0) {
goto done;
if (kerr != 0) {
goto done;
goto done;
goto done;
goto done;
if (kerr != 0) {
goto done;
done:
return ret;
int ret;
goto done;
if (kerr != 0) {
if (kerr != 0) {
goto done;
if (kerr == 0) {
done:
return ret;
int status;
int ret;
if (kerr != 0) {
return ret;
int ret;
int kerr;
const char *ccname;
goto done;
if (kerr != 0) {
goto done;
if (kerr != 0) {
goto done;
if (kerr != 0) {
goto done;
goto done;
if (kerr != 0) {
goto done;
if (kerr != 0) {
goto done;
kerr = 0;
done:
return ret;
int ret;
if (ret != 0) {
return ret;
return EINVAL;
switch (auth_token_type) {
case SSS_AUTHTOK_TYPE_EMPTY:
case SSS_AUTHTOK_TYPE_CCFILE:
return EINVAL;
*p += auth_token_length;
return ret;
size_t p = 0;
p += len;
p += len;
p += len;
if (ret) {
return ret;
if (ret) {
return ret;
p += len;
return EOK;
return EOK;
if (krberr != 0) {
goto done;
if (krberr != 0) {
krberr = 0;
goto done;
krberr = 0;
done:
return krberr;
const char *realm,
const char *keytab_name,
char **fast_ccname)
char *ccname;
char *server_name;
goto done;
goto done;
if (kerr) {
goto done;
if (kerr != 0) {
goto done;
goto done;
if (kerr != 0) {
goto done;
if (kerr == 0) {
goto done;
if (kerr != 0) {
goto done;
kerr = 0;
done:
if (kerr == 0) {
return kerr;
static errno_t
if (kerr) {
return EIO;
return EOK;
char *lifetime_str;
char *use_fast_str;
char *tmp_str;
goto failed;
case SSS_PAM_AUTHENTICATE:
if (offline) {
case SSS_PAM_CHAUTHTOK:
case SSS_PAM_CHAUTHTOK_PRELIM:
case SSS_PAM_ACCT_MGMT:
case SSS_CMD_RENEW:
if (!offline) {
goto failed;
goto failed;
if (kerr != 0) {
goto failed;
if (kerr != 0) {
goto failed;
if (kerr != 0) {
goto failed;
goto failed;
if (kerr != 0) {
goto failed;
if (kerr != 0) {
goto failed;
if (kerr != 0) {
lifetime_str));
goto failed;
if (kerr != 0) {
lifetime_str));
goto failed;
if (!offline) {
if (!tmp_str) {
if (kerr) {
goto failed;
&tmp_str);
if (kerr) {
goto failed;
if (!fast_principal) {
goto failed;
if (!fast_principal_realm) {
goto failed;
if (kerr != 0) {
goto failed;
if (kerr != 0) {
goto failed;
if (kerr != 0) {
goto failed;
goto failed;
return EOK;
return kerr;
int ret;
int opt;
switch(opt) {
if (!debug_prg_name) {
goto fail;
goto fail;
goto fail;
errno = 0;
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
fail: