krb5_auth.c revision 8f4aaae28c88c707853f8f28d8babc4efe0c1bf6
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen/*
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen SSSD
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen Kerberos 5 Backend Module
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen Authors:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen Sumit Bose <sbose@redhat.com>
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen Copyright (C) 2009 Red Hat
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen This program is free software; you can redistribute it and/or modify
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen it under the terms of the GNU General Public License as published by
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen the Free Software Foundation; either version 3 of the License, or
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen (at your option) any later version.
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen This program is distributed in the hope that it will be useful,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen but WITHOUT ANY WARRANTY; without even the implied warranty of
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen GNU General Public License for more details.
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen You should have received a copy of the GNU General Public License
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen along with this program. If not, see <http://www.gnu.org/licenses/>.
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen*/
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#include <errno.h>
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#include <sys/time.h>
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#include <sys/types.h>
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#include <sys/wait.h>
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#include <pwd.h>
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#include <sys/stat.h>
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen#include <security/pam_modules.h>
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#include "util/util.h"
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#include "util/find_uid.h"
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#include "db/sysdb.h"
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#include "providers/child_common.h"
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#include "providers/krb5/krb5_auth.h"
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#include "providers/krb5/krb5_utils.h"
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#ifndef SSSD_LIBEXEC_PATH
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#error "SSSD_LIBEXEC_PATH not defined"
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#else
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#define KRB5_CHILD SSSD_LIBEXEC_PATH"/krb5_child"
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen#endif
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic errno_t add_krb5_env(struct dp_option *opts, const char *ccname,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct pam_data *pd)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen const char *dummy;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen char *env;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen TALLOC_CTX *tmp_ctx = NULL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen tmp_ctx = talloc_new(NULL);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (tmp_ctx == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("talloc_new failed.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return ENOMEM;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ccname != NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen env = talloc_asprintf(tmp_ctx, "%s=%s",CCACHE_ENV_NAME, ccname);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (env == NULL) {
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen DEBUG(1, ("talloc_asprintf failed.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = ENOMEM;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto done;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = pam_add_response(pd, SSS_PAM_ENV_ITEM, strlen(env)+1,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen (uint8_t *) env);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret != EOK) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("pam_add_response failed.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto done;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
e22ec7998afd426c53c658483ce66b6e404e27c6Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen dummy = dp_opt_get_cstring(opts, KRB5_REALM);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (dummy != NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen env = talloc_asprintf(tmp_ctx, "%s=%s", SSSD_KRB5_REALM, dummy);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (env == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("talloc_asprintf failed.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = ENOMEM;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto done;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = pam_add_response(pd, SSS_PAM_ENV_ITEM, strlen(env)+1,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen (uint8_t *) env);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret != EOK) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("pam_add_response failed.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto done;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen dummy = dp_opt_get_cstring(opts, KRB5_KDC);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (dummy != NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen env = talloc_asprintf(tmp_ctx, "%s=%s", SSSD_KRB5_KDC, dummy);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (env == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("talloc_asprintf failed.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = ENOMEM;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto done;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = pam_add_response(pd, SSS_PAM_ENV_ITEM, strlen(env)+1,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen (uint8_t *) env);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret != EOK) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("pam_add_response failed.\n"));
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen goto done;
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen }
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen }
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen ret = EOK;
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainendone:
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen talloc_free(tmp_ctx);
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen return ret;
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen}
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainenstatic errno_t check_if_ccache_file_is_used(uid_t uid, const char *ccname,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen bool *result)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen size_t offset = 0;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct stat stat_buf;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen const char *filename;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen bool active;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen *result = false;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ccname == NULL || *ccname == '\0') {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return EINVAL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (strncmp(ccname, "FILE:", 5) == 0) {
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen offset = 5;
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen }
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen filename = ccname + offset;
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen if (filename[0] != '/') {
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen DEBUG(1, ("Only absolute path names are allowed.\n"));
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen return EINVAL;
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen }
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen ret = lstat(filename, &stat_buf);
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen if (ret == -1 && errno != ENOENT) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("stat failed [%d][%s].\n", errno, strerror(errno)));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return errno;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen } else if (ret == EOK) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (stat_buf.st_uid != uid) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("Cache file [%s] exists, but is owned by [%d] instead of "
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen "[%d].\n", filename, stat_buf.st_uid, uid));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return EINVAL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (!S_ISREG(stat_buf.st_mode)) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("Cache file [%s] exists, but is not a regular file.\n",
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen filename));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return EINVAL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = check_if_uid_is_active(uid, &active);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret != EOK) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("check_if_uid_is_active failed.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (!active) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(5, ("User [%d] is not active\n", uid));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen } else {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(9, ("User [%d] is still active, reusing ccache file [%s].\n",
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen uid, filename));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen *result = true;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return EOK;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstruct krb5_save_ccname_state {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct tevent_context *ev;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct sysdb_ctx *sysdb;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct sysdb_handle *handle;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct sss_domain_info *domain;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen const char *name;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct sysdb_attrs *attrs;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen};
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic void krb5_save_ccname_trans(struct tevent_req *subreq);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic void krb5_set_user_attr_done(struct tevent_req *subreq);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic struct tevent_req *krb5_save_ccname_send(TALLOC_CTX *mem_ctx,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct tevent_context *ev,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct sysdb_ctx *sysdb,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct sss_domain_info *domain,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen const char *name,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen const char *ccname)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct tevent_req *req;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct tevent_req *subreq;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct krb5_save_ccname_state *state;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (name == NULL || ccname == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("Missing user or ccache name.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return NULL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen req = tevent_req_create(mem_ctx, &state, struct krb5_save_ccname_state);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (req == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("tevent_req_create failed.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return NULL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen state->ev = ev;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen state->sysdb = sysdb;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen state->handle = NULL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen state->domain = domain;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen state->name = name;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen state->attrs = sysdb_new_attrs(state);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = sysdb_attrs_add_string(state->attrs, SYSDB_CCACHE_FILE, ccname);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret != EOK) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("sysdb_attrs_add_string failed.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto failed;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen subreq = sysdb_transaction_send(state, ev, sysdb);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (subreq == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto failed;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen tevent_req_set_callback(subreq, krb5_save_ccname_trans, req);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return req;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenfailed:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen talloc_free(req);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return NULL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic void krb5_save_ccname_trans(struct tevent_req *subreq)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct tevent_req *req = tevent_req_callback_data(subreq,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct tevent_req);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct krb5_save_ccname_state *state = tevent_req_data(req,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct krb5_save_ccname_state);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = sysdb_transaction_recv(subreq, state, &state->handle);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen talloc_zfree(subreq);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret != EOK) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen tevent_req_error(req, ret);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen subreq = sysdb_set_user_attr_send(state, state->ev, state->handle,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen state->domain, state->name,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen state->attrs, SYSDB_MOD_REP);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (subreq == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(6, ("Error: Out of memory\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen tevent_req_error(req, ENOMEM);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen tevent_req_set_callback(subreq, krb5_set_user_attr_done, req);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic void krb5_set_user_attr_done(struct tevent_req *subreq)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct tevent_req *req = tevent_req_callback_data(subreq,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct tevent_req);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct krb5_save_ccname_state *state = tevent_req_data(req,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct krb5_save_ccname_state);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = sysdb_set_user_attr_recv(subreq);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen talloc_zfree(subreq);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret != EOK) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen tevent_req_error(req, ret);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen subreq = sysdb_transaction_commit_send(state, state->ev, state->handle);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (subreq == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(6, ("Error: Out of memory\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen tevent_req_error(req, ENOMEM);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen tevent_req_set_callback(subreq, sysdb_transaction_complete, req);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenint krb5_save_ccname_recv(struct tevent_req *req)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen TEVENT_REQ_RETURN_ON_ERROR(req);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return EOK;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenerrno_t create_send_buffer(struct krb5child_req *kr, struct io_buffer **io_buf)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct io_buffer *buf;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen size_t rp;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen const char *keytab;
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen uint32_t validate;
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen keytab = dp_opt_get_cstring(kr->krb5_ctx->opts, KRB5_KEYTAB);
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen if (keytab == NULL) {
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen DEBUG(1, ("Missing keytab option.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return EINVAL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen validate = dp_opt_get_bool(kr->krb5_ctx->opts, KRB5_VALIDATE) ? 1 : 0;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen buf = talloc(kr, struct io_buffer);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (buf == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("talloc failed.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return ENOMEM;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen buf->size = 9*sizeof(uint32_t) + strlen(kr->upn) + strlen(kr->ccname) +
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen strlen(keytab) +
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen kr->pd->authtok_size;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (kr->pd->cmd == SSS_PAM_CHAUTHTOK) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen buf->size += sizeof(uint32_t) + kr->pd->newauthtok_size;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen buf->data = talloc_size(kr, buf->size);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (buf->data == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("talloc_size failed.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen talloc_free(buf);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return ENOMEM;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen rp = 0;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen SAFEALIGN_COPY_UINT32(&buf->data[rp], &kr->pd->cmd, &rp);
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen SAFEALIGN_COPY_UINT32(&buf->data[rp], &kr->uid, &rp);
6ea145a99eeee923602f04d3c9183bbdba6cd190Timo Sirainen SAFEALIGN_COPY_UINT32(&buf->data[rp], &kr->gid, &rp);
6ea145a99eeee923602f04d3c9183bbdba6cd190Timo Sirainen SAFEALIGN_COPY_UINT32(&buf->data[rp], &validate, &rp);
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen SAFEALIGN_COPY_UINT32(&buf->data[rp], &kr->is_offline, &rp);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen SAFEALIGN_SET_UINT32(&buf->data[rp], strlen(kr->upn), &rp);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen safealign_memcpy(&buf->data[rp], kr->upn, strlen(kr->upn), &rp);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen SAFEALIGN_SET_UINT32(&buf->data[rp], strlen(kr->ccname), &rp);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen safealign_memcpy(&buf->data[rp], kr->ccname, strlen(kr->ccname), &rp);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen SAFEALIGN_SET_UINT32(&buf->data[rp], strlen(keytab), &rp);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen safealign_memcpy(&buf->data[rp], keytab, strlen(keytab), &rp);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen SAFEALIGN_COPY_UINT32(&buf->data[rp], &kr->pd->authtok_size, &rp);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen safealign_memcpy(&buf->data[rp], kr->pd->authtok,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen kr->pd->authtok_size, &rp);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (kr->pd->cmd == SSS_PAM_CHAUTHTOK) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen SAFEALIGN_COPY_UINT32(&buf->data[rp], &kr->pd->newauthtok_size, &rp);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen safealign_memcpy(&buf->data[rp], kr->pd->newauthtok,
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen kr->pd->newauthtok_size, &rp);
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen }
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen *io_buf = buf;
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen return EOK;
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen}
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainen
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainenstatic struct krb5_ctx *get_krb5_ctx(struct be_req *be_req)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct pam_data *pd;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen pd = talloc_get_type(be_req->req_data, struct pam_data);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen switch (pd->cmd) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen case SSS_PAM_AUTHENTICATE:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return talloc_get_type(be_req->be_ctx->bet_info[BET_AUTH].pvt_bet_data,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct krb5_ctx);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen break;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen case SSS_PAM_CHAUTHTOK:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen case SSS_PAM_CHAUTHTOK_PRELIM:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return talloc_get_type(be_req->be_ctx->bet_info[BET_CHPASS].pvt_bet_data,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct krb5_ctx);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen break;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen default:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("Unsupported PAM task.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return NULL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic void krb_reply(struct be_req *req, int dp_err, int result);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
a1044a46a8f3512173f4ea2684ef1fc3e61645c7Timo Sirainenstatic void krb5_child_timeout(struct tevent_context *ev,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct tevent_timer *te,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct timeval tv, void *pvt)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct krb5child_req *kr = talloc_get_type(pvt, struct krb5child_req);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct be_req *be_req = kr->req;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct pam_data *pd = kr->pd;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (kr->timeout_handler == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(9, ("timeout for child [%d] reached.\n", kr->child_pid));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen ret = kill(kr->child_pid, SIGKILL);
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen if (ret == -1) {
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen DEBUG(1, ("kill failed [%d][%s].\n", errno, strerror(errno)));
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen }
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen talloc_zfree(kr);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen pd->pam_status = PAM_AUTHINFO_UNAVAIL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen be_mark_offline(be_req->be_ctx);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen krb_reply(be_req, DP_ERR_OFFLINE, pd->pam_status);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic errno_t activate_child_timeout_handler(struct krb5child_req *kr)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct timeval tv;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen tv = tevent_timeval_current();
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen tv = tevent_timeval_add(&tv,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen dp_opt_get_int(kr->krb5_ctx->opts,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen KRB5_AUTH_TIMEOUT),
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen 0);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen kr->timeout_handler = tevent_add_timer(kr->req->be_ctx->ev, kr, tv,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen krb5_child_timeout, kr);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (kr->timeout_handler == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("tevent_add_timer failed.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return ENOMEM;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return EOK;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b457d2ecf97fb52064f9dd563fd4e8065af39dfbTimo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic int krb5_cleanup(void *ptr)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct krb5child_req *kr = talloc_get_type(ptr, struct krb5child_req);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (kr == NULL) return EOK;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen child_cleanup(kr->read_from_child_fd, kr->write_to_child_fd);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen memset(kr, 0, sizeof(struct krb5child_req));
f0e811f0e306bb20d3da9c26353bdd5669132f29Timo Sirainen
f0e811f0e306bb20d3da9c26353bdd5669132f29Timo Sirainen return EOK;
f0e811f0e306bb20d3da9c26353bdd5669132f29Timo Sirainen}
f0e811f0e306bb20d3da9c26353bdd5669132f29Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic errno_t krb5_setup(struct be_req *req, struct krb5child_req **krb5_req)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct krb5child_req *kr = NULL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct krb5_ctx *krb5_ctx;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct pam_data *pd;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen errno_t err;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen pd = talloc_get_type(req->req_data, struct pam_data);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen krb5_ctx = get_krb5_ctx(req);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (krb5_ctx == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("Kerberos context not available.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen err = EINVAL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto failed;
48ce7a375ada1b80545bc6767adb8e8fb23699a8Timo Sirainen }
48ce7a375ada1b80545bc6767adb8e8fb23699a8Timo Sirainen
48ce7a375ada1b80545bc6767adb8e8fb23699a8Timo Sirainen kr = talloc_zero(req, struct krb5child_req);
48ce7a375ada1b80545bc6767adb8e8fb23699a8Timo Sirainen if (kr == NULL) {
48ce7a375ada1b80545bc6767adb8e8fb23699a8Timo Sirainen DEBUG(1, ("talloc failed.\n"));
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen err = ENOMEM;
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen goto failed;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen kr->read_from_child_fd = -1;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen kr->write_to_child_fd = -1;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen kr->is_offline = false;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen kr->active_ccache_present = true;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen talloc_set_destructor((TALLOC_CTX *) kr, krb5_cleanup);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen kr->pd = pd;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen kr->req = req;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen kr->krb5_ctx = krb5_ctx;
1856c361aad526948d56d8aafd576bca94516b92Timo Sirainen
1856c361aad526948d56d8aafd576bca94516b92Timo Sirainen *krb5_req = kr;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return EOK;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenfailed:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen talloc_zfree(kr);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return err;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic errno_t fork_child(struct krb5child_req *kr)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int pipefd_to_child[2];
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int pipefd_from_child[2];
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen pid_t pid;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen errno_t err;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = pipe(pipefd_from_child);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret == -1) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen err = errno;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("pipe failed [%d][%s].\n", errno, strerror(errno)));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return err;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = pipe(pipefd_to_child);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret == -1) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen err = errno;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("pipe failed [%d][%s].\n", errno, strerror(errno)));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return err;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen pid = fork();
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (pid == 0) { /* child */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* We need to keep the root privileges to read the keytab file if
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen * validation is enabled, otherwise we can drop them here and run
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen * krb5_child with user privileges.
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen * If authtok_size is zero we are offline and want to create an empty
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen * ccache file. In this case we can drop the privileges, too. */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (!dp_opt_get_bool(kr->krb5_ctx->opts, KRB5_VALIDATE) ||
6ea145a99eeee923602f04d3c9183bbdba6cd190Timo Sirainen kr->pd->authtok_size == 0) {
6ea145a99eeee923602f04d3c9183bbdba6cd190Timo Sirainen ret = become_user(kr->uid, kr->gid);
6ea145a99eeee923602f04d3c9183bbdba6cd190Timo Sirainen if (ret != EOK) {
6ea145a99eeee923602f04d3c9183bbdba6cd190Timo Sirainen DEBUG(1, ("become_user failed.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen err = exec_child(kr,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen pipefd_to_child, pipefd_from_child,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen KRB5_CHILD, kr->krb5_ctx->child_debug_fd);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (err != EOK) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("Could not exec LDAP child: [%d][%s].\n",
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen err, strerror(err)));
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen return err;
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen } else if (pid > 0) { /* parent */
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen kr->child_pid = pid;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen kr->read_from_child_fd = pipefd_from_child[0];
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen close(pipefd_from_child[1]);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen kr->write_to_child_fd = pipefd_to_child[1];
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen close(pipefd_to_child[0]);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen fd_nonblocking(kr->read_from_child_fd);
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen fd_nonblocking(kr->write_to_child_fd);
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen err = activate_child_timeout_handler(kr);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (err != EOK) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("activate_child_timeout_handler failed.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen } else { /* error */
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen err = errno;
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen DEBUG(1, ("fork failed [%d][%s].\n", errno, strerror(errno)));
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen return err;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return EOK;
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstruct handle_child_state {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct tevent_context *ev;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct krb5child_req *kr;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen uint8_t *buf;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ssize_t len;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen};
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic void handle_child_step(struct tevent_req *subreq);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic void handle_child_done(struct tevent_req *subreq);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic struct tevent_req *handle_child_send(TALLOC_CTX *mem_ctx,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct tevent_context *ev,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct krb5child_req *kr)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct tevent_req *req, *subreq;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct handle_child_state *state;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct io_buffer *buf;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen req = tevent_req_create(mem_ctx, &state, struct handle_child_state);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (req == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return NULL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen state->ev = ev;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen state->kr = kr;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen state->buf = NULL;
e07677bb15404a3c18ad205efae86d6db31c3150Timo Sirainen state->len = 0;
e07677bb15404a3c18ad205efae86d6db31c3150Timo Sirainen
e07677bb15404a3c18ad205efae86d6db31c3150Timo Sirainen ret = create_send_buffer(kr, &buf);
e07677bb15404a3c18ad205efae86d6db31c3150Timo Sirainen if (ret != EOK) {
e07677bb15404a3c18ad205efae86d6db31c3150Timo Sirainen DEBUG(1, ("create_send_buffer failed.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto fail;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = fork_child(kr);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret != EOK) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("fork_child failed.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto fail;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen subreq = write_pipe_send(state, ev, buf->data, buf->size,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen kr->write_to_child_fd);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (!subreq) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = ENOMEM;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto fail;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen tevent_req_set_callback(subreq, handle_child_step, req);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return req;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenfail:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen tevent_req_error(req, ret);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen tevent_req_post(req, ev);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return req;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic void handle_child_step(struct tevent_req *subreq)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct tevent_req *req = tevent_req_callback_data(subreq,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct tevent_req);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct handle_child_state *state = tevent_req_data(req,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct handle_child_state);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = write_pipe_recv(subreq);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen talloc_zfree(subreq);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret != EOK) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen tevent_req_error(req, ret);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen close(state->kr->write_to_child_fd);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen state->kr->write_to_child_fd = -1;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen subreq = read_pipe_send(state, state->ev, state->kr->read_from_child_fd);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (!subreq) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen tevent_req_error(req, ENOMEM);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen tevent_req_set_callback(subreq, handle_child_done, req);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic void handle_child_done(struct tevent_req *subreq)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct tevent_req *req = tevent_req_callback_data(subreq,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct tevent_req);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct handle_child_state *state = tevent_req_data(req,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct handle_child_state);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = read_pipe_recv(subreq, state, &state->buf, &state->len);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen talloc_zfree(subreq);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret != EOK) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen tevent_req_error(req, ret);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen close(state->kr->read_from_child_fd);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen state->kr->read_from_child_fd = -1;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen tevent_req_done(req);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic int handle_child_recv(struct tevent_req *req,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen TALLOC_CTX *mem_ctx,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen uint8_t **buf, ssize_t *len)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct handle_child_state *state = tevent_req_data(req,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct handle_child_state);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen TEVENT_REQ_RETURN_ON_ERROR(req);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen *buf = talloc_move(mem_ctx, &state->buf);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen *len = state->len;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return EOK;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic void get_user_attr_done(void *pvt, int err, struct ldb_result *res);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic void krb5_resolve_done(struct tevent_req *req);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic void krb5_save_ccname_done(struct tevent_req *req);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic void krb5_child_done(struct tevent_req *req);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic void krb5_pam_handler_cache_done(struct tevent_req *treq);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenvoid krb5_pam_handler(struct be_req *be_req)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct pam_data *pd;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen const char **attrs;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int pam_status = PAM_SYSTEM_ERR;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int dp_err = DP_ERR_FATAL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen pd = talloc_get_type(be_req->req_data, struct pam_data);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen switch (pd->cmd) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen case SSS_PAM_AUTHENTICATE:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen case SSS_PAM_CHAUTHTOK:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen case SSS_PAM_CHAUTHTOK_PRELIM:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen break;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen case SSS_PAM_ACCT_MGMT:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen case SSS_PAM_SETCRED:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen case SSS_PAM_OPEN_SESSION:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen case SSS_PAM_CLOSE_SESSION:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen pam_status = PAM_SUCCESS;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen dp_err = DP_ERR_OK;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto done;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen break;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen default:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(4, ("krb5 does not handles pam task %d.\n", pd->cmd));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen pam_status = PAM_MODULE_UNKNOWN;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen dp_err = DP_ERR_OK;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto done;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (be_is_offline(be_req->be_ctx) &&
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen (pd->cmd == SSS_PAM_CHAUTHTOK || pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM)) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(9, ("Password changes are not possible while offline.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen pam_status = PAM_AUTHINFO_UNAVAIL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen dp_err = DP_ERR_OFFLINE;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto done;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen attrs = talloc_array(be_req, const char *, 6);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (attrs == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto done;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen attrs[0] = SYSDB_UPN;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen attrs[1] = SYSDB_HOMEDIR;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen attrs[2] = SYSDB_CCACHE_FILE;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen attrs[3] = SYSDB_UIDNUM;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen attrs[4] = SYSDB_GIDNUM;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen attrs[5] = NULL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = sysdb_get_user_attr(be_req, be_req->be_ctx->sysdb,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen be_req->be_ctx->domain, pd->user, attrs,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen get_user_attr_done, be_req);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto done;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainendone:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen pd->pam_status = pam_status;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen krb_reply(be_req, dp_err, pd->pam_status);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic void get_user_attr_done(void *pvt, int err, struct ldb_result *res)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct be_req *be_req = talloc_get_type(pvt, struct be_req);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct krb5_ctx *krb5_ctx;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct krb5child_req *kr = NULL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct tevent_req *req;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen krb5_error_code kerr;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct pam_data *pd = talloc_get_type(be_req->req_data, struct pam_data);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int pam_status = PAM_SYSTEM_ERR;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int dp_err = DP_ERR_FATAL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen const char *ccache_file = NULL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen const char *realm;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = krb5_setup(be_req, &kr);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret != EOK) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("krb5_setup failed.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto failed;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen krb5_ctx = kr->krb5_ctx;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (err != LDB_SUCCESS) {
6b4b3e5fe8d9e84f4b1356ee898ca76996a11fe1Timo Sirainen DEBUG(5, ("sysdb search for upn of user [%s] failed.\n", pd->user));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto failed;
6b4b3e5fe8d9e84f4b1356ee898ca76996a11fe1Timo Sirainen }
6b4b3e5fe8d9e84f4b1356ee898ca76996a11fe1Timo Sirainen
6b4b3e5fe8d9e84f4b1356ee898ca76996a11fe1Timo Sirainen realm = dp_opt_get_cstring(krb5_ctx->opts, KRB5_REALM);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (realm == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("Missing Kerberos realm.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto failed;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
e22ec7998afd426c53c658483ce66b6e404e27c6Timo Sirainen switch (res->count) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen case 0:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(5, ("No attributes for user [%s] found.\n", pd->user));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto failed;
e22ec7998afd426c53c658483ce66b6e404e27c6Timo Sirainen break;
e22ec7998afd426c53c658483ce66b6e404e27c6Timo Sirainen
e22ec7998afd426c53c658483ce66b6e404e27c6Timo Sirainen case 1:
e22ec7998afd426c53c658483ce66b6e404e27c6Timo Sirainen kr->upn = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_UPN, NULL);
e22ec7998afd426c53c658483ce66b6e404e27c6Timo Sirainen if (kr->upn == NULL) {
e22ec7998afd426c53c658483ce66b6e404e27c6Timo Sirainen /* NOTE: this is a hack, works only in some environments */
e22ec7998afd426c53c658483ce66b6e404e27c6Timo Sirainen kr->upn = talloc_asprintf(be_req, "%s@%s", pd->user, realm);
e22ec7998afd426c53c658483ce66b6e404e27c6Timo Sirainen if (kr->upn == NULL) {
e22ec7998afd426c53c658483ce66b6e404e27c6Timo Sirainen DEBUG(1, ("failed to build simple upn.\n"));
e22ec7998afd426c53c658483ce66b6e404e27c6Timo Sirainen goto failed;
e22ec7998afd426c53c658483ce66b6e404e27c6Timo Sirainen }
e22ec7998afd426c53c658483ce66b6e404e27c6Timo Sirainen DEBUG(9, ("Using simple UPN [%s].\n", kr->upn));
e22ec7998afd426c53c658483ce66b6e404e27c6Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen kr->homedir = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_HOMEDIR,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen NULL);
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen if (kr->homedir == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(4, ("Home directory for user [%s] not known.\n", pd->user));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen kr->uid = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_UIDNUM, 0);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (kr->uid == 0) {
6b4b3e5fe8d9e84f4b1356ee898ca76996a11fe1Timo Sirainen DEBUG(4, ("UID for user [%s] not known.\n", pd->user));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto failed;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen kr->gid = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_GIDNUM, 0);
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen if (kr->gid == 0) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(4, ("GID for user [%s] not known.\n", pd->user));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto failed;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ccache_file = ldb_msg_find_attr_as_string(res->msgs[0],
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen SYSDB_CCACHE_FILE,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen NULL);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ccache_file != NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = check_if_ccache_file_is_used(kr->uid, ccache_file,
6b4b3e5fe8d9e84f4b1356ee898ca76996a11fe1Timo Sirainen &kr->active_ccache_present);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret != EOK) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("check_if_ccache_file_is_used failed.\n"));
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen goto failed;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen kerr = check_for_valid_tgt(ccache_file, realm, kr->upn,
ce74395e2a932342e04fb682395bcce111574969Timo Sirainen &kr->valid_tgt_present);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (kerr != 0) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("check_for_valid_tgt failed.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto failed;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen } else {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen kr->active_ccache_present = false;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen kr->valid_tgt_present = false;
e22ec7998afd426c53c658483ce66b6e404e27c6Timo Sirainen DEBUG(4, ("No ccache file for user [%s] found.\n", pd->user));
e22ec7998afd426c53c658483ce66b6e404e27c6Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(9, ("Ccache_file is [%s] and is %s active and TGT is %s valid.\n",
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ccache_file ? ccache_file : "not set",
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen kr->active_ccache_present ? "" : "not",
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen kr->valid_tgt_present ? "" : "not"));
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen kr->ccname = ccache_file;
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen break;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen default:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("A user search by name (%s) returned > 1 results!\n",
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen pd->user));
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen goto failed;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen break;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen req = be_resolve_server_send(kr, be_req->be_ctx->ev, be_req->be_ctx,
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen krb5_ctx->service->name);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (req == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("handle_child_send failed.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto failed;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen tevent_req_set_callback(req, krb5_resolve_done, kr);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return;
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenfailed:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen talloc_free(kr);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen pd->pam_status = pam_status;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen krb_reply(be_req, dp_err, pd->pam_status);
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen}
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainenstatic void krb5_resolve_done(struct tevent_req *req)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct krb5child_req *kr = tevent_req_callback_data(req,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct krb5child_req);
e22ec7998afd426c53c658483ce66b6e404e27c6Timo Sirainen int ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int pam_status = PAM_SYSTEM_ERR;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int dp_err = DP_ERR_FATAL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct pam_data *pd = kr->pd;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct be_req *be_req = kr->req;
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen char *msg;
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen size_t offset = 0;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = be_resolve_server_recv(req, &kr->srv);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen talloc_zfree(req);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen /* all servers have been tried and none
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen * was found good, setting offline,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen * but we still have to call the child to setup
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen * the ccache file. */
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen be_mark_offline(be_req->be_ctx);
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen kr->is_offline = true;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (kr->ccname == NULL ||
e22ec7998afd426c53c658483ce66b6e404e27c6Timo Sirainen (be_is_offline(be_req->be_ctx) && !kr->active_ccache_present &&
e22ec7998afd426c53c658483ce66b6e404e27c6Timo Sirainen !kr->valid_tgt_present) ||
e22ec7998afd426c53c658483ce66b6e404e27c6Timo Sirainen (!be_is_offline(be_req->be_ctx) && !kr->active_ccache_present)) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(9, ("Recreating ccache file.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (kr->ccname != NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (strncmp(kr->ccname, "FILE:", 5) == 0) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen offset = 5;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (kr->ccname[offset] != '/') {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("Ccache file name [%s] is not an absolute path.\n",
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen kr->ccname + offset));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto done;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = unlink(kr->ccname + offset);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret == -1 && errno != ENOENT) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("unlink [%s] failed [%d][%s].\n", kr->ccname,
e22ec7998afd426c53c658483ce66b6e404e27c6Timo Sirainen errno, strerror(errno)));
b50234708ad651e98a4198e1b910106b279aae32Timo Sirainen goto done;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b650f04c3b2e7dea2295bdbe3239eb82ec03ada0Timo Sirainen kr->ccname = expand_ccname_template(kr, kr,
6b4b3e5fe8d9e84f4b1356ee898ca76996a11fe1Timo Sirainen dp_opt_get_cstring(kr->krb5_ctx->opts,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen KRB5_CCNAME_TMPL)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen );
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (kr->ccname == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("expand_ccname_template failed.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto done;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (be_is_offline(be_req->be_ctx)) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(9, ("Preparing for offline operation.\n"));
6b4b3e5fe8d9e84f4b1356ee898ca76996a11fe1Timo Sirainen kr->is_offline = true;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (kr->valid_tgt_present) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(9, ("Valid TGT available, nothing to do.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen msg = talloc_asprintf(pd, "%s=%s", CCACHE_ENV_NAME, kr->ccname);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (msg == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("talloc_asprintf failed.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto done;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ret = pam_add_response(pd, SSS_PAM_ENV_ITEM, strlen(msg) + 1,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen (uint8_t *) msg);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (ret != EOK) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("pam_add_response failed.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen pam_status = PAM_AUTHINFO_UNAVAIL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen dp_err = DP_ERR_OFFLINE;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto done;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen memset(pd->authtok, 0, pd->authtok_size);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen pd->authtok_size = 0;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (kr->active_ccache_present) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen req = krb5_save_ccname_send(kr, be_req->be_ctx->ev,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen be_req->be_ctx->sysdb,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen be_req->be_ctx->domain, pd->user,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen kr->ccname);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (req == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("krb5_save_ccname_send failed.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto done;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen tevent_req_set_callback(req, krb5_save_ccname_done, kr);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen req = handle_child_send(kr, be_req->be_ctx->ev, kr);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen if (req == NULL) {
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen DEBUG(1, ("handle_child_send failed.\n"));
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen goto done;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen }
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen tevent_req_set_callback(req, krb5_child_done, kr);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen return;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainendone:
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen talloc_free(kr);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen pd->pam_status = pam_status;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen krb_reply(be_req, dp_err, pd->pam_status);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen}
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainenstatic void krb5_child_done(struct tevent_req *req)
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen{
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct krb5child_req *kr = tevent_req_callback_data(req,
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct krb5child_req);
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct pam_data *pd = kr->pd;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen struct be_req *be_req = kr->req;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int ret;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen uint8_t *buf = NULL;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ssize_t len = -1;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen ssize_t pref_len;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int p;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int32_t *msg_status;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int32_t *msg_type;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int32_t *msg_len;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int pam_status = PAM_SYSTEM_ERR;
b772ddf3cfb606dddaa465b317a0dc01bf06c6e4Timo Sirainen int dp_err = DP_ERR_FATAL;
ret = handle_child_recv(req, pd, &buf, &len);
talloc_zfree(kr->timeout_handler);
talloc_zfree(req);
if (ret != EOK) {
DEBUG(1, ("child failed (%d [%s])\n", ret, strerror(ret)));
goto done;
}
if ((size_t) len < 3*sizeof(int32_t)) {
DEBUG(1, ("message too short.\n"));
goto done;
}
p=0;
msg_status = ((int32_t *)(buf+p));
p += sizeof(int32_t);
msg_type = ((int32_t *)(buf+p));
p += sizeof(int32_t);
msg_len = ((int32_t *)(buf+p));
p += sizeof(int32_t);
DEBUG(4, ("child response [%d][%d][%d].\n", *msg_status, *msg_type,
*msg_len));
if ((p + *msg_len) != len) {
DEBUG(1, ("message format error.\n"));
goto done;
}
if (*msg_status != PAM_SUCCESS && *msg_status != PAM_AUTHINFO_UNAVAIL) {
pam_status = *msg_status;
dp_err = DP_ERR_OK;
ret = pam_add_response(pd, *msg_type, *msg_len, &buf[p]);
if (ret != EOK) {
DEBUG(1, ("pam_add_response failed.\n"));
}
goto done;
} else {
pd->pam_status = *msg_status;
}
if (*msg_status == PAM_SUCCESS && pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM) {
pam_status = PAM_SUCCESS;
dp_err = DP_ERR_OK;
goto done;
}
pref_len = strlen(CCACHE_ENV_NAME)+1;
if (*msg_len > pref_len &&
strncmp((const char *) &buf[p], CCACHE_ENV_NAME"=", pref_len) == 0) {
kr->ccname = talloc_strndup(kr, (char *) &buf[p+pref_len],
*msg_len-pref_len);
if (kr->ccname == NULL) {
DEBUG(1, ("talloc_strndup failed.\n"));
goto done;
}
} else {
DEBUG(1, ("Missing ccache name in child response [%.*s].\n", *msg_len,
&buf[p]));
goto done;
}
if (*msg_status == PAM_AUTHINFO_UNAVAIL) {
if (kr->srv != NULL) {
fo_set_port_status(kr->srv, PORT_NOT_WORKING);
}
be_mark_offline(be_req->be_ctx);
kr->is_offline = true;
} else if (kr->srv != NULL) {
fo_set_port_status(kr->srv, PORT_WORKING);
}
struct sysdb_attrs *attrs;
attrs = sysdb_new_attrs(kr);
ret = sysdb_attrs_add_string(attrs, SYSDB_CCACHE_FILE, kr->ccname);
if (ret != EOK) {
DEBUG(1, ("sysdb_attrs_add_string failed.\n"));
goto done;
}
req = krb5_save_ccname_send(kr, be_req->be_ctx->ev, be_req->be_ctx->sysdb,
be_req->be_ctx->domain, pd->user, kr->ccname);
if (req == NULL) {
DEBUG(1, ("krb5_save_ccname_send failed.\n"));
goto done;
}
tevent_req_set_callback(req, krb5_save_ccname_done, kr);
return;
done:
talloc_free(kr);
pd->pam_status = pam_status;
krb_reply(be_req, dp_err, pd->pam_status);
}
static void krb5_save_ccname_done(struct tevent_req *req)
{
struct krb5child_req *kr = tevent_req_callback_data(req,
struct krb5child_req);
struct pam_data *pd = kr->pd;
struct be_req *be_req = kr->req;
struct krb5_ctx *krb5_ctx = kr->krb5_ctx;
int pam_status = PAM_SYSTEM_ERR;
int dp_err = DP_ERR_FATAL;
int ret;
char *password = NULL;
if (pd->cmd == SSS_PAM_AUTHENTICATE || pd->cmd == SSS_PAM_CHAUTHTOK) {
ret = add_krb5_env(krb5_ctx->opts, kr->ccname, pd);
if (ret != EOK) {
DEBUG(1, ("add_krb5_env failed.\n"));
goto failed;
}
}
ret = sysdb_set_user_attr_recv(req);
talloc_zfree(req);
if (ret != EOK) {
DEBUG(1, ("Saving ccache name failed.\n"));
goto failed;
}
if (kr->is_offline) {
DEBUG(4, ("Backend is marked offline, retry later!\n"));
pam_status = PAM_AUTHINFO_UNAVAIL;
dp_err = DP_ERR_OFFLINE;
goto failed;
}
if (be_req->be_ctx->domain->cache_credentials == TRUE) {
/* password caching failures are not fatal errors */
pd->pam_status = PAM_SUCCESS;
switch(pd->cmd) {
case SSS_PAM_AUTHENTICATE:
case SSS_PAM_CHAUTHTOK_PRELIM:
password = talloc_size(be_req, pd->authtok_size + 1);
if (password != NULL) {
memcpy(password, pd->authtok, pd->authtok_size);
password[pd->authtok_size] = '\0';
}
break;
case SSS_PAM_CHAUTHTOK:
password = talloc_size(be_req, pd->newauthtok_size + 1);
if (password != NULL) {
memcpy(password, pd->newauthtok, pd->newauthtok_size);
password[pd->newauthtok_size] = '\0';
}
break;
default:
DEBUG(0, ("unsupported PAM command [%d].\n", pd->cmd));
}
if (password == NULL) {
DEBUG(0, ("password not available, offline auth may not work.\n"));
goto failed;
}
talloc_set_destructor((TALLOC_CTX *)password, password_destructor);
req = sysdb_cache_password_send(be_req, be_req->be_ctx->ev,
be_req->be_ctx->sysdb, NULL,
be_req->be_ctx->domain, pd->user,
password);
if (req == NULL) {
DEBUG(2, ("cache_password_send failed, offline auth may not work.\n"));
goto failed;
}
tevent_req_set_callback(req, krb5_pam_handler_cache_done, be_req);
return;
}
pam_status = PAM_SUCCESS;
dp_err = DP_ERR_OK;
failed:
talloc_free(kr);
pd->pam_status = pam_status;
krb_reply(be_req, dp_err, pd->pam_status);
}
static void krb5_pam_handler_cache_done(struct tevent_req *subreq)
{
struct be_req *be_req = tevent_req_callback_data(subreq, struct be_req);
int ret;
/* password caching failures are not fatal errors */
ret = sysdb_cache_password_recv(subreq);
talloc_zfree(subreq);
/* so we just log it any return */
if (ret) {
DEBUG(2, ("Failed to cache password (%d)[%s]!?\n",
ret, strerror(ret)));
}
krb_reply(be_req, DP_ERR_OK, PAM_SUCCESS);
}
static void krb_reply(struct be_req *req, int dp_err, int result)
{
req->fn(req, dp_err, result, NULL);
}