krb5_auth.c revision 02e38eae1b9cb5df2036a707dafd86f6047c17de
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder/*
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder SSSD
e9458b1a7a19a63aa4c179f9ab20f4d50681c168Jens Elkner
e6d40133bc9f858308654afb1262b8b483ec5922Till Mossakowski Kerberos 5 Backend Module
2725abe920f91de62ae5c0b7230c1627cccf5fabChristian Maeder
98890889ffb2e8f6f722b00e265a211f13b5a861Corneliu-Claudiu Prodescu Authors:
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder Sumit Bose <sbose@redhat.com>
3f69b6948966979163bdfe8331c38833d5d90ecdChristian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder Copyright (C) 2009-2010 Red Hat
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder This program is free software; you can redistribute it and/or modify
f3a94a197960e548ecd6520bb768cb0d547457bbChristian Maeder it under the terms of the GNU General Public License as published by
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder the Free Software Foundation; either version 3 of the License, or
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder (at your option) any later version.
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder This program is distributed in the hope that it will be useful,
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder but WITHOUT ANY WARRANTY; without even the implied warranty of
0a26144c20fa9cdcd05011ca5019cbac8e4afae0cmaeder MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0a26144c20fa9cdcd05011ca5019cbac8e4afae0cmaeder GNU General Public License for more details.
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder
93603bd881e43d4ff5a57d7ca4e2b9fa619f25b4cmaeder You should have received a copy of the GNU General Public License
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder along with this program. If not, see <http://www.gnu.org/licenses/>.
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder*/
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder#include <errno.h>
4811c997e10bcfbd8e0fdfb130c3368abd33bbcaEugen Kuksa#include <sys/time.h>
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist
df87ff823273ae2969e9d29e833845b4c0a9ee77notanartist#include <sys/types.h>
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder#include <sys/wait.h>
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder#include <pwd.h>
ea5ccb1c6e89486a54e1f4bd95840147e96093edChristian Maeder#include <sys/stat.h>
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder#include <security/pam_modules.h>
85e1d54a475bfc30b3eac5ae6c5e42a2d7e93f10Christian Maeder
85e1d54a475bfc30b3eac5ae6c5e42a2d7e93f10Christian Maeder#include "util/util.h"
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder#include "util/find_uid.h"
fe495a0978e5aa70776103c37fb0eb2bd6abea69Eugen Kuksa#include "db/sysdb.h"
91e24fc45834b35f2a3830d72565640251149bf3Christian Maeder#include "providers/child_common.h"
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder#include "providers/krb5/krb5_auth.h"
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder#include "providers/krb5/krb5_utils.h"
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder#ifndef SSSD_LIBEXEC_PATH
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder#error "SSSD_LIBEXEC_PATH not defined"
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder#else
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder#define KRB5_CHILD SSSD_LIBEXEC_PATH"/krb5_child"
0130083f314580170af1195037be3325f125fbceChristian Maeder#endif
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder
0130083f314580170af1195037be3325f125fbceChristian Maederstatic errno_t check_if_ccache_file_is_used(uid_t uid, const char *ccname,
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder bool *result)
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder{
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder int ret;
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder size_t offset = 0;
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder struct stat stat_buf;
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder const char *filename;
bbba6dd86153aacb0f662b182b128df0eb09fd54Christian Maeder bool active;
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder
a461314c811f4187dff85c8be079a41b2f13f176Christian Maeder *result = false;
4eb859461f8fd904f40f57261cf23e5c73cf8ecaChristian Maeder
a31430de8b0632d29f42634d6395e982bf31b14dChristian Maeder if (ccname == NULL || *ccname == '\0') {
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder return EINVAL;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder if (strncmp(ccname, "FILE:", 5) == 0) {
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa offset = 5;
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa }
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder filename = ccname + offset;
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder
f39b8dd9651dfcc38b06191cda23cacbfc298323Christian Maeder if (filename[0] != '/') {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(1, ("Only absolute path names are allowed.\n"));
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder return EINVAL;
3a9d784341454573b50b32fa1b494e7418df3086Christian Maeder }
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ret = lstat(filename, &stat_buf);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
9d6562465b41f17c7967d4e5678f34811d958cb2Christian Maeder if (ret == -1 && errno != ENOENT) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(1, ("stat failed [%d][%s].\n", errno, strerror(errno)));
502483734c83d0bf1eadcc94113d0362f8713784Christian Maeder return errno;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder } else if (ret == EOK) {
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder if (stat_buf.st_uid != uid) {
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder DEBUG(1, ("Cache file [%s] exists, but is owned by [%d] instead of "
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder "[%d].\n", filename, stat_buf.st_uid, uid));
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder return EINVAL;
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
4eb859461f8fd904f40f57261cf23e5c73cf8ecaChristian Maeder if (!S_ISREG(stat_buf.st_mode)) {
4eb859461f8fd904f40f57261cf23e5c73cf8ecaChristian Maeder DEBUG(1, ("Cache file [%s] exists, but is not a regular file.\n",
4eb859461f8fd904f40f57261cf23e5c73cf8ecaChristian Maeder filename));
4eb859461f8fd904f40f57261cf23e5c73cf8ecaChristian Maeder return EINVAL;
4eb859461f8fd904f40f57261cf23e5c73cf8ecaChristian Maeder }
4eb859461f8fd904f40f57261cf23e5c73cf8ecaChristian Maeder }
4eb859461f8fd904f40f57261cf23e5c73cf8ecaChristian Maeder
4eb859461f8fd904f40f57261cf23e5c73cf8ecaChristian Maeder ret = check_if_uid_is_active(uid, &active);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (ret != EOK) {
2353f65833a3da763392f771223250cd50b8d873Christian Maeder DEBUG(1, ("check_if_uid_is_active failed.\n"));
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder return ret;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder if (!active) {
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa DEBUG(5, ("User [%d] is not active\n", uid));
fe495a0978e5aa70776103c37fb0eb2bd6abea69Eugen Kuksa } else {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(9, ("User [%d] is still active, reusing ccache file [%s].\n",
d81905a5b924415c524d702df26204683c82c12eChristian Maeder uid, filename));
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder *result = true;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder return EOK;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder}
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maederstatic int krb5_save_ccname(TALLOC_CTX *mem_ctx,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct sysdb_ctx *sysdb,
cb2044812811d66efe038d914966e04290be93faChristian Maeder struct sss_domain_info *domain,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder const char *name,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder const char *ccname)
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder{
0ae7a79e865d4a6022d705d160530682b3c1f825Christian Maeder TALLOC_CTX *tmpctx;
083bc1972a66d73749760eab3a90bf4eb9ca7951Christian Maeder struct sysdb_attrs *attrs;
6352f3c31da3043783a13be6594aacb2147378baRazvan Pascanu int ret;
fefee7e1dee1ee5f0768a03a4abae88d1ca2c3fdRazvan Pascanu
b324cda6178c49ddeead3ce62b832ccf644cbcabRazvan Pascanu if (name == NULL || ccname == NULL) {
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa DEBUG(1, ("Missing user or ccache name.\n"));
fefee7e1dee1ee5f0768a03a4abae88d1ca2c3fdRazvan Pascanu return EINVAL;
fe495a0978e5aa70776103c37fb0eb2bd6abea69Eugen Kuksa }
bc263f610d20a9cd3014ddfca903026127fa0d48Christian Maeder
966519955f5f7111abac20118563132b9dd41165Christian Maeder tmpctx = talloc_new(mem_ctx);
8c8545dd3bf34fbcbc16904b65d249658f8f9efcChristian Maeder if (!tmpctx) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder return ENOMEM;
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder }
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder attrs = sysdb_new_attrs(mem_ctx);
33fcc19ef2b59493b4e91eebf701df95fd230765Christian Maeder if (!attrs) {
33fcc19ef2b59493b4e91eebf701df95fd230765Christian Maeder ret = ENOMEM;
33fcc19ef2b59493b4e91eebf701df95fd230765Christian Maeder goto done;
d4ebd9e5adc974cfa2bdf4bdd155e07be0e26f75Christian Maeder }
d4ebd9e5adc974cfa2bdf4bdd155e07be0e26f75Christian Maeder
d4ebd9e5adc974cfa2bdf4bdd155e07be0e26f75Christian Maeder ret = sysdb_attrs_add_string(attrs, SYSDB_CCACHE_FILE, ccname);
7bb0a9e92bc7a6f868eaa0b9c3212c0af4f96b7fEugen Kuksa if (ret != EOK) {
7bb0a9e92bc7a6f868eaa0b9c3212c0af4f96b7fEugen Kuksa DEBUG(1, ("sysdb_attrs_add_string failed.\n"));
7bb0a9e92bc7a6f868eaa0b9c3212c0af4f96b7fEugen Kuksa goto done;
0d79ea4ed8512a802ecb6645edac141e0fbcee3fChristian Maeder }
0d79ea4ed8512a802ecb6645edac141e0fbcee3fChristian Maeder
0d79ea4ed8512a802ecb6645edac141e0fbcee3fChristian Maeder ret = sysdb_transaction_start(sysdb);
a31430de8b0632d29f42634d6395e982bf31b14dChristian Maeder if (ret != EOK) {
a31430de8b0632d29f42634d6395e982bf31b14dChristian Maeder DEBUG(6, ("Error %d starting transaction (%s)\n", ret, strerror(ret)));
a31430de8b0632d29f42634d6395e982bf31b14dChristian Maeder goto done;
31bc219bae758272d0f064281b8ce7740a4553e9Till Mossakowski }
31bc219bae758272d0f064281b8ce7740a4553e9Till Mossakowski
31bc219bae758272d0f064281b8ce7740a4553e9Till Mossakowski ret = sysdb_set_user_attr(tmpctx, sysdb,
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder domain, name, attrs, SYSDB_MOD_REP);
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder if (ret != EOK) {
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder sysdb_transaction_cancel(sysdb);
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder goto done;
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder }
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder ret = sysdb_transaction_commit(sysdb);
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder if (ret != EOK) {
9ee80c455784287a8b5e1b6bac1f8efa6a2f4bb3cmaeder DEBUG(1, ("Failed to commit transaction!\n"));
93603bd881e43d4ff5a57d7ca4e2b9fa619f25b4cmaeder }
9ee80c455784287a8b5e1b6bac1f8efa6a2f4bb3cmaeder
fb89f291c4e12ee44de11d4a900c445ed727b90dEugen Kuksadone:
fb89f291c4e12ee44de11d4a900c445ed727b90dEugen Kuksa talloc_zfree(tmpctx);
fb89f291c4e12ee44de11d4a900c445ed727b90dEugen Kuksa return ret;
8865728716566f42fa73e7e0bc080ba3225df764Christian Maeder}
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maedererrno_t create_send_buffer(struct krb5child_req *kr, struct io_buffer **io_buf)
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder{
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct io_buffer *buf;
1f2c732265a1292f0d7c51a4a7ca6be5dd370df6cmaeder size_t rp;
1f2c732265a1292f0d7c51a4a7ca6be5dd370df6cmaeder const char *keytab;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder uint32_t validate;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder keytab = dp_opt_get_cstring(kr->krb5_ctx->opts, KRB5_KEYTAB);
fdac680252d7347858bd67b4c2a2aaa52e623815Christian Maeder if (keytab == NULL) {
fdac680252d7347858bd67b4c2a2aaa52e623815Christian Maeder DEBUG(1, ("Missing keytab option.\n"));
a9e804dbec424ec36e34bab955cbe90edac5baa6Christian Maeder return EINVAL;
f8cc2399c16fcda7e3bf9d901a0de0cc8a455f86Ewaryst Schulz }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
b76d27eba526ecac2a20400fa505ec5c642ae7d2Dominik Luecke validate = dp_opt_get_bool(kr->krb5_ctx->opts, KRB5_VALIDATE) ? 1 : 0;
b76d27eba526ecac2a20400fa505ec5c642ae7d2Dominik Luecke
8a5c05062ef501bf725a86a370a5145a198e81fdKlaus Luettich buf = talloc(kr, struct io_buffer);
8a5c05062ef501bf725a86a370a5145a198e81fdKlaus Luettich if (buf == NULL) {
8a5c05062ef501bf725a86a370a5145a198e81fdKlaus Luettich DEBUG(1, ("talloc failed.\n"));
2353f65833a3da763392f771223250cd50b8d873Christian Maeder return ENOMEM;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
2353f65833a3da763392f771223250cd50b8d873Christian Maeder buf->size = 9*sizeof(uint32_t) + strlen(kr->upn) + strlen(kr->ccname) +
2353f65833a3da763392f771223250cd50b8d873Christian Maeder strlen(keytab) +
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder kr->pd->authtok_size;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (kr->pd->cmd == SSS_PAM_CHAUTHTOK) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder buf->size += sizeof(uint32_t) + kr->pd->newauthtok_size;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder buf->data = talloc_size(kr, buf->size);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (buf->data == NULL) {
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder DEBUG(1, ("talloc_size failed.\n"));
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder talloc_free(buf);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder return ENOMEM;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
00df6fd583c19393fa141d5a0e21ac74c7bf5b19Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder rp = 0;
cb2044812811d66efe038d914966e04290be93faChristian Maeder SAFEALIGN_COPY_UINT32(&buf->data[rp], &kr->pd->cmd, &rp);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder SAFEALIGN_COPY_UINT32(&buf->data[rp], &kr->uid, &rp);
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder SAFEALIGN_COPY_UINT32(&buf->data[rp], &kr->gid, &rp);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder SAFEALIGN_COPY_UINT32(&buf->data[rp], &validate, &rp);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder SAFEALIGN_COPY_UINT32(&buf->data[rp], &kr->is_offline, &rp);
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa SAFEALIGN_SET_UINT32(&buf->data[rp], strlen(kr->upn), &rp);
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa safealign_memcpy(&buf->data[rp], kr->upn, strlen(kr->upn), &rp);
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa SAFEALIGN_SET_UINT32(&buf->data[rp], strlen(kr->ccname), &rp);
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa safealign_memcpy(&buf->data[rp], kr->ccname, strlen(kr->ccname), &rp);
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa SAFEALIGN_SET_UINT32(&buf->data[rp], strlen(keytab), &rp);
8d780c893d6df5dab3dcc7d8444b7517f6547f11Christian Maeder safealign_memcpy(&buf->data[rp], keytab, strlen(keytab), &rp);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder SAFEALIGN_COPY_UINT32(&buf->data[rp], &kr->pd->authtok_size, &rp);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder safealign_memcpy(&buf->data[rp], kr->pd->authtok,
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder kr->pd->authtok_size, &rp);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (kr->pd->cmd == SSS_PAM_CHAUTHTOK) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder SAFEALIGN_COPY_UINT32(&buf->data[rp], &kr->pd->newauthtok_size, &rp);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder safealign_memcpy(&buf->data[rp], kr->pd->newauthtok,
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder kr->pd->newauthtok_size, &rp);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
bc263f610d20a9cd3014ddfca903026127fa0d48Christian Maeder *io_buf = buf;
966519955f5f7111abac20118563132b9dd41165Christian Maeder
bbba6dd86153aacb0f662b182b128df0eb09fd54Christian Maeder return EOK;
55282ad62e8b6758abec43734ebde0015ac14b89Eugen Kuksa}
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder
d96bfd1d7a4595bfff87771b91797330fa939455Christian Maederstatic struct krb5_ctx *get_krb5_ctx(struct be_req *be_req)
d96bfd1d7a4595bfff87771b91797330fa939455Christian Maeder{
8c8545dd3bf34fbcbc16904b65d249658f8f9efcChristian Maeder struct pam_data *pd;
d27b1887e61f1dc53d77c37f59dbf5019242a686Christian Maeder
34d14197eb3dd643a8e6ef3ed8cba5629528e97fAivaras Jakubauskas pd = talloc_get_type(be_req->req_data, struct pam_data);
fe495a0978e5aa70776103c37fb0eb2bd6abea69Eugen Kuksa
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder switch (pd->cmd) {
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder case SSS_PAM_AUTHENTICATE:
d4ebd9e5adc974cfa2bdf4bdd155e07be0e26f75Christian Maeder return talloc_get_type(be_req->be_ctx->bet_info[BET_AUTH].pvt_bet_data,
0d79ea4ed8512a802ecb6645edac141e0fbcee3fChristian Maeder struct krb5_ctx);
31bc219bae758272d0f064281b8ce7740a4553e9Till Mossakowski break;
a31430de8b0632d29f42634d6395e982bf31b14dChristian Maeder case SSS_PAM_CHAUTHTOK:
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder case SSS_PAM_CHAUTHTOK_PRELIM:
9ee80c455784287a8b5e1b6bac1f8efa6a2f4bb3cmaeder return talloc_get_type(be_req->be_ctx->bet_info[BET_CHPASS].pvt_bet_data,
fb89f291c4e12ee44de11d4a900c445ed727b90dEugen Kuksa struct krb5_ctx);
7bb0a9e92bc7a6f868eaa0b9c3212c0af4f96b7fEugen Kuksa break;
7bb0a9e92bc7a6f868eaa0b9c3212c0af4f96b7fEugen Kuksa default:
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(1, ("Unsupported PAM task.\n"));
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder return NULL;
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder}
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maederstatic void krb_reply(struct be_req *req, int dp_err, int result);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maederstatic int krb5_cleanup(void *ptr)
2360728d4185c0c04279c999941c64d36626af79Christian Maeder{
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder struct krb5child_req *kr = talloc_get_type(ptr, struct krb5child_req);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
00df6fd583c19393fa141d5a0e21ac74c7bf5b19Christian Maeder if (kr == NULL) return EOK;
2360728d4185c0c04279c999941c64d36626af79Christian Maeder
2360728d4185c0c04279c999941c64d36626af79Christian Maeder child_cleanup(kr->read_from_child_fd, kr->write_to_child_fd);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder memset(kr, 0, sizeof(struct krb5child_req));
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder
2360728d4185c0c04279c999941c64d36626af79Christian Maeder return EOK;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder}
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksastatic errno_t krb5_setup(TALLOC_CTX *mem_ctx, struct pam_data *pd,
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa struct krb5_ctx *krb5_ctx,
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa struct krb5child_req **krb5_req)
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa{
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa struct krb5child_req *kr = NULL;
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa kr = talloc_zero(mem_ctx, struct krb5child_req);
8d780c893d6df5dab3dcc7d8444b7517f6547f11Christian Maeder if (kr == NULL) {
2360728d4185c0c04279c999941c64d36626af79Christian Maeder DEBUG(1, ("talloc failed.\n"));
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder return ENOMEM;
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder }
2360728d4185c0c04279c999941c64d36626af79Christian Maeder kr->read_from_child_fd = -1;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder kr->write_to_child_fd = -1;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder kr->is_offline = false;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder kr->active_ccache_present = true;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder talloc_set_destructor((TALLOC_CTX *) kr, krb5_cleanup);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder kr->pd = pd;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder kr->krb5_ctx = krb5_ctx;
bc263f610d20a9cd3014ddfca903026127fa0d48Christian Maeder
966519955f5f7111abac20118563132b9dd41165Christian Maeder *krb5_req = kr;
bbba6dd86153aacb0f662b182b128df0eb09fd54Christian Maeder
55282ad62e8b6758abec43734ebde0015ac14b89Eugen Kuksa return EOK;
5a448e9be8c4482a978b174b744237757335140fChristian Maeder}
d96bfd1d7a4595bfff87771b91797330fa939455Christian Maeder
8c8545dd3bf34fbcbc16904b65d249658f8f9efcChristian Maederstruct handle_child_state {
d27b1887e61f1dc53d77c37f59dbf5019242a686Christian Maeder struct tevent_context *ev;
34d14197eb3dd643a8e6ef3ed8cba5629528e97fAivaras Jakubauskas struct krb5child_req *kr;
fe495a0978e5aa70776103c37fb0eb2bd6abea69Eugen Kuksa uint8_t *buf;
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder ssize_t len;
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder};
d4ebd9e5adc974cfa2bdf4bdd155e07be0e26f75Christian Maeder
0d79ea4ed8512a802ecb6645edac141e0fbcee3fChristian Maederstatic void krb5_child_timeout(struct tevent_context *ev,
31bc219bae758272d0f064281b8ce7740a4553e9Till Mossakowski struct tevent_timer *te,
a31430de8b0632d29f42634d6395e982bf31b14dChristian Maeder struct timeval tv, void *pvt)
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder{
9ee80c455784287a8b5e1b6bac1f8efa6a2f4bb3cmaeder struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
fb89f291c4e12ee44de11d4a900c445ed727b90dEugen Kuksa struct handle_child_state *state = tevent_req_data(req,
7bb0a9e92bc7a6f868eaa0b9c3212c0af4f96b7fEugen Kuksa struct handle_child_state);
7bb0a9e92bc7a6f868eaa0b9c3212c0af4f96b7fEugen Kuksa struct krb5child_req *kr = state->kr;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder int ret;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder if (kr->timeout_handler == NULL) {
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder return;
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder }
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder DEBUG(9, ("timeout for child [%d] reached.\n", kr->child_pid));
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder ret = kill(kr->child_pid, SIGKILL);
31bc219bae758272d0f064281b8ce7740a4553e9Till Mossakowski if (ret == -1) {
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder DEBUG(1, ("kill failed [%d][%s].\n", errno, strerror(errno)));
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder }
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder tevent_req_error(req, ETIMEDOUT);
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder}
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maederstatic errno_t activate_child_timeout_handler(struct tevent_req *req,
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder struct tevent_context *ev,
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder struct krb5child_req *kr)
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder{
fb89f291c4e12ee44de11d4a900c445ed727b90dEugen Kuksa struct timeval tv;
fb89f291c4e12ee44de11d4a900c445ed727b90dEugen Kuksa struct handle_child_state *state = tevent_req_data(req,
fb89f291c4e12ee44de11d4a900c445ed727b90dEugen Kuksa struct handle_child_state);
9ee80c455784287a8b5e1b6bac1f8efa6a2f4bb3cmaeder
9ee80c455784287a8b5e1b6bac1f8efa6a2f4bb3cmaeder tv = tevent_timeval_current();
9ee80c455784287a8b5e1b6bac1f8efa6a2f4bb3cmaeder tv = tevent_timeval_add(&tv,
cb2044812811d66efe038d914966e04290be93faChristian Maeder dp_opt_get_int(kr->krb5_ctx->opts,
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder KRB5_AUTH_TIMEOUT),
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder 0);
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder kr->timeout_handler = tevent_add_timer(ev, state, tv,
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder krb5_child_timeout, req);
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder if (kr->timeout_handler == NULL) {
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder DEBUG(1, ("tevent_add_timer failed.\n"));
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder return ENOMEM;
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder }
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder return EOK;
fe495a0978e5aa70776103c37fb0eb2bd6abea69Eugen Kuksa}
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maederstatic errno_t fork_child(struct tevent_req *req, struct tevent_context *ev,
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder struct krb5child_req *kr)
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder{
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder int pipefd_to_child[2];
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder int pipefd_from_child[2];
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder pid_t pid;
7bb0a9e92bc7a6f868eaa0b9c3212c0af4f96b7fEugen Kuksa int ret;
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder errno_t err;
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder ret = pipe(pipefd_from_child);
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder if (ret == -1) {
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder err = errno;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(1, ("pipe failed [%d][%s].\n", errno, strerror(errno)));
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder return err;
8bb80c9684e905de8dcfcfb1291542677e7d77b6Christian Maeder }
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder ret = pipe(pipefd_to_child);
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder if (ret == -1) {
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder err = errno;
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder DEBUG(1, ("pipe failed [%d][%s].\n", errno, strerror(errno)));
8bb80c9684e905de8dcfcfb1291542677e7d77b6Christian Maeder return err;
00df6fd583c19393fa141d5a0e21ac74c7bf5b19Christian Maeder }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder pid = fork();
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (pid == 0) { /* child */
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder /* We need to keep the root privileges to read the keytab file if
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder * validation is enabled, otherwise we can drop them here and run
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder * krb5_child with user privileges.
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder * If we are offline and want to create an empty ccache file. In this
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder * case we can drop the privileges, too. */
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (!dp_opt_get_bool(kr->krb5_ctx->opts, KRB5_VALIDATE) ||
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder kr->is_offline) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder ret = become_user(kr->uid, kr->gid);
60e6795dd310e10194e12bb660575aadf941328bEugen Kuksa if (ret != EOK) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(1, ("become_user failed.\n"));
bc263f610d20a9cd3014ddfca903026127fa0d48Christian Maeder return ret;
966519955f5f7111abac20118563132b9dd41165Christian Maeder }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder err = exec_child(kr,
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder pipefd_to_child, pipefd_from_child,
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder KRB5_CHILD, kr->krb5_ctx->child_debug_fd);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (err != EOK) {
cb2044812811d66efe038d914966e04290be93faChristian Maeder DEBUG(1, ("Could not exec LDAP child: [%d][%s].\n",
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder err, strerror(err)));
8d780c893d6df5dab3dcc7d8444b7517f6547f11Christian Maeder return err;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder } else if (pid > 0) { /* parent */
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder kr->child_pid = pid;
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa kr->read_from_child_fd = pipefd_from_child[0];
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa close(pipefd_from_child[1]);
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa kr->write_to_child_fd = pipefd_to_child[1];
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa close(pipefd_to_child[0]);
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa fd_nonblocking(kr->read_from_child_fd);
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa fd_nonblocking(kr->write_to_child_fd);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder ret = child_handler_setup(ev, pid, NULL, NULL);
00df6fd583c19393fa141d5a0e21ac74c7bf5b19Christian Maeder if (ret != EOK) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(1, ("Could not set up child signal handler\n"));
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder return ret;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
bbba6dd86153aacb0f662b182b128df0eb09fd54Christian Maeder err = activate_child_timeout_handler(req, ev, kr);
55282ad62e8b6758abec43734ebde0015ac14b89Eugen Kuksa if (err != EOK) {
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder DEBUG(1, ("activate_child_timeout_handler failed.\n"));
8c8545dd3bf34fbcbc16904b65d249658f8f9efcChristian Maeder }
33fcc19ef2b59493b4e91eebf701df95fd230765Christian Maeder
d27b1887e61f1dc53d77c37f59dbf5019242a686Christian Maeder } else { /* error */
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder err = errno;
fe495a0978e5aa70776103c37fb0eb2bd6abea69Eugen Kuksa DEBUG(1, ("fork failed [%d][%s].\n", errno, strerror(errno)));
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder return err;
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder }
34d14197eb3dd643a8e6ef3ed8cba5629528e97fAivaras Jakubauskas
0d79ea4ed8512a802ecb6645edac141e0fbcee3fChristian Maeder return EOK;
d4ebd9e5adc974cfa2bdf4bdd155e07be0e26f75Christian Maeder}
7bb0a9e92bc7a6f868eaa0b9c3212c0af4f96b7fEugen Kuksa
31bc219bae758272d0f064281b8ce7740a4553e9Till Mossakowskistatic void handle_child_step(struct tevent_req *subreq);
a31430de8b0632d29f42634d6395e982bf31b14dChristian Maederstatic void handle_child_done(struct tevent_req *subreq);
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder
9ee80c455784287a8b5e1b6bac1f8efa6a2f4bb3cmaederstatic struct tevent_req *handle_child_send(TALLOC_CTX *mem_ctx,
fb89f291c4e12ee44de11d4a900c445ed727b90dEugen Kuksa struct tevent_context *ev,
9b3e946be44391d35acb2168f4e67d629e560f79Till Mossakowski struct krb5child_req *kr)
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder{
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct tevent_req *req, *subreq;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct handle_child_state *state;
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder struct io_buffer *buf;
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder int ret;
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder
12aef5992d3af07dee81a4e02cf4be65a83f28bcChristian Maeder req = tevent_req_create(mem_ctx, &state, struct handle_child_state);
2360728d4185c0c04279c999941c64d36626af79Christian Maeder if (req == NULL) {
2360728d4185c0c04279c999941c64d36626af79Christian Maeder return NULL;
fe495a0978e5aa70776103c37fb0eb2bd6abea69Eugen Kuksa }
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder state->ev = ev;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder state->kr = kr;
f39b8dd9651dfcc38b06191cda23cacbfc298323Christian Maeder state->buf = NULL;
2360728d4185c0c04279c999941c64d36626af79Christian Maeder state->len = 0;
2360728d4185c0c04279c999941c64d36626af79Christian Maeder
0130083f314580170af1195037be3325f125fbceChristian Maeder ret = create_send_buffer(kr, &buf);
d81905a5b924415c524d702df26204683c82c12eChristian Maeder if (ret != EOK) {
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder DEBUG(1, ("create_send_buffer failed.\n"));
2360728d4185c0c04279c999941c64d36626af79Christian Maeder goto fail;
f39b8dd9651dfcc38b06191cda23cacbfc298323Christian Maeder }
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa ret = fork_child(req, ev, kr);
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa if (ret != EOK) {
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa DEBUG(1, ("fork_child failed.\n"));
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa goto fail;
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa }
8d780c893d6df5dab3dcc7d8444b7517f6547f11Christian Maeder
2360728d4185c0c04279c999941c64d36626af79Christian Maeder subreq = write_pipe_send(state, ev, buf->data, buf->size,
bc263f610d20a9cd3014ddfca903026127fa0d48Christian Maeder kr->write_to_child_fd);
966519955f5f7111abac20118563132b9dd41165Christian Maeder if (!subreq) {
2360728d4185c0c04279c999941c64d36626af79Christian Maeder ret = ENOMEM;
2360728d4185c0c04279c999941c64d36626af79Christian Maeder goto fail;
00df6fd583c19393fa141d5a0e21ac74c7bf5b19Christian Maeder }
2360728d4185c0c04279c999941c64d36626af79Christian Maeder tevent_req_set_callback(subreq, handle_child_step, req);
f39b8dd9651dfcc38b06191cda23cacbfc298323Christian Maeder
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder return req;
2360728d4185c0c04279c999941c64d36626af79Christian Maeder
2360728d4185c0c04279c999941c64d36626af79Christian Maederfail:
2360728d4185c0c04279c999941c64d36626af79Christian Maeder tevent_req_error(req, ret);
2360728d4185c0c04279c999941c64d36626af79Christian Maeder tevent_req_post(req, ev);
55282ad62e8b6758abec43734ebde0015ac14b89Eugen Kuksa return req;
55282ad62e8b6758abec43734ebde0015ac14b89Eugen Kuksa}
2360728d4185c0c04279c999941c64d36626af79Christian Maeder
d27b1887e61f1dc53d77c37f59dbf5019242a686Christian Maederstatic void handle_child_step(struct tevent_req *subreq)
8994ef587ce7c7c39ddd20f0f7e4575838a6694aChristian Maeder{
33fcc19ef2b59493b4e91eebf701df95fd230765Christian Maeder struct tevent_req *req = tevent_req_callback_data(subreq,
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder struct tevent_req);
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder struct handle_child_state *state = tevent_req_data(req,
31bc219bae758272d0f064281b8ce7740a4553e9Till Mossakowski struct handle_child_state);
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder int ret;
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder ret = write_pipe_recv(subreq);
7bb0a9e92bc7a6f868eaa0b9c3212c0af4f96b7fEugen Kuksa talloc_zfree(subreq);
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder if (ret != EOK) {
9ee80c455784287a8b5e1b6bac1f8efa6a2f4bb3cmaeder tevent_req_error(req, ret);
fb89f291c4e12ee44de11d4a900c445ed727b90dEugen Kuksa return;
2360728d4185c0c04279c999941c64d36626af79Christian Maeder }
2360728d4185c0c04279c999941c64d36626af79Christian Maeder
60e6795dd310e10194e12bb660575aadf941328bEugen Kuksa close(state->kr->write_to_child_fd);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder state->kr->write_to_child_fd = -1;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder subreq = read_pipe_send(state, state->ev, state->kr->read_from_child_fd);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (!subreq) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder tevent_req_error(req, ENOMEM);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder return;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder tevent_req_set_callback(subreq, handle_child_done, req);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder}
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
91e24fc45834b35f2a3830d72565640251149bf3Christian Maederstatic void handle_child_done(struct tevent_req *subreq)
91e24fc45834b35f2a3830d72565640251149bf3Christian Maeder{
91e24fc45834b35f2a3830d72565640251149bf3Christian Maeder struct tevent_req *req = tevent_req_callback_data(subreq,
91e24fc45834b35f2a3830d72565640251149bf3Christian Maeder struct tevent_req);
91e24fc45834b35f2a3830d72565640251149bf3Christian Maeder struct handle_child_state *state = tevent_req_data(req,
91e24fc45834b35f2a3830d72565640251149bf3Christian Maeder struct handle_child_state);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder int ret;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
d56ece59c372cb887355825901222b9f3377f7e6Thiemo Wiedemeyer ret = read_pipe_recv(subreq, state, &state->buf, &state->len);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder talloc_zfree(subreq);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (ret != EOK) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder tevent_req_error(req, ret);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder return;
2360728d4185c0c04279c999941c64d36626af79Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder close(state->kr->read_from_child_fd);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder state->kr->read_from_child_fd = -1;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder tevent_req_done(req);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder return;
8762d0e3d492aba4d1621fb0de685f0be1372864notanartist}
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maederstatic int handle_child_recv(struct tevent_req *req,
76d027be764e2ff61bef959efb3ac8f56499e646Christian Maeder TALLOC_CTX *mem_ctx,
9f85afecbd79b3df5a0bb17bd28cd0b288dc3213Kristina Sojakova uint8_t **buf, ssize_t *len)
a166da43d4e8f9dfa7a2651d033c6bea02627ca6Mihai Codescu{
22b772f8753f0cdb4508ba460356c238de2ee375Jonathan von Schroeder struct handle_child_state *state = tevent_req_data(req,
7bbfb15142ab4286dfc6fcde2fc94a5512297e41Jonathan von Schroeder struct handle_child_state);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder TEVENT_REQ_RETURN_ON_ERROR(req);
63da71bfb4226f504944b293fb77177ebcaea7d4Ewaryst Schulz
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder *buf = talloc_move(mem_ctx, &state->buf);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder *len = state->len;
8762d0e3d492aba4d1621fb0de685f0be1372864notanartist
af6e92e4a9ca308f928f9909acee115f801c5db5Ewaryst Schulz return EOK;
b47b1ea8a412f6e4c731779f6a572384e7cf06d8Christian Maeder}
26b1c101b72100b69045effdfaab3889de6c8c93Christian Maeder
a68ff26ddb1d300f7e16097edef615f130fcd5ceChristian Maederstatic void krb5_resolve_kdc_done(struct tevent_req *subreq);
9f226cec9f978edaba67aee4c4e04e3d3b994b87Daniel Calegaristatic void krb5_resolve_kpasswd_done(struct tevent_req *subreq);
f730570f7c284b252ad2e24cf23cc594021f9e25Jonathan von Schroederstatic void krb5_find_ccache_step(struct tevent_req *req);
6f70475dddc12732bdbef3e3dd116373e34cd6b9Christian Maederstatic void krb5_save_ccname_done(struct tevent_req *req);
897a04683fb30873e84dc3360dea770a4435971cChristian Maederstatic void krb5_child_done(struct tevent_req *req);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maederstatic void krb5_pam_handler_cache_auth_step(struct tevent_req *req);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maederstruct krb5_auth_state {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder struct tevent_context *ev;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder struct be_ctx *be_ctx;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder struct pam_data *pd;
8762d0e3d492aba4d1621fb0de685f0be1372864notanartist struct krb5_ctx *krb5_ctx;
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist struct krb5child_req *kr;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
63da71bfb4226f504944b293fb77177ebcaea7d4Ewaryst Schulz int pam_status;
76d027be764e2ff61bef959efb3ac8f56499e646Christian Maeder int dp_err;
9f85afecbd79b3df5a0bb17bd28cd0b288dc3213Kristina Sojakova};
a166da43d4e8f9dfa7a2651d033c6bea02627ca6Mihai Codescu
22b772f8753f0cdb4508ba460356c238de2ee375Jonathan von Schroederint krb5_auth_recv(struct tevent_req *req, int *pam_status, int *dp_err)
7bbfb15142ab4286dfc6fcde2fc94a5512297e41Jonathan von Schroeder{
f730570f7c284b252ad2e24cf23cc594021f9e25Jonathan von Schroeder struct krb5_auth_state *state = tevent_req_data(req, struct krb5_auth_state);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder *pam_status = state->pam_status;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder *dp_err = state->dp_err;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
8762d0e3d492aba4d1621fb0de685f0be1372864notanartist TEVENT_REQ_RETURN_ON_ERROR(req);
af6e92e4a9ca308f928f9909acee115f801c5db5Ewaryst Schulz
b47b1ea8a412f6e4c731779f6a572384e7cf06d8Christian Maeder return EOK;
26b1c101b72100b69045effdfaab3889de6c8c93Christian Maeder}
a68ff26ddb1d300f7e16097edef615f130fcd5ceChristian Maeder
9f226cec9f978edaba67aee4c4e04e3d3b994b87Daniel Calegaristruct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx,
6f70475dddc12732bdbef3e3dd116373e34cd6b9Christian Maeder struct tevent_context *ev,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct be_ctx *be_ctx,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct pam_data *pd,
2353f65833a3da763392f771223250cd50b8d873Christian Maeder struct krb5_ctx *krb5_ctx)
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist{
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist const char **attrs;
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist struct krb5_auth_state *state;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct ldb_result *res;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct krb5child_req *kr = NULL;
897a04683fb30873e84dc3360dea770a4435971cChristian Maeder const char *ccache_file = NULL;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder const char *realm;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder krb5_error_code kerr;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder struct tevent_req *req;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder struct tevent_req *subreq;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder int ret;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
8762d0e3d492aba4d1621fb0de685f0be1372864notanartist req = tevent_req_create(mem_ctx, &state, struct krb5_auth_state);
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist if (req == NULL) {
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist DEBUG(1, ("tevent_req_create failed.\n"));
8762d0e3d492aba4d1621fb0de685f0be1372864notanartist return NULL;
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist }
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist state->ev = ev;
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist state->be_ctx = be_ctx;
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist state->pd = pd;
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist state->krb5_ctx = krb5_ctx;
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist state->kr = NULL;
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist state->pam_status = PAM_SYSTEM_ERR;
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist state->dp_err = DP_ERR_FATAL;
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist switch (pd->cmd) {
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist case SSS_PAM_AUTHENTICATE:
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist case SSS_PAM_CHAUTHTOK:
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist break;
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist case SSS_PAM_CHAUTHTOK_PRELIM:
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist if (pd->priv == 1 && pd->authtok_size == 0) {
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist DEBUG(4, ("Password reset by root is not supported.\n"));
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist state->pam_status = PAM_PERM_DENIED;
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist state->dp_err = DP_ERR_OK;
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist ret = EOK;
8762d0e3d492aba4d1621fb0de685f0be1372864notanartist goto done;
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist }
df87ff823273ae2969e9d29e833845b4c0a9ee77notanartist break;
df87ff823273ae2969e9d29e833845b4c0a9ee77notanartist case SSS_PAM_ACCT_MGMT:
df87ff823273ae2969e9d29e833845b4c0a9ee77notanartist case SSS_PAM_SETCRED:
df87ff823273ae2969e9d29e833845b4c0a9ee77notanartist case SSS_PAM_OPEN_SESSION:
df87ff823273ae2969e9d29e833845b4c0a9ee77notanartist case SSS_PAM_CLOSE_SESSION:
df87ff823273ae2969e9d29e833845b4c0a9ee77notanartist state->pam_status = PAM_SUCCESS;
df87ff823273ae2969e9d29e833845b4c0a9ee77notanartist state->dp_err = DP_ERR_OK;
df87ff823273ae2969e9d29e833845b4c0a9ee77notanartist ret = EOK;
c3b00d3435293c71ab4e750be084a2d8dcf6209fnotanartist goto done;
e38219f3dd2f5711440478cbffa76ce3db530543cmaeder break;
8a5c05062ef501bf725a86a370a5145a198e81fdKlaus Luettich default:
8a5c05062ef501bf725a86a370a5145a198e81fdKlaus Luettich DEBUG(4, ("krb5 does not handles pam task %d.\n", pd->cmd));
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder state->pam_status = PAM_MODULE_UNKNOWN;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder state->dp_err = DP_ERR_OK;
2360728d4185c0c04279c999941c64d36626af79Christian Maeder ret = EOK;
8a5c05062ef501bf725a86a370a5145a198e81fdKlaus Luettich goto done;
8a5c05062ef501bf725a86a370a5145a198e81fdKlaus Luettich }
7ebcceae3d34771cae3bbb8c8060bef0b894376eChristian Maeder
8a5c05062ef501bf725a86a370a5145a198e81fdKlaus Luettich if (be_is_offline(be_ctx) &&
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder (pd->cmd == SSS_PAM_CHAUTHTOK || pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM)) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(9, ("Password changes are not possible while offline.\n"));
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder state->pam_status = PAM_AUTHINFO_UNAVAIL;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder state->dp_err = DP_ERR_OFFLINE;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder ret = EOK;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder goto done;
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist }
3ec3a22fe2b9c38a3575c98a82b4e3f988af64a6Eugen Kuksa
4c872eeb600fe8479dbda395405cf13c3d573c24Soeren D. Schulze attrs = talloc_array(state, const char *, 6);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (attrs == NULL) {
bc263f610d20a9cd3014ddfca903026127fa0d48Christian Maeder goto done;
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa }
024703c9d1326c23e307c0b0d453ed3358e87fe4cmaeder
f8cc2399c16fcda7e3bf9d901a0de0cc8a455f86Ewaryst Schulz attrs[0] = SYSDB_UPN;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder attrs[1] = SYSDB_HOMEDIR;
53a3042e1da2253fd3f103bfef4deb47fc0bf6a6Ewaryst Schulz attrs[2] = SYSDB_CCACHE_FILE;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder attrs[3] = SYSDB_UIDNUM;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder attrs[4] = SYSDB_GIDNUM;
7bb0a9e92bc7a6f868eaa0b9c3212c0af4f96b7fEugen Kuksa attrs[5] = NULL;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
726baec6dfb69adb27f2afb4b2027fe5e7670c4aTill Mossakowski ret = krb5_setup(state, pd, krb5_ctx, &state->kr);
8762d0e3d492aba4d1621fb0de685f0be1372864notanartist if (ret != EOK) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(1, ("krb5_setup failed.\n"));
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder goto done;
c30231257d9116b514dce02703a515fe21cd427dTill Mossakowski }
427ff3172ae2dfebe3c8fc972735158999997e8aChristian Maeder kr = state->kr;
e38219f3dd2f5711440478cbffa76ce3db530543cmaeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ret = sysdb_get_user_attr(state, be_ctx->sysdb, be_ctx->domain,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder state->pd->user, attrs, &res);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (ret) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(5, ("sysdb search for upn of user [%s] failed.\n", pd->user));
1f2c732265a1292f0d7c51a4a7ca6be5dd370df6cmaeder state->pam_status = PAM_SYSTEM_ERR;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder state->dp_err = DP_ERR_OK;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder goto done;
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist }
3ec3a22fe2b9c38a3575c98a82b4e3f988af64a6Eugen Kuksa
4c872eeb600fe8479dbda395405cf13c3d573c24Soeren D. Schulze realm = dp_opt_get_cstring(krb5_ctx->opts, KRB5_REALM);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (realm == NULL) {
bc263f610d20a9cd3014ddfca903026127fa0d48Christian Maeder DEBUG(1, ("Missing Kerberos realm.\n"));
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa ret = ENOENT;
024703c9d1326c23e307c0b0d453ed3358e87fe4cmaeder goto done;
f8cc2399c16fcda7e3bf9d901a0de0cc8a455f86Ewaryst Schulz }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
53a3042e1da2253fd3f103bfef4deb47fc0bf6a6Ewaryst Schulz switch (res->count) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder case 0:
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(5, ("No attributes for user [%s] found.\n", pd->user));
7bb0a9e92bc7a6f868eaa0b9c3212c0af4f96b7fEugen Kuksa ret = ENOENT;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder goto done;
726baec6dfb69adb27f2afb4b2027fe5e7670c4aTill Mossakowski break;
987bd66ac5bc367e2bbe50ce2b6355993fb335d9cmaeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder case 1:
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder kr->upn = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_UPN, NULL);
c30231257d9116b514dce02703a515fe21cd427dTill Mossakowski if (kr->upn == NULL) {
427ff3172ae2dfebe3c8fc972735158999997e8aChristian Maeder /* NOTE: this is a hack, works only in some environments */
3490b73f69b58ab742417b0867d0e2d4a7778cc0Christian Maeder kr->upn = talloc_asprintf(kr, "%s@%s", pd->user, realm);
3490b73f69b58ab742417b0867d0e2d4a7778cc0Christian Maeder if (kr->upn == NULL) {
59aa5703ac7f3b99e97cd5926e77088b256c5f40Christian Maeder DEBUG(1, ("failed to build simple upn.\n"));
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist ret = ENOMEM;
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa goto done;
7bb0a9e92bc7a6f868eaa0b9c3212c0af4f96b7fEugen Kuksa }
7bb0a9e92bc7a6f868eaa0b9c3212c0af4f96b7fEugen Kuksa DEBUG(9, ("Using simple UPN [%s].\n", kr->upn));
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder }
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder
7968d3a131e5a684ec1ff0c6d88aae638549153dChristian Maeder kr->homedir = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_HOMEDIR,
3490b73f69b58ab742417b0867d0e2d4a7778cc0Christian Maeder NULL);
78c294da55788b25e175180168371c9536a6d440Christian Maeder if (kr->homedir == NULL) {
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder DEBUG(4, ("Home directory for user [%s] not known.\n", pd->user));
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder }
8a5c05062ef501bf725a86a370a5145a198e81fdKlaus Luettich
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder kr->uid = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_UIDNUM, 0);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (kr->uid == 0) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(4, ("UID for user [%s] not known.\n", pd->user));
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist ret = ENOENT;
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder goto done;
e38219f3dd2f5711440478cbffa76ce3db530543cmaeder }
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder kr->gid = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_GIDNUM, 0);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (kr->gid == 0) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(4, ("GID for user [%s] not known.\n", pd->user));
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder ret = ENOENT;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder goto done;
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder }
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder
78c294da55788b25e175180168371c9536a6d440Christian Maeder ccache_file = ldb_msg_find_attr_as_string(res->msgs[0],
e38219f3dd2f5711440478cbffa76ce3db530543cmaeder SYSDB_CCACHE_FILE,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder NULL);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (ccache_file != NULL) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder ret = check_if_ccache_file_is_used(kr->uid, ccache_file,
78c294da55788b25e175180168371c9536a6d440Christian Maeder &kr->active_ccache_present);
78c294da55788b25e175180168371c9536a6d440Christian Maeder if (ret != EOK) {
bc263f610d20a9cd3014ddfca903026127fa0d48Christian Maeder DEBUG(1, ("check_if_ccache_file_is_used failed.\n"));
511284753313165e629cedf508752d6818ccc4d2Christian Maeder goto done;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
78c294da55788b25e175180168371c9536a6d440Christian Maeder kerr = check_for_valid_tgt(ccache_file, realm, kr->upn,
78c294da55788b25e175180168371c9536a6d440Christian Maeder &kr->valid_tgt_present);
78c294da55788b25e175180168371c9536a6d440Christian Maeder if (kerr != 0) {
78c294da55788b25e175180168371c9536a6d440Christian Maeder DEBUG(1, ("check_for_valid_tgt failed.\n"));
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ret = kerr;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder goto done;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder } else {
e38219f3dd2f5711440478cbffa76ce3db530543cmaeder kr->active_ccache_present = false;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder kr->valid_tgt_present = false;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(4, ("No ccache file for user [%s] found.\n", pd->user));
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(9, ("Ccache_file is [%s] and is %s active and TGT is %s valid.\n",
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ccache_file ? ccache_file : "not set",
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder kr->active_ccache_present ? "" : "not",
8865728716566f42fa73e7e0bc080ba3225df764Christian Maeder kr->valid_tgt_present ? "" : "not"));
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder kr->ccname = ccache_file;
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder break;
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder default:
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(1, ("User search for (%s) returned > 1 results!\n", pd->user));
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder ret = EINVAL;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder goto done;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder break;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
8bb80c9684e905de8dcfcfb1291542677e7d77b6Christian Maeder
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder kr->srv = NULL;
91ba5d95b2472cb075646b6120a559dc6581a867Christian Maeder kr->kpasswd_srv = NULL;
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder subreq = be_resolve_server_send(state, state->ev, state->be_ctx,
91ba5d95b2472cb075646b6120a559dc6581a867Christian Maeder krb5_ctx->service->name);
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder if (req == NULL) {
60e6795dd310e10194e12bb660575aadf941328bEugen Kuksa DEBUG(1, ("be_resolve_server_send failed.\n"));
60e6795dd310e10194e12bb660575aadf941328bEugen Kuksa ret = ENOMEM;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder goto done;
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder tevent_req_set_callback(subreq, krb5_resolve_kdc_done, req);
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder
91ba5d95b2472cb075646b6120a559dc6581a867Christian Maeder return req;
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder
91ba5d95b2472cb075646b6120a559dc6581a867Christian Maederdone:
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder if (ret == EOK) {
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder tevent_req_done(req);
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder } else {
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder tevent_req_error(req, ret);
fe495a0978e5aa70776103c37fb0eb2bd6abea69Eugen Kuksa }
fe495a0978e5aa70776103c37fb0eb2bd6abea69Eugen Kuksa tevent_req_post(req, state->ev);
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder return req;
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder}
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder
31bc219bae758272d0f064281b8ce7740a4553e9Till Mossakowskistatic void krb5_resolve_kdc_done(struct tevent_req *subreq)
31bc219bae758272d0f064281b8ce7740a4553e9Till Mossakowski{
a31430de8b0632d29f42634d6395e982bf31b14dChristian Maeder struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req);
a31430de8b0632d29f42634d6395e982bf31b14dChristian Maeder struct krb5_auth_state *state = tevent_req_data(req, struct krb5_auth_state);
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder struct krb5child_req *kr = state->kr;
f03420e44d8204b2945edaab5c70a84e7c381892Christian Maeder int ret;
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder ret = be_resolve_server_recv(subreq, &kr->srv);
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder talloc_zfree(subreq);
91ba5d95b2472cb075646b6120a559dc6581a867Christian Maeder if (ret) {
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder /* all servers have been tried and none
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder * was found good, setting offline,
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder * but we still have to call the child to setup
91ba5d95b2472cb075646b6120a559dc6581a867Christian Maeder * the ccache file. */
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder be_mark_offline(state->be_ctx);
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder kr->is_offline = true;
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder } else {
f03420e44d8204b2945edaab5c70a84e7c381892Christian Maeder if (state->pd->cmd == SSS_PAM_CHAUTHTOK &&
7bb0a9e92bc7a6f868eaa0b9c3212c0af4f96b7fEugen Kuksa kr->krb5_ctx->kpasswd_service != NULL) {
7bb0a9e92bc7a6f868eaa0b9c3212c0af4f96b7fEugen Kuksa subreq = be_resolve_server_send(state, state->ev, state->be_ctx,
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder kr->krb5_ctx->kpasswd_service->name);
d81905a5b924415c524d702df26204683c82c12eChristian Maeder if (req == NULL) {
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder DEBUG(1, ("be_resolve_server_send failed.\n"));
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder ret = ENOMEM;
f03420e44d8204b2945edaab5c70a84e7c381892Christian Maeder goto failed;
f03420e44d8204b2945edaab5c70a84e7c381892Christian Maeder }
f03420e44d8204b2945edaab5c70a84e7c381892Christian Maeder
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder tevent_req_set_callback(subreq, krb5_resolve_kpasswd_done, req);
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder return;
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder }
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder }
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder krb5_find_ccache_step(req);
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder return;
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maederfailed:
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder tevent_req_error(req, ret);
f03420e44d8204b2945edaab5c70a84e7c381892Christian Maeder}
f03420e44d8204b2945edaab5c70a84e7c381892Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maederstatic void krb5_resolve_kpasswd_done(struct tevent_req *subreq)
818b228955ef40dd5a253bd942dd6ab8779ed713Christian Maeder{
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req);
bbba6dd86153aacb0f662b182b128df0eb09fd54Christian Maeder struct krb5_auth_state *state = tevent_req_data(req, struct krb5_auth_state);
55282ad62e8b6758abec43734ebde0015ac14b89Eugen Kuksa int ret;
55282ad62e8b6758abec43734ebde0015ac14b89Eugen Kuksa
55282ad62e8b6758abec43734ebde0015ac14b89Eugen Kuksa ret = be_resolve_server_recv(subreq, &state->kr->kpasswd_srv);
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder talloc_zfree(req);
353187efd08a2cb65226f414f192b59d312f27acChristian Maeder if (ret) {
8c8545dd3bf34fbcbc16904b65d249658f8f9efcChristian Maeder /* all kpasswd servers have been tried and none was found good, but the
33fcc19ef2b59493b4e91eebf701df95fd230765Christian Maeder * kdc seems ok. Password changes are not possible but
d4ebd9e5adc974cfa2bdf4bdd155e07be0e26f75Christian Maeder * authentication. We return an PAM error here, but do not mark the
7bb0a9e92bc7a6f868eaa0b9c3212c0af4f96b7fEugen Kuksa * backend offline. */
0d79ea4ed8512a802ecb6645edac141e0fbcee3fChristian Maeder state->pam_status = PAM_AUTHTOK_LOCK_BUSY;
9ee80c455784287a8b5e1b6bac1f8efa6a2f4bb3cmaeder state->dp_err = DP_ERR_OK;
9ee80c455784287a8b5e1b6bac1f8efa6a2f4bb3cmaeder tevent_req_done(req);
fb89f291c4e12ee44de11d4a900c445ed727b90dEugen Kuksa return;
fb89f291c4e12ee44de11d4a900c445ed727b90dEugen Kuksa }
fb89f291c4e12ee44de11d4a900c445ed727b90dEugen Kuksa
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder krb5_find_ccache_step(req);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder}
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder
4a2f7efdf67dfcda0946f1b6373f41976ddea7a4Christian Maederstatic void krb5_find_ccache_step(struct tevent_req *req)
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder{
3490b73f69b58ab742417b0867d0e2d4a7778cc0Christian Maeder struct krb5_auth_state *state = tevent_req_data(req, struct krb5_auth_state);
7968d3a131e5a684ec1ff0c6d88aae638549153dChristian Maeder int ret;
7968d3a131e5a684ec1ff0c6d88aae638549153dChristian Maeder struct krb5child_req *kr = state->kr;
3490b73f69b58ab742417b0867d0e2d4a7778cc0Christian Maeder struct pam_data *pd = kr->pd;
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder char *msg;
78c294da55788b25e175180168371c9536a6d440Christian Maeder size_t offset = 0;
1f2c732265a1292f0d7c51a4a7ca6be5dd370df6cmaeder bool private_path = false;
ab2f38d9cd1249f6bc9cc5b838dc2fcd76189c0fChristian Maeder struct tevent_req *subreq = NULL;
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa /* The ccache file should be (re)created if one of the following conditions
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa * is true:
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa * - it doesn't exist (kr->ccname == NULL)
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa * - the backend is online and the current ccache file is not used, i.e
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa * the related user is currently not logged in
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa * (!be_is_offline(state->be_ctx) && !kr->active_ccache_present)
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa * - the backend is offline and the current cache file not used and
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa * it does not contain a valid tgt
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa * (be_is_offline(state->be_ctx) &&
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa * !kr->active_ccache_present && !kr->valid_tgt_present)
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa */
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa if (kr->ccname == NULL ||
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa (be_is_offline(state->be_ctx) && !kr->active_ccache_present &&
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa !kr->valid_tgt_present) ||
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa (!be_is_offline(state->be_ctx) && !kr->active_ccache_present)) {
8d780c893d6df5dab3dcc7d8444b7517f6547f11Christian Maeder DEBUG(9, ("Recreating ccache file.\n"));
8d780c893d6df5dab3dcc7d8444b7517f6547f11Christian Maeder if (kr->ccname != NULL) {
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder if (strncmp(kr->ccname, "FILE:", 5) == 0) {
083bc1972a66d73749760eab3a90bf4eb9ca7951Christian Maeder offset = 5;
bc263f610d20a9cd3014ddfca903026127fa0d48Christian Maeder }
bc263f610d20a9cd3014ddfca903026127fa0d48Christian Maeder if (kr->ccname[offset] != '/') {
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder DEBUG(1, ("Ccache file name [%s] is not an absolute path.\n",
966519955f5f7111abac20118563132b9dd41165Christian Maeder kr->ccname + offset));
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder ret = EINVAL;
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder goto done;
00df6fd583c19393fa141d5a0e21ac74c7bf5b19Christian Maeder }
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder ret = unlink(kr->ccname + offset);
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder if (ret == -1 && errno != ENOENT) {
0ae7a79e865d4a6022d705d160530682b3c1f825Christian Maeder ret = errno;
f03420e44d8204b2945edaab5c70a84e7c381892Christian Maeder DEBUG(1, ("unlink [%s] failed [%d][%s].\n", kr->ccname, ret,
0ae7a79e865d4a6022d705d160530682b3c1f825Christian Maeder strerror(ret)));
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder goto done;
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder }
34d14197eb3dd643a8e6ef3ed8cba5629528e97fAivaras Jakubauskas }
34d14197eb3dd643a8e6ef3ed8cba5629528e97fAivaras Jakubauskas kr->ccname = expand_ccname_template(kr, kr,
34d14197eb3dd643a8e6ef3ed8cba5629528e97fAivaras Jakubauskas dp_opt_get_cstring(kr->krb5_ctx->opts,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder KRB5_CCNAME_TMPL),
0a26144c20fa9cdcd05011ca5019cbac8e4afae0cmaeder true, &private_path);
0a26144c20fa9cdcd05011ca5019cbac8e4afae0cmaeder if (kr->ccname == NULL) {
0a26144c20fa9cdcd05011ca5019cbac8e4afae0cmaeder DEBUG(1, ("expand_ccname_template failed.\n"));
0a26144c20fa9cdcd05011ca5019cbac8e4afae0cmaeder ret = ENOMEM;
0a26144c20fa9cdcd05011ca5019cbac8e4afae0cmaeder goto done;
0a26144c20fa9cdcd05011ca5019cbac8e4afae0cmaeder }
0a26144c20fa9cdcd05011ca5019cbac8e4afae0cmaeder
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder ret = create_ccache_dir(kr, kr->ccname,
01a143ff12e858a18437e18aab76b32f5bbb18c4cmaeder kr->krb5_ctx->illegal_path_re,
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder kr->uid, kr->gid, private_path);
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder if (ret != EOK) {
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder DEBUG(1, ("create_ccache_dir failed.\n"));
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder goto done;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (be_is_offline(state->be_ctx)) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(9, ("Preparing for offline operation.\n"));
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder kr->is_offline = true;
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder if (kr->valid_tgt_present || kr->active_ccache_present) {
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder DEBUG(9, ("Valid TGT available or "
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder "ccache file is already in use.\n"));
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder msg = talloc_asprintf(pd, "%s=%s", CCACHE_ENV_NAME, kr->ccname);
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder if (msg == NULL) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(1, ("talloc_asprintf failed.\n"));
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder } else {
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder ret = pam_add_response(pd, SSS_PAM_ENV_ITEM, strlen(msg) + 1,
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder (uint8_t *) msg);
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder if (ret != EOK) {
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder DEBUG(1, ("pam_add_response failed.\n"));
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder }
fefee7e1dee1ee5f0768a03a4abae88d1ca2c3fdRazvan Pascanu }
fefee7e1dee1ee5f0768a03a4abae88d1ca2c3fdRazvan Pascanu
fefee7e1dee1ee5f0768a03a4abae88d1ca2c3fdRazvan Pascanu if (dp_opt_get_bool(kr->krb5_ctx->opts,
fefee7e1dee1ee5f0768a03a4abae88d1ca2c3fdRazvan Pascanu KRB5_STORE_PASSWORD_IF_OFFLINE)) {
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder krb5_pam_handler_cache_auth_step(req);
fefee7e1dee1ee5f0768a03a4abae88d1ca2c3fdRazvan Pascanu return;
9308cb2aebeae23f49713896e6d7028b0ac0f83enotanartist }
2360728d4185c0c04279c999941c64d36626af79Christian Maeder
fefee7e1dee1ee5f0768a03a4abae88d1ca2c3fdRazvan Pascanu state->pam_status = PAM_AUTHINFO_UNAVAIL;
fefee7e1dee1ee5f0768a03a4abae88d1ca2c3fdRazvan Pascanu state->dp_err = DP_ERR_OFFLINE;
fefee7e1dee1ee5f0768a03a4abae88d1ca2c3fdRazvan Pascanu ret = EOK;
66a774f13272fde036481edd2298081ab3d04678Razvan Pascanu goto done;
9308cb2aebeae23f49713896e6d7028b0ac0f83enotanartist
2360728d4185c0c04279c999941c64d36626af79Christian Maeder }
66a774f13272fde036481edd2298081ab3d04678Razvan Pascanu }
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder subreq = handle_child_send(state, state->ev, kr);
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder if (subreq == NULL) {
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder DEBUG(1, ("handle_child_send failed.\n"));
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder ret = ENOMEM;
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder goto done;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
9dd71ac51c9a6e72bcb126224f9c64131698b636Christian Maeder tevent_req_set_callback(subreq, krb5_child_done, req);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder return;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maederdone:
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder if (ret == EOK) {
0ea2cddb8715a770e646895e16b7b8085f49167cChristian Maeder tevent_req_done(req);
0ea2cddb8715a770e646895e16b7b8085f49167cChristian Maeder } else {
7245138e91992b96b153b8ac527e263d9dc8ff5bChristian Maeder tevent_req_error(req, ret);
7245138e91992b96b153b8ac527e263d9dc8ff5bChristian Maeder }
7245138e91992b96b153b8ac527e263d9dc8ff5bChristian Maeder}
7245138e91992b96b153b8ac527e263d9dc8ff5bChristian Maeder
7245138e91992b96b153b8ac527e263d9dc8ff5bChristian Maederstatic struct tevent_req *krb5_next_server(struct tevent_req *req);
0ea2cddb8715a770e646895e16b7b8085f49167cChristian Maederstatic struct tevent_req *krb5_next_kdc(struct tevent_req *req);
7968d3a131e5a684ec1ff0c6d88aae638549153dChristian Maederstatic struct tevent_req *krb5_next_kpasswd(struct tevent_req *req);
7968d3a131e5a684ec1ff0c6d88aae638549153dChristian Maeder
7968d3a131e5a684ec1ff0c6d88aae638549153dChristian Maederstatic void krb5_child_done(struct tevent_req *subreq)
7968d3a131e5a684ec1ff0c6d88aae638549153dChristian Maeder{
a461314c811f4187dff85c8be079a41b2f13f176Christian Maeder struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req);
a461314c811f4187dff85c8be079a41b2f13f176Christian Maeder struct krb5_auth_state *state = tevent_req_data(req, struct krb5_auth_state);
a461314c811f4187dff85c8be079a41b2f13f176Christian Maeder
a461314c811f4187dff85c8be079a41b2f13f176Christian Maeder struct krb5child_req *kr = state->kr;
a461314c811f4187dff85c8be079a41b2f13f176Christian Maeder struct pam_data *pd = state->pd;
a461314c811f4187dff85c8be079a41b2f13f176Christian Maeder int ret;
0130083f314580170af1195037be3325f125fbceChristian Maeder uint8_t *buf = NULL;
0130083f314580170af1195037be3325f125fbceChristian Maeder ssize_t len = -1;
c770b05f3d85f8eeb25ba15f7192044f9dd534ddSoeren D. Schulze ssize_t pref_len;
c770b05f3d85f8eeb25ba15f7192044f9dd534ddSoeren D. Schulze size_t p;
c770b05f3d85f8eeb25ba15f7192044f9dd534ddSoeren D. Schulze int32_t msg_status;
c770b05f3d85f8eeb25ba15f7192044f9dd534ddSoeren D. Schulze int32_t msg_type;
c770b05f3d85f8eeb25ba15f7192044f9dd534ddSoeren D. Schulze int32_t msg_len;
c770b05f3d85f8eeb25ba15f7192044f9dd534ddSoeren D. Schulze
0130083f314580170af1195037be3325f125fbceChristian Maeder ret = handle_child_recv(subreq, pd, &buf, &len);
0130083f314580170af1195037be3325f125fbceChristian Maeder talloc_zfree(kr->timeout_handler);
0130083f314580170af1195037be3325f125fbceChristian Maeder talloc_zfree(subreq);
0130083f314580170af1195037be3325f125fbceChristian Maeder if (ret != EOK) {
0130083f314580170af1195037be3325f125fbceChristian Maeder DEBUG(1, ("child failed (%d [%s])\n", ret, strerror(ret)));
0130083f314580170af1195037be3325f125fbceChristian Maeder if (ret == ETIMEDOUT) {
0130083f314580170af1195037be3325f125fbceChristian Maeder if (krb5_next_server(req) == NULL) {
057b3bffc58757a98e8e7c1aeaf5cbbc986b3117Christian Maeder tevent_req_error(req, ENOMEM);
3bcd9d942601d59dd55a6069d8b2d1c33d7ced0eChristian Maeder }
3bcd9d942601d59dd55a6069d8b2d1c33d7ced0eChristian Maeder } else {
057b3bffc58757a98e8e7c1aeaf5cbbc986b3117Christian Maeder tevent_req_error(req, ret);
c770b05f3d85f8eeb25ba15f7192044f9dd534ddSoeren D. Schulze }
c770b05f3d85f8eeb25ba15f7192044f9dd534ddSoeren D. Schulze return;
c770b05f3d85f8eeb25ba15f7192044f9dd534ddSoeren D. Schulze }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
9d6562465b41f17c7967d4e5678f34811d958cb2Christian Maeder /* A buffer with the following structure is expected.
9d6562465b41f17c7967d4e5678f34811d958cb2Christian Maeder * int32_t status of the request (required)
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder * message (zero or more)
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder *
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder * A message consists of:
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder * int32_t type of the message
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder * int32_t length of the following data
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder * uint8_t[len] data
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder */
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if ((size_t) len < sizeof(int32_t)) {
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder DEBUG(1, ("message too short.\n"));
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder ret = EINVAL;
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder goto done;
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder }
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder p=0;
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder SAFEALIGN_COPY_INT32(&msg_status, buf+p, &p);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder while (p < len) {
93bc87ee96c68506945dbad8c704badaa42ecf14Christian Maeder SAFEALIGN_COPY_INT32(&msg_type, buf+p, &p);
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder SAFEALIGN_COPY_INT32(&msg_len, buf+p, &p);
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder DEBUG(9, ("child response [%d][%d][%d].\n", msg_status, msg_type,
3bcd9d942601d59dd55a6069d8b2d1c33d7ced0eChristian Maeder msg_len));
9db2bd64088c7e5935b94dd9c3ad5cdc24f48814Christian Maeder
0a64bfd28dff15bc93e1f7a86e0a8052e879636dChristian Maeder if ((p + msg_len) > len) {
0a64bfd28dff15bc93e1f7a86e0a8052e879636dChristian Maeder DEBUG(1, ("message format error [%d] > [%d].\n", p+msg_len, len));
0a64bfd28dff15bc93e1f7a86e0a8052e879636dChristian Maeder ret = EINVAL;
0a64bfd28dff15bc93e1f7a86e0a8052e879636dChristian Maeder goto done;
0a64bfd28dff15bc93e1f7a86e0a8052e879636dChristian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder /* We need to save the name of the credential cache file. To find it
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder * we check if the data part of a message starts with
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder * CCACHE_ENV_NAME"=". pref_len also counts the trailing '=' because
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder * sizeof() counts the trailing '\0' of a string. */
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder pref_len = sizeof(CCACHE_ENV_NAME);
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder if (msg_len > pref_len &&
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder strncmp((const char *) &buf[p], CCACHE_ENV_NAME"=", pref_len) == 0) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder kr->ccname = talloc_strndup(kr, (char *) &buf[p+pref_len],
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder msg_len-pref_len);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (kr->ccname == NULL) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(1, ("talloc_strndup failed.\n"));
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ret = ENOMEM;
2353f65833a3da763392f771223250cd50b8d873Christian Maeder goto done;
2353f65833a3da763392f771223250cd50b8d873Christian Maeder }
9308cb2aebeae23f49713896e6d7028b0ac0f83enotanartist }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ret = pam_add_response(pd, msg_type, msg_len, &buf[p]);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (ret != EOK) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder /* This is not a fatal error */
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(1, ("pam_add_response failed.\n"));
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder p += msg_len;
9308cb2aebeae23f49713896e6d7028b0ac0f83enotanartist
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if ((p < len) && (p + 2*sizeof(int32_t) >= len)) {
2353f65833a3da763392f771223250cd50b8d873Christian Maeder DEBUG(1, ("The remainder of the message is too short.\n"));
00df6fd583c19393fa141d5a0e21ac74c7bf5b19Christian Maeder ret = EINVAL;
00df6fd583c19393fa141d5a0e21ac74c7bf5b19Christian Maeder goto done;
00df6fd583c19393fa141d5a0e21ac74c7bf5b19Christian Maeder }
f39b8dd9651dfcc38b06191cda23cacbfc298323Christian Maeder }
528539f3d544c24afe14e979fe51f03e50aa6e9cChristian Maeder
0ae7a79e865d4a6022d705d160530682b3c1f825Christian Maeder /* If the child request failed, but did not return an offline error code,
863d4b011d04907325f3eed8e89975e38603cb05Christian Maeder * return with the status */
0ae7a79e865d4a6022d705d160530682b3c1f825Christian Maeder if (msg_status != PAM_SUCCESS && msg_status != PAM_AUTHINFO_UNAVAIL &&
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder msg_status != PAM_AUTHTOK_LOCK_BUSY) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder state->pam_status = msg_status;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder state->dp_err = DP_ERR_OK;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder ret = EOK;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder goto done;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder } else {
59a10395caff224b2ec541f94dac5082a506c00fChristian Maeder state->pam_status = msg_status;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder /* If the child request was successful and we run the first pass of the
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder * change password request just return success. */
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (msg_status == PAM_SUCCESS && pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder state->pam_status = PAM_SUCCESS;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder state->dp_err = DP_ERR_OK;
2353f65833a3da763392f771223250cd50b8d873Christian Maeder ret = EOK;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder goto done;
9308cb2aebeae23f49713896e6d7028b0ac0f83enotanartist }
2353f65833a3da763392f771223250cd50b8d873Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder /* if using a dedicated kpasswd server.. */
12aef5992d3af07dee81a4e02cf4be65a83f28bcChristian Maeder if (kr->kpasswd_srv != NULL) {
12aef5992d3af07dee81a4e02cf4be65a83f28bcChristian Maeder /* ..which is unreachable by now.. */
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (msg_status == PAM_AUTHTOK_LOCK_BUSY) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder fo_set_port_status(kr->kpasswd_srv, PORT_NOT_WORKING);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder /* ..try to resolve next kpasswd server */
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (krb5_next_kpasswd(req) == NULL) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder tevent_req_error(req, ENOMEM);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder return;
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder } else {
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder fo_set_port_status(kr->kpasswd_srv, PORT_WORKING);
057b3bffc58757a98e8e7c1aeaf5cbbc986b3117Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa
057b3bffc58757a98e8e7c1aeaf5cbbc986b3117Christian Maeder /* if the KDC for auth (PAM_AUTHINFO_UNAVAIL) or
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa * chpass (PAM_AUTHTOK_LOCK_BUSY) was not available while using KDC
502483734c83d0bf1eadcc94113d0362f8713784Christian Maeder * also for chpass operation... */
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa if (msg_status == PAM_AUTHINFO_UNAVAIL ||
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa (kr->kpasswd_srv == NULL && msg_status == PAM_AUTHTOK_LOCK_BUSY)) {
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa if (kr->srv != NULL) {
649fdc0d0502d62d160c150684356fef2c273484Eugen Kuksa fo_set_port_status(kr->srv, PORT_NOT_WORKING);
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa /* ..try to resolve next KDC */
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa if (krb5_next_kdc(req) == NULL) {
649fdc0d0502d62d160c150684356fef2c273484Eugen Kuksa tevent_req_error(req, ENOMEM);
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa }
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa return;
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa }
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa } else if (kr->srv != NULL) {
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa fo_set_port_status(kr->srv, PORT_WORKING);
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa }
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa /* The following cases are left now:
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa * - offline (msg_status == PAM_AUTHINFO_UNAVAIL or
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa * msg_status == PAM_AUTHTOK_LOCK_BUSY)
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa * - successful authentication or password change
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa *
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa * For all these cases we expect that one of the messages for the
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa * received buffer contains the name of the credential cache file. */
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa if (kr->ccname == NULL) {
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa DEBUG(1, ("Missing ccache name in child response.\n"));
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa ret = EINVAL;
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa goto done;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
fe495a0978e5aa70776103c37fb0eb2bd6abea69Eugen Kuksa
fe495a0978e5aa70776103c37fb0eb2bd6abea69Eugen Kuksa struct sysdb_attrs *attrs;
fe495a0978e5aa70776103c37fb0eb2bd6abea69Eugen Kuksa attrs = sysdb_new_attrs(state);
fe495a0978e5aa70776103c37fb0eb2bd6abea69Eugen Kuksa ret = sysdb_attrs_add_string(attrs, SYSDB_CCACHE_FILE, kr->ccname);
fe495a0978e5aa70776103c37fb0eb2bd6abea69Eugen Kuksa if (ret != EOK) {
fe495a0978e5aa70776103c37fb0eb2bd6abea69Eugen Kuksa DEBUG(1, ("sysdb_attrs_add_string failed.\n"));
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder goto done;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder ret = krb5_save_ccname(state, state->be_ctx->sysdb,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder state->be_ctx->domain,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder pd->user, kr->ccname);
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder if (ret) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(1, ("krb5_save_ccname_send failed.\n"));
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder goto done;
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder }
60e6795dd310e10194e12bb660575aadf941328bEugen Kuksa
afb32b54f3e87b51c5a6242040022f497f7f20abChristian Maeder krb5_save_ccname_done(req);
60e6795dd310e10194e12bb660575aadf941328bEugen Kuksa return;
60e6795dd310e10194e12bb660575aadf941328bEugen Kuksa
60e6795dd310e10194e12bb660575aadf941328bEugen Kuksadone:
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder if (ret == EOK) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder tevent_req_done(req);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder } else {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder tevent_req_error(req, ret);
2353f65833a3da763392f771223250cd50b8d873Christian Maeder }
4b1833c7d3af466e6bcba24f16304e0a78e8da87Christian Maeder}
fba4eac6b080849889892e1e273ac4c74ddde840Christian Maeder
4347b243063d414f97a68b64e30a4f27a612af0aChristian Maederstatic struct tevent_req *krb5_next_server(struct tevent_req *req)
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder{
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct krb5_auth_state *state = tevent_req_data(req, struct krb5_auth_state);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct pam_data *pd = state->pd;
2353f65833a3da763392f771223250cd50b8d873Christian Maeder struct tevent_req *next_req = NULL;
2353f65833a3da763392f771223250cd50b8d873Christian Maeder
9d6562465b41f17c7967d4e5678f34811d958cb2Christian Maeder switch (pd->cmd) {
9d6562465b41f17c7967d4e5678f34811d958cb2Christian Maeder case SSS_PAM_AUTHENTICATE:
502483734c83d0bf1eadcc94113d0362f8713784Christian Maeder fo_set_port_status(state->kr->srv, PORT_NOT_WORKING);
9d6562465b41f17c7967d4e5678f34811d958cb2Christian Maeder next_req = krb5_next_kdc(req);
9d6562465b41f17c7967d4e5678f34811d958cb2Christian Maeder break;
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder case SSS_PAM_CHAUTHTOK:
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder case SSS_PAM_CHAUTHTOK_PRELIM:
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder if (state->kr->kpasswd_srv) {
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder fo_set_port_status(state->kr->kpasswd_srv, PORT_NOT_WORKING);
9d6562465b41f17c7967d4e5678f34811d958cb2Christian Maeder next_req = krb5_next_kpasswd(req);
2353f65833a3da763392f771223250cd50b8d873Christian Maeder break;
dbc98cd8a9a829e020cfa0a9f3aff89de75caaa9Christian Maeder } else {
2353f65833a3da763392f771223250cd50b8d873Christian Maeder fo_set_port_status(state->kr->srv, PORT_NOT_WORKING);
cb2044812811d66efe038d914966e04290be93faChristian Maeder next_req = krb5_next_kdc(req);
cb2044812811d66efe038d914966e04290be93faChristian Maeder break;
9d6562465b41f17c7967d4e5678f34811d958cb2Christian Maeder }
0130083f314580170af1195037be3325f125fbceChristian Maeder default:
0130083f314580170af1195037be3325f125fbceChristian Maeder DEBUG(1, ("Unexpected PAM task\n"));
502483734c83d0bf1eadcc94113d0362f8713784Christian Maeder }
cb2044812811d66efe038d914966e04290be93faChristian Maeder
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder return next_req;
0130083f314580170af1195037be3325f125fbceChristian Maeder}
0130083f314580170af1195037be3325f125fbceChristian Maeder
7bb0a9e92bc7a6f868eaa0b9c3212c0af4f96b7fEugen Kuksastatic struct tevent_req *krb5_next_kdc(struct tevent_req *req)
7bb0a9e92bc7a6f868eaa0b9c3212c0af4f96b7fEugen Kuksa{
7bb0a9e92bc7a6f868eaa0b9c3212c0af4f96b7fEugen Kuksa struct tevent_req *next_req;
7bb0a9e92bc7a6f868eaa0b9c3212c0af4f96b7fEugen Kuksa struct krb5_auth_state *state = tevent_req_data(req, struct krb5_auth_state);
0130083f314580170af1195037be3325f125fbceChristian Maeder
0130083f314580170af1195037be3325f125fbceChristian Maeder next_req = be_resolve_server_send(state, state->ev,
0130083f314580170af1195037be3325f125fbceChristian Maeder state->be_ctx,
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder state->krb5_ctx->service->name);
cb2044812811d66efe038d914966e04290be93faChristian Maeder if (next_req == NULL) {
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder DEBUG(1, ("be_resolve_server_send failed.\n"));
0130083f314580170af1195037be3325f125fbceChristian Maeder return NULL;
502483734c83d0bf1eadcc94113d0362f8713784Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder tevent_req_set_callback(next_req, krb5_resolve_kdc_done, req);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder return next_req;
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder}
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder
502483734c83d0bf1eadcc94113d0362f8713784Christian Maederstatic struct tevent_req *krb5_next_kpasswd(struct tevent_req *req)
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder{
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder struct tevent_req *next_req;
2353f65833a3da763392f771223250cd50b8d873Christian Maeder struct krb5_auth_state *state = tevent_req_data(req, struct krb5_auth_state);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder next_req = be_resolve_server_send(state, state->ev,
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder state->be_ctx,
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder state->krb5_ctx->kpasswd_service->name);
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder if (next_req == NULL) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(1, ("be_resolve_server_send failed.\n"));
2360728d4185c0c04279c999941c64d36626af79Christian Maeder return NULL;
cb2044812811d66efe038d914966e04290be93faChristian Maeder }
2360728d4185c0c04279c999941c64d36626af79Christian Maeder tevent_req_set_callback(next_req, krb5_resolve_kpasswd_done, req);
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder return next_req;
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder}
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maederstatic void krb5_save_ccname_done(struct tevent_req *req)
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder{
8c8545dd3bf34fbcbc16904b65d249658f8f9efcChristian Maeder struct krb5_auth_state *state = tevent_req_data(req, struct krb5_auth_state);
8c8545dd3bf34fbcbc16904b65d249658f8f9efcChristian Maeder struct krb5child_req *kr = state->kr;
8c8545dd3bf34fbcbc16904b65d249658f8f9efcChristian Maeder struct pam_data *pd = state->pd;
8c8545dd3bf34fbcbc16904b65d249658f8f9efcChristian Maeder int ret;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder char *password = NULL;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (kr->is_offline) {
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder if (dp_opt_get_bool(kr->krb5_ctx->opts,KRB5_STORE_PASSWORD_IF_OFFLINE)) {
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder krb5_pam_handler_cache_auth_step(req);
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder return;
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder DEBUG(4, ("Backend is marked offline, retry later!\n"));
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder state->pam_status = PAM_AUTHINFO_UNAVAIL;
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder state->dp_err = DP_ERR_OFFLINE;
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder ret = EOK;
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder goto done;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (state->be_ctx->domain->cache_credentials == TRUE) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
0ede68718d0fd43b5d67c233ccfb7a2b673fc9cbChristian Maeder /* password caching failures are not fatal errors */
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder state->pam_status = PAM_SUCCESS;
0ede68718d0fd43b5d67c233ccfb7a2b673fc9cbChristian Maeder state->dp_err = DP_ERR_OK;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
0ede68718d0fd43b5d67c233ccfb7a2b673fc9cbChristian Maeder switch(pd->cmd) {
502483734c83d0bf1eadcc94113d0362f8713784Christian Maeder case SSS_PAM_AUTHENTICATE:
502483734c83d0bf1eadcc94113d0362f8713784Christian Maeder case SSS_PAM_CHAUTHTOK_PRELIM:
1c4dfa148603d4fcf4cdd2ed66c8b6e1de0dd696Till Mossakowski password = talloc_size(state, pd->authtok_size + 1);
1c4dfa148603d4fcf4cdd2ed66c8b6e1de0dd696Till Mossakowski if (password != NULL) {
502483734c83d0bf1eadcc94113d0362f8713784Christian Maeder memcpy(password, pd->authtok, pd->authtok_size);
502483734c83d0bf1eadcc94113d0362f8713784Christian Maeder password[pd->authtok_size] = '\0';
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder break;
9175e29c044318498a40f323f189f9dfd50378efChristian Maeder case SSS_PAM_CHAUTHTOK:
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder password = talloc_size(state, pd->newauthtok_size + 1);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (password != NULL) {
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder memcpy(password, pd->newauthtok, pd->newauthtok_size);
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder password[pd->newauthtok_size] = '\0';
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder break;
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder default:
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(0, ("unsupported PAM command [%d].\n", pd->cmd));
bbba6dd86153aacb0f662b182b128df0eb09fd54Christian Maeder }
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder
7968d3a131e5a684ec1ff0c6d88aae638549153dChristian Maeder if (password == NULL) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(0, ("password not available, offline auth may not work.\n"));
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder ret = EOK; /* password caching failures are not fatal errors */
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder goto done;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder talloc_set_destructor((TALLOC_CTX *)password, password_destructor);
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder ret = sysdb_cache_password(state, state->be_ctx->sysdb,
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa state->be_ctx->domain, pd->user,
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa password);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (ret) {
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa DEBUG(2, ("Failed to cache password, offline auth may not work."
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa " (%d)[%s]!?\n", ret, strerror(ret)));
a389e88e0acb83d8489bdc5e55bc5522b152bbecEugen Kuksa }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
5941ba0b9a99ac98f78a89a9f3303102657e36ccChristian Maeder state->pam_status = PAM_SUCCESS;
5941ba0b9a99ac98f78a89a9f3303102657e36ccChristian Maeder state->dp_err = DP_ERR_OK;
ret = EOK;
done:
if (ret == EOK) {
tevent_req_done(req);
} else {
tevent_req_error(req, ret);
}
}
static void krb5_pam_handler_cache_auth_step(struct tevent_req *req)
{
struct krb5_auth_state *state = tevent_req_data(req, struct krb5_auth_state);
struct pam_data *pd = state->pd;
struct krb5_ctx *krb5_ctx = state->kr->krb5_ctx;
int ret;
ret = sysdb_cache_auth(state, state->be_ctx->sysdb, state->be_ctx->domain,
pd->user, pd->authtok, pd->authtok_size,
state->be_ctx->cdb, true, NULL, NULL);
if (ret != EOK) {
DEBUG(1, ("Offline authentication failed\n"));
state->pam_status = PAM_SYSTEM_ERR;
state->dp_err = DP_ERR_OK;
} else {
ret = add_user_to_delayed_online_authentication(krb5_ctx, pd,
state->kr->uid);
if (ret != EOK) {
/* This error is not fatal */
DEBUG(1, ("add_user_to_delayed_online_authentication failed.\n"));
}
state->pam_status = PAM_AUTHINFO_UNAVAIL;
state->dp_err = DP_ERR_OFFLINE;
}
tevent_req_done(req);
}
static void krb_reply(struct be_req *req, int dp_err, int result)
{
req->fn(req, dp_err, result, NULL);
}
void krb5_auth_done(struct tevent_req *req);
void krb5_pam_handler(struct be_req *be_req)
{
struct tevent_req *req;
struct pam_data *pd;
struct krb5_ctx *krb5_ctx;
pd = talloc_get_type(be_req->req_data, struct pam_data);
krb5_ctx = get_krb5_ctx(be_req);
if (krb5_ctx == NULL) {
DEBUG(1, ("Kerberos context not available.\n"));
goto failed;
}
req = krb5_auth_send(be_req, be_req->be_ctx->ev, be_req->be_ctx, pd,
krb5_ctx);
if (req == NULL) {
DEBUG(1, ("krb5_auth_send failed.\n"));
goto failed;
}
tevent_req_set_callback(req, krb5_auth_done, be_req);
return;
failed:
pd->pam_status = PAM_SYSTEM_ERR;
krb_reply(be_req, DP_ERR_FATAL, pd->pam_status);
}
void krb5_auth_done(struct tevent_req *req)
{
int ret;
struct be_req *be_req = tevent_req_callback_data(req, struct be_req);
int pam_status;
int dp_err;
struct pam_data *pd;
pd = talloc_get_type(be_req->req_data, struct pam_data);
ret = krb5_auth_recv(req, &pam_status, &dp_err);
talloc_zfree(req);
if (ret) {
pd->pam_status = PAM_SYSTEM_ERR;
dp_err = DP_ERR_OK;
} else {
pd->pam_status = pam_status;
}
krb_reply(be_req, dp_err, pd->pam_status);
}