krb5_child.c revision f5db13d4462faa531c9924181f0fd51364647e2d
306763c67bb99228487345b32ab8c5c6cd41f23cChristian Maeder/*
306763c67bb99228487345b32ab8c5c6cd41f23cChristian Maeder SSSD
259e677d54077052680efe571d6280897801962aChristian Maeder
d5fe06af711a6912ae028ebf873eada4ee8733f8Christian Maeder Kerberos 5 Backend Module -- tgt_req and changepw child
98890889ffb2e8f6f722b00e265a211f13b5a861Corneliu-Claudiu Prodescu
306763c67bb99228487345b32ab8c5c6cd41f23cChristian Maeder Authors:
34bff097c14521b5e57ce37279a34256e1f78aa5Klaus Luettich Sumit Bose <sbose@redhat.com>
306763c67bb99228487345b32ab8c5c6cd41f23cChristian Maeder
698573ebc6be4bd63c295a3704fd9459a0c6699cChristian Maeder Copyright (C) 2009-2010 Red Hat
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
f3a94a197960e548ecd6520bb768cb0d547457bbChristian Maeder This program is free software; you can redistribute it and/or modify
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers it under the terms of the GNU General Public License as published by
698573ebc6be4bd63c295a3704fd9459a0c6699cChristian Maeder the Free Software Foundation; either version 3 of the License, or
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers (at your option) any later version.
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers This program is distributed in the hope that it will be useful,
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers but WITHOUT ANY WARRANTY; without even the implied warranty of
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers GNU General Public License for more details.
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers You should have received a copy of the GNU General Public License
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers along with this program. If not, see <http://www.gnu.org/licenses/>.
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder*/
3bcd9d942601d59dd55a6069d8b2d1c33d7ced0eChristian Maeder
3bcd9d942601d59dd55a6069d8b2d1c33d7ced0eChristian Maeder#include <sys/types.h>
3bcd9d942601d59dd55a6069d8b2d1c33d7ced0eChristian Maeder#include <unistd.h>
3bcd9d942601d59dd55a6069d8b2d1c33d7ced0eChristian Maeder#include <sys/stat.h>
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers#include <popt.h>
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder#include <security/pam_modules.h>
c64d33a7fbeae730cbe65193fe3cc24e7aa1ddd6Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder#include "util/util.h"
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers#include "util/sss_krb5.h"
ad270004874ce1d0697fb30d7309f180553bb315Christian Maeder#include "util/user_info_msg.h"
ef9e8535c168d3f774d9e74368a2317a9eda5826Christian Maeder#include "util/child_common.h"
ef9e8535c168d3f774d9e74368a2317a9eda5826Christian Maeder#include "util/find_uid.h"
ef9e8535c168d3f774d9e74368a2317a9eda5826Christian Maeder#include "src/util/util_errors.h"
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers#include "providers/dp_backend.h"
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers#include "providers/krb5/krb5_auth.h"
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers#include "providers/krb5/krb5_utils.h"
697e63e30aa3c309a1ef1f9357745111f8dfc5a9Christian Maeder#include "sss_cli.h"
1544471d4ce2b4a5d9622e975f17e4081140e596Christian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers#define SSSD_KRB5_CHANGEPW_PRINCIPAL "kadmin/changepw"
0ce46d5315b16108b74d20b86aeff37c48f48828Christian Maeder
ea8e98e298f33f9362293f392c8fb192722b8904Eugen Kuksaenum k5c_fast_opt {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers K5C_FAST_NEVER,
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers K5C_FAST_TRY,
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers K5C_FAST_DEMAND,
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers};
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckersstruct krb5_req {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers krb5_context ctx;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers krb5_principal princ;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers char* name;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers krb5_creds *creds;
35db0960aa2e2a13652381c756fae5fb2b27213bChristian Maeder bool otp;
bccea164bdfc2ddc3d1e20749bb5477a46eab3a6Christian Maeder char *otp_vendor;
bccea164bdfc2ddc3d1e20749bb5477a46eab3a6Christian Maeder char *otp_token_id;
6c4ee04931dded62728f3a9954b2799beed536e9Christian Maeder char *otp_challenge;
12cb8453ba3b8c36acaf9547549ce6d792cca58dChristian Maeder krb5_get_init_creds_opt *options;
1544471d4ce2b4a5d9622e975f17e4081140e596Christian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers struct pam_data *pd;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers char *realm;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder char *ccname;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers char *keytab;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers bool validate;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder bool send_pac;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers bool use_enterprise_princ;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers char *fast_ccname;
c64d33a7fbeae730cbe65193fe3cc24e7aa1ddd6Christian Maeder
6c4ee04931dded62728f3a9954b2799beed536e9Christian Maeder const char *upn;
6c4ee04931dded62728f3a9954b2799beed536e9Christian Maeder uid_t uid;
6c4ee04931dded62728f3a9954b2799beed536e9Christian Maeder gid_t gid;
6c4ee04931dded62728f3a9954b2799beed536e9Christian Maeder
6c4ee04931dded62728f3a9954b2799beed536e9Christian Maeder char *old_ccname;
6c4ee04931dded62728f3a9954b2799beed536e9Christian Maeder bool old_cc_valid;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers bool old_cc_active;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers enum k5c_fast_opt fast_val;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers uid_t fast_uid;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers gid_t fast_gid;
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder};
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maederstatic krb5_context krb5_error_ctx;
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder#define KRB5_CHILD_DEBUG(level, error) KRB5_DEBUG(level, krb5_error_ctx, error)
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maederstatic krb5_error_code set_lifetime_options(krb5_get_init_creds_opt *options)
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder{
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers char *lifetime_str;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers krb5_error_code kerr;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers krb5_deltat lifetime;
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder lifetime_str = getenv(SSSD_KRB5_RENEWABLE_LIFETIME);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (lifetime_str == NULL) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_CONF_SETTINGS, "Cannot read [%s] from environment.\n",
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers SSSD_KRB5_RENEWABLE_LIFETIME);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers /* Unset option flag to make sure defaults from krb5.conf are used. */
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers options->flags &= ~(KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE);
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder } else {
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder kerr = krb5_string_to_deltat(lifetime_str, &lifetime);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (kerr != 0) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers DEBUG(SSSDBG_CRIT_FAILURE,
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers "krb5_string_to_deltat failed for [%s].\n",
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder lifetime_str);
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers return kerr;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder DEBUG(SSSDBG_CONF_SETTINGS, "%s is set to [%s]\n",
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder SSSD_KRB5_RENEWABLE_LIFETIME, lifetime_str);
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder krb5_get_init_creds_opt_set_renew_life(options, lifetime);
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder lifetime_str = getenv(SSSD_KRB5_LIFETIME);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers if (lifetime_str == NULL) {
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder DEBUG(SSSDBG_CONF_SETTINGS, "Cannot read [%s] from environment.\n",
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder SSSD_KRB5_LIFETIME);
c64d33a7fbeae730cbe65193fe3cc24e7aa1ddd6Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder /* Unset option flag to make sure defaults from krb5.conf are used. */
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers options->flags &= ~(KRB5_GET_INIT_CREDS_OPT_TKT_LIFE);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers } else {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder kerr = krb5_string_to_deltat(lifetime_str, &lifetime);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers if (kerr != 0) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_CRIT_FAILURE,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder "krb5_string_to_deltat failed for [%s].\n",
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder lifetime_str);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder return kerr;
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_CONF_SETTINGS,
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder "%s is set to [%s]\n", SSSD_KRB5_LIFETIME, lifetime_str);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers krb5_get_init_creds_opt_set_tkt_life(options, lifetime);
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder return 0;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder}
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maederstatic void set_canonicalize_option(krb5_get_init_creds_opt *opts)
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder{
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder int canonicalize = 0;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder char *tmp_str;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder tmp_str = getenv(SSSD_KRB5_CANONICALIZE);
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder if (tmp_str != NULL && strcasecmp(tmp_str, "true") == 0) {
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder canonicalize = 1;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder DEBUG(SSSDBG_CONF_SETTINGS, "%s is set to [%s]\n",
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder SSSD_KRB5_CANONICALIZE, tmp_str ? tmp_str : "not set");
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder sss_krb5_get_init_creds_opt_set_canonicalize(opts, canonicalize);
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder}
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maederstatic void set_changepw_options(krb5_get_init_creds_opt *options)
fea14169cb07365fe4d12fea734d7b761ea8b287Christian Maeder{
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers sss_krb5_get_init_creds_opt_set_canonicalize(options, 0);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers krb5_get_init_creds_opt_set_forwardable(options, 0);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_get_init_creds_opt_set_proxiable(options, 0);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers krb5_get_init_creds_opt_set_renew_life(options, 0);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers krb5_get_init_creds_opt_set_tkt_life(options, 5*60);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers}
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
fea14169cb07365fe4d12fea734d7b761ea8b287Christian Maederstatic void revert_changepw_options(krb5_get_init_creds_opt *options)
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder{
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_error_code kerr;
fea14169cb07365fe4d12fea734d7b761ea8b287Christian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers set_canonicalize_option(options);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers /* Currently we do not set forwardable and proxiable explicitly, the flags
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers * must be removed so that libkrb5 can take the defaults from krb5.conf */
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder options->flags &= ~(KRB5_GET_INIT_CREDS_OPT_FORWARDABLE);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers options->flags &= ~(KRB5_GET_INIT_CREDS_OPT_PROXIABLE);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers kerr = set_lifetime_options(options);
42c01284bba8d7c8d995c8dfb96ace57d28ed1bcTill Mossakowski if (kerr != 0) {
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder DEBUG(SSSDBG_OP_FAILURE, ("set_lifetime_options failed.\n"));
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder}
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
42c01284bba8d7c8d995c8dfb96ace57d28ed1bcTill Mossakowskistatic errno_t sss_send_pac(krb5_authdata **pac_authdata)
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder{
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder struct sss_cli_req_data sss_data;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers int ret;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers int errnop;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers sss_data.len = pac_authdata[0]->length;
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder sss_data.data = pac_authdata[0]->contents;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder ret = sss_pac_make_request(SSS_PAC_ADD_PAC_USER, &sss_data,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder NULL, NULL, &errnop);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (ret != NSS_STATUS_SUCCESS || errnop != 0) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers DEBUG(SSSDBG_OP_FAILURE, "sss_pac_make_request failed [%d][%d].\n",
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers ret, errnop);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return EIO;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers return EOK;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder}
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
6c4ee04931dded62728f3a9954b2799beed536e9Christian Maederstatic void sss_krb5_expire_callback_func(krb5_context context, void *data,
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers krb5_timestamp password_expiration,
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder krb5_timestamp account_expiration,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_boolean is_last_req)
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers{
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers int ret;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers uint32_t *blob;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder long exp_time;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder struct krb5_req *kr = talloc_get_type(data, struct krb5_req);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (password_expiration == 0) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers exp_time = password_expiration - time(NULL);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers if (exp_time < 0 || exp_time > UINT32_MAX) {
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder DEBUG(SSSDBG_CRIT_FAILURE, "Time to expire out of range.\n");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers DEBUG(SSSDBG_TRACE_INTERNAL, "exp_time: [%ld]\n", exp_time);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers blob = talloc_array(kr->pd, uint32_t, 2);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (blob == NULL) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed.\n");
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers return;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
6c4ee04931dded62728f3a9954b2799beed536e9Christian Maeder blob[0] = SSS_PAM_USER_INFO_EXPIRE_WARN;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers blob[1] = (uint32_t) exp_time;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers ret = pam_add_response(kr->pd, SSS_PAM_USER_INFO, 2 * sizeof(uint32_t),
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers (uint8_t *) blob);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers if (ret != EOK) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n");
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers return;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers}
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_RESPONDER
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers/*
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder * TODO: These features generally would requires a significant refactoring
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder * of SSSD and MIT krb5 doesn't support them anyway. They are listed here
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers * simply as a reminder of things that might become future feature potential.
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers *
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers * 1. tokeninfo selection
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder * 2. challenge
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder * 3. discreet token/pin prompting
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers * 4. interactive otp format correction
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers * 5. nextOTP
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers *
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers */
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroedertypedef int (*checker)(int c);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckersstatic inline checker pick_checker(int format)
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers{
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers switch (format) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers case KRB5_RESPONDER_OTP_FORMAT_DECIMAL:
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers return isdigit;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder case KRB5_RESPONDER_OTP_FORMAT_HEXADECIMAL:
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder return isxdigit;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder case KRB5_RESPONDER_OTP_FORMAT_ALPHANUMERIC:
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers return isalnum;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder return NULL;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder}
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckersstatic int token_pin_destructor(char *mem)
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers{
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder safezero(mem, strlen(mem));
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return 0;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers}
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maederstatic krb5_error_code tokeninfo_matches_2fa(TALLOC_CTX *mem_ctx,
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers const krb5_responder_otp_tokeninfo *ti,
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder const char *fa1, size_t fa1_len,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder const char *fa2, size_t fa2_len,
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers char **out_token, char **out_pin)
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers{
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder char *token = NULL, *pin = NULL;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder checker check = NULL;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers int i;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (ti->flags & KRB5_RESPONDER_OTP_FLAGS_NEXTOTP) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return ENOTSUP;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (ti->challenge != NULL) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return ENOTSUP;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers /* This is a non-sensical value. */
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers if (ti->length == 0) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return EPROTO;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (ti->flags & KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (ti->length > 0 && ti->length != fa2_len) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers DEBUG(SSSDBG_CRIT_FAILURE,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder "Expected [%d] and given [%zu] token size "
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder "do not match.\n", ti->length, fa2_len);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return EMSGSIZE;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers if (ti->flags & KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (ti->flags & KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder pin = talloc_strndup(mem_ctx, fa1, fa1_len);
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder if (pin == NULL) {
42c01284bba8d7c8d995c8dfb96ace57d28ed1bcTill Mossakowski talloc_free(token);
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder return ENOMEM;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder talloc_set_destructor(pin, token_pin_destructor);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
42c01284bba8d7c8d995c8dfb96ace57d28ed1bcTill Mossakowski token = talloc_strndup(mem_ctx, fa2, fa2_len);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (token == NULL) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return ENOMEM;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder talloc_set_destructor(token, token_pin_destructor);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers check = pick_checker(ti->format);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder } else {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder token = talloc_asprintf(mem_ctx, "%s%s", fa1, fa2);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (token == NULL) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers return ENOMEM;
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder talloc_set_destructor(token, token_pin_destructor);
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers check = pick_checker(ti->format);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder } else {
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder /* Assuming PIN only required */
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder pin = talloc_strndup(mem_ctx, fa1, fa1_len);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (pin == NULL) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return ENOMEM;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder talloc_set_destructor(pin, token_pin_destructor);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder /* If check is set, we need to verify the contents of the token. */
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder for (i = 0; check != NULL && token[i] != '\0'; i++) {
fea14169cb07365fe4d12fea734d7b761ea8b287Christian Maeder if (!check(token[i])) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers talloc_free(token);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder talloc_free(pin);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return EBADMSG;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers *out_token = token;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers *out_pin = pin;
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder return 0;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder}
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maederstatic krb5_error_code tokeninfo_matches_pwd(TALLOC_CTX *mem_ctx,
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder const krb5_responder_otp_tokeninfo *ti,
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers const char *pwd, size_t len,
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers char **out_token, char **out_pin)
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers{
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers char *token = NULL, *pin = NULL;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers checker check = NULL;
42c01284bba8d7c8d995c8dfb96ace57d28ed1bcTill Mossakowski int i;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
bccea164bdfc2ddc3d1e20749bb5477a46eab3a6Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (ti->flags & KRB5_RESPONDER_OTP_FLAGS_NEXTOTP) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return ENOTSUP;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
42c01284bba8d7c8d995c8dfb96ace57d28ed1bcTill Mossakowski if (ti->challenge != NULL) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers return ENOTSUP;
bccea164bdfc2ddc3d1e20749bb5477a46eab3a6Christian Maeder }
9271474a25bfadbf6d91b82ec60f614fb0dff492Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder /* This is a non-sensical value. */
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (ti->length == 0) {
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder return EPROTO;
9271474a25bfadbf6d91b82ec60f614fb0dff492Christian Maeder }
9271474a25bfadbf6d91b82ec60f614fb0dff492Christian Maeder
9271474a25bfadbf6d91b82ec60f614fb0dff492Christian Maeder if (ti->flags & KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN) {
9271474a25bfadbf6d91b82ec60f614fb0dff492Christian Maeder /* ASSUMPTION: authtok has one of the following formats:
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder * 1. TokenValue
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder * 2. PIN+TokenValue
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder */
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers token = talloc_strndup(mem_ctx, pwd, len);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (token == NULL) {
e07538a3c4dbc690e57f61aded6db89d876b2374Christian Maeder return ENOMEM;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder talloc_set_destructor(token, token_pin_destructor);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (ti->flags & KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder /* If the server desires a separate pin, we will split it.
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder * ASSUMPTION: Format of authtok is PIN+TokenValue. */
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (ti->flags & KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (ti->length < 1) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder talloc_free(token);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return ENOTSUP;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (ti->length >= len) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder talloc_free(token);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers return EMSGSIZE;
e07538a3c4dbc690e57f61aded6db89d876b2374Christian Maeder }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder /* Copy the PIN from the front of the value. */
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder pin = talloc_strndup(NULL, pwd, len - ti->length);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (pin == NULL) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder talloc_free(token);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder return ENOMEM;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder talloc_set_destructor(pin, token_pin_destructor);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder /* Remove the PIN from the front of the token value. */
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder memmove(token, token + len - ti->length, ti->length + 1);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder check = pick_checker(ti->format);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder } else {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (ti->length > 0 && ti->length > len) {
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder talloc_free(token);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return EMSGSIZE;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder } else {
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (ti->length > 0 && ti->length != len) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder talloc_free(token);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return EMSGSIZE;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder check = pick_checker(ti->format);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder } else {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder pin = talloc_strndup(mem_ctx, pwd, len);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (pin == NULL) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return ENOMEM;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder talloc_set_destructor(pin, token_pin_destructor);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder /* If check is set, we need to verify the contents of the token. */
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder for (i = 0; check != NULL && token[i] != '\0'; i++) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (!check(token[i])) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder talloc_free(token);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder talloc_free(pin);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers return EBADMSG;
e07538a3c4dbc690e57f61aded6db89d876b2374Christian Maeder }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder *out_token = token;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder *out_pin = pin;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return 0;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder}
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maederstatic krb5_error_code tokeninfo_matches(TALLOC_CTX *mem_ctx,
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder const krb5_responder_otp_tokeninfo *ti,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder struct sss_auth_token *auth_tok,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder char **out_token, char **out_pin)
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder{
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder int ret;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder const char *pwd;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder size_t len;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder const char *fa2;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder size_t fa2_len;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder switch (sss_authtok_get_type(auth_tok)) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder case SSS_AUTHTOK_TYPE_PASSWORD:
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder ret = sss_authtok_get_password(auth_tok, &pwd, &len);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (ret != EOK) {
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder DEBUG(SSSDBG_OP_FAILURE, "sss_authtok_get_password failed.\n");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return ret;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return tokeninfo_matches_pwd(mem_ctx, ti, pwd, len, out_token, out_pin);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder break;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder case SSS_AUTHTOK_TYPE_2FA:
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder ret = sss_authtok_get_2fa(auth_tok, &pwd, &len, &fa2, &fa2_len);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (ret != EOK) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_OP_FAILURE, "sss_authtok_get_2fa failed.\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return ret;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return tokeninfo_matches_2fa(mem_ctx, ti, pwd, len, fa2, fa2_len,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder out_token, out_pin);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder break;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers default:
e07538a3c4dbc690e57f61aded6db89d876b2374Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported authtok type.\n");
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return EINVAL;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder}
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maederstatic krb5_error_code answer_otp(krb5_context ctx,
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder struct krb5_req *kr,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_responder_context rctx)
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder{
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_responder_otp_challenge *chl;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder char *token = NULL, *pin = NULL;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_error_code ret;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder size_t i;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder ret = krb5_responder_otp_get_challenge(ctx, rctx, &chl);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (ret != EOK || chl == NULL) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder /* Either an error, or nothing to do. */
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return ret;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (chl->tokeninfo == NULL || chl->tokeninfo[0] == NULL) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder /* No tokeninfos? Absurd! */
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder ret = EINVAL;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder goto done;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kr->otp = true;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kr->pd->cmd == SSS_PAM_PREAUTH) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder for (i = 0; chl->tokeninfo[i] != NULL; i++) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_TRACE_ALL, "[%zu] Vendor [%s].\n",
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder i, chl->tokeninfo[i]->vendor);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_TRACE_ALL, "[%zu] Token-ID [%s].\n",
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder i, chl->tokeninfo[i]->token_id);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_TRACE_ALL, "[%zu] Challenge [%s].\n",
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder i, chl->tokeninfo[i]->challenge);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers DEBUG(SSSDBG_TRACE_ALL, "[%zu] Flags [%d].\n",
e07538a3c4dbc690e57f61aded6db89d876b2374Christian Maeder i, chl->tokeninfo[i]->flags);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (chl->tokeninfo[0]->vendor != NULL) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kr->otp_vendor = talloc_strdup(kr, chl->tokeninfo[0]->vendor);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (chl->tokeninfo[0]->token_id != NULL) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kr->otp_token_id = talloc_strdup(kr, chl->tokeninfo[0]->token_id);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (chl->tokeninfo[0]->challenge != NULL) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder kr->otp_challenge = talloc_strdup(kr, chl->tokeninfo[0]->challenge);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder /* Allocation errors are ignored on purpose */
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_TRACE_INTERNAL, "Exit answer_otp during pre-auth.\n");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return EAGAIN;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder /* Find the first supported tokeninfo which matches our authtoken. */
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder for (i = 0; chl->tokeninfo[i] != NULL; i++) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder ret = tokeninfo_matches(kr, chl->tokeninfo[i], kr->pd->authtok,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder &token, &pin);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (ret == EOK) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder break;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder switch (ret) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers case EBADMSG:
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers case EMSGSIZE:
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers case ENOTSUP:
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder case EPROTO:
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder break;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder default:
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder goto done;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (chl->tokeninfo[i] == NULL) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_CRIT_FAILURE,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder "No tokeninfos found which match our credentials.\n");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder ret = EOK;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder goto done;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (chl->tokeninfo[i]->flags & KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder /* Don't let SSSD cache the OTP authtok since it is single-use. */
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder ret = pam_add_response(kr->pd, SSS_OTP, 0, NULL);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (ret != EOK) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder goto done;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder /* Respond with the appropriate answer. */
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder ret = krb5_responder_otp_set_answer(ctx, rctx, i, token, pin);
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maederdone:
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder talloc_free(token);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder talloc_free(pin);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_responder_otp_challenge_free(ctx, rctx, chl);
42c01284bba8d7c8d995c8dfb96ace57d28ed1bcTill Mossakowski return ret;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder}
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maederstatic krb5_error_code sss_krb5_responder(krb5_context ctx,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder void *data,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_responder_context rctx)
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder{
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder struct krb5_req *kr = talloc_get_type(data, struct krb5_req);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers if (kr == NULL) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers return EINVAL;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return answer_otp(ctx, kr, rctx);
6c4ee04931dded62728f3a9954b2799beed536e9Christian Maeder}
6c4ee04931dded62728f3a9954b2799beed536e9Christian Maeder#endif
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maederstatic krb5_error_code sss_krb5_prompter(krb5_context context, void *data,
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder const char *name, const char *banner,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder int num_prompts, krb5_prompt prompts[])
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder{
6c4ee04931dded62728f3a9954b2799beed536e9Christian Maeder int ret;
6c4ee04931dded62728f3a9954b2799beed536e9Christian Maeder struct krb5_req *kr = talloc_get_type(data, struct krb5_req);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (num_prompts != 0) {
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder DEBUG(SSSDBG_CRIT_FAILURE, "Cannot handle password prompts.\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return KRB5_LIBOS_CANTREADPWD;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (banner == NULL || *banner == '\0') {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_FUNC_DATA,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder "Prompter called with empty banner, nothing to do.\n");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return EOK;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
6c4ee04931dded62728f3a9954b2799beed536e9Christian Maeder DEBUG(SSSDBG_FUNC_DATA, "Prompter called with [%s].\n", banner);
6c4ee04931dded62728f3a9954b2799beed536e9Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder ret = pam_add_response(kr->pd, SSS_PAM_TEXT_MSG, strlen(banner)+1,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder (const uint8_t *) banner);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (ret != EOK) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return EOK;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder}
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckersstatic krb5_error_code create_empty_cred(krb5_context ctx, krb5_principal princ,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_creds **_cred)
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder{
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_error_code kerr;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_creds *cred = NULL;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_data *krb5_realm;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder cred = calloc(sizeof(krb5_creds), 1);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (cred == NULL) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers DEBUG(SSSDBG_CRIT_FAILURE, "calloc failed.\n");
e07538a3c4dbc690e57f61aded6db89d876b2374Christian Maeder return ENOMEM;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder kerr = krb5_copy_principal(ctx, princ, &cred->client);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kerr != 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "krb5_copy_principal failed.\n");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder goto done;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_realm = krb5_princ_realm(ctx, princ);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = krb5_build_principal_ext(ctx, &cred->server,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_realm->length, krb5_realm->data,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_realm->length, krb5_realm->data, 0);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (kerr != 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "krb5_build_principal_ext failed.\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder goto done;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_TRACE_INTERNAL, "Created empty krb5_creds.\n");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maederdone:
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (kerr != 0) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers krb5_free_cred_contents(ctx, cred);
e07538a3c4dbc690e57f61aded6db89d876b2374Christian Maeder free(cred);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers } else {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder *_cred = cred;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return kerr;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder}
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maederstatic errno_t handle_randomized(char *in)
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder{
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder size_t ccname_len;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder char *ccname = NULL;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder int ret;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder /* We only treat the FILE type case in a special way due to the history
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder * of storing FILE type ccache in /tmp and associated security issues */
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (in[0] == '/') {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder ccname = in;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder } else if (strncmp(in, "FILE:", 5) == 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder ccname = in + 5;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder } else {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return EOK;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers ccname_len = strlen(ccname);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers if (ccname_len >= 6 && strcmp(ccname + (ccname_len - 6), "XXXXXX") == 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder /* NOTE: this call is only used to create a unique name, as later
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder * krb5_cc_initialize() will unlink and recreate the file.
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder * This is ok because this part of the code is called with
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder * privileges already dropped when handling user ccache, or the ccache
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder * is stored in a private directory. So we do not have huge issues if
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder * something races, we mostly care only about not accidentally use
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder * an existing name and thus failing in the process of saving the
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder * cache. Malicious races can only be avoided by libkrb5 itself. */
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder ret = sss_unique_filename(NULL, ccname);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (ret != EOK) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder "mkstemp(\"%s\") failed [%d]: %s!\n",
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder ccname, ret, strerror(ret));
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return ret;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return EOK;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder}
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
6c4ee04931dded62728f3a9954b2799beed536e9Christian Maeder/* NOTE: callers rely on 'name' being *changed* if it needs to be randomized,
6c4ee04931dded62728f3a9954b2799beed536e9Christian Maeder * as they will then send the name back to the new name via the return call
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder * k5c_attach_ccname_msg(). Callers will send in a copy of the name if they
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder * do not care for changes. */
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maederstatic krb5_error_code create_ccache(char *ccname, krb5_creds *creds)
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder{
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_context kctx = NULL;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_ccache kcc = NULL;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder const char *type;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_error_code kerr;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder#ifdef HAVE_KRB5_CC_COLLECTION
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_ccache cckcc;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers bool switch_to_cc = false;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers#endif
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder /* Set a restrictive umask, just in case we end up creating any file */
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder umask(077);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder /* we create a new context here as the main process one may have been
6c4ee04931dded62728f3a9954b2799beed536e9Christian Maeder * opened as root and contain possibly references (even open handles ?)
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder * to resources we do not have or do not want to have access to */
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder kerr = krb5_init_context(&kctx);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kerr) {
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return ERR_INTERNAL;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder kerr = handle_randomized(ccname);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kerr) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "handle_randomized failed: %d\n", kerr);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder goto done;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers kerr = krb5_cc_resolve(kctx, ccname, &kcc);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers if (kerr) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder goto done;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder type = krb5_cc_get_type(kctx, kcc);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_TRACE_ALL, "Initializing ccache of type [%s]\n", type);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder#ifdef HAVE_KRB5_CC_COLLECTION
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (krb5_cc_support_switch(kctx, type)) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_TRACE_ALL, "CC supports switch\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = krb5_cc_set_default_name(kctx, ccname);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kerr) {
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder DEBUG(SSSDBG_TRACE_ALL, "Cannot set default name!\n");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder goto done;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder kerr = krb5_cc_cache_match(kctx, creds->client, &cckcc);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kerr == KRB5_CC_NOTFOUND) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_TRACE_ALL, "Match not found\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = krb5_cc_new_unique(kctx, type, NULL, &cckcc);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder switch_to_cc = true;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (kerr) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_TRACE_ALL, "krb5_cc_cache_match failed\n");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers goto done;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers krb5_cc_close(kctx, kcc);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kcc = cckcc;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder#endif
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = krb5_cc_initialize(kctx, kcc, creds->client);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kerr) {
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder DEBUG(SSSDBG_TRACE_ALL, "krb5_cc_initialize failed\n");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder goto done;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = krb5_cc_store_cred(kctx, kcc, creds);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (kerr) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_TRACE_ALL, "krb5_cc_store_cred failed\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder goto done;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder#ifdef HAVE_KRB5_CC_COLLECTION
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (switch_to_cc) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_TRACE_ALL, "switch_to_cc\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = krb5_cc_switch(kctx, kcc);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (kerr) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_TRACE_ALL, "krb5_cc_switch\n");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers goto done;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder#endif
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_TRACE_ALL, "returning: %d\n", kerr);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maederdone:
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kcc) {
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder /* FIXME: should we krb5_cc_destroy in case of error ? */
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_cc_close(kctx, kcc);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return kerr;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers}
e07538a3c4dbc690e57f61aded6db89d876b2374Christian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckersstatic errno_t pack_response_packet(TALLOC_CTX *mem_ctx, errno_t error,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder struct response_data *resp_list,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder uint8_t **_buf, size_t *_len)
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder{
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder uint8_t *buf;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder size_t size = 0;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder size_t p = 0;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder struct response_data *pdr;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder /* A buffer with the following structure must be created:
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder * int32_t status of the request (required)
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder * message (zero or more)
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder *
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder * A message consists of:
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder * int32_t type of the message
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder * int32_t length of the following data
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder * uint8_t[len] data
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder */
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder size = sizeof(int32_t);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder for (pdr = resp_list; pdr != NULL; pdr = pdr->next) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder size += 2*sizeof(int32_t) + pdr->len;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder buf = talloc_array(mem_ctx, uint8_t, size);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (!buf) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "Insufficient memory to create message.\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return ENOMEM;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder SAFEALIGN_SET_INT32(&buf[p], error, &p);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder for (pdr = resp_list; pdr != NULL; pdr = pdr->next) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder SAFEALIGN_SET_INT32(&buf[p], pdr->type, &p);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder SAFEALIGN_SET_INT32(&buf[p], pdr->len, &p);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder safealign_memcpy(&buf[p], pdr->data, pdr->len, &p);
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder }
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder DEBUG(SSSDBG_TRACE_INTERNAL, "response packet size: [%zu]\n", p);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder *_buf = buf;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder *_len = p;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder return EOK;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder}
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maederstatic errno_t k5c_attach_otp_info_msg(struct krb5_req *kr)
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder{
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder uint8_t *msg = NULL;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder size_t msg_len;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder int ret;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder size_t vendor_len = 0;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder size_t token_id_len = 0;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder size_t challenge_len = 0;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder size_t idx = 0;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder msg_len = 3;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kr->otp_vendor != NULL) {
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder vendor_len = strlen(kr->otp_vendor);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder msg_len += vendor_len;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kr->otp_token_id != NULL) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder token_id_len = strlen(kr->otp_token_id);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder msg_len += token_id_len;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kr->otp_challenge != NULL) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder challenge_len = strlen(kr->otp_challenge);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder msg_len += challenge_len;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder msg = talloc_zero_size(kr, msg_len);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (msg == NULL) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return ENOMEM;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kr->otp_vendor != NULL) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder memcpy(msg, kr->otp_vendor, vendor_len);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder idx += vendor_len +1;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (kr->otp_token_id != NULL) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder memcpy(msg + idx, kr->otp_token_id, token_id_len);
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers idx += token_id_len +1;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (kr->otp_challenge != NULL) {
42c01284bba8d7c8d995c8dfb96ace57d28ed1bcTill Mossakowski memcpy(msg + idx, kr->otp_challenge, challenge_len);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder ret = pam_add_response(kr->pd, SSS_PAM_OTP_INFO, msg_len, msg);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder talloc_zfree(msg);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return ret;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers}
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckersstatic errno_t k5c_attach_ccname_msg(struct krb5_req *kr)
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers{
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder char *msg = NULL;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers int ret;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (kr->ccname == NULL) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers DEBUG(SSSDBG_CRIT_FAILURE, "Error obtaining ccname.\n");
fea14169cb07365fe4d12fea734d7b761ea8b287Christian Maeder return ERR_INTERNAL;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers msg = talloc_asprintf(kr, "%s=%s",CCACHE_ENV_NAME, kr->ccname);
ea8e98e298f33f9362293f392c8fb192722b8904Eugen Kuksa if (msg == NULL) {
ea8e98e298f33f9362293f392c8fb192722b8904Eugen Kuksa DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
ea8e98e298f33f9362293f392c8fb192722b8904Eugen Kuksa return ENOMEM;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
ea8e98e298f33f9362293f392c8fb192722b8904Eugen Kuksa ret = pam_add_response(kr->pd, SSS_PAM_ENV_ITEM,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder strlen(msg) + 1, (uint8_t *)msg);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder talloc_zfree(msg);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
ea8e98e298f33f9362293f392c8fb192722b8904Eugen Kuksa return ret;
ea8e98e298f33f9362293f392c8fb192722b8904Eugen Kuksa}
ea8e98e298f33f9362293f392c8fb192722b8904Eugen Kuksa
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maederstatic errno_t k5c_send_data(struct krb5_req *kr, int fd, errno_t error)
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers{
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers ssize_t written;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers uint8_t *buf;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder size_t len;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder int ret;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers DEBUG(SSSDBG_FUNC_DATA, "Received error code %d\n", error);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers ret = pack_response_packet(kr, error, kr->pd->resp_list, &buf, &len);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (ret != EOK) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "pack_response_packet failed.\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return ret;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder errno = 0;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder written = sss_atomic_write_s(fd, buf, len);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (written == -1) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder ret = errno;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder "write failed [%d][%s].\n", ret, strerror(ret));
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return ret;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (written != len) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_CRIT_FAILURE,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder "Write error, wrote [%zu] bytes, expected [%zu]\n",
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder written, len);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers return EOK;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_TRACE_ALL, "Response sent.\n");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return EOK;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder}
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maederstatic errno_t add_ticket_times_and_upn_to_response(struct krb5_req *kr)
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder{
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder int ret;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder int64_t t[4];
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder krb5_error_code kerr;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder char *upn = NULL;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder unsigned int upn_len = 0;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder t[0] = (int64_t) kr->creds->times.authtime;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder t[1] = (int64_t) kr->creds->times.starttime;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder t[2] = (int64_t) kr->creds->times.endtime;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder t[3] = (int64_t) kr->creds->times.renew_till;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder ret = pam_add_response(kr->pd, SSS_KRB5_INFO_TGT_LIFETIME,
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers 4*sizeof(int64_t), (uint8_t *) t);
e07538a3c4dbc690e57f61aded6db89d876b2374Christian Maeder if (ret != EOK) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers DEBUG(SSSDBG_CRIT_FAILURE, "pack_response_packet failed.\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder goto done;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = krb5_unparse_name_ext(kr->ctx, kr->creds->client, &upn, &upn_len);
9bfdf40cbc2c61dd8281904a03ac598d51e0a872Christian Maeder if (kerr != 0) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_OP_FAILURE, "krb5_unparse_name failed.\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder goto done;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder ret = pam_add_response(kr->pd, SSS_KRB5_INFO_UPN, upn_len,
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder (uint8_t *) upn);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_free_unparsed_name(kr->ctx, upn);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (ret != EOK) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "pack_response_packet failed.\n");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder goto done;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maederdone:
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return ret;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder}
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maederstatic krb5_error_code validate_tgt(struct krb5_req *kr)
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder{
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_error_code kerr;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_error_code kt_err;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder char *principal = NULL;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_keytab keytab;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_kt_cursor cursor;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder krb5_keytab_entry entry;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_verify_init_creds_opt opt;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_principal validation_princ = NULL;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder bool realm_entry_found = false;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_ccache validation_ccache = NULL;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_authdata **pac_authdata = NULL;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder memset(&keytab, 0, sizeof(keytab));
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = krb5_kt_resolve(kr->ctx, kr->keytab, &keytab);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kerr != 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "error resolving keytab [%s], " \
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder "not verifying TGT.\n", kr->keytab);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers return kerr;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder memset(&cursor, 0, sizeof(cursor));
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder kerr = krb5_kt_start_seq_get(kr->ctx, keytab, &cursor);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kerr != 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "error reading keytab [%s], " \
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder "not verifying TGT.\n", kr->keytab);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return kerr;
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder /* We look for the first entry from our realm or take the last one */
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder memset(&entry, 0, sizeof(entry));
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder while ((kt_err = krb5_kt_next_entry(kr->ctx, keytab, &entry, &cursor)) == 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (validation_princ != NULL) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_free_principal(kr->ctx, validation_princ);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder validation_princ = NULL;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = krb5_copy_principal(kr->ctx, entry.principal,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder &validation_princ);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (kerr != 0) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "krb5_copy_principal failed.\n");
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers goto done;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = sss_krb5_free_keytab_entry_contents(kr->ctx, &entry);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (kerr != 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_MINOR_FAILURE, "Failed to free keytab entry.\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder memset(&entry, 0, sizeof(entry));
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (krb5_realm_compare(kr->ctx, validation_princ, kr->creds->client)) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_TRACE_INTERNAL,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder "Found keytab entry with the realm of the credential.\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder realm_entry_found = true;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder break;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (!realm_entry_found) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers DEBUG(SSSDBG_TRACE_INTERNAL,
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers "Keytab entry with the realm of the credential not found "
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers "in keytab. Using the last entry.\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder /* Close the keytab here. Even though we're using cursors, the file
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder * handle is stored in the krb5_keytab structure, and it gets
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder * overwritten when the verify_init_creds() call below creates its own
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder * cursor, creating a leak. */
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder kerr = krb5_kt_end_seq_get(kr->ctx, keytab, &cursor);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kerr != 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "krb5_kt_end_seq_get failed, " \
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder "not verifying TGT.\n");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder goto done;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder /* check if we got any errors from krb5_kt_next_entry */
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (kt_err != 0 && kt_err != KRB5_KT_END) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers DEBUG(SSSDBG_CRIT_FAILURE, "error reading keytab [%s], " \
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers "not verifying TGT.\n", kr->keytab);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers goto done;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder /* Get the principal to which the key belongs, for logging purposes. */
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder principal = NULL;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = krb5_unparse_name(kr->ctx, validation_princ, &principal);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (kerr != 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "internal error parsing principal name, "
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder "not verifying TGT.\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder goto done;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_verify_init_creds_opt_init(&opt);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder kerr = krb5_verify_init_creds(kr->ctx, kr->creds, validation_princ, keytab,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder &validation_ccache, &opt);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers if (kerr == 0) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers DEBUG(SSSDBG_TRACE_FUNC, "TGT verified using key for [%s].\n",
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers principal);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder } else {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_CRIT_FAILURE ,"TGT failed verification using key " \
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder "for [%s].\n", principal);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder goto done;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder /* Try to find and send the PAC to the PAC responder.
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder * Failures are not critical. */
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kr->send_pac) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = sss_extract_pac(kr->ctx, validation_ccache, validation_princ,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kr->creds->client, keytab, &pac_authdata);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (kerr != 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_OP_FAILURE, "sss_extract_and_send_pac failed, group " \
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder "membership for user with principal [%s] " \
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder "might not be correct.\n", kr->name);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder kerr = 0;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder goto done;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder kerr = sss_send_pac(pac_authdata);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers krb5_free_authdata(kr->ctx, pac_authdata);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers if (kerr != 0) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers DEBUG(SSSDBG_OP_FAILURE, "sss_send_pac failed, group " \
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder "membership for user with principal [%s] " \
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder "might not be correct.\n", kr->name);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = 0;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maederdone:
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (validation_ccache != NULL) {
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder krb5_cc_destroy(kr->ctx, validation_ccache);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (krb5_kt_close(kr->ctx, keytab) != 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_MINOR_FAILURE, "krb5_kt_close failed\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (validation_princ != NULL) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_free_principal(kr->ctx, validation_princ);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers if (principal != NULL) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers sss_krb5_free_unparsed_name(kr->ctx, principal);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return kerr;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder}
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maederstatic krb5_error_code get_and_save_tgt_with_keytab(krb5_context ctx,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_principal princ,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_keytab keytab,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder char *ccname)
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder{
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_error_code kerr = 0;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_creds creds;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_get_init_creds_opt options;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder memset(&creds, 0, sizeof(creds));
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder memset(&options, 0, sizeof(options));
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_get_init_creds_opt_set_address_list(&options, NULL);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers krb5_get_init_creds_opt_set_forwardable(&options, 0);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_get_init_creds_opt_set_proxiable(&options, 0);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers set_canonicalize_option(&options);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers kerr = krb5_get_init_creds_keytab(ctx, &creds, princ, keytab, 0, NULL,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder &options);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (kerr != 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return kerr;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder /* Use the updated principal in the creds in case canonicalized */
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = create_ccache(ccname, &creds);
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder if (kerr != 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder goto done;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder kerr = 0;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maederdone:
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers krb5_free_cred_contents(ctx, &creds);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers return kerr;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder}
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maederstatic krb5_error_code get_and_save_tgt(struct krb5_req *kr,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder const char *password)
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder{
97f7ac06b3cbf4fc22c0a9eef523b68ee34fc164Christian Maeder const char *realm_name;
97f7ac06b3cbf4fc22c0a9eef523b68ee34fc164Christian Maeder int realm_length;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_error_code kerr;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder char *cc_name;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = sss_krb5_get_init_creds_opt_set_expire_callback(kr->ctx, kr->options,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder sss_krb5_expire_callback_func,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder kr);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kerr != 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder "Failed to set expire callback, continue without.\n");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder sss_krb5_princ_realm(kr->ctx, kr->princ, &realm_name, &realm_length);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (realm_length == 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "sss_krb5_princ_realm failed.\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return KRB5KRB_ERR_GENERIC;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_TRACE_FUNC,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder "Attempting kinit for realm [%s]\n",realm_name);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder discard_const(password),
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder sss_krb5_prompter, kr, 0,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder NULL, kr->options);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kr->pd->cmd == SSS_PAM_PREAUTH) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder /* Any errors are ignored during pre-auth, only data is collected to
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder * be send back to the client.*/
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_TRACE_FUNC,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder "krb5_get_init_creds_password returned [%d} during pre-auth.\n",
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return 0;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder } else {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kerr != 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return kerr;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (kr->validate) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = validate_tgt(kr);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kerr != 0) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return kerr;
ea8e98e298f33f9362293f392c8fb192722b8904Eugen Kuksa }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder } else {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CONF_SETTINGS, "TGT validation is disabled.\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder /* If kr->ccname is cache collection (DIR:/...), we want to work
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder * directly with file ccache (DIR::/...), but cache collection
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder * should be returned back to back end.
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers */
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder cc_name = sss_get_ccache_name_for_principal(kr->pd, kr->ctx,
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers kr->creds->client,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder kr->ccname);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (cc_name == NULL) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder cc_name = kr->ccname;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers /* Use the updated principal in the creds in case canonicalized */
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = create_ccache(cc_name, kr->creds);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (kerr != 0) {
0e9494f7ac18b504a9dab7e9f001d8a94bd3baaaChristian Maeder goto done;
0e9494f7ac18b504a9dab7e9f001d8a94bd3baaaChristian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder /* Successfull authentication! Check if ccache contains the
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder * right principal...
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder */
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = sss_krb5_check_ccache_princ(kr->ctx, kr->ccname, kr->creds->client);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kerr) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder "No ccache for %s in %s?\n", kr->upn, kr->ccname);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder goto done;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder kerr = safe_remove_old_ccache_file(kr->old_ccname, kr->ccname,
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers kr->uid, kr->gid);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers if (kerr != EOK) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers DEBUG(SSSDBG_MINOR_FAILURE,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder "Failed to remove old ccache file [%s], "
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder "please remove it manually.\n", kr->old_ccname);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder kerr = add_ticket_times_and_upn_to_response(kr);
0e9494f7ac18b504a9dab7e9f001d8a94bd3baaaChristian Maeder if (kerr != 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE,
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder "add_ticket_times_and_upn_to_response failed.\n");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = 0;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maederdone:
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder krb5_free_cred_contents(kr->ctx, kr->creds);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return kerr;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder}
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maederstatic errno_t map_krb5_error(krb5_error_code kerr)
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder{
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (kerr != 0) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers switch (kerr) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers case 0:
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers return ERR_OK;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder case KRB5_LIBOS_CANTREADPWD:
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return ERR_NO_CREDS;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder case KRB5_KDCREP_SKEW:
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder case KRB5KRB_AP_ERR_SKEW:
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder case KRB5_KDC_UNREACH:
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder case KRB5_REALM_CANT_RESOLVE:
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return ERR_NETWORK_IO;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder case KRB5KDC_ERR_CLIENT_REVOKED:
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return ERR_ACCOUNT_EXPIRED;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder case KRB5KDC_ERR_KEY_EXP:
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return ERR_CREDS_EXPIRED;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers case KRB5KRB_AP_ERR_BAD_INTEGRITY:
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers return ERR_AUTH_FAILED;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder /* ERR_CREDS_INVALID is used to indicate to the IPA provider that trying
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder * password migration would make sense. All Kerberos error codes which can
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder * be seen while migrating LDAP users to IPA should be added here. */
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder case KRB5_PROG_ETYPE_NOSUPP:
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder case KRB5_PREAUTH_FAILED:
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder case KRB5KDC_ERR_PREAUTH_FAILED:
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return ERR_CREDS_INVALID;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder /* Please do not remove KRB5KRB_ERR_GENERIC here, it is a _generic_ error
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder * code and we cannot make any assumptions about the reason for the error.
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder * As a consequence we cannot return a different error code than a generic
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder * one which unfortunately might result in a unspecific system error
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder * message to the user.
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers *
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers * If there are cases where libkrb5 calls return KRB5KRB_ERR_GENERIC where
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers * SSSD should behave differently this has to be detected by different
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder * means, e.g. by evaluation error messages, and then the error code
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder * should be changed to a more suitable KRB5* error code or immediately to
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder * a SSSD ERR_* error code to avoid the default handling here. */
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder case KRB5KRB_ERR_GENERIC:
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder default:
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return ERR_INTERNAL;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder}
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maederstatic errno_t changepw_child(struct krb5_req *kr, bool prelim)
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder{
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder int ret;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_error_code kerr = 0;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers const char *password = NULL;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers const char *newpassword = NULL;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers int result_code = -1;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_data result_code_string;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_data result_string;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder char *user_error_message = NULL;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder size_t user_resp_len;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder uint8_t *user_resp;
587fb54160b66128cf17e4c9bca7494a7f2c3c4aChristian Maeder krb5_prompter_fct prompter = NULL;
587fb54160b66128cf17e4c9bca7494a7f2c3c4aChristian Maeder const char *realm_name;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder int realm_length;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder size_t msg_len;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder uint8_t *msg;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder uint32_t user_info_type;
ea8e98e298f33f9362293f392c8fb192722b8904Eugen Kuksa
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_TRACE_LIBS, "Password change operation\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder ret = sss_authtok_get_password(kr->pd->authtok, &password, NULL);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (ret != EOK) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder "Failed to fetch current password [%d] %s.\n",
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder ret, strerror(ret));
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return ERR_NO_CREDS;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (!prelim) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers /* We do not need a password expiration warning here. */
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers prompter = sss_krb5_prompter;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers set_changepw_options(kr->options);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers sss_krb5_princ_realm(kr->ctx, kr->princ, &realm_name, &realm_length);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers if (realm_length == 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "sss_krb5_princ_realm failed.\n");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return ERR_INTERNAL;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_TRACE_FUNC,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder "Attempting kinit for realm [%s]\n",realm_name);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder discard_const(password),
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder prompter, kr, 0,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder SSSD_KRB5_CHANGEPW_PRINCIPAL,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder kr->options);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_TRACE_INTERNAL,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder "chpass is%s using OTP\n", kr->otp ? "" : " not");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (kerr != 0) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder ret = pack_user_info_chpass_error(kr->pd, "Old password not accepted.",
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers &msg_len, &msg);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (ret != EOK) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_CRIT_FAILURE,
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers "pack_user_info_chpass_error failed.\n");
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers } else {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers ret = pam_add_response(kr->pd, SSS_PAM_USER_INFO, msg_len,
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers msg);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers if (ret != EOK) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder "pam_add_response failed.\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return kerr;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder sss_authtok_set_empty(kr->pd->authtok);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (prelim) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_TRACE_LIBS,
55b14de0878c596dc00920ecac65bab478e930e8Christian Maeder "Initial authentication for change password operation "
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder "successful.\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_free_cred_contents(kr->ctx, kr->creds);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return EOK;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder ret = sss_authtok_get_password(kr->pd->newauthtok, &newpassword, NULL);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (ret != EOK) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "Failed to fetch new password [%d] %s.\n",
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder ret, strerror(ret));
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers return ERR_NO_CREDS;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder memset(&result_code_string, 0, sizeof(krb5_data));
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder memset(&result_string, 0, sizeof(krb5_data));
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = krb5_change_password(kr->ctx, kr->creds,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder discard_const(newpassword), &result_code,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder &result_code_string, &result_string);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (kerr == KRB5_KDC_UNREACH) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return ERR_NETWORK_IO;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kerr != 0 || result_code != 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kerr != 0) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers if (result_code_string.length > 0) {
fa3833ff4dad97e760264971215091d6f49d3766Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE,
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder "krb5_change_password failed [%d][%.*s].\n", result_code,
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder result_code_string.length, result_code_string.data);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder user_error_message = talloc_strndup(kr->pd, result_code_string.data,
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder result_code_string.length);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (user_error_message == NULL) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strndup failed.\n");
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder }
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder if (result_string.length > 0 && result_string.data[0] != '\0') {
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder DEBUG(SSSDBG_CRIT_FAILURE,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder "krb5_change_password failed [%d][%.*s].\n", result_code,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder result_string.length, result_string.data);
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder talloc_free(user_error_message);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder user_error_message = talloc_strndup(kr->pd, result_string.data,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder result_string.length);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (user_error_message == NULL) {
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strndup failed.\n");
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder }
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder } else if (result_code == KRB5_KPASSWD_SOFTERROR) {
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder user_error_message = talloc_strdup(kr->pd, "Please make sure the "
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder "password meets the complexity constraints.");
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder if (user_error_message == NULL) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strndup failed.\n");
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers if (user_error_message != NULL) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers ret = pack_user_info_chpass_error(kr->pd, user_error_message,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder &user_resp_len, &user_resp);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (ret != EOK) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder "pack_user_info_chpass_error failed.\n");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder } else {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder ret = pam_add_response(kr->pd, SSS_PAM_USER_INFO, user_resp_len,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder user_resp);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (ret != EOK) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder "pack_response_packet failed.\n");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
55b14de0878c596dc00920ecac65bab478e930e8Christian Maeder }
fa3833ff4dad97e760264971215091d6f49d3766Christian Maeder }
fa3833ff4dad97e760264971215091d6f49d3766Christian Maeder
fa3833ff4dad97e760264971215091d6f49d3766Christian Maeder return ERR_CHPASS_FAILED;
fa3833ff4dad97e760264971215091d6f49d3766Christian Maeder }
fa3833ff4dad97e760264971215091d6f49d3766Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_free_cred_contents(kr->ctx, kr->creds);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kr->otp == true) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder user_info_type = SSS_PAM_USER_INFO_OTP_CHPASS;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder ret = pam_add_response(kr->pd, SSS_PAM_USER_INFO, sizeof(uint32_t),
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder (const uint8_t *) &user_info_type);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (ret != EOK) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder /* Not fatal */
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder sss_authtok_set_empty(kr->pd->newauthtok);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return map_krb5_error(kerr);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers /* We changed some of the gic options for the password change, now we have
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder * to change them back to get a fresh TGT. */
fa3833ff4dad97e760264971215091d6f49d3766Christian Maeder revert_changepw_options(kr->options);
fa3833ff4dad97e760264971215091d6f49d3766Christian Maeder
fa3833ff4dad97e760264971215091d6f49d3766Christian Maeder kerr = get_and_save_tgt(kr, newpassword);
fa3833ff4dad97e760264971215091d6f49d3766Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder sss_authtok_set_empty(kr->pd->newauthtok);
fa3833ff4dad97e760264971215091d6f49d3766Christian Maeder
fa3833ff4dad97e760264971215091d6f49d3766Christian Maeder if (kerr == 0) {
fa3833ff4dad97e760264971215091d6f49d3766Christian Maeder kerr = k5c_attach_ccname_msg(kr);
fa3833ff4dad97e760264971215091d6f49d3766Christian Maeder }
fa3833ff4dad97e760264971215091d6f49d3766Christian Maeder return map_krb5_error(kerr);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder}
fa3833ff4dad97e760264971215091d6f49d3766Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maederstatic errno_t tgt_req_child(struct krb5_req *kr)
fa3833ff4dad97e760264971215091d6f49d3766Christian Maeder{
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers const char *password = NULL;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers krb5_error_code kerr;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers int ret;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
55b14de0878c596dc00920ecac65bab478e930e8Christian Maeder DEBUG(SSSDBG_TRACE_LIBS, "Attempting to get a TGT\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder /* No password is needed for pre-auth, or if we have 2FA */
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (kr->pd->cmd != SSS_PAM_PREAUTH
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers && sss_authtok_get_type(kr->pd->authtok) != SSS_AUTHTOK_TYPE_2FA) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers ret = sss_authtok_get_password(kr->pd->authtok, &password, NULL);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder switch (ret) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder case EOK:
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder break;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder case EACCES:
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers DEBUG(SSSDBG_OP_FAILURE, "Invalid authtok type\n");
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers return ERR_INVALID_CRED_TYPE;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers break;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers default:
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers DEBUG(SSSDBG_OP_FAILURE, "No credentials available\n");
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers return ERR_NO_CREDS;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder break;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = get_and_save_tgt(kr, password);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (kerr != KRB5KDC_ERR_KEY_EXP) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kr->pd->cmd == SSS_PAM_PREAUTH) {
ea8e98e298f33f9362293f392c8fb192722b8904Eugen Kuksa /* add OTP tokeninfo messge if available */
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (kr->otp) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder kerr = k5c_attach_otp_info_msg(kr);
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder }
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder } else {
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder if (kerr == 0) {
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder kerr = k5c_attach_ccname_msg(kr);
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder }
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder }
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder ret = map_krb5_error(kerr);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder goto done;
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder /* If the password is expired the KDC will always return
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder KRB5KDC_ERR_KEY_EXP regardless if the supplied password is correct or
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder not. In general the password can still be used to get a changepw ticket.
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder So we validate the password by trying to get a changepw ticket. */
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder DEBUG(SSSDBG_TRACE_LIBS, "Password was expired\n");
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder kerr = sss_krb5_get_init_creds_opt_set_expire_callback(kr->ctx,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder kr->options,
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder NULL, NULL);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (kerr != 0) {
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder DEBUG(SSSDBG_CRIT_FAILURE,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder "Failed to unset expire callback, continue ...\n");
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder }
ea8e98e298f33f9362293f392c8fb192722b8904Eugen Kuksa
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder set_changepw_options(kr->options);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder discard_const(password),
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder sss_krb5_prompter, kr, 0,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder SSSD_KRB5_CHANGEPW_PRINCIPAL,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder kr->options);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_free_cred_contents(kr->ctx, kr->creds);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (kerr == 0) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder ret = ERR_CREDS_EXPIRED;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder /* If the password is expired we can safely remove the ccache from the
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder * cache and disk if it is not actively used anymore. This will allow
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder * to create a new random ccache if sshd with privilege separation is
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder * used. */
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kr->old_cc_active == false && kr->old_ccname) {
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder ret = safe_remove_old_ccache_file(kr->old_ccname, NULL,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kr->uid, kr->gid);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (ret != EOK) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder "Failed to remove old ccache file [%s], "
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder "please remove it manually.\n", kr->old_ccname);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder ret = ERR_CREDS_EXPIRED_CCACHE;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder } else {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder ret = map_krb5_error(kerr);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maederdone:
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers sss_authtok_set_empty(kr->pd->authtok);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return ret;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder}
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maederstatic errno_t kuserok_child(struct krb5_req *kr)
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers{
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_boolean access_allowed;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_error_code kerr;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_TRACE_LIBS, "Verifying if principal can log in as user\n");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers /* krb5_kuserok tries to verify that kr->pd->user is a locally known
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers * account, so we have to unset _SSS_LOOPS to make getpwnam() work. */
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers if (unsetenv("_SSS_LOOPS") != 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "Failed to unset _SSS_LOOPS, "
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder "krb5_kuserok will most certainly fail.\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = krb5_set_default_realm(kr->ctx, kr->realm);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kerr != 0) {
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder DEBUG(SSSDBG_CRIT_FAILURE, "krb5_set_default_realm failed, "
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder "krb5_kuserok may fail.\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder access_allowed = krb5_kuserok(kr->ctx, kr->princ, kr->pd->user);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_TRACE_LIBS,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder "Access was %s\n", access_allowed ? "allowed" : "denied");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (access_allowed) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers return EOK;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return ERR_AUTH_DENIED;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder}
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
55b14de0878c596dc00920ecac65bab478e930e8Christian Maederstatic errno_t renew_tgt_child(struct krb5_req *kr)
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder{
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder const char *ccname;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder krb5_ccache ccache = NULL;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_error_code kerr;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder int ret;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_TRACE_LIBS, "Renewing a ticket\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder ret = sss_authtok_get_ccfile(kr->pd->authtok, &ccname, NULL);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (ret != EOK) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_OP_FAILURE,
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers "Unsupported authtok type for TGT renewal [%d].\n",
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers sss_authtok_get_type(kr->pd->authtok));
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers return ERR_INVALID_CRED_TYPE;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = krb5_cc_resolve(kr->ctx, ccname, &ccache);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kerr != 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder goto done;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = krb5_get_renewed_creds(kr->ctx, kr->creds, kr->princ, ccache, NULL);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kerr != 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder goto done;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kr->validate) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = validate_tgt(kr);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kerr != 0) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder goto done;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder } else {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CONF_SETTINGS, "TGT validation is disabled.\n");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
55b14de0878c596dc00920ecac65bab478e930e8Christian Maeder kerr = krb5_cc_initialize(kr->ctx, ccache, kr->princ);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kerr != 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder goto done;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = krb5_cc_store_cred(kr->ctx, ccache, kr->creds);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (kerr != 0) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder goto done;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers kerr = add_ticket_times_and_upn_to_response(kr);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kerr != 0) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_CRIT_FAILURE,
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder "add_ticket_times_and_upn_to_response failed.\n");
4e521879e36515b983525ff9a4ea82ba44e5bbffChristian Maeder }
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder kerr = k5c_attach_ccname_msg(kr);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maederdone:
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_free_cred_contents(kr->ctx, kr->creds);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (ccache != NULL) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_cc_close(kr->ctx, ccache);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers return map_krb5_error(kerr);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder}
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckersstatic errno_t create_empty_ccache(struct krb5_req *kr)
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder{
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_creds *creds = NULL;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_error_code kerr;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kr->old_cc_valid == false) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_TRACE_LIBS, "Creating empty ccache\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = create_empty_cred(kr->ctx, kr->princ, &creds);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (kerr == 0) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = create_ccache(kr->ccname, creds);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder } else {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_TRACE_LIBS, "Existing ccache still valid, reusing\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kerr = 0;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (kerr == 0) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers kerr = k5c_attach_ccname_msg(kr);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_free_creds(kr->ctx, creds);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return map_krb5_error(kerr);
ea8e98e298f33f9362293f392c8fb192722b8904Eugen Kuksa}
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maederstatic errno_t unpack_authtok(struct sss_auth_token *tok,
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder uint8_t *buf, size_t size, size_t *p)
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder{
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder uint32_t auth_token_type;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder uint32_t auth_token_length;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder errno_t ret = EOK;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
ea8e98e298f33f9362293f392c8fb192722b8904Eugen Kuksa SAFEALIGN_COPY_UINT32_CHECK(&auth_token_type, buf + *p, size, p);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder SAFEALIGN_COPY_UINT32_CHECK(&auth_token_length, buf + *p, size, p);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if ((*p + auth_token_length) > size) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return EINVAL;
0e9494f7ac18b504a9dab7e9f001d8a94bd3baaaChristian Maeder }
0e9494f7ac18b504a9dab7e9f001d8a94bd3baaaChristian Maeder switch (auth_token_type) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder case SSS_AUTHTOK_TYPE_EMPTY:
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder sss_authtok_set_empty(tok);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder break;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder case SSS_AUTHTOK_TYPE_PASSWORD:
55b14de0878c596dc00920ecac65bab478e930e8Christian Maeder ret = sss_authtok_set_password(tok, (char *)(buf + *p), 0);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder break;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder case SSS_AUTHTOK_TYPE_CCFILE:
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder ret = sss_authtok_set_ccfile(tok, (char *)(buf + *p), 0);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder break;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder case SSS_AUTHTOK_TYPE_2FA:
ea8e98e298f33f9362293f392c8fb192722b8904Eugen Kuksa ret = sss_authtok_set(tok, SSS_AUTHTOK_TYPE_2FA, (buf + *p),
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder auth_token_length);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder break;
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder default:
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return EINVAL;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (ret == EOK) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder *p += auth_token_length;
3fea26a73b8fa69b22dfd2653d8f7bdacb45b9c9Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return ret;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder}
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maederstatic errno_t unpack_buffer(uint8_t *buf, size_t size,
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers struct krb5_req *kr, uint32_t *offline)
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder{
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder size_t p = 0;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder uint32_t len;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers uint32_t validate;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder uint32_t send_pac;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder uint32_t use_enterprise_princ;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder struct pam_data *pd;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder errno_t ret;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_TRACE_LIBS, "total buffer size: [%zu]\n", size);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (!offline || !kr) return EINVAL;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder pd = create_pam_data(kr);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (pd == NULL) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n");
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return ENOMEM;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder kr->pd = pd;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder SAFEALIGN_COPY_UINT32_CHECK(&pd->cmd, buf + p, size, &p);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder SAFEALIGN_COPY_UINT32_CHECK(&kr->uid, buf + p, size, &p);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder SAFEALIGN_COPY_UINT32_CHECK(&kr->gid, buf + p, size, &p);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder SAFEALIGN_COPY_UINT32_CHECK(&validate, buf + p, size, &p);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kr->validate = (validate == 0) ? false : true;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder SAFEALIGN_COPY_UINT32_CHECK(offline, buf + p, size, &p);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder SAFEALIGN_COPY_UINT32_CHECK(&send_pac, buf + p, size, &p);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers kr->send_pac = (send_pac == 0) ? false : true;
3fea26a73b8fa69b22dfd2653d8f7bdacb45b9c9Christian Maeder SAFEALIGN_COPY_UINT32_CHECK(&use_enterprise_princ, buf + p, size, &p);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers kr->use_enterprise_princ = (use_enterprise_princ == 0) ? false : true;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p);
3fea26a73b8fa69b22dfd2653d8f7bdacb45b9c9Christian Maeder if ((p + len ) > size) return EINVAL;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kr->upn = talloc_strndup(pd, (char *)(buf + p), len);
ea8e98e298f33f9362293f392c8fb192722b8904Eugen Kuksa if (kr->upn == NULL) return ENOMEM;
3fea26a73b8fa69b22dfd2653d8f7bdacb45b9c9Christian Maeder p += len;
3fea26a73b8fa69b22dfd2653d8f7bdacb45b9c9Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_CONF_SETTINGS,
ea8e98e298f33f9362293f392c8fb192722b8904Eugen Kuksa "cmd [%d] uid [%llu] gid [%llu] validate [%s] "
ea8e98e298f33f9362293f392c8fb192722b8904Eugen Kuksa "enterprise principal [%s] offline [%s] UPN [%s]\n",
3fea26a73b8fa69b22dfd2653d8f7bdacb45b9c9Christian Maeder pd->cmd, (unsigned long long) kr->uid,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder (unsigned long long) kr->gid, kr->validate ? "true" : "false",
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kr->use_enterprise_princ ? "true" : "false",
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder *offline ? "true" : "false", kr->upn ? kr->upn : "none");
3fea26a73b8fa69b22dfd2653d8f7bdacb45b9c9Christian Maeder
3fea26a73b8fa69b22dfd2653d8f7bdacb45b9c9Christian Maeder if (pd->cmd == SSS_PAM_AUTHENTICATE ||
3fea26a73b8fa69b22dfd2653d8f7bdacb45b9c9Christian Maeder pd->cmd == SSS_CMD_RENEW ||
3fea26a73b8fa69b22dfd2653d8f7bdacb45b9c9Christian Maeder pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM || pd->cmd == SSS_PAM_CHAUTHTOK) {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p);
e49fd57c63845c7806860a9736ad09f6d44dbaedChristian Maeder if ((p + len ) > size) return EINVAL;
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers kr->ccname = talloc_strndup(pd, (char *)(buf + p), len);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kr->ccname == NULL) return ENOMEM;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder p += len;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
db6729e623b4053149084ccf4b35e5308ac7e359Christian Maeder SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if ((p + len ) > size) return EINVAL;
db6729e623b4053149084ccf4b35e5308ac7e359Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (len > 0) {
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder kr->old_ccname = talloc_strndup(pd, (char *)(buf + p), len);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if (kr->old_ccname == NULL) return ENOMEM;
e49fd57c63845c7806860a9736ad09f6d44dbaedChristian Maeder p += len;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder } else {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder DEBUG(SSSDBG_TRACE_INTERNAL, "No old ccache\n");
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if ((p + len ) > size) return EINVAL;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder kr->keytab = talloc_strndup(pd, (char *)(buf + p), len);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers if (kr->keytab == NULL) return ENOMEM;
db6729e623b4053149084ccf4b35e5308ac7e359Christian Maeder p += len;
db6729e623b4053149084ccf4b35e5308ac7e359Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder ret = unpack_authtok(pd->authtok, buf, size, &p);
0ce46d5315b16108b74d20b86aeff37c48f48828Christian Maeder if (ret) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return ret;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
db6729e623b4053149084ccf4b35e5308ac7e359Christian Maeder DEBUG(SSSDBG_CONF_SETTINGS,
db6729e623b4053149084ccf4b35e5308ac7e359Christian Maeder "ccname: [%s] old_ccname: [%s] keytab: [%s]\n",
db6729e623b4053149084ccf4b35e5308ac7e359Christian Maeder kr->ccname,
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kr->old_ccname ? kr->old_ccname : "not set",
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kr->keytab);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder } else {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder kr->ccname = NULL;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder kr->old_ccname = NULL;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder kr->keytab = NULL;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder sss_authtok_set_empty(pd->authtok);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
e49fd57c63845c7806860a9736ad09f6d44dbaedChristian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers if (pd->cmd == SSS_PAM_CHAUTHTOK) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder ret = unpack_authtok(pd->newauthtok, buf, size, &p);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (ret) {
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder return ret;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder } else {
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder sss_authtok_set_empty(pd->newauthtok);
e49fd57c63845c7806860a9736ad09f6d44dbaedChristian Maeder }
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder if (pd->cmd == SSS_PAM_ACCT_MGMT) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if ((p + len ) > size) return EINVAL;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder pd->user = talloc_strndup(pd, (char *)(buf + p), len);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (pd->user == NULL) return ENOMEM;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder p += len;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_CONF_SETTINGS, "user: [%s]\n", pd->user);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers } else {
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers pd->user = NULL;
e07538a3c4dbc690e57f61aded6db89d876b2374Christian Maeder }
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers return EOK;
e07538a3c4dbc690e57f61aded6db89d876b2374Christian Maeder}
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckersstatic int krb5_cleanup(struct krb5_req *kr)
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder{
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers if (kr == NULL) return EOK;
42c01284bba8d7c8d995c8dfb96ace57d28ed1bcTill Mossakowski
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (kr->options != NULL) {
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder sss_krb5_get_init_creds_opt_free(kr->ctx, kr->options);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
42c01284bba8d7c8d995c8dfb96ace57d28ed1bcTill Mossakowski
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers if (kr->creds != NULL) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_free_cred_contents(kr->ctx, kr->creds);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_free_creds(kr->ctx, kr->creds);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers }
42c01284bba8d7c8d995c8dfb96ace57d28ed1bcTill Mossakowski if (kr->name != NULL)
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder sss_krb5_free_unparsed_name(kr->ctx, kr->name);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (kr->princ != NULL)
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_free_principal(kr->ctx, kr->princ);
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder if (kr->ctx != NULL)
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_free_context(kr->ctx);
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers
42c01284bba8d7c8d995c8dfb96ace57d28ed1bcTill Mossakowski memset(kr, 0, sizeof(struct krb5_req));
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder return EOK;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder}
9c84ea0239ba21e070e7d76d47d30713a3610327Christian Maeder
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maederstatic krb5_error_code get_tgt_times(krb5_context ctx, const char *ccname,
42c01284bba8d7c8d995c8dfb96ace57d28ed1bcTill Mossakowski krb5_principal server_principal,
42c01284bba8d7c8d995c8dfb96ace57d28ed1bcTill Mossakowski krb5_principal client_principal,
42c01284bba8d7c8d995c8dfb96ace57d28ed1bcTill Mossakowski sss_krb5_ticket_times *tgtt)
42c01284bba8d7c8d995c8dfb96ace57d28ed1bcTill Mossakowski{
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers krb5_error_code krberr;
42c01284bba8d7c8d995c8dfb96ace57d28ed1bcTill Mossakowski krb5_ccache ccache = NULL;
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krb5_creds mcred;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder krb5_creds cred;
0cb5f9c8582ad87ceef1c16b5d92347ae0878019Christian Maeder
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder krberr = krb5_cc_resolve(ctx, ccname, &ccache);
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder if (krberr != 0) {
94e112d16f89130a688db8b03ad3224903f5e97eChristian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_resolve failed.\n");
c1c5a93b6f5bf18be1f4a0a9da6c0e32ff00266cFelix Reckers KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, krberr);
goto done;
}
memset(&mcred, 0, sizeof(mcred));
memset(&cred, 0, sizeof(mcred));
mcred.server = server_principal;
mcred.client = client_principal;
krberr = krb5_cc_retrieve_cred(ctx, ccache, 0, &mcred, &cred);
if (krberr == KRB5_FCC_NOFILE) {
DEBUG(SSSDBG_TRACE_LIBS, "FAST ccache must be recreated\n");
} else if (krberr != 0) {
DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_retrieve_cred failed\n");
KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, krberr);
krberr = 0;
goto done;
}
tgtt->authtime = cred.times.authtime;
tgtt->starttime = cred.times.starttime;
tgtt->endtime = cred.times.endtime;
tgtt->renew_till = cred.times.renew_till;
krb5_free_cred_contents(ctx, &cred);
krberr = 0;
done:
if (ccache != NULL) {
krb5_cc_close(ctx, ccache);
}
return krberr;
}
static krb5_error_code check_fast_ccache(TALLOC_CTX *mem_ctx,
krb5_context ctx,
uid_t fast_uid,
gid_t fast_gid,
const char *primary,
const char *realm,
const char *keytab_name,
char **fast_ccname)
{
TALLOC_CTX *tmp_ctx = NULL;
krb5_error_code kerr;
char *ccname;
char *server_name;
sss_krb5_ticket_times tgtt;
krb5_keytab keytab = NULL;
krb5_principal client_princ = NULL;
krb5_principal server_princ = NULL;
pid_t fchild_pid;
int status;
tmp_ctx = talloc_new(NULL);
if (tmp_ctx == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n");
return ENOMEM;
}
ccname = talloc_asprintf(tmp_ctx, "FILE:%s/fast_ccache_%s", DB_PATH, realm);
if (ccname == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
kerr = ENOMEM;
goto done;
}
if (keytab_name != NULL) {
kerr = krb5_kt_resolve(ctx, keytab_name, &keytab);
} else {
kerr = krb5_kt_default(ctx, &keytab);
}
if (kerr) {
DEBUG(SSSDBG_FATAL_FAILURE,
"Failed to read keytab file [%s]: %s\n",
KEYTAB_CLEAN_NAME,
sss_krb5_get_error_message(ctx, kerr));
goto done;
}
kerr = find_principal_in_keytab(ctx, keytab, primary, realm, &client_princ);
if (kerr != 0) {
DEBUG(SSSDBG_MINOR_FAILURE,
"find_principal_in_keytab failed for principal %s@%s.\n",
primary, realm);
goto done;
}
server_name = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s", realm, realm);
if (server_name == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
kerr = ENOMEM;
goto done;
}
kerr = krb5_parse_name(ctx, server_name, &server_princ);
if (kerr != 0) {
DEBUG(SSSDBG_CRIT_FAILURE, "krb5_parse_name failed.\n");
goto done;
}
memset(&tgtt, 0, sizeof(tgtt));
kerr = get_tgt_times(ctx, ccname, server_princ, client_princ, &tgtt);
if (kerr == 0) {
if (tgtt.endtime > time(NULL)) {
DEBUG(SSSDBG_FUNC_DATA, "FAST TGT is still valid.\n");
goto done;
}
}
/* Need to recreate the FAST ccache */
fchild_pid = fork();
switch (fchild_pid) {
case -1:
DEBUG(SSSDBG_CRIT_FAILURE, "fork failed\n");
kerr = EIO;
goto done;
case 0:
/* Child */
debug_prg_name = talloc_asprintf(NULL, "[sssd[krb5_child[%d]]]", getpid());
if (debug_prg_name == NULL) {
debug_prg_name = "[sssd[krb5_child]]";
DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
/* Try to carry on */
}
kerr = become_user(fast_uid, fast_gid);
if (kerr != 0) {
DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed: %d\n", kerr);
exit(1);
}
DEBUG(SSSDBG_TRACE_INTERNAL,
"Running as [%"SPRIuid"][%"SPRIgid"].\n", geteuid(), getegid());
kerr = get_and_save_tgt_with_keytab(ctx, client_princ,
keytab, ccname);
if (kerr != 0) {
DEBUG(SSSDBG_CRIT_FAILURE,
"get_and_save_tgt_with_keytab failed: %d\n", kerr);
exit(2);
}
exit(0);
default:
/* Parent */
do {
errno = 0;
kerr = waitpid(fchild_pid, &status, 0);
} while (kerr == -1 && errno == EINTR);
if (kerr > 0) {
if (WIFEXITED(status)) {
kerr = WEXITSTATUS(status);
/* Don't blindly fail if the child fails, but check
* the ccache again */
if (kerr != 0) {
DEBUG(SSSDBG_MINOR_FAILURE,
"Creating FAST ccache failed, krb5_child will "
"likely fail!\n");
}
} else {
DEBUG(SSSDBG_CRIT_FAILURE,
"krb5_child subprocess %d terminated unexpectedly\n",
fchild_pid);
}
} else {
DEBUG(SSSDBG_CRIT_FAILURE,
"Failed to wait for child %d\n", fchild_pid);
/* Let the code re-check the TGT times and fail if we
* can't find the updated principal */
}
}
/* Check the ccache times again. Should be updated ... */
memset(&tgtt, 0, sizeof(tgtt));
kerr = get_tgt_times(ctx, ccname, server_princ, client_princ, &tgtt);
if (kerr != 0) {
DEBUG(SSSDBG_OP_FAILURE, "get_tgt_times() failed\n");
goto done;
}
if (tgtt.endtime < time(NULL)) {
DEBUG(SSSDBG_OP_FAILURE,
"FAST TGT was renewed but is already expired, please check that "
"time is synchronized with server.\n");
kerr = ERR_CREDS_EXPIRED;
goto done;
}
DEBUG(SSSDBG_FUNC_DATA, "FAST TGT was successfully recreated!\n");
done:
if (client_princ != NULL) {
krb5_free_principal(ctx, client_princ);
}
if (server_princ != NULL) {
krb5_free_principal(ctx, server_princ);
}
if (kerr == 0) {
*fast_ccname = talloc_steal(mem_ctx, ccname);
}
talloc_free(tmp_ctx);
if (keytab != NULL) {
krb5_kt_close(ctx, keytab);
}
return kerr;
}
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;
ret = (ret == 0) ? EINVAL: ret;
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(SSSDBG_CRIT_FAILURE, "unpack_buffer failed.\n");
}
return ret;
}
static int k5c_setup_fast(struct krb5_req *kr, 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;
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 (kerr) {
DEBUG(SSSDBG_CRIT_FAILURE, "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(SSSDBG_CRIT_FAILURE, "sss_krb5_unparse_name_flags failed.\n");
return kerr;
}
fast_principal = talloc_strdup(kr, tmp_str);
if (!fast_principal) {
DEBUG(SSSDBG_CRIT_FAILURE, "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(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
return ENOMEM;
}
} else {
fast_principal_realm = kr->realm;
fast_principal = NULL;
}
kerr = check_fast_ccache(kr, kr->ctx, kr->fast_uid, kr->fast_gid,
fast_principal, fast_principal_realm,
kr->keytab, &kr->fast_ccname);
if (kerr != 0) {
DEBUG(SSSDBG_CRIT_FAILURE, "check_fast_ccache failed.\n");
KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
return kerr;
}
kerr = copy_ccache_into_memory(kr, kr->ctx, kr->fast_ccname, &new_ccname);
if (kerr != 0) {
DEBUG(SSSDBG_CRIT_FAILURE, "copy_ccache_into_memory failed.\n");
return kerr;
}
talloc_free(kr->fast_ccname);
kr->fast_ccname = new_ccname;
kerr = sss_krb5_get_init_creds_opt_set_fast_ccache_name(kr->ctx,
kr->options,
kr->fast_ccname);
if (kerr != 0) {
DEBUG(SSSDBG_CRIT_FAILURE,
"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(SSSDBG_CRIT_FAILURE,
"sss_krb5_get_init_creds_opt_set_fast_flags "
"failed.\n");
KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
return kerr;
}
}
return EOK;
}
static errno_t check_use_fast(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;
} else if (strcasecmp(use_fast_str, "try") == 0) {
fast_val = K5C_FAST_TRY;
} else if (strcasecmp(use_fast_str, "demand") == 0) {
fast_val = K5C_FAST_DEMAND;
} else {
DEBUG(SSSDBG_CRIT_FAILURE,
"Unsupported value [%s] for krb5_use_fast.\n",
use_fast_str);
return EINVAL;
}
*_fast_val = fast_val;
return EOK;
}
static errno_t old_ccache_valid(struct krb5_req *kr, bool *_valid)
{
errno_t ret;
bool valid;
valid = false;
ret = sss_krb5_cc_verify_ccache(kr->old_ccname,
kr->uid, kr->gid,
kr->realm, kr->upn);
switch (ret) {
case ERR_NOT_FOUND:
case ENOENT:
DEBUG(SSSDBG_TRACE_FUNC,
"Saved ccache %s doesn't exist, ignoring\n", kr->old_ccname);
break;
case EINVAL:
/* cache found but no tgt or expired */
case EOK:
valid = true;
break;
default:
DEBUG(SSSDBG_OP_FAILURE,
"Cannot check if saved ccache %s is valid\n",
kr->old_ccname);
return ret;
}
*_valid = valid;
return EOK;
}
static int k5c_check_old_ccache(struct krb5_req *kr)
{
errno_t ret;
if (kr->old_ccname) {
ret = old_ccache_valid(kr, &kr->old_cc_valid);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "old_ccache_valid failed.\n");
return ret;
}
ret = check_if_uid_is_active(kr->uid, &kr->old_cc_active);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "check_if_uid_is_active failed.\n");
return ret;
}
DEBUG(SSSDBG_TRACE_ALL,
"Ccache_file is [%s] and is %s active and TGT is %s valid.\n",
kr->old_ccname ? kr->old_ccname : "not set",
kr->old_cc_active ? "" : "not",
kr->old_cc_valid ? "" : "not");
}
return EOK;
}
static int k5c_precreate_ccache(struct krb5_req *kr, uint32_t offline)
{
errno_t ret;
/* The ccache file should be (re)created if one of the following conditions
* is true:
* - it doesn't exist (kr->old_ccname == NULL)
* - the backend is online and the current ccache file is not used, i.e
* the related user is currently not logged in and it is not a renewal
* request
* (offline && !kr->old_cc_active && kr->pd->cmd != SSS_CMD_RENEW)
* - the backend is offline and the current cache file not used and
* it does not contain a valid tgt
* (offline && !kr->old_cc_active && !kr->valid_tgt)
*/
if (kr->old_ccname == NULL ||
(offline && !kr->old_cc_active && !kr->old_cc_valid) ||
(!offline && !kr->old_cc_active && kr->pd->cmd != SSS_CMD_RENEW)) {
DEBUG(SSSDBG_TRACE_ALL, "Recreating ccache\n");
ret = sss_krb5_precreate_ccache(kr->ccname, kr->uid, kr->gid);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "ccache creation failed.\n");
return ret;
}
} else {
/* We can reuse the old ccache */
kr->ccname = kr->old_ccname;
}
return EOK;
}
static int k5c_ccache_setup(struct krb5_req *kr, uint32_t offline)
{
errno_t ret;
if (kr->pd->cmd == SSS_PAM_ACCT_MGMT) {
return EOK;
}
ret = k5c_check_old_ccache(kr);
if (ret != 0) {
DEBUG(SSSDBG_CRIT_FAILURE, "Cannot check old ccache [%s]: [%d][%s]. " \
"Assuming old cache is invalid " \
"and not used.\n",
kr->old_ccname, ret, sss_strerror(ret));
}
/* Pre-creating the ccache must be done as root, otherwise we can't mkdir
* some of the DIR: cache components. One example is /run/user/$UID because
* logind doesn't create the directory until the session phase, whereas
* we need the directory during the auth phase already
*/
ret = k5c_precreate_ccache(kr, offline);
if (ret != 0) {
DEBUG(SSSDBG_OP_FAILURE, "Cannot precreate ccache\n");
return ret;
}
return EOK;
}
static int k5c_setup(struct krb5_req *kr, uint32_t offline)
{
krb5_error_code kerr;
int parse_flags;
if (offline || (kr->fast_val == K5C_FAST_NEVER && kr->validate == false)) {
/* If krb5_child was started as setuid, but we don't need to
* perform either validation or FAST, just drop privileges to
* the user who is logging in. The same applies to the offline case
* the user who is logging in. The same applies to the offline case.
*/
kerr = become_user(kr->uid, kr->gid);
if (kerr != 0) {
DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed.\n");
return kerr;
}
}
DEBUG(SSSDBG_TRACE_INTERNAL,
"Running as [%"SPRIuid"][%"SPRIgid"].\n", geteuid(), getegid());
/* 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 != 0) {
KRB5_CHILD_DEBUG(SSSDBG_MINOR_FAILURE, kerr);
return EIO;
}
}
/* Enterprise principals require that a default realm is available. To
* make SSSD more robust in the case that the default realm option is
* missing in krb5.conf or to allow SSSD to work with multiple unconnected
* realms (e.g. AD domains without trust between them) the default realm
* will be set explicitly. */
if (kr->use_enterprise_princ) {
kerr = krb5_set_default_realm(kr->ctx, kr->realm);
if (kerr != 0) {
DEBUG(SSSDBG_CRIT_FAILURE, "krb5_set_default_realm failed.\n");
}
}
parse_flags = kr->use_enterprise_princ ? KRB5_PRINCIPAL_PARSE_ENTERPRISE : 0;
kerr = sss_krb5_parse_name_flags(kr->ctx, kr->upn, parse_flags, &kr->princ);
if (kerr != 0) {
KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
return kerr;
}
kerr = krb5_unparse_name(kr->ctx, kr->princ, &kr->name);
if (kerr != 0) {
KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
return kerr;
}
kr->creds = calloc(1, sizeof(krb5_creds));
if (kr->creds == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n");
return ENOMEM;
}
#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_RESPONDER
kerr = krb5_get_init_creds_opt_set_responder(kr->ctx, kr->options,
sss_krb5_responder, kr);
if (kerr != 0) {
KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
return kerr;
}
#endif
#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_CHANGE_PASSWORD_PROMPT
/* A prompter is used to catch messages about when a password will
* expired. The library shall not use the prompter to ask for a new password
* but shall return KRB5KDC_ERR_KEY_EXP. */
krb5_get_init_creds_opt_set_change_password_prompt(kr->options, 0);
#endif
kerr = set_lifetime_options(kr->options);
if (kerr != 0) {
DEBUG(SSSDBG_OP_FAILURE, "set_lifetime_options failed.\n");
return kerr;
}
if (!offline) {
set_canonicalize_option(kr->options);
}
/* TODO: set options, e.g.
* krb5_get_init_creds_opt_set_forwardable
* krb5_get_init_creds_opt_set_proxiable
* krb5_get_init_creds_opt_set_etype_list
* krb5_get_init_creds_opt_set_address_list
* krb5_get_init_creds_opt_set_preauth_list
* krb5_get_init_creds_opt_set_salt
* krb5_get_init_creds_opt_set_change_password_prompt
* krb5_get_init_creds_opt_set_pa
*/
return kerr;
}
static krb5_error_code privileged_krb5_setup(struct krb5_req *kr,
uint32_t offline)
{
krb5_error_code kerr;
int ret;
char *mem_keytab;
kr->realm = getenv(SSSD_KRB5_REALM);
if (kr->realm == NULL) {
DEBUG(SSSDBG_MINOR_FAILURE,
"Cannot read [%s] from environment.\n", SSSD_KRB5_REALM);
}
kerr = krb5_init_context(&kr->ctx);
if (kerr != 0) {
KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
return kerr;
}
kerr = sss_krb5_get_init_creds_opt_alloc(kr->ctx, &kr->options);
if (kerr != 0) {
KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
return kerr;
}
ret = check_use_fast(&kr->fast_val);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "check_use_fast failed.\n");
return ret;;
}
/* For ccache types FILE: and DIR: we might need to create some directory
* components as root. Cache files are not needed during preauth. */
if (kr->pd->cmd != SSS_PAM_PREAUTH) {
ret = k5c_ccache_setup(kr, offline);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "k5c_ccache_setup failed.\n");
return ret;
}
}
if (!(offline ||
(kr->fast_val == K5C_FAST_NEVER && kr->validate == false))) {
kerr = copy_keytab_into_memory(kr, kr->ctx, kr->keytab, &mem_keytab,
NULL);
if (kerr != 0) {
DEBUG(SSSDBG_OP_FAILURE, "copy_keytab_into_memory failed.\n");
return kerr;
}
talloc_free(kr->keytab);
kr->keytab = mem_keytab;
if (kr->fast_val != K5C_FAST_NEVER) {
kerr = k5c_setup_fast(kr, kr->fast_val == K5C_FAST_DEMAND);
if (kerr != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "Cannot set up FAST\n");
return kerr;
}
}
}
if (kr->send_pac) {
ret = sss_pac_check_and_open();
if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE, "Cannot open the PAC responder socket\n");
/* Not fatal */
}
}
return 0;
}
int main(int argc, const char *argv[])
{
struct krb5_req *kr = NULL;
uint32_t offline;
int opt;
poptContext pc;
int debug_fd = -1;
errno_t ret;
krb5_error_code kerr;
uid_t fast_uid;
gid_t fast_gid;
struct poptOption long_options[] = {
POPT_AUTOHELP
{"debug-level", 'd', POPT_ARG_INT, &debug_level, 0,
_("Debug level"), NULL},
{"debug-timestamps", 0, POPT_ARG_INT, &debug_timestamps, 0,
_("Add debug timestamps"), NULL},
{"debug-microseconds", 0, POPT_ARG_INT, &debug_microseconds, 0,
_("Show timestamps with microseconds"), NULL},
{"debug-fd", 0, POPT_ARG_INT, &debug_fd, 0,
_("An open file descriptor for the debug logs"), NULL},
{"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,
_("The user to create FAST ccache as"), NULL},
{"fast-ccache-gid", 0, POPT_ARG_INT, &fast_gid, 0,
_("The group to create FAST ccache as"), NULL},
POPT_TABLEEND
};
/* Set debug level to invalid value so we can decide if -d 0 was used. */
debug_level = SSSDBG_INVALID;
pc = poptGetContext(argv[0], argc, argv, long_options, 0);
while((opt = poptGetNextOpt(pc)) != -1) {
switch(opt) {
default:
fprintf(stderr, "\nInvalid option %s: %s\n\n",
poptBadOption(pc, 0), poptStrerror(opt));
poptPrintUsage(pc, stderr, 0);
_exit(-1);
}
}
poptFreeContext(pc);
DEBUG_INIT(debug_level);
debug_prg_name = talloc_asprintf(NULL, "[sssd[krb5_child[%d]]]", getpid());
if (!debug_prg_name) {
debug_prg_name = "[sssd[krb5_child]]";
DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
ret = ENOMEM;
goto done;
}
if (debug_fd != -1) {
ret = set_debug_file_from_fd(debug_fd);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "set_debug_file_from_fd failed.\n");
}
}
DEBUG(SSSDBG_TRACE_FUNC, "krb5_child started.\n");
kr = talloc_zero(NULL, struct krb5_req);
if (kr == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n");
ret = ENOMEM;
goto done;
}
talloc_steal(kr, debug_prg_name);
kr->fast_uid = fast_uid;
kr->fast_gid = fast_gid;
ret = k5c_recv_data(kr, STDIN_FILENO, &offline);
if (ret != EOK) {
goto done;
}
close(STDIN_FILENO);
kerr = privileged_krb5_setup(kr, offline);
if (kerr != 0) {
DEBUG(SSSDBG_CRIT_FAILURE, "privileged_krb5_setup failed.\n");
ret = EFAULT;
goto done;
}
kerr = become_user(kr->uid, kr->gid);
if (kerr != 0) {
DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed.\n");
ret = EFAULT;
goto done;
}
DEBUG(SSSDBG_TRACE_INTERNAL,
"Running as [%"SPRIuid"][%"SPRIgid"].\n", geteuid(), getegid());
ret = k5c_setup(kr, offline);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "krb5_child_setup failed.\n");
goto done;
}
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);
} else {
DEBUG(SSSDBG_TRACE_FUNC, "Will perform online auth\n");
ret = tgt_req_child(kr);
}
break;
case SSS_PAM_CHAUTHTOK:
DEBUG(SSSDBG_TRACE_FUNC, "Will perform password change\n");
ret = changepw_child(kr, false);
break;
case SSS_PAM_CHAUTHTOK_PRELIM:
DEBUG(SSSDBG_TRACE_FUNC, "Will perform password change checks\n");
ret = changepw_child(kr, true);
break;
case SSS_PAM_ACCT_MGMT:
DEBUG(SSSDBG_TRACE_FUNC, "Will perform account management\n");
ret = kuserok_child(kr);
break;
case SSS_CMD_RENEW:
if (offline) {
DEBUG(SSSDBG_CRIT_FAILURE, "Cannot renew TGT while offline\n");
ret = KRB5_KDC_UNREACH;
goto done;
}
DEBUG(SSSDBG_TRACE_FUNC, "Will perform ticket renewal\n");
ret = renew_tgt_child(kr);
break;
case SSS_PAM_PREAUTH:
DEBUG(SSSDBG_TRACE_FUNC, "Will perform pre-auth\n");
ret = tgt_req_child(kr);
break;
default:
DEBUG(SSSDBG_CRIT_FAILURE,
"PAM command [%d] not supported.\n", kr->pd->cmd);
ret = EINVAL;
goto done;
}
ret = k5c_send_data(kr, STDOUT_FILENO, ret);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "Failed to send reply\n");
}
done:
if (ret == EOK) {
DEBUG(SSSDBG_TRACE_FUNC, "krb5_child completed successfully\n");
ret = 0;
} else {
DEBUG(SSSDBG_CRIT_FAILURE, "krb5_child failed!\n");
ret = -1;
}
krb5_cleanup(kr);
talloc_free(kr);
exit(ret);
}