b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose/*
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose SSSD
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose Kerberos 5 Backend Module - Manage krb5_child
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose Authors:
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose Sumit Bose <sbose@redhat.com>
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose Copyright (C) 2010 Red Hat
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose This program is free software; you can redistribute it and/or modify
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose it under the terms of the GNU General Public License as published by
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose the Free Software Foundation; either version 3 of the License, or
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose (at your option) any later version.
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose This program is distributed in the hope that it will be useful,
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose but WITHOUT ANY WARRANTY; without even the implied warranty of
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose GNU General Public License for more details.
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose You should have received a copy of the GNU General Public License
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose along with this program. If not, see <http://www.gnu.org/licenses/>.
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose*/
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
91141c6ae6e6a255cfd66266581671ddd16086b3Lukas Slebodnik#include <signal.h>
91141c6ae6e6a255cfd66266581671ddd16086b3Lukas Slebodnik
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose#include "util/util.h"
87c07559af5cfcd2752295ef7c425bd3205f426fStephen Gallagher#include "util/child_common.h"
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose#include "providers/krb5/krb5_common.h"
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose#include "providers/krb5/krb5_auth.h"
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose#include "src/providers/krb5/krb5_utils.h"
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
248a24eda712d738127897264290ad1b751faf12Jakub Hrozek#ifndef KRB5_CHILD_DIR
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose#ifndef SSSD_LIBEXEC_PATH
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose#error "SSSD_LIBEXEC_PATH not defined"
248a24eda712d738127897264290ad1b751faf12Jakub Hrozek#endif /* SSSD_LIBEXEC_PATH */
248a24eda712d738127897264290ad1b751faf12Jakub Hrozek
248a24eda712d738127897264290ad1b751faf12Jakub Hrozek#define KRB5_CHILD_DIR SSSD_LIBEXEC_PATH
248a24eda712d738127897264290ad1b751faf12Jakub Hrozek#endif /* KRB5_CHILD_DIR */
248a24eda712d738127897264290ad1b751faf12Jakub Hrozek
248a24eda712d738127897264290ad1b751faf12Jakub Hrozek#define KRB5_CHILD KRB5_CHILD_DIR"/krb5_child"
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek#define TIME_T_MAX LONG_MAX
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek#define int64_to_time_t(val) ((time_t)((val) < TIME_T_MAX ? val : TIME_T_MAX))
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bosestruct handle_child_state {
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct tevent_context *ev;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct krb5child_req *kr;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose uint8_t *buf;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose ssize_t len;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct tevent_timer *timeout_handler;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose pid_t child_pid;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
06f10b2a0ebb26f2460cd445f8040e9205de7500Jakub Hrozek struct child_io_fds *io;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose};
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorcestatic errno_t pack_authtok(struct io_buffer *buf, size_t *rp,
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce struct sss_auth_token *tok)
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce{
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce uint32_t auth_token_type;
9f37bb2012faa136ef7c1f9fe93689ce2be85637Ondrej Kos uint32_t auth_token_length = 0;
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce const char *data;
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce size_t len;
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce errno_t ret = EOK;
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce auth_token_type = sss_authtok_get_type(tok);
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce switch (auth_token_type) {
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce case SSS_AUTHTOK_TYPE_EMPTY:
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce auth_token_length = 0;
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce data = "";
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce break;
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce case SSS_AUTHTOK_TYPE_PASSWORD:
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce ret = sss_authtok_get_password(tok, &data, &len);
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce auth_token_length = len + 1;
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce break;
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce case SSS_AUTHTOK_TYPE_CCFILE:
1de61a60ea50700ef687969b0b70d53907994255Sumit Bose ret = sss_authtok_get_ccfile(tok, &data, &len);
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce auth_token_length = len + 1;
4b1b2e60d0764fed289eada9a7afbfd1993cadcdSumit Bose break;
4b1b2e60d0764fed289eada9a7afbfd1993cadcdSumit Bose case SSS_AUTHTOK_TYPE_2FA:
52f45837ded98564968da42229b37db6a36ad627Sumit Bose case SSS_AUTHTOK_TYPE_SC_PIN:
52f45837ded98564968da42229b37db6a36ad627Sumit Bose case SSS_AUTHTOK_TYPE_SC_KEYPAD:
4b1b2e60d0764fed289eada9a7afbfd1993cadcdSumit Bose data = (char *) sss_authtok_get_data(tok);
4b1b2e60d0764fed289eada9a7afbfd1993cadcdSumit Bose auth_token_length = sss_authtok_get_size(tok);
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce break;
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce default:
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce ret = EINVAL;
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce }
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce if (ret == EOK) {
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce SAFEALIGN_COPY_UINT32(&buf->data[*rp], &auth_token_type, rp);
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce SAFEALIGN_COPY_UINT32(&buf->data[*rp], &auth_token_length, rp);
2d527aab0bab0c5323b7ea09c9a8c3820f4f8736Sumit Bose if (data != NULL) {
2d527aab0bab0c5323b7ea09c9a8c3820f4f8736Sumit Bose safealign_memcpy(&buf->data[*rp], data, auth_token_length, rp);
2d527aab0bab0c5323b7ea09c9a8c3820f4f8736Sumit Bose }
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce }
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce return ret;
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce}
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bosestatic errno_t create_send_buffer(struct krb5child_req *kr,
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct io_buffer **io_buf)
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose{
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct io_buffer *buf;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose size_t rp;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose const char *keytab;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose uint32_t validate;
fa4a9c4afcc0c62a693034e21f33356e64735687Sumit Bose uint32_t send_pac;
edaa983d094c239c3e1ba667bcd20ed3934be3b8Sumit Bose uint32_t use_enterprise_principal;
861ab44e8148208425b67c4711bc8fade10fd3edJakub Hrozek uint32_t posix_domain;
8bbf89c5ab798c112773fe23515c3a9df56dde71Nick Guay size_t username_len = 0;
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce errno_t ret;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose keytab = dp_opt_get_cstring(kr->krb5_ctx->opts, KRB5_KEYTAB);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose if (keytab == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Missing keytab option.\n");
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose return EINVAL;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose validate = dp_opt_get_bool(kr->krb5_ctx->opts, KRB5_VALIDATE) ? 1 : 0;
fa4a9c4afcc0c62a693034e21f33356e64735687Sumit Bose
48657b5de36a63b0c13ed5d53065871d59d8f10bJakub Hrozek /* Always send PAC except for local IPA users and IPA server mode */
48657b5de36a63b0c13ed5d53065871d59d8f10bJakub Hrozek switch (kr->krb5_ctx->config_type) {
48657b5de36a63b0c13ed5d53065871d59d8f10bJakub Hrozek case K5C_IPA_CLIENT:
48657b5de36a63b0c13ed5d53065871d59d8f10bJakub Hrozek send_pac = kr->upn_from_different_realm ? 1 : 0;
48657b5de36a63b0c13ed5d53065871d59d8f10bJakub Hrozek break;
48657b5de36a63b0c13ed5d53065871d59d8f10bJakub Hrozek case K5C_IPA_SERVER:
48657b5de36a63b0c13ed5d53065871d59d8f10bJakub Hrozek send_pac = 0;
48657b5de36a63b0c13ed5d53065871d59d8f10bJakub Hrozek break;
48657b5de36a63b0c13ed5d53065871d59d8f10bJakub Hrozek default:
48657b5de36a63b0c13ed5d53065871d59d8f10bJakub Hrozek send_pac = 1;
48657b5de36a63b0c13ed5d53065871d59d8f10bJakub Hrozek break;
fa4a9c4afcc0c62a693034e21f33356e64735687Sumit Bose }
695cc8754aecb3dcc3a617d86b7d4b6470af175dSumit Bose
861ab44e8148208425b67c4711bc8fade10fd3edJakub Hrozek switch (kr->dom->type) {
861ab44e8148208425b67c4711bc8fade10fd3edJakub Hrozek case DOM_TYPE_POSIX:
861ab44e8148208425b67c4711bc8fade10fd3edJakub Hrozek posix_domain = 1;
861ab44e8148208425b67c4711bc8fade10fd3edJakub Hrozek break;
861ab44e8148208425b67c4711bc8fade10fd3edJakub Hrozek case DOM_TYPE_APPLICATION:
861ab44e8148208425b67c4711bc8fade10fd3edJakub Hrozek posix_domain = 0;
861ab44e8148208425b67c4711bc8fade10fd3edJakub Hrozek break;
861ab44e8148208425b67c4711bc8fade10fd3edJakub Hrozek default:
861ab44e8148208425b67c4711bc8fade10fd3edJakub Hrozek return EINVAL;
861ab44e8148208425b67c4711bc8fade10fd3edJakub Hrozek }
861ab44e8148208425b67c4711bc8fade10fd3edJakub Hrozek
614057ea85c05d3a6d4b62217a41b8b5db8d5d38Sumit Bose if (kr->pd->cmd == SSS_CMD_RENEW || kr->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM
614057ea85c05d3a6d4b62217a41b8b5db8d5d38Sumit Bose || kr->pd->cmd == SSS_PAM_CHAUTHTOK || kr->is_offline) {
695cc8754aecb3dcc3a617d86b7d4b6470af175dSumit Bose use_enterprise_principal = false;
695cc8754aecb3dcc3a617d86b7d4b6470af175dSumit Bose } else {
695cc8754aecb3dcc3a617d86b7d4b6470af175dSumit Bose use_enterprise_principal = dp_opt_get_bool(kr->krb5_ctx->opts,
edaa983d094c239c3e1ba667bcd20ed3934be3b8Sumit Bose KRB5_USE_ENTERPRISE_PRINCIPAL) ? 1 : 0;
695cc8754aecb3dcc3a617d86b7d4b6470af175dSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose buf = talloc(kr, struct io_buffer);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose if (buf == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n");
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose return ENOMEM;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
f772649cb8b624f4b4dfa5521f487ef38e3f8931Jakub Hrozek buf->size = 9*sizeof(uint32_t) + strlen(kr->upn);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose if (kr->pd->cmd == SSS_PAM_AUTHENTICATE ||
2d527aab0bab0c5323b7ea09c9a8c3820f4f8736Sumit Bose kr->pd->cmd == SSS_PAM_PREAUTH ||
f3f9ce8024d7610439d6c70ddafab1ab025cf8a8Sumit Bose kr->pd->cmd == SSS_CMD_RENEW ||
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose kr->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM ||
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose kr->pd->cmd == SSS_PAM_CHAUTHTOK) {
f772649cb8b624f4b4dfa5521f487ef38e3f8931Jakub Hrozek buf->size += 4*sizeof(uint32_t) + strlen(kr->ccname) + strlen(keytab) +
9acfb09f7969a69f58bd45c856b01700541853caLukas Slebodnik sss_authtok_get_size(kr->pd->authtok);
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek buf->size += sizeof(uint32_t);
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek if (kr->old_ccname) {
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek buf->size += strlen(kr->old_ccname);
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose if (kr->pd->cmd == SSS_PAM_CHAUTHTOK) {
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce buf->size += 2*sizeof(uint32_t) +
9acfb09f7969a69f58bd45c856b01700541853caLukas Slebodnik sss_authtok_get_size(kr->pd->newauthtok);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose if (kr->pd->cmd == SSS_PAM_ACCT_MGMT) {
fedfb7c62b4efa89d18d0d3a7895a2a34ec4ce42Jakub Hrozek username_len = strlen(kr->kuserok_user);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose buf->size += sizeof(uint32_t) + username_len;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose buf->data = talloc_size(kr, buf->size);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose if (buf->data == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed.\n");
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose talloc_free(buf);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose return ENOMEM;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose rp = 0;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose SAFEALIGN_COPY_UINT32(&buf->data[rp], &kr->pd->cmd, &rp);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose SAFEALIGN_COPY_UINT32(&buf->data[rp], &kr->uid, &rp);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose SAFEALIGN_COPY_UINT32(&buf->data[rp], &kr->gid, &rp);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose SAFEALIGN_COPY_UINT32(&buf->data[rp], &validate, &rp);
861ab44e8148208425b67c4711bc8fade10fd3edJakub Hrozek SAFEALIGN_COPY_UINT32(&buf->data[rp], &posix_domain, &rp);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose SAFEALIGN_COPY_UINT32(&buf->data[rp], &kr->is_offline, &rp);
fa4a9c4afcc0c62a693034e21f33356e64735687Sumit Bose SAFEALIGN_COPY_UINT32(&buf->data[rp], &send_pac, &rp);
edaa983d094c239c3e1ba667bcd20ed3934be3b8Sumit Bose SAFEALIGN_COPY_UINT32(&buf->data[rp], &use_enterprise_principal, &rp);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose SAFEALIGN_SET_UINT32(&buf->data[rp], strlen(kr->upn), &rp);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose safealign_memcpy(&buf->data[rp], kr->upn, strlen(kr->upn), &rp);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose if (kr->pd->cmd == SSS_PAM_AUTHENTICATE ||
2d527aab0bab0c5323b7ea09c9a8c3820f4f8736Sumit Bose kr->pd->cmd == SSS_PAM_PREAUTH ||
f3f9ce8024d7610439d6c70ddafab1ab025cf8a8Sumit Bose kr->pd->cmd == SSS_CMD_RENEW ||
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose kr->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM ||
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose kr->pd->cmd == SSS_PAM_CHAUTHTOK) {
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose SAFEALIGN_SET_UINT32(&buf->data[rp], strlen(kr->ccname), &rp);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose safealign_memcpy(&buf->data[rp], kr->ccname, strlen(kr->ccname), &rp);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek if (kr->old_ccname) {
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek SAFEALIGN_SET_UINT32(&buf->data[rp], strlen(kr->old_ccname), &rp);
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek safealign_memcpy(&buf->data[rp], kr->old_ccname,
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek strlen(kr->old_ccname), &rp);
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek } else {
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek SAFEALIGN_SET_UINT32(&buf->data[rp], 0, &rp);
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek }
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose SAFEALIGN_SET_UINT32(&buf->data[rp], strlen(keytab), &rp);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose safealign_memcpy(&buf->data[rp], keytab, strlen(keytab), &rp);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
9acfb09f7969a69f58bd45c856b01700541853caLukas Slebodnik ret = pack_authtok(buf, &rp, kr->pd->authtok);
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce if (ret) {
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce return ret;
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose if (kr->pd->cmd == SSS_PAM_CHAUTHTOK) {
9acfb09f7969a69f58bd45c856b01700541853caLukas Slebodnik ret = pack_authtok(buf, &rp, kr->pd->newauthtok);
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce if (ret) {
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce return ret;
64af76e2bef2565caa9738f675c108a4b3789237Simo Sorce }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose if (kr->pd->cmd == SSS_PAM_ACCT_MGMT) {
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose SAFEALIGN_SET_UINT32(&buf->data[rp], username_len, &rp);
fedfb7c62b4efa89d18d0d3a7895a2a34ec4ce42Jakub Hrozek safealign_memcpy(&buf->data[rp], kr->kuserok_user, username_len, &rp);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose *io_buf = buf;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose return EOK;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose}
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bosestatic void krb5_child_timeout(struct tevent_context *ev,
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct tevent_timer *te,
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct timeval tv, void *pvt)
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose{
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct handle_child_state *state = tevent_req_data(req,
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct handle_child_state);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose int ret;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose if (state->timeout_handler == NULL) {
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose return;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
07270cd9739b942c63602ef57c513c6a50e6f7eePavel Reichl DEBUG(SSSDBG_IMPORTANT_INFO,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Timeout for child [%d] reached. In case KDC is distant or network "
07270cd9739b942c63602ef57c513c6a50e6f7eePavel Reichl "is slow you may consider increasing value of krb5_auth_timeout.\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov state->child_pid);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose ret = kill(state->child_pid, SIGKILL);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose if (ret == -1) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "kill failed [%d][%s].\n", errno, strerror(errno));
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose tevent_req_error(req, ETIMEDOUT);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose}
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bosestatic errno_t activate_child_timeout_handler(struct tevent_req *req,
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct tevent_context *ev,
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose const uint32_t timeout_seconds)
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose{
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct timeval tv;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct handle_child_state *state = tevent_req_data(req,
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct handle_child_state);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose tv = tevent_timeval_current();
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose tv = tevent_timeval_add(&tv, timeout_seconds, 0);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose state->timeout_handler = tevent_add_timer(ev, state, tv,
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose krb5_child_timeout, req);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose if (state->timeout_handler == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_timer failed.\n");
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose return ENOMEM;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose return EOK;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose}
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Boseerrno_t set_extra_args(TALLOC_CTX *mem_ctx, struct krb5_ctx *krb5_ctx,
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose const char ***krb5_child_extra_args)
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose{
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose const char **extra_args;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose size_t c = 0;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose int ret;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose if (krb5_ctx == NULL || krb5_child_extra_args == NULL) {
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose return EINVAL;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose }
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose
d380148b0a23dd1a04d1d0767ba41d3e76fb7d23Lukas Slebodnik extra_args = talloc_zero_array(mem_ctx, const char *, 10);
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose if (extra_args == NULL) {
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_array failed.\n");
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose return ENOMEM;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose }
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose extra_args[c] = talloc_asprintf(extra_args,
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose "--"CHILD_OPT_FAST_CCACHE_UID"=%"SPRIuid,
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose getuid());
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose if (extra_args[c] == NULL) {
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose ret = ENOMEM;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose goto done;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose }
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose c++;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose extra_args[c] = talloc_asprintf(extra_args,
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose "--"CHILD_OPT_FAST_CCACHE_GID"=%"SPRIgid,
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose getgid());
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose if (extra_args[c] == NULL) {
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose ret = ENOMEM;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose goto done;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose }
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose c++;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose if (krb5_ctx->realm != NULL) {
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose extra_args[c] = talloc_asprintf(extra_args, "--"CHILD_OPT_REALM"=%s",
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose krb5_ctx->realm);
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose if (extra_args[c] == NULL) {
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose ret = ENOMEM;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose goto done;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose }
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose c++;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose }
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose if (krb5_ctx->lifetime_str != NULL) {
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose extra_args[c] = talloc_asprintf(extra_args, "--"CHILD_OPT_LIFETIME"=%s",
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose krb5_ctx->lifetime_str);
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose if (extra_args[c] == NULL) {
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose ret = ENOMEM;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose goto done;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose }
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose c++;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose }
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose if (krb5_ctx->rlife_str != NULL) {
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose extra_args[c] = talloc_asprintf(extra_args,
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose "--"CHILD_OPT_RENEWABLE_LIFETIME"=%s",
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose krb5_ctx->rlife_str);
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose if (extra_args[c] == NULL) {
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose ret = ENOMEM;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose goto done;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose }
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose c++;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose }
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose if (krb5_ctx->use_fast_str != NULL) {
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose extra_args[c] = talloc_asprintf(extra_args, "--"CHILD_OPT_USE_FAST"=%s",
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose krb5_ctx->use_fast_str);
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose if (extra_args[c] == NULL) {
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose ret = ENOMEM;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose goto done;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose }
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose c++;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose if (krb5_ctx->fast_principal != NULL) {
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose extra_args[c] = talloc_asprintf(extra_args,
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose "--"CHILD_OPT_FAST_PRINCIPAL"=%s",
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose krb5_ctx->fast_principal);
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose if (extra_args[c] == NULL) {
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose ret = ENOMEM;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose goto done;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose }
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose c++;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose }
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose }
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose if (krb5_ctx->canonicalize) {
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose extra_args[c] = talloc_strdup(extra_args,
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose "--" CHILD_OPT_CANONICALIZE);
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose if (extra_args[c] == NULL) {
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose ret = ENOMEM;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose goto done;
d380148b0a23dd1a04d1d0767ba41d3e76fb7d23Lukas Slebodnik }
d380148b0a23dd1a04d1d0767ba41d3e76fb7d23Lukas Slebodnik c++;
d380148b0a23dd1a04d1d0767ba41d3e76fb7d23Lukas Slebodnik }
d380148b0a23dd1a04d1d0767ba41d3e76fb7d23Lukas Slebodnik
d380148b0a23dd1a04d1d0767ba41d3e76fb7d23Lukas Slebodnik if (krb5_ctx->sss_creds_password) {
d380148b0a23dd1a04d1d0767ba41d3e76fb7d23Lukas Slebodnik extra_args[c] = talloc_strdup(extra_args,
d380148b0a23dd1a04d1d0767ba41d3e76fb7d23Lukas Slebodnik "--" CHILD_OPT_SSS_CREDS_PASSWORD);
d380148b0a23dd1a04d1d0767ba41d3e76fb7d23Lukas Slebodnik if (extra_args[c] == NULL) {
d380148b0a23dd1a04d1d0767ba41d3e76fb7d23Lukas Slebodnik ret = ENOMEM;
d380148b0a23dd1a04d1d0767ba41d3e76fb7d23Lukas Slebodnik goto done;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose }
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose c++;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose }
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose extra_args[c] = NULL;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose *krb5_child_extra_args = extra_args;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose ret = EOK;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bosedone:
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose if (ret != EOK) {
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose talloc_free(extra_args);
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose }
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose return ret;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose}
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bosestatic errno_t fork_child(struct tevent_req *req)
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose{
45e11be651dbd3855a35de4abd2922e5b9d4b963Jakub Hrozek int pipefd_to_child[2] = PIPE_INIT;
45e11be651dbd3855a35de4abd2922e5b9d4b963Jakub Hrozek int pipefd_from_child[2] = PIPE_INIT;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose pid_t pid;
45e11be651dbd3855a35de4abd2922e5b9d4b963Jakub Hrozek errno_t ret;
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose const char **krb5_child_extra_args;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct handle_child_state *state = tevent_req_data(req,
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct handle_child_state);
543d1652e0185abadd5d8b45c718a3db96cd2828Jakub Hrozek
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose ret = set_extra_args(state, state->kr->krb5_ctx, &krb5_child_extra_args);
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose if (ret != EOK) {
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose DEBUG(SSSDBG_OP_FAILURE, "set_extra_args failed.\n");
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose goto fail;
543d1652e0185abadd5d8b45c718a3db96cd2828Jakub Hrozek }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose ret = pipe(pipefd_from_child);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose if (ret == -1) {
45e11be651dbd3855a35de4abd2922e5b9d4b963Jakub Hrozek ret = errno;
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "pipe failed [%d][%s].\n", errno, strerror(errno));
45e11be651dbd3855a35de4abd2922e5b9d4b963Jakub Hrozek goto fail;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose ret = pipe(pipefd_to_child);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose if (ret == -1) {
45e11be651dbd3855a35de4abd2922e5b9d4b963Jakub Hrozek ret = errno;
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "pipe failed [%d][%s].\n", errno, strerror(errno));
45e11be651dbd3855a35de4abd2922e5b9d4b963Jakub Hrozek goto fail;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose pid = fork();
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose if (pid == 0) { /* child */
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek exec_child_ex(state,
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek pipefd_to_child, pipefd_from_child,
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek KRB5_CHILD, state->kr->krb5_ctx->child_debug_fd,
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose krb5_child_extra_args, false,
7e394400eefd0e7c5ba0c64ab3fa28bee21ef2d7Sumit Bose STDIN_FILENO, STDOUT_FILENO);
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek /* We should never get here */
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "BUG: Could not exec KRB5 child\n");
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose } else if (pid > 0) { /* parent */
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose state->child_pid = pid;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose state->io->read_from_child_fd = pipefd_from_child[0];
45e11be651dbd3855a35de4abd2922e5b9d4b963Jakub Hrozek PIPE_FD_CLOSE(pipefd_from_child[1]);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose state->io->write_to_child_fd = pipefd_to_child[1];
45e11be651dbd3855a35de4abd2922e5b9d4b963Jakub Hrozek PIPE_FD_CLOSE(pipefd_to_child[0]);
f3d91181d4ee9da3f8bbf4ddf8782951c0ae46c1Jakub Hrozek sss_fd_nonblocking(state->io->read_from_child_fd);
f3d91181d4ee9da3f8bbf4ddf8782951c0ae46c1Jakub Hrozek sss_fd_nonblocking(state->io->write_to_child_fd);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
711bba7e2f72a816774effa389ad13bcc46e7843Pavel Bƙezina ret = child_handler_setup(state->ev, pid, NULL, NULL, NULL);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose if (ret != EOK) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Could not set up child signal handler\n");
45e11be651dbd3855a35de4abd2922e5b9d4b963Jakub Hrozek goto fail;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
45e11be651dbd3855a35de4abd2922e5b9d4b963Jakub Hrozek ret = activate_child_timeout_handler(req, state->ev,
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose dp_opt_get_int(state->kr->krb5_ctx->opts, KRB5_AUTH_TIMEOUT));
45e11be651dbd3855a35de4abd2922e5b9d4b963Jakub Hrozek if (ret != EOK) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "activate_child_timeout_handler failed.\n");
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose } else { /* error */
45e11be651dbd3855a35de4abd2922e5b9d4b963Jakub Hrozek ret = errno;
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
45e11be651dbd3855a35de4abd2922e5b9d4b963Jakub Hrozek "fork failed [%d][%s].\n", errno, strerror(ret));
45e11be651dbd3855a35de4abd2922e5b9d4b963Jakub Hrozek goto fail;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose return EOK;
45e11be651dbd3855a35de4abd2922e5b9d4b963Jakub Hrozek
45e11be651dbd3855a35de4abd2922e5b9d4b963Jakub Hrozekfail:
45e11be651dbd3855a35de4abd2922e5b9d4b963Jakub Hrozek PIPE_CLOSE(pipefd_from_child);
45e11be651dbd3855a35de4abd2922e5b9d4b963Jakub Hrozek PIPE_CLOSE(pipefd_to_child);
45e11be651dbd3855a35de4abd2922e5b9d4b963Jakub Hrozek return ret;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose}
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bosestatic void handle_child_step(struct tevent_req *subreq);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bosestatic void handle_child_done(struct tevent_req *subreq);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bosestruct tevent_req *handle_child_send(TALLOC_CTX *mem_ctx,
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct tevent_context *ev,
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct krb5child_req *kr)
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose{
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct tevent_req *req, *subreq;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct handle_child_state *state;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose int ret;
9f37bb2012faa136ef7c1f9fe93689ce2be85637Ondrej Kos struct io_buffer *buf = NULL;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose req = tevent_req_create(mem_ctx, &state, struct handle_child_state);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose if (req == NULL) {
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose return NULL;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose state->ev = ev;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose state->kr = kr;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose state->buf = NULL;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose state->len = 0;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose state->child_pid = -1;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose state->timeout_handler = NULL;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
06f10b2a0ebb26f2460cd445f8040e9205de7500Jakub Hrozek state->io = talloc(state, struct child_io_fds);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose if (state->io == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n");
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose ret = ENOMEM;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose goto fail;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose state->io->write_to_child_fd = -1;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose state->io->read_from_child_fd = -1;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose talloc_set_destructor((void *) state->io, child_io_destructor);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose ret = create_send_buffer(kr, &buf);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose if (ret != EOK) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "create_send_buffer failed.\n");
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose goto fail;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose ret = fork_child(req);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose if (ret != EOK) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "fork_child failed.\n");
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose goto fail;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose subreq = write_pipe_send(state, ev, buf->data, buf->size,
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose state->io->write_to_child_fd);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose if (!subreq) {
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose ret = ENOMEM;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose goto fail;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose tevent_req_set_callback(subreq, handle_child_step, req);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose return req;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bosefail:
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose tevent_req_error(req, ret);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose tevent_req_post(req, ev);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose return req;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose}
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bosestatic void handle_child_step(struct tevent_req *subreq)
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose{
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct tevent_req *req = tevent_req_callback_data(subreq,
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct tevent_req);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct handle_child_state *state = tevent_req_data(req,
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct handle_child_state);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose int ret;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose ret = write_pipe_recv(subreq);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose talloc_zfree(subreq);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose if (ret != EOK) {
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose tevent_req_error(req, ret);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose return;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
45e11be651dbd3855a35de4abd2922e5b9d4b963Jakub Hrozek PIPE_FD_CLOSE(state->io->write_to_child_fd);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose subreq = read_pipe_send(state, state->ev, state->io->read_from_child_fd);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose if (!subreq) {
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose tevent_req_error(req, ENOMEM);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose return;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose tevent_req_set_callback(subreq, handle_child_done, req);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose}
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bosestatic void handle_child_done(struct tevent_req *subreq)
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose{
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct tevent_req *req = tevent_req_callback_data(subreq,
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct tevent_req);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct handle_child_state *state = tevent_req_data(req,
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct handle_child_state);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose int ret;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose talloc_zfree(state->timeout_handler);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose ret = read_pipe_recv(subreq, state, &state->buf, &state->len);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose talloc_zfree(subreq);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose if (ret != EOK) {
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose tevent_req_error(req, ret);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose return;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose }
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
45e11be651dbd3855a35de4abd2922e5b9d4b963Jakub Hrozek PIPE_FD_CLOSE(state->io->read_from_child_fd);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose tevent_req_done(req);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose return;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose}
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Boseint handle_child_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose uint8_t **buf, ssize_t *len)
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose{
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct handle_child_state *state = tevent_req_data(req,
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose struct handle_child_state);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose TEVENT_REQ_RETURN_ON_ERROR(req);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose *buf = talloc_move(mem_ctx, &state->buf);
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose *len = state->len;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose return EOK;
b87233035e26cee919dcf46adaec29ba7fdaa51eSumit Bose}
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozekerrno_t
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozekparse_krb5_child_response(TALLOC_CTX *mem_ctx, uint8_t *buf, ssize_t len,
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek struct pam_data *pd, int pwd_exp_warning,
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek struct krb5_child_response **_res)
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek{
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek ssize_t pref_len;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek size_t p;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek errno_t ret;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek bool skip;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek char *ccname = NULL;
08e3f641a8b8d6b5d7eb0b523599702eda960da2Lukas Slebodnik size_t ccname_len = 0;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek int32_t msg_status;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek int32_t msg_type;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek int32_t msg_len;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek int64_t time_data;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek struct tgt_times tgtt;
84fbb0cad534308254a8a8ad837d1924496cfe71Michal Zidek uint32_t expiration;
84fbb0cad534308254a8a8ad837d1924496cfe71Michal Zidek uint32_t msg_subtype;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek struct krb5_child_response *res;
d3dca30d3a6feba062d0299718d1a9fcdc8b9d17Sumit Bose const char *upn = NULL;
08e3f641a8b8d6b5d7eb0b523599702eda960da2Lukas Slebodnik size_t upn_len = 0;
b40583c6d52b72e41bf01106534535e54b4fba4fNathaniel McCallum bool otp = false;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek if ((size_t) len < sizeof(int32_t)) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "message too short.\n");
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek return EINVAL;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek }
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek
92c6d2bbff680c3f4a83fbb1360eed098e7bcf2eStephen Gallagher memset(&tgtt, 0, sizeof(struct tgt_times));
92c6d2bbff680c3f4a83fbb1360eed098e7bcf2eStephen Gallagher
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek if (pwd_exp_warning < 0) {
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek pwd_exp_warning = KERBEROS_PWEXPIRE_WARNING_TIME;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek }
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek /* A buffer with the following structure is expected.
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek * int32_t status of the request (required)
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek * message (zero or more)
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek *
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek * A message consists of:
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek * int32_t type of the message
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek * int32_t length of the following data
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek * uint8_t[len] data
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek */
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek p=0;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek SAFEALIGN_COPY_INT32(&msg_status, buf+p, &p);
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek while (p < len) {
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek skip = false;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek SAFEALIGN_COPY_INT32(&msg_type, buf+p, &p);
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek SAFEALIGN_COPY_INT32(&msg_len, buf+p, &p);
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_LIBS, "child response [%d][%d][%d].\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov msg_status, msg_type, msg_len);
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek
9f0bffebd070115ab47a92eadc6890a721c7b78dMichal Ćœidek if (msg_len > len - p) {
9f0bffebd070115ab47a92eadc6890a721c7b78dMichal Ćœidek DEBUG(SSSDBG_CRIT_FAILURE, "message format error [%d] > [%zu].\n",
9f0bffebd070115ab47a92eadc6890a721c7b78dMichal Ćœidek msg_len, len - p);
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek return EINVAL;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek }
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek /* We need to save the name of the credential cache file. To find it
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek * we check if the data part of a message starts with
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek * CCACHE_ENV_NAME"=". pref_len also counts the trailing '=' because
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek * sizeof() counts the trailing '\0' of a string. */
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek pref_len = sizeof(CCACHE_ENV_NAME);
fe521d1ad610920ce5411589a158157d6a5f0794Alexander Bokovoy if ((msg_type == SSS_PAM_ENV_ITEM) &&
fe521d1ad610920ce5411589a158157d6a5f0794Alexander Bokovoy (msg_len > pref_len) &&
fe521d1ad610920ce5411589a158157d6a5f0794Alexander Bokovoy (strncmp((const char *) &buf[p], CCACHE_ENV_NAME"=", pref_len) == 0)) {
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek ccname = (char *) &buf[p+pref_len];
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek ccname_len = msg_len-pref_len;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek }
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek if (msg_type == SSS_KRB5_INFO_TGT_LIFETIME &&
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek msg_len == 4*sizeof(int64_t)) {
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek SAFEALIGN_COPY_INT64(&time_data, buf+p, NULL);
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek tgtt.authtime = int64_to_time_t(time_data);
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek SAFEALIGN_COPY_INT64(&time_data, buf+p+sizeof(int64_t), NULL);
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek tgtt.starttime = int64_to_time_t(time_data);
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek SAFEALIGN_COPY_INT64(&time_data, buf+p+2*sizeof(int64_t), NULL);
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek tgtt.endtime = int64_to_time_t(time_data);
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek SAFEALIGN_COPY_INT64(&time_data, buf+p+3*sizeof(int64_t), NULL);
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek tgtt.renew_till = int64_to_time_t(time_data);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_LIBS, "TGT times are [%ld][%ld][%ld][%ld].\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov tgtt.authtime, tgtt.starttime, tgtt.endtime, tgtt.renew_till);
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek }
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek
d3dca30d3a6feba062d0299718d1a9fcdc8b9d17Sumit Bose if (msg_type == SSS_KRB5_INFO_UPN) {
d3dca30d3a6feba062d0299718d1a9fcdc8b9d17Sumit Bose upn = (char *) buf + p;
d3dca30d3a6feba062d0299718d1a9fcdc8b9d17Sumit Bose upn_len = msg_len;
d3dca30d3a6feba062d0299718d1a9fcdc8b9d17Sumit Bose }
d3dca30d3a6feba062d0299718d1a9fcdc8b9d17Sumit Bose
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek if (msg_type == SSS_PAM_USER_INFO) {
84fbb0cad534308254a8a8ad837d1924496cfe71Michal Zidek SAFEALIGN_COPY_UINT32(&msg_subtype, buf + p, NULL);
84fbb0cad534308254a8a8ad837d1924496cfe71Michal Zidek if (msg_subtype == SSS_PAM_USER_INFO_EXPIRE_WARN) {
84fbb0cad534308254a8a8ad837d1924496cfe71Michal Zidek SAFEALIGN_COPY_UINT32(&expiration,
84fbb0cad534308254a8a8ad837d1924496cfe71Michal Zidek buf + p + sizeof(uint32_t), NULL);
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek if (pwd_exp_warning > 0 &&
84fbb0cad534308254a8a8ad837d1924496cfe71Michal Zidek difftime(pwd_exp_warning, expiration) < 0.0) {
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek skip = true;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek }
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek }
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek }
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek
b40583c6d52b72e41bf01106534535e54b4fba4fNathaniel McCallum if (msg_type == SSS_OTP) {
b40583c6d52b72e41bf01106534535e54b4fba4fNathaniel McCallum otp = true;
b40583c6d52b72e41bf01106534535e54b4fba4fNathaniel McCallum skip = true;
b40583c6d52b72e41bf01106534535e54b4fba4fNathaniel McCallum }
b40583c6d52b72e41bf01106534535e54b4fba4fNathaniel McCallum
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek if (!skip) {
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek ret = pam_add_response(pd, msg_type, msg_len, &buf[p]);
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek if (ret != EOK) {
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek /* This is not a fatal error */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n");
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek }
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek }
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek p += msg_len;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek
fe521d1ad610920ce5411589a158157d6a5f0794Alexander Bokovoy if ((p < len) && (p + 2*sizeof(int32_t) > len)) {
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "The remainder of the message is too short.\n");
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek return EINVAL;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek }
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek }
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek res = talloc_zero(mem_ctx, struct krb5_child_response);
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek if (!res) return ENOMEM;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek
b40583c6d52b72e41bf01106534535e54b4fba4fNathaniel McCallum res->otp = otp;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek res->msg_status = msg_status;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek memcpy(&res->tgtt, &tgtt, sizeof(tgtt));
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek if (ccname) {
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek res->ccname = talloc_strndup(res, ccname, ccname_len);
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek if (res->ccname == NULL) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strndup failed.\n");
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek talloc_free(res);
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek return ENOMEM;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek }
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek }
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek
d3dca30d3a6feba062d0299718d1a9fcdc8b9d17Sumit Bose if (upn != NULL) {
d3dca30d3a6feba062d0299718d1a9fcdc8b9d17Sumit Bose res->correct_upn = talloc_strndup(res, upn, upn_len);
d3dca30d3a6feba062d0299718d1a9fcdc8b9d17Sumit Bose if (res->correct_upn == NULL) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strndup failed.\n");
d3dca30d3a6feba062d0299718d1a9fcdc8b9d17Sumit Bose talloc_free(res);
d3dca30d3a6feba062d0299718d1a9fcdc8b9d17Sumit Bose return ENOMEM;
d3dca30d3a6feba062d0299718d1a9fcdc8b9d17Sumit Bose }
d3dca30d3a6feba062d0299718d1a9fcdc8b9d17Sumit Bose }
d3dca30d3a6feba062d0299718d1a9fcdc8b9d17Sumit Bose
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek *_res = res;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek return EOK;
7b14a9e64fd248103149eb1cb422ee752d91ba58Jakub Hrozek}