summaryrefslogtreecommitdiffstats
path: root/server/providers/krb5
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2010-02-18 07:49:04 -0500
committerStephen Gallagher <sgallagh@redhat.com>2010-02-18 13:48:45 -0500
commit1c48b5a62f73234ed26bb20f0ab345ab61cda0ab (patch)
tree0b6cddd567a862e1a7b5df23764869782a62ca78 /server/providers/krb5
parent8c56df3176f528fe0260974b3bf934173c4651ea (diff)
downloadsssd-1c48b5a62f73234ed26bb20f0ab345ab61cda0ab.tar.gz
sssd-1c48b5a62f73234ed26bb20f0ab345ab61cda0ab.tar.xz
sssd-1c48b5a62f73234ed26bb20f0ab345ab61cda0ab.zip
Rename server/ directory to src/
Also update BUILD.txt
Diffstat (limited to 'server/providers/krb5')
-rw-r--r--server/providers/krb5/krb5_auth.c1193
-rw-r--r--server/providers/krb5/krb5_auth.h91
-rw-r--r--server/providers/krb5/krb5_become_user.c61
-rw-r--r--server/providers/krb5/krb5_child.c1030
-rw-r--r--server/providers/krb5/krb5_common.c356
-rw-r--r--server/providers/krb5/krb5_common.h72
-rw-r--r--server/providers/krb5/krb5_init.c152
-rw-r--r--server/providers/krb5/krb5_utils.c145
-rw-r--r--server/providers/krb5/krb5_utils.h39
9 files changed, 0 insertions, 3139 deletions
diff --git a/server/providers/krb5/krb5_auth.c b/server/providers/krb5/krb5_auth.c
deleted file mode 100644
index a2dadc808..000000000
--- a/server/providers/krb5/krb5_auth.c
+++ /dev/null
@@ -1,1193 +0,0 @@
-/*
- SSSD
-
- Kerberos 5 Backend Module
-
- Authors:
- Sumit Bose <sbose@redhat.com>
-
- Copyright (C) 2009 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <errno.h>
-#include <sys/time.h>
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <pwd.h>
-#include <sys/stat.h>
-
-#include <security/pam_modules.h>
-
-#include "util/util.h"
-#include "util/find_uid.h"
-#include "db/sysdb.h"
-#include "providers/child_common.h"
-#include "providers/krb5/krb5_auth.h"
-#include "providers/krb5/krb5_utils.h"
-
-#ifndef SSSD_LIBEXEC_PATH
-#error "SSSD_LIBEXEC_PATH not defined"
-#else
-#define KRB5_CHILD SSSD_LIBEXEC_PATH"/krb5_child"
-#endif
-
-static errno_t add_krb5_env(struct dp_option *opts, const char *ccname,
- struct pam_data *pd)
-{
- int ret;
- const char *dummy;
- char *env;
- TALLOC_CTX *tmp_ctx = NULL;
-
- tmp_ctx = talloc_new(NULL);
- if (tmp_ctx == NULL) {
- DEBUG(1, ("talloc_new failed.\n"));
- return ENOMEM;
- }
-
- if (ccname != NULL) {
- env = talloc_asprintf(tmp_ctx, "%s=%s",CCACHE_ENV_NAME, ccname);
- if (env == NULL) {
- DEBUG(1, ("talloc_asprintf failed.\n"));
- ret = ENOMEM;
- goto done;
- }
- ret = pam_add_response(pd, SSS_PAM_ENV_ITEM, strlen(env)+1,
- (uint8_t *) env);
- if (ret != EOK) {
- DEBUG(1, ("pam_add_response failed.\n"));
- goto done;
- }
- }
-
- dummy = dp_opt_get_cstring(opts, KRB5_REALM);
- if (dummy != NULL) {
- env = talloc_asprintf(tmp_ctx, "%s=%s", SSSD_KRB5_REALM, dummy);
- if (env == NULL) {
- DEBUG(1, ("talloc_asprintf failed.\n"));
- ret = ENOMEM;
- goto done;
- }
- ret = pam_add_response(pd, SSS_PAM_ENV_ITEM, strlen(env)+1,
- (uint8_t *) env);
- if (ret != EOK) {
- DEBUG(1, ("pam_add_response failed.\n"));
- goto done;
- }
- }
-
- dummy = dp_opt_get_cstring(opts, KRB5_KDC);
- if (dummy != NULL) {
- env = talloc_asprintf(tmp_ctx, "%s=%s", SSSD_KRB5_KDC, dummy);
- if (env == NULL) {
- DEBUG(1, ("talloc_asprintf failed.\n"));
- ret = ENOMEM;
- goto done;
- }
- ret = pam_add_response(pd, SSS_PAM_ENV_ITEM, strlen(env)+1,
- (uint8_t *) env);
- if (ret != EOK) {
- DEBUG(1, ("pam_add_response failed.\n"));
- goto done;
- }
- }
-
- ret = EOK;
-
-done:
- talloc_free(tmp_ctx);
- return ret;
-}
-
-static errno_t check_if_ccache_file_is_used(uid_t uid, const char *ccname,
- bool *result)
-{
- int ret;
- size_t offset = 0;
- struct stat stat_buf;
- const char *filename;
- bool active;
-
- *result = false;
-
- if (ccname == NULL || *ccname == '\0') {
- return EINVAL;
- }
-
- if (strncmp(ccname, "FILE:", 5) == 0) {
- offset = 5;
- }
-
- filename = ccname + offset;
-
- if (filename[0] != '/') {
- DEBUG(1, ("Only absolute path names are allowed"));
- return EINVAL;
- }
-
- ret = lstat(filename, &stat_buf);
-
- if (ret == -1 && errno != ENOENT) {
- DEBUG(1, ("stat failed [%d][%s].\n", errno, strerror(errno)));
- return errno;
- } else if (ret == EOK) {
- if (stat_buf.st_uid != uid) {
- DEBUG(1, ("Cache file [%s] exists, but is owned by [%d] instead of "
- "[%d].\n", filename, stat_buf.st_uid, uid));
- return EINVAL;
- }
-
- if (!S_ISREG(stat_buf.st_mode)) {
- DEBUG(1, ("Cache file [%s] exists, but is not a regular file.\n",
- filename));
- return EINVAL;
- }
- }
-
- ret = check_if_uid_is_active(uid, &active);
- if (ret != EOK) {
- DEBUG(1, ("check_if_uid_is_active failed.\n"));
- return ret;
- }
-
- if (!active) {
- DEBUG(5, ("User [%d] is not active\n", uid));
- } else {
- DEBUG(9, ("User [%d] is still active, reusing ccache file [%s].\n",
- uid, filename));
- *result = true;
- }
- return EOK;
-}
-
-struct krb5_save_ccname_state {
- struct tevent_context *ev;
- struct sysdb_ctx *sysdb;
- struct sysdb_handle *handle;
- struct sss_domain_info *domain;
- const char *name;
- struct sysdb_attrs *attrs;
-};
-
-static void krb5_save_ccname_trans(struct tevent_req *subreq);
-static void krb5_set_user_attr_done(struct tevent_req *subreq);
-
-static struct tevent_req *krb5_save_ccname_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_ctx *sysdb,
- struct sss_domain_info *domain,
- const char *name,
- const char *ccname)
-{
- struct tevent_req *req;
- struct tevent_req *subreq;
- struct krb5_save_ccname_state *state;
- int ret;
-
- if (name == NULL || ccname == NULL) {
- DEBUG(1, ("Missing user or ccache name.\n"));
- return NULL;
- }
-
- req = tevent_req_create(mem_ctx, &state, struct krb5_save_ccname_state);
- if (req == NULL) {
- DEBUG(1, ("tevent_req_create failed.\n"));
- return NULL;
- }
-
- state->ev = ev;
- state->sysdb = sysdb;
- state->handle = NULL;
- state->domain = domain;
- state->name = name;
-
- state->attrs = sysdb_new_attrs(state);
- ret = sysdb_attrs_add_string(state->attrs, SYSDB_CCACHE_FILE, ccname);
- if (ret != EOK) {
- DEBUG(1, ("sysdb_attrs_add_string failed.\n"));
- goto failed;
- }
-
- subreq = sysdb_transaction_send(state, ev, sysdb);
- if (subreq == NULL) {
- goto failed;
- }
- tevent_req_set_callback(subreq, krb5_save_ccname_trans, req);
-
- return req;
-
-failed:
- talloc_free(req);
- return NULL;
-}
-
-static void krb5_save_ccname_trans(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct krb5_save_ccname_state *state = tevent_req_data(req,
- struct krb5_save_ccname_state);
- int ret;
-
- ret = sysdb_transaction_recv(subreq, state, &state->handle);
- talloc_zfree(subreq);
- if (ret != EOK) {
- DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
- tevent_req_error(req, ret);
- return;
- }
-
- subreq = sysdb_set_user_attr_send(state, state->ev, state->handle,
- state->domain, state->name,
- state->attrs, SYSDB_MOD_REP);
- if (subreq == NULL) {
- DEBUG(6, ("Error: Out of memory\n"));
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, krb5_set_user_attr_done, req);
-}
-
-static void krb5_set_user_attr_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct krb5_save_ccname_state *state = tevent_req_data(req,
- struct krb5_save_ccname_state);
- int ret;
-
- ret = sysdb_set_user_attr_recv(subreq);
- talloc_zfree(subreq);
- if (ret != EOK) {
- DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
- tevent_req_error(req, ret);
- return;
- }
-
- subreq = sysdb_transaction_commit_send(state, state->ev, state->handle);
- if (subreq == NULL) {
- DEBUG(6, ("Error: Out of memory\n"));
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, sysdb_transaction_complete, req);
- return;
-}
-
-int krb5_save_ccname_recv(struct tevent_req *req)
-{
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- return EOK;
-}
-
-errno_t create_send_buffer(struct krb5child_req *kr, struct io_buffer **io_buf)
-{
- struct io_buffer *buf;
- size_t rp;
- const char *keytab;
- uint32_t validate;
-
- keytab = dp_opt_get_cstring(kr->krb5_ctx->opts, KRB5_KEYTAB);
- if (keytab == NULL) {
- DEBUG(1, ("Missing keytab option.\n"));
- return EINVAL;
- }
-
- validate = dp_opt_get_bool(kr->krb5_ctx->opts, KRB5_VALIDATE) ? 1 : 0;
-
- buf = talloc(kr, struct io_buffer);
- if (buf == NULL) {
- DEBUG(1, ("talloc failed.\n"));
- return ENOMEM;
- }
-
- buf->size = 9*sizeof(uint32_t) + strlen(kr->pd->upn) + strlen(kr->ccname) +
- strlen(keytab) +
- kr->pd->authtok_size;
- if (kr->pd->cmd == SSS_PAM_CHAUTHTOK) {
- buf->size += sizeof(uint32_t) + kr->pd->newauthtok_size;
- }
-
- buf->data = talloc_size(kr, buf->size);
- if (buf->data == NULL) {
- DEBUG(1, ("talloc_size failed.\n"));
- talloc_free(buf);
- return ENOMEM;
- }
-
- rp = 0;
- COPY_UINT32(&buf->data[rp], &kr->pd->cmd, rp);
- COPY_UINT32(&buf->data[rp], &kr->pd->pw_uid, rp);
- COPY_UINT32(&buf->data[rp], &kr->pd->gr_gid, rp);
- COPY_UINT32(&buf->data[rp], &validate, rp);
- COPY_UINT32(&buf->data[rp], &kr->is_offline, rp);
-
- COPY_UINT32_VALUE(&buf->data[rp], strlen(kr->pd->upn), rp);
- COPY_MEM(&buf->data[rp], kr->pd->upn, rp, strlen(kr->pd->upn));
-
- COPY_UINT32_VALUE(&buf->data[rp], strlen(kr->ccname), rp);
- COPY_MEM(&buf->data[rp], kr->ccname, rp, strlen(kr->ccname));
-
- COPY_UINT32_VALUE(&buf->data[rp], strlen(keytab), rp);
- COPY_MEM(&buf->data[rp], keytab, rp, strlen(keytab));
-
- COPY_UINT32(&buf->data[rp], &kr->pd->authtok_size, rp);
- COPY_MEM(&buf->data[rp], kr->pd->authtok, rp, kr->pd->authtok_size);
-
- if (kr->pd->cmd == SSS_PAM_CHAUTHTOK) {
- COPY_UINT32(&buf->data[rp], &kr->pd->newauthtok_size, rp);
- COPY_MEM(&buf->data[rp], kr->pd->newauthtok,
- rp, kr->pd->newauthtok_size);
- }
-
- *io_buf = buf;
-
- return EOK;
-}
-
-static struct krb5_ctx *get_krb5_ctx(struct be_req *be_req)
-{
- struct pam_data *pd;
-
- pd = talloc_get_type(be_req->req_data, struct pam_data);
-
- switch (pd->cmd) {
- case SSS_PAM_AUTHENTICATE:
- return talloc_get_type(be_req->be_ctx->bet_info[BET_AUTH].pvt_bet_data,
- struct krb5_ctx);
- break;
- case SSS_PAM_CHAUTHTOK:
- case SSS_PAM_CHAUTHTOK_PRELIM:
- return talloc_get_type(be_req->be_ctx->bet_info[BET_CHPASS].pvt_bet_data,
- struct krb5_ctx);
- break;
- default:
- DEBUG(1, ("Unsupported PAM task.\n"));
- return NULL;
- }
-}
-
-static void krb_reply(struct be_req *req, int dp_err, int result);
-
-static void krb5_child_timeout(struct tevent_context *ev,
- struct tevent_timer *te,
- struct timeval tv, void *pvt)
-{
- struct krb5child_req *kr = talloc_get_type(pvt, struct krb5child_req);
- struct be_req *be_req = kr->req;
- struct pam_data *pd = kr->pd;
- int ret;
-
- if (kr->timeout_handler == NULL) {
- return;
- }
-
- DEBUG(9, ("timeout for child [%d] reached.\n", kr->child_pid));
-
- ret = kill(kr->child_pid, SIGKILL);
- if (ret == -1) {
- DEBUG(1, ("kill failed [%d][%s].\n", errno, strerror(errno)));
- }
-
- talloc_zfree(kr);
-
- pd->pam_status = PAM_AUTHINFO_UNAVAIL;
- be_mark_offline(be_req->be_ctx);
-
- krb_reply(be_req, DP_ERR_OFFLINE, pd->pam_status);
-}
-
-static errno_t activate_child_timeout_handler(struct krb5child_req *kr)
-{
- struct timeval tv;
-
- tv = tevent_timeval_current();
- tv = tevent_timeval_add(&tv,
- dp_opt_get_int(kr->krb5_ctx->opts,
- KRB5_AUTH_TIMEOUT),
- 0);
- kr->timeout_handler = tevent_add_timer(kr->req->be_ctx->ev, kr, tv,
- krb5_child_timeout, kr);
- if (kr->timeout_handler == NULL) {
- DEBUG(1, ("tevent_add_timer failed.\n"));
- return ENOMEM;
- }
-
- return EOK;
-}
-
-static int krb5_cleanup(void *ptr)
-{
- struct krb5child_req *kr = talloc_get_type(ptr, struct krb5child_req);
-
- if (kr == NULL) return EOK;
-
- child_cleanup(kr->read_from_child_fd, kr->write_to_child_fd);
- memset(kr, 0, sizeof(struct krb5child_req));
-
- return EOK;
-}
-
-static errno_t krb5_setup(struct be_req *req, struct krb5child_req **krb5_req)
-{
- struct krb5child_req *kr = NULL;
- struct krb5_ctx *krb5_ctx;
- struct pam_data *pd;
- errno_t err;
-
- pd = talloc_get_type(req->req_data, struct pam_data);
-
- krb5_ctx = get_krb5_ctx(req);
- if (krb5_ctx == NULL) {
- DEBUG(1, ("Kerberos context not available.\n"));
- err = EINVAL;
- goto failed;
- }
-
- kr = talloc_zero(req, struct krb5child_req);
- if (kr == NULL) {
- DEBUG(1, ("talloc failed.\n"));
- err = ENOMEM;
- goto failed;
- }
- kr->read_from_child_fd = -1;
- kr->write_to_child_fd = -1;
- kr->is_offline = false;
- kr->active_ccache_present = true;
- talloc_set_destructor((TALLOC_CTX *) kr, krb5_cleanup);
-
- kr->pd = pd;
- kr->req = req;
- kr->krb5_ctx = krb5_ctx;
-
- *krb5_req = kr;
-
- return EOK;
-
-failed:
- talloc_zfree(kr);
-
- return err;
-}
-
-static errno_t fork_child(struct krb5child_req *kr)
-{
- int pipefd_to_child[2];
- int pipefd_from_child[2];
- pid_t pid;
- int ret;
- errno_t err;
-
- ret = pipe(pipefd_from_child);
- if (ret == -1) {
- err = errno;
- DEBUG(1, ("pipe failed [%d][%s].\n", errno, strerror(errno)));
- return err;
- }
- ret = pipe(pipefd_to_child);
- if (ret == -1) {
- err = errno;
- DEBUG(1, ("pipe failed [%d][%s].\n", errno, strerror(errno)));
- return err;
- }
-
- pid = fork();
-
- if (pid == 0) { /* child */
- /* We need to keep the root privileges to read the keytab file if
- * validation is enabled, otherwise we can drop them here and run
- * krb5_child with user privileges.
- * If authtok_size is zero we are offline and want to create an empty
- * ccache file. In this case we can drop the privileges, too. */
- if (!dp_opt_get_bool(kr->krb5_ctx->opts, KRB5_VALIDATE) ||
- kr->pd->authtok_size == 0) {
- ret = become_user(kr->pd->pw_uid, kr->pd->gr_gid);
- if (ret != EOK) {
- DEBUG(1, ("become_user failed.\n"));
- return ret;
- }
- }
-
- err = exec_child(kr,
- pipefd_to_child, pipefd_from_child,
- KRB5_CHILD, kr->krb5_ctx->child_debug_fd);
- if (err != EOK) {
- DEBUG(1, ("Could not exec LDAP child: [%d][%s].\n",
- err, strerror(err)));
- return err;
- }
- } else if (pid > 0) { /* parent */
- kr->child_pid = pid;
- kr->read_from_child_fd = pipefd_from_child[0];
- close(pipefd_from_child[1]);
- kr->write_to_child_fd = pipefd_to_child[1];
- close(pipefd_to_child[0]);
- fd_nonblocking(kr->read_from_child_fd);
- fd_nonblocking(kr->write_to_child_fd);
-
- err = activate_child_timeout_handler(kr);
- if (err != EOK) {
- DEBUG(1, ("activate_child_timeout_handler failed.\n"));
- }
-
- } else { /* error */
- err = errno;
- DEBUG(1, ("fork failed [%d][%s].\n", errno, strerror(errno)));
- return err;
- }
-
- return EOK;
-}
-
-struct handle_child_state {
- struct tevent_context *ev;
- struct krb5child_req *kr;
- uint8_t *buf;
- ssize_t len;
-};
-
-static void handle_child_step(struct tevent_req *subreq);
-static void handle_child_done(struct tevent_req *subreq);
-
-static struct tevent_req *handle_child_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct krb5child_req *kr)
-{
- struct tevent_req *req, *subreq;
- struct handle_child_state *state;
- struct io_buffer *buf;
- int ret;
-
- req = tevent_req_create(mem_ctx, &state, struct handle_child_state);
- if (req == NULL) {
- return NULL;
- }
-
- state->ev = ev;
- state->kr = kr;
- state->buf = NULL;
- state->len = 0;
-
- ret = create_send_buffer(kr, &buf);
- if (ret != EOK) {
- DEBUG(1, ("create_send_buffer failed.\n"));
- goto fail;
- }
-
- ret = fork_child(kr);
- if (ret != EOK) {
- DEBUG(1, ("fork_child failed.\n"));
- goto fail;
- }
-
- subreq = write_pipe_send(state, ev, buf->data, buf->size,
- kr->write_to_child_fd);
- if (!subreq) {
- ret = ENOMEM;
- goto fail;
- }
- tevent_req_set_callback(subreq, handle_child_step, req);
-
- return req;
-
-fail:
- tevent_req_error(req, ret);
- tevent_req_post(req, ev);
- return req;
-}
-
-static void handle_child_step(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct handle_child_state *state = tevent_req_data(req,
- struct handle_child_state);
- int ret;
-
- ret = write_pipe_recv(subreq);
- talloc_zfree(subreq);
- if (ret != EOK) {
- tevent_req_error(req, ret);
- return;
- }
-
- close(state->kr->write_to_child_fd);
- state->kr->write_to_child_fd = -1;
-
- subreq = read_pipe_send(state, state->ev, state->kr->read_from_child_fd);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, handle_child_done, req);
-}
-
-static void handle_child_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct handle_child_state *state = tevent_req_data(req,
- struct handle_child_state);
- int ret;
-
- ret = read_pipe_recv(subreq, state, &state->buf, &state->len);
- talloc_zfree(subreq);
- if (ret != EOK) {
- tevent_req_error(req, ret);
- return;
- }
-
- close(state->kr->read_from_child_fd);
- state->kr->read_from_child_fd = -1;
-
- tevent_req_done(req);
- return;
-}
-
-static int handle_child_recv(struct tevent_req *req,
- TALLOC_CTX *mem_ctx,
- uint8_t **buf, ssize_t *len)
-{
- struct handle_child_state *state = tevent_req_data(req,
- struct handle_child_state);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- *buf = talloc_move(mem_ctx, &state->buf);
- *len = state->len;
-
- return EOK;
-}
-
-static void get_user_attr_done(void *pvt, int err, struct ldb_result *res);
-static void krb5_resolve_done(struct tevent_req *req);
-static void krb5_save_ccname_done(struct tevent_req *req);
-static void krb5_child_done(struct tevent_req *req);
-static void krb5_pam_handler_cache_done(struct tevent_req *treq);
-
-void krb5_pam_handler(struct be_req *be_req)
-{
- struct pam_data *pd;
- const char **attrs;
- int pam_status = PAM_SYSTEM_ERR;
- int dp_err = DP_ERR_FATAL;
- int ret;
-
- pd = talloc_get_type(be_req->req_data, struct pam_data);
-
- switch (pd->cmd) {
- case SSS_PAM_AUTHENTICATE:
- case SSS_PAM_CHAUTHTOK:
- case SSS_PAM_CHAUTHTOK_PRELIM:
- break;
- case SSS_PAM_ACCT_MGMT:
- case SSS_PAM_SETCRED:
- case SSS_PAM_OPEN_SESSION:
- case SSS_PAM_CLOSE_SESSION:
- pam_status = PAM_SUCCESS;
- dp_err = DP_ERR_OK;
- goto done;
- break;
- default:
- DEBUG(4, ("krb5 does not handles pam task %d.\n", pd->cmd));
- pam_status = PAM_MODULE_UNKNOWN;
- dp_err = DP_ERR_OK;
- goto done;
- }
-
- if (be_is_offline(be_req->be_ctx) &&
- (pd->cmd == SSS_PAM_CHAUTHTOK || pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM)) {
- DEBUG(9, ("Password changes are not possible while offline.\n"));
- pam_status = PAM_AUTHINFO_UNAVAIL;
- dp_err = DP_ERR_OFFLINE;
- goto done;
- }
-
- attrs = talloc_array(be_req, const char *, 4);
- if (attrs == NULL) {
- goto done;
- }
-
- attrs[0] = SYSDB_UPN;
- attrs[1] = SYSDB_HOMEDIR;
- attrs[2] = SYSDB_CCACHE_FILE;
- attrs[3] = NULL;
-
- ret = sysdb_get_user_attr(be_req, be_req->be_ctx->sysdb,
- be_req->be_ctx->domain, pd->user, attrs,
- get_user_attr_done, be_req);
-
- if (ret) {
- goto done;
- }
-
- return;
-
-done:
- pd->pam_status = pam_status;
-
- krb_reply(be_req, dp_err, pd->pam_status);
-}
-
-static void get_user_attr_done(void *pvt, int err, struct ldb_result *res)
-{
- struct be_req *be_req = talloc_get_type(pvt, struct be_req);
- struct krb5_ctx *krb5_ctx;
- struct krb5child_req *kr = NULL;
- struct tevent_req *req;
- krb5_error_code kerr;
- int ret;
- struct pam_data *pd = talloc_get_type(be_req->req_data, struct pam_data);
- int pam_status=PAM_SYSTEM_ERR;
- int dp_err = DP_ERR_FATAL;
- const char *ccache_file = NULL;
- const char *realm;
-
- ret = krb5_setup(be_req, &kr);
- if (ret != EOK) {
- DEBUG(1, ("krb5_setup failed.\n"));
- goto failed;
- }
-
- krb5_ctx = kr->krb5_ctx;
-
- if (err != LDB_SUCCESS) {
- DEBUG(5, ("sysdb search for upn of user [%s] failed.\n", pd->user));
- goto failed;
- }
-
- realm = dp_opt_get_cstring(krb5_ctx->opts, KRB5_REALM);
- if (realm == NULL) {
- DEBUG(1, ("Missing Kerberos realm.\n"));
- goto failed;
- }
-
- switch (res->count) {
- case 0:
- DEBUG(5, ("No attributes for user [%s] found.\n", pd->user));
- goto failed;
- break;
-
- case 1:
- pd->upn = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_UPN, NULL);
- if (pd->upn == NULL) {
- /* NOTE: this is a hack, works only in some environments */
- pd->upn = talloc_asprintf(be_req, "%s@%s", pd->user, realm);
- if (pd->upn == NULL) {
- DEBUG(1, ("failed to build simple upn.\n"));
- goto failed;
- }
- DEBUG(9, ("Using simple UPN [%s].\n", pd->upn));
- }
-
- kr->homedir = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_HOMEDIR,
- NULL);
- if (kr->homedir == NULL) {
- DEBUG(4, ("Home directory for user [%s] not known.\n", pd->user));
- }
-
- ccache_file = ldb_msg_find_attr_as_string(res->msgs[0],
- SYSDB_CCACHE_FILE,
- NULL);
- if (ccache_file != NULL) {
- ret = check_if_ccache_file_is_used(pd->pw_uid, ccache_file,
- &kr->active_ccache_present);
- if (ret != EOK) {
- DEBUG(1, ("check_if_ccache_file_is_used failed.\n"));
- goto failed;
- }
-
- kerr = check_for_valid_tgt(ccache_file, realm, pd->upn,
- &kr->valid_tgt_present);
- if (kerr != 0) {
- DEBUG(1, ("check_for_valid_tgt failed.\n"));
- goto failed;
- }
- } else {
- kr->active_ccache_present = false;
- kr->valid_tgt_present = false;
- DEBUG(4, ("No ccache file for user [%s] found.\n", pd->user));
- }
- DEBUG(9, ("Ccache_file is [%s] and is %s active and TGT is %s valid.\n",
- ccache_file ? ccache_file : "not set",
- kr->active_ccache_present ? "" : "not",
- kr->valid_tgt_present ? "" : "not"));
- kr->ccname = ccache_file;
- break;
-
- default:
- DEBUG(1, ("A user search by name (%s) returned > 1 results!\n",
- pd->user));
- goto failed;
- break;
- }
-
- req = be_resolve_server_send(kr, be_req->be_ctx->ev, be_req->be_ctx,
- krb5_ctx->service->name);
- if (req == NULL) {
- DEBUG(1, ("handle_child_send failed.\n"));
- goto failed;
- }
-
- tevent_req_set_callback(req, krb5_resolve_done, kr);
-
- return;
-
-failed:
- talloc_free(kr);
-
- pd->pam_status = pam_status;
- krb_reply(be_req, dp_err, pd->pam_status);
-}
-
-static void krb5_resolve_done(struct tevent_req *req)
-{
- struct krb5child_req *kr = tevent_req_callback_data(req,
- struct krb5child_req);
- int ret;
- int pam_status = PAM_SYSTEM_ERR;
- int dp_err = DP_ERR_FATAL;
- struct pam_data *pd = kr->pd;
- struct be_req *be_req = kr->req;
- char *msg;
- size_t offset = 0;
-
- ret = be_resolve_server_recv(req, &kr->srv);
- talloc_zfree(req);
- if (ret) {
- /* all servers have been tried and none
- * was found good, setting offline,
- * but we still have to call the child to setup
- * the ccache file. */
- be_mark_offline(be_req->be_ctx);
- kr->is_offline = true;
- }
-
- if (kr->ccname == NULL ||
- (be_is_offline(be_req->be_ctx) && !kr->active_ccache_present &&
- !kr->valid_tgt_present) ||
- (!be_is_offline(be_req->be_ctx) && !kr->active_ccache_present)) {
- DEBUG(9, ("Recreating ccache file.\n"));
- if (kr->ccname != NULL) {
- if (strncmp(kr->ccname, "FILE:", 5) == 0) {
- offset = 5;
- }
- if (kr->ccname[offset] != '/') {
- DEBUG(1, ("Ccache file name [%s] is not an absolute path.\n",
- kr->ccname + offset));
- goto done;
- }
- ret = unlink(kr->ccname + offset);
- if (ret == -1 && errno != ENOENT) {
- DEBUG(1, ("unlink [%s] failed [%d][%s].\n", kr->ccname,
- errno, strerror(errno)));
- goto done;
- }
- }
- kr->ccname = expand_ccname_template(kr, kr,
- dp_opt_get_cstring(kr->krb5_ctx->opts,
- KRB5_CCNAME_TMPL)
- );
- if (kr->ccname == NULL) {
- DEBUG(1, ("expand_ccname_template failed.\n"));
- goto done;
- }
- }
-
- if (be_is_offline(be_req->be_ctx)) {
- DEBUG(9, ("Preparing for offline operation.\n"));
- kr->is_offline = true;
-
- if (kr->valid_tgt_present) {
- DEBUG(9, ("Valid TGT available, nothing to do.\n"));
- msg = talloc_asprintf(pd, "%s=%s", CCACHE_ENV_NAME, kr->ccname);
- if (msg == NULL) {
- DEBUG(1, ("talloc_asprintf failed.\n"));
- goto done;
- }
-
- ret = pam_add_response(pd, SSS_PAM_ENV_ITEM, strlen(msg) + 1,
- (uint8_t *) msg);
- if (ret != EOK) {
- DEBUG(1, ("pam_add_response failed.\n"));
- }
-
- pam_status = PAM_AUTHINFO_UNAVAIL;
- dp_err = DP_ERR_OFFLINE;
- goto done;
- }
- memset(pd->authtok, 0, pd->authtok_size);
- pd->authtok_size = 0;
-
- if (kr->active_ccache_present) {
- 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;
- }
- }
-
- req = handle_child_send(kr, be_req->be_ctx->ev, kr);
- if (req == NULL) {
- DEBUG(1, ("handle_child_send failed.\n"));
- goto done;
- }
-
- tevent_req_set_callback(req, krb5_child_done, kr);
- return;
-
-done:
- talloc_free(kr);
- pd->pam_status = pam_status;
- krb_reply(be_req, dp_err, pd->pam_status);
-}
-
-static void krb5_child_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;
- int ret;
- uint8_t *buf = NULL;
- ssize_t len = -1;
- ssize_t pref_len;
- int p;
- int32_t *msg_status;
- int32_t *msg_type;
- int32_t *msg_len;
- int pam_status = PAM_SYSTEM_ERR;
- 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) {
- 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);
-}
-
diff --git a/server/providers/krb5/krb5_auth.h b/server/providers/krb5/krb5_auth.h
deleted file mode 100644
index a011af890..000000000
--- a/server/providers/krb5/krb5_auth.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- SSSD
-
- Kerberos Backend, private header file
-
- Authors:
- Sumit Bose <sbose@redhat.com>
-
- Copyright (C) 2009 Red Hat
-
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __KRB5_AUTH_H__
-#define __KRB5_AUTH_H__
-
-#include "util/sss_krb5.h"
-#include "providers/dp_backend.h"
-#include "providers/krb5/krb5_common.h"
-
-#define CCACHE_ENV_NAME "KRB5CCNAME"
-#define SSSD_KRB5_CHANGEPW_PRINCIPLE "SSSD_KRB5_CHANGEPW_PRINCIPLE"
-
-typedef enum { INIT_PW, INIT_KT, RENEW, VALIDATE } action_type;
-
-struct krb5child_req {
- pid_t child_pid;
- int read_from_child_fd;
- int write_to_child_fd;
-
- struct be_req *req;
- struct pam_data *pd;
- struct krb5_ctx *krb5_ctx;
-
- struct tevent_timer *timeout_handler;
-
- const char *ccname;
- const char *homedir;
- bool is_offline;
- struct fo_server *srv;
- bool active_ccache_present;
- bool valid_tgt_present;
-};
-
-struct fo_service;
-
-struct krb5_ctx {
- /* opts taken from kinit */
- /* in seconds */
- krb5_deltat starttime;
- krb5_deltat lifetime;
- krb5_deltat rlife;
-
- int forwardable;
- int proxiable;
- int addresses;
-
- int not_forwardable;
- int not_proxiable;
- int no_addresses;
-
- int verbose;
-
- char* principal_name;
- char* service_name;
- char* keytab_name;
- char* k5_cache_name;
- char* k4_cache_name;
-
- action_type action;
-
- struct dp_option *opts;
- struct krb5_service *service;
- int child_debug_fd;
-};
-
-void krb5_pam_handler(struct be_req *be_req);
-
-#endif /* __KRB5_AUTH_H__ */
diff --git a/server/providers/krb5/krb5_become_user.c b/server/providers/krb5/krb5_become_user.c
deleted file mode 100644
index 351f539a3..000000000
--- a/server/providers/krb5/krb5_become_user.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- SSSD
-
- Kerberos 5 Backend Module -- Utilities
-
- Authors:
- Sumit Bose <sbose@redhat.com>
-
- Copyright (C) 2009 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "util/util.h"
-
-errno_t become_user(uid_t uid, gid_t gid)
-{
- int ret;
-
- DEBUG(9, ("Trying to become user [%d][%d].\n", uid, gid));
- ret = setgid(gid);
- if (ret == -1) {
- DEBUG(1, ("setgid failed [%d][%s].\n", errno, strerror(errno)));
- return errno;
- }
-
- ret = setuid(uid);
- if (ret == -1) {
- DEBUG(1, ("setuid failed [%d][%s].\n", errno, strerror(errno)));
- return errno;
- }
-
- ret = setegid(gid);
- if (ret == -1) {
- DEBUG(1, ("setegid failed [%d][%s].\n", errno, strerror(errno)));
- return errno;
- }
-
- ret = seteuid(uid);
- if (ret == -1) {
- DEBUG(1, ("seteuid failed [%d][%s].\n", errno, strerror(errno)));
- return errno;
- }
-
- return EOK;
-}
-
diff --git a/server/providers/krb5/krb5_child.c b/server/providers/krb5/krb5_child.c
deleted file mode 100644
index 5e185940e..000000000
--- a/server/providers/krb5/krb5_child.c
+++ /dev/null
@@ -1,1030 +0,0 @@
-/*
- SSSD
-
- Kerberos 5 Backend Module -- tgt_req and changepw child
-
- Authors:
- Sumit Bose <sbose@redhat.com>
-
- Copyright (C) 2009 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <sys/types.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <popt.h>
-
-#include <security/pam_modules.h>
-
-#include "util/util.h"
-#include "util/user_info_msg.h"
-#include "providers/child_common.h"
-#include "providers/dp_backend.h"
-#include "providers/krb5/krb5_auth.h"
-#include "providers/krb5/krb5_utils.h"
-
-struct krb5_child_ctx {
- /* opts taken from kinit */
- /* in seconds */
- krb5_deltat starttime;
- krb5_deltat lifetime;
- krb5_deltat rlife;
-
- int forwardable;
- int proxiable;
- int addresses;
-
- int not_forwardable;
- int not_proxiable;
- int no_addresses;
-
- int verbose;
-
- char* principal_name;
- char* service_name;
- char* keytab_name;
- char* k5_cache_name;
- char* k4_cache_name;
-
- action_type action;
-
- char *kdcip;
- char *realm;
- char *changepw_principle;
- char *ccache_dir;
- char *ccname_template;
- int auth_timeout;
-
- int child_debug_fd;
-};
-
-struct krb5_req {
- krb5_context ctx;
- krb5_principal princ;
- char* name;
- krb5_creds *creds;
- krb5_get_init_creds_opt *options;
- pid_t child_pid;
- int read_from_child_fd;
- int write_to_child_fd;
-
- struct be_req *req;
- struct pam_data *pd;
- struct krb5_child_ctx *krb5_ctx;
- errno_t (*child_req)(int fd, struct krb5_req *kr);
-
- char *ccname;
- char *keytab;
- bool validate;
-};
-
-static krb5_context krb5_error_ctx;
-static const char *__krb5_error_msg;
-#define KRB5_DEBUG(level, krb5_error) do { \
- __krb5_error_msg = sss_krb5_get_error_message(krb5_error_ctx, krb5_error); \
- DEBUG(level, ("%d: [%d][%s]\n", __LINE__, krb5_error, __krb5_error_msg)); \
- sss_krb5_free_error_message(krb5_error_ctx, __krb5_error_msg); \
-} while(0);
-
-static krb5_error_code create_empty_cred(struct krb5_req *kr, krb5_creds **_cred)
-{
- krb5_error_code kerr;
- krb5_creds *cred = NULL;
- krb5_data *krb5_realm;
-
- cred = calloc(sizeof(krb5_creds), 1);
- if (cred == NULL) {
- DEBUG(1, ("calloc failed.\n"));
- return ENOMEM;
- }
-
- kerr = krb5_copy_principal(kr->ctx, kr->princ, &cred->client);
- if (kerr != 0) {
- DEBUG(1, ("krb5_copy_principal failed.\n"));
- goto done;
- }
-
- krb5_realm = krb5_princ_realm(kr->ctx, kr->princ);
-
- kerr = krb5_build_principal_ext(kr->ctx, &cred->server,
- krb5_realm->length, krb5_realm->data,
- KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME,
- krb5_realm->length, krb5_realm->data, 0);
- if (kerr != 0) {
- DEBUG(1, ("krb5_build_principal_ext failed.\n"));
- goto done;
- }
-
-done:
- if (kerr != 0) {
- if (cred != NULL && cred->client != NULL) {
- krb5_free_principal(kr->ctx, cred->client);
- }
-
- free(cred);
- } else {
- *_cred = cred;
- }
-
- return kerr;
-}
-
-static krb5_error_code create_ccache_file(struct krb5_req *kr, krb5_creds *creds)
-{
- krb5_error_code kerr;
- krb5_ccache tmp_cc = NULL;
- char *cc_file_name;
- int fd = -1;
- size_t ccname_len;
- char *dummy;
- char *tmp_ccname;
- krb5_creds *l_cred;
-
- if (strncmp(kr->ccname, "FILE:", 5) == 0) {
- cc_file_name = kr->ccname + 5;
- } else {
- cc_file_name = kr->ccname;
- }
-
- if (cc_file_name[0] != '/') {
- DEBUG(1, ("Ccache filename is not an absolute path.\n"));
- return EINVAL;
- }
-
- dummy = strrchr(cc_file_name, '/');
- tmp_ccname = talloc_strndup(kr, cc_file_name, (size_t) (dummy-cc_file_name));
- if (tmp_ccname == NULL) {
- DEBUG(1, ("talloc_strdup failed.\n"));
- return ENOMEM;
- }
- tmp_ccname = talloc_asprintf_append(tmp_ccname, "/.krb5cc_dummy_XXXXXX");
-
- fd = mkstemp(tmp_ccname);
- if (fd == -1) {
- DEBUG(1, ("mkstemp failed [%d][%s].\n", errno, strerror(errno)));
- return errno;
- }
-
- kerr = krb5_cc_resolve(kr->ctx, tmp_ccname, &tmp_cc);
- if (kerr != 0) {
- KRB5_DEBUG(1, kerr);
- goto done;
- }
-
- kerr = krb5_cc_initialize(kr->ctx, tmp_cc, kr->princ);
- if (kerr != 0) {
- KRB5_DEBUG(1, kerr);
- goto done;
- }
- if (fd != -1) {
- close(fd);
- fd = -1;
- }
-
- if (creds == NULL) {
- kerr = create_empty_cred(kr, &l_cred);
- if (kerr != 0) {
- KRB5_DEBUG(1, kerr);
- goto done;
- }
- } else {
- l_cred = creds;
- }
-
- kerr = krb5_cc_store_cred(kr->ctx, tmp_cc, l_cred);
- if (kerr != 0) {
- KRB5_DEBUG(1, kerr);
- goto done;
- }
-
- kerr = krb5_cc_close(kr->ctx, tmp_cc);
- if (kerr != 0) {
- KRB5_DEBUG(1, kerr);
- goto done;
- }
- tmp_cc = NULL;
-
- ccname_len = strlen(cc_file_name);
- if (ccname_len >= 6 && strcmp(cc_file_name + (ccname_len-6), "XXXXXX")==0 ) {
- fd = mkstemp(cc_file_name);
- if (fd == -1) {
- DEBUG(1, ("mkstemp failed [%d][%s].\n", errno, strerror(errno)));
- kerr = errno;
- goto done;
- }
- }
-
- kerr = rename(tmp_ccname, cc_file_name);
- if (kerr == -1) {
- DEBUG(1, ("rename failed [%d][%s].\n", errno, strerror(errno)));
- }
-
-done:
- if (fd != -1) {
- close(fd);
- fd = -1;
- }
- if (kerr != 0 && tmp_cc != NULL) {
- krb5_cc_destroy(kr->ctx, tmp_cc);
- }
- return kerr;
-}
-
-static struct response *init_response(TALLOC_CTX *mem_ctx) {
- struct response *r;
- r = talloc(mem_ctx, struct response);
- r->buf = talloc_size(mem_ctx, MAX_CHILD_MSG_SIZE);
- if (r->buf == NULL) {
- DEBUG(1, ("talloc_size failed.\n"));
- return NULL;
- }
- r->max_size = MAX_CHILD_MSG_SIZE;
- r->size = 0;
-
- return r;
-}
-
-static errno_t pack_response_packet(struct response *resp, int status, int type,
- size_t len, const uint8_t *data)
-{
- int p=0;
-
- if ((3*sizeof(int32_t) + len +1) > resp->max_size) {
- DEBUG(1, ("response message too big.\n"));
- return ENOMEM;
- }
-
- COPY_INT32_VALUE(&resp->buf[p], status, p);
- COPY_INT32_VALUE(&resp->buf[p], type, p);
- COPY_INT32_VALUE(&resp->buf[p], len, p);
- COPY_MEM(&resp->buf[p], data, p, len);
-
- resp->size = p;
-
- return EOK;
-}
-
-static struct response *prepare_response_message(struct krb5_req *kr,
- krb5_error_code kerr,
- char *user_error_message,
- int pam_status)
-{
- char *msg = NULL;
- const char *krb5_msg = NULL;
- int ret;
- struct response *resp;
- size_t user_resp_len;
- uint8_t *user_resp;
-
- resp = init_response(kr);
- if (resp == NULL) {
- DEBUG(1, ("init_response failed.\n"));
- return NULL;
- }
-
- if (kerr == 0) {
- if(kr->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM) {
- ret = pack_response_packet(resp, PAM_SUCCESS, SSS_PAM_SYSTEM_INFO,
- strlen("success") + 1,
- (const uint8_t *) "success");
- } else {
- if (kr->ccname == NULL) {
- DEBUG(1, ("Error obtaining ccname.\n"));
- return NULL;
- }
-
- msg = talloc_asprintf(kr, "%s=%s",CCACHE_ENV_NAME, kr->ccname);
- if (msg == NULL) {
- DEBUG(1, ("talloc_asprintf failed.\n"));
- return NULL;
- }
-
- ret = pack_response_packet(resp, PAM_SUCCESS, SSS_PAM_ENV_ITEM,
- strlen(msg) + 1, (uint8_t *) msg);
- talloc_zfree(msg);
- }
- } else {
-
- if (user_error_message != NULL) {
- ret = pack_user_info_chpass_error(kr, user_error_message,
- &user_resp_len, &user_resp);
- if (ret != EOK) {
- DEBUG(1, ("pack_user_info_chpass_error failed.\n"));
- talloc_zfree(user_error_message);
- } else {
- ret = pack_response_packet(resp, pam_status, SSS_PAM_USER_INFO,
- user_resp_len, user_resp);
- if (ret != EOK) {
- DEBUG(1, ("pack_response_packet failed.\n"));
- talloc_zfree(user_error_message);
- }
- }
- }
-
- if (user_error_message == NULL) {
- krb5_msg = sss_krb5_get_error_message(krb5_error_ctx, kerr);
- if (krb5_msg == NULL) {
- DEBUG(1, ("sss_krb5_get_error_message failed.\n"));
- return NULL;
- }
-
- ret = pack_response_packet(resp, pam_status, SSS_PAM_SYSTEM_INFO,
- strlen(krb5_msg) + 1,
- (const uint8_t *) krb5_msg);
- sss_krb5_free_error_message(krb5_error_ctx, krb5_msg);
- } else {
-
- }
-
- }
-
- if (ret != EOK) {
- DEBUG(1, ("pack_response_packet failed.\n"));
- return NULL;
- }
-
- return resp;
-}
-
-static errno_t sendresponse(int fd, krb5_error_code kerr,
- char *user_error_message, int pam_status,
- struct krb5_req *kr)
-{
- struct response *resp;
- size_t written;
- int ret;
-
- resp = prepare_response_message(kr, kerr, user_error_message, pam_status);
- if (resp == NULL) {
- DEBUG(1, ("prepare_response_message failed.\n"));
- return ENOMEM;
- }
-
- written = 0;
- while (written < resp->size) {
- ret = write(fd, resp->buf + written, resp->size - written);
- if (ret == -1) {
- if (errno == EAGAIN || errno == EINTR) {
- continue;
- }
- ret = errno;
- DEBUG(1, ("write failed [%d][%s].\n", ret, strerror(ret)));
- return ret;
- }
- written += ret;
- }
-
- return EOK;
-}
-
-static krb5_error_code validate_tgt(struct krb5_req *kr)
-{
- krb5_error_code kerr;
- krb5_error_code kt_err;
- char *principal;
- krb5_keytab keytab;
- krb5_kt_cursor cursor;
- krb5_keytab_entry entry;
- krb5_verify_init_creds_opt opt;
-
- memset(&keytab, 0, sizeof(keytab));
- kerr = krb5_kt_resolve(kr->ctx, kr->keytab, &keytab);
- if (kerr != 0) {
- DEBUG(1, ("error resolving keytab [%s], not verifying TGT.\n",
- kr->keytab));
- return kerr;
- }
-
- memset(&cursor, 0, sizeof(cursor));
- kerr = krb5_kt_start_seq_get(kr->ctx, keytab, &cursor);
- if (kerr != 0) {
- DEBUG(1, ("error reading keytab [%s], not verifying TGT.\n",
- kr->keytab));
- return kerr;
- }
-
- /* We look for the first entry from our realm or take the last one */
- memset(&entry, 0, sizeof(entry));
- while ((kt_err = krb5_kt_next_entry(kr->ctx, keytab, &entry, &cursor)) == 0) {
- if (krb5_realm_compare(kr->ctx, entry.principal, kr->princ)) {
- DEBUG(9, ("Found keytab entry with the realm of the credential.\n"));
- break;
- }
-
- kerr = krb5_free_keytab_entry_contents(kr->ctx, &entry);
- if (kerr != 0) {
- DEBUG(1, ("Failed to free keytab entry.\n"));
- }
- memset(&entry, 0, sizeof(entry));
- }
-
- /* Close the keytab here. Even though we're using cursors, the file
- * handle is stored in the krb5_keytab structure, and it gets
- * overwritten when the verify_init_creds() call below creates its own
- * cursor, creating a leak. */
- kerr = krb5_kt_end_seq_get(kr->ctx, keytab, &cursor);
- if (kerr != 0) {
- DEBUG(1, ("krb5_kt_end_seq_get failed, not verifying TGT.\n"));
- goto done;
- }
-
- /* check if we got any errors from krb5_kt_next_entry */
- if (kt_err != 0 && kt_err != KRB5_KT_END) {
- DEBUG(1, ("error reading keytab [%s], not verifying TGT.\n",
- kr->keytab));
- goto done;
- }
-
- /* Get the principal to which the key belongs, for logging purposes. */
- principal = NULL;
- kerr = krb5_unparse_name(kr->ctx, entry.principal, &principal);
- if (kerr != 0) {
- DEBUG(1, ("internal error parsing principal name, "
- "not verifying TGT.\n"));
- goto done;
- }
-
-
- krb5_verify_init_creds_opt_init(&opt);
- kerr = krb5_verify_init_creds(kr->ctx, kr->creds, entry.principal, keytab,
- NULL, &opt);
-
- if (kerr == 0) {
- DEBUG(5, ("TGT verified using key for [%s].\n", principal));
- } else {
- DEBUG(1 ,("TGT failed verification using key for [%s].\n", principal));
- }
-
-done:
- if (krb5_kt_close(kr->ctx, keytab) != 0) {
- DEBUG(1, ("krb5_kt_close failed"));
- }
- if (krb5_free_keytab_entry_contents(kr->ctx, &entry) != 0) {
- DEBUG(1, ("Failed to free keytab entry.\n"));
- }
- if (principal != NULL) {
- sss_krb5_free_unparsed_name(kr->ctx, principal);
- }
-
- return kerr;
-
-}
-
-static krb5_error_code get_and_save_tgt(struct krb5_req *kr,
- char *password)
-{
- krb5_error_code kerr = 0;
- int ret;
-
- kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ,
- password, NULL, NULL, 0, NULL,
- kr->options);
- if (kerr != 0) {
- KRB5_DEBUG(1, kerr);
- return kerr;
- }
-
- if (kr->validate) {
- kerr = validate_tgt(kr);
- if (kerr != 0) {
- KRB5_DEBUG(1, kerr);
- return kerr;
- }
-
- /* We drop root privileges which were needed to read the keytab file
- * for the validation validation of the credentials here to run the
- * ccache I/O operations with user privileges. */
- ret = become_user(kr->pd->pw_uid, kr->pd->gr_gid);
- if (ret != EOK) {
- DEBUG(1, ("become_user failed.\n"));
- return ret;
- }
- } else {
- DEBUG(9, ("TGT validation is disabled.\n"));
- }
-
- kerr = create_ccache_file(kr, kr->creds);
- if (kerr != 0) {
- KRB5_DEBUG(1, kerr);
- goto done;
- }
-
- kerr = 0;
-
-done:
- krb5_free_cred_contents(kr->ctx, kr->creds);
-
- return kerr;
-
-}
-
-static errno_t changepw_child(int fd, struct krb5_req *kr)
-{
- int ret;
- krb5_error_code kerr = 0;
- char *pass_str = NULL;
- char *newpass_str = NULL;
- int pam_status = PAM_SYSTEM_ERR;
- int result_code = -1;
- krb5_data result_code_string;
- krb5_data result_string;
- char *user_error_message = NULL;
-
- pass_str = talloc_strndup(kr, (const char *) kr->pd->authtok,
- kr->pd->authtok_size);
- if (pass_str == NULL) {
- DEBUG(1, ("talloc_strndup failed.\n"));
- kerr = KRB5KRB_ERR_GENERIC;
- goto sendresponse;
- }
-
- kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ,
- pass_str, NULL, NULL, 0,
- kr->krb5_ctx->changepw_principle,
- kr->options);
- if (kerr != 0) {
- KRB5_DEBUG(1, kerr);
- if (kerr == KRB5_KDC_UNREACH) {
- pam_status = PAM_AUTHINFO_UNAVAIL;
- }
- goto sendresponse;
- }
-
- memset(pass_str, 0, kr->pd->authtok_size);
- talloc_zfree(pass_str);
- memset(kr->pd->authtok, 0, kr->pd->authtok_size);
-
- if (kr->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM) {
- DEBUG(9, ("Initial authentication for change password operation "
- "successfull.\n"));
- krb5_free_cred_contents(kr->ctx, kr->creds);
- pam_status = PAM_SUCCESS;
- goto sendresponse;
- }
-
- newpass_str = talloc_strndup(kr, (const char *) kr->pd->newauthtok,
- kr->pd->newauthtok_size);
- if (newpass_str == NULL) {
- DEBUG(1, ("talloc_strndup failed.\n"));
- kerr = KRB5KRB_ERR_GENERIC;
- goto sendresponse;
- }
-
- kerr = krb5_change_password(kr->ctx, kr->creds, newpass_str, &result_code,
- &result_code_string, &result_string);
-
- if (kerr != 0 || result_code != 0) {
- if (kerr != 0) {
- KRB5_DEBUG(1, kerr);
- } else {
- kerr = KRB5KRB_ERR_GENERIC;
- }
-
- if (result_code_string.length > 0) {
- DEBUG(1, ("krb5_change_password failed [%d][%.*s].\n", result_code,
- result_code_string.length, result_code_string.data));
- user_error_message = talloc_strndup(kr->pd, result_code_string.data,
- result_code_string.length);
- if (user_error_message == NULL) {
- DEBUG(1, ("talloc_strndup failed.\n"));
- }
- }
-
- if (result_string.length > 0) {
- DEBUG(1, ("krb5_change_password failed [%d][%.*s].\n", result_code,
- result_string.length, result_string.data));
- talloc_free(user_error_message);
- user_error_message = talloc_strndup(kr->pd, result_string.data,
- result_string.length);
- if (user_error_message == NULL) {
- DEBUG(1, ("talloc_strndup failed.\n"));
- }
- }
-
- pam_status = PAM_AUTHTOK_ERR;
- goto sendresponse;
- }
-
- krb5_free_cred_contents(kr->ctx, kr->creds);
-
- kerr = get_and_save_tgt(kr, newpass_str);
- memset(newpass_str, 0, kr->pd->newauthtok_size);
- talloc_zfree(newpass_str);
- memset(kr->pd->newauthtok, 0, kr->pd->newauthtok_size);
-
- if (kerr != 0) {
- KRB5_DEBUG(1, kerr);
- if (kerr == KRB5_KDC_UNREACH) {
- pam_status = PAM_AUTHINFO_UNAVAIL;
- }
- }
-
-sendresponse:
- ret = sendresponse(fd, kerr, user_error_message, pam_status, kr);
- if (ret != EOK) {
- DEBUG(1, ("sendresponse failed.\n"));
- }
-
- return ret;
-}
-
-static errno_t tgt_req_child(int fd, struct krb5_req *kr)
-{
- int ret;
- krb5_error_code kerr = 0;
- char *pass_str = NULL;
- int pam_status = PAM_SYSTEM_ERR;
-
- pass_str = talloc_strndup(kr, (const char *) kr->pd->authtok,
- kr->pd->authtok_size);
- if (pass_str == NULL) {
- DEBUG(1, ("talloc_strndup failed.\n"));
- kerr = KRB5KRB_ERR_GENERIC;
- goto sendresponse;
- }
-
- kerr = get_and_save_tgt(kr, pass_str);
-
- /* If the password is expired the KDC will always return
- KRB5KDC_ERR_KEY_EXP regardless if the supplied password is correct or
- not. In general the password can still be used to get a changepw ticket.
- So we validate the password by trying to get a changepw ticket. */
- if (kerr == KRB5KDC_ERR_KEY_EXP) {
- kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ,
- pass_str, NULL, NULL, 0,
- kr->krb5_ctx->changepw_principle,
- kr->options);
- krb5_free_cred_contents(kr->ctx, kr->creds);
- if (kerr == 0) {
- kerr = KRB5KDC_ERR_KEY_EXP;
- }
- }
-
- memset(pass_str, 0, kr->pd->authtok_size);
- talloc_zfree(pass_str);
- memset(kr->pd->authtok, 0, kr->pd->authtok_size);
-
- if (kerr != 0) {
- KRB5_DEBUG(1, kerr);
- switch (kerr) {
- case KRB5_KDC_UNREACH:
- pam_status = PAM_AUTHINFO_UNAVAIL;
- break;
- case KRB5KDC_ERR_KEY_EXP:
- pam_status = PAM_AUTHTOK_EXPIRED;
- break;
- case KRB5KDC_ERR_PREAUTH_FAILED:
- pam_status = PAM_CRED_ERR;
- break;
- default:
- pam_status = PAM_SYSTEM_ERR;
- }
- }
-
-sendresponse:
- ret = sendresponse(fd, kerr, NULL, pam_status, kr);
- if (ret != EOK) {
- DEBUG(1, ("sendresponse failed.\n"));
- }
-
- return ret;
-}
-
-static errno_t create_empty_ccache(int fd, struct krb5_req *kr)
-{
- int ret;
- int pam_status = PAM_SUCCESS;
-
- ret = create_ccache_file(kr, NULL);
- if (ret != 0) {
- KRB5_DEBUG(1, ret);
- pam_status = PAM_SYSTEM_ERR;
- }
-
- ret = sendresponse(fd, ret, NULL, pam_status, kr);
- if (ret != EOK) {
- DEBUG(1, ("sendresponse failed.\n"));
- }
-
- return ret;
-}
-
-static errno_t unpack_buffer(uint8_t *buf, size_t size, struct pam_data *pd,
- char **ccname, char **keytab, uint32_t *validate,
- uint32_t *offline)
-{
- size_t p = 0;
- uint32_t len;
-
- COPY_UINT32_CHECK(&pd->cmd, buf + p, p, size);
- COPY_UINT32_CHECK(&pd->pw_uid, buf + p, p, size);
- COPY_UINT32_CHECK(&pd->gr_gid, buf + p, p, size);
- COPY_UINT32_CHECK(validate, buf + p, p, size);
- COPY_UINT32_CHECK(offline, buf + p, p, size);
-
- COPY_UINT32_CHECK(&len, buf + p, p, size);
- if ((p + len ) > size) return EINVAL;
- pd->upn = talloc_strndup(pd, (char *)(buf + p), len);
- if (pd->upn == NULL) return ENOMEM;
- p += len;
-
- COPY_UINT32_CHECK(&len, buf + p, p, size);
- if ((p + len ) > size) return EINVAL;
- *ccname = talloc_strndup(pd, (char *)(buf + p), len);
- if (*ccname == NULL) return ENOMEM;
- p += len;
-
- COPY_UINT32_CHECK(&len, buf + p, p, size);
- if ((p + len ) > size) return EINVAL;
- *keytab = talloc_strndup(pd, (char *)(buf + p), len);
- if (*keytab == NULL) return ENOMEM;
- p += len;
-
- COPY_UINT32_CHECK(&len, buf + p, p, size);
- if ((p + len) > size) return EINVAL;
- pd->authtok = (uint8_t *)talloc_strndup(pd, (char *)(buf + p), len);
- if (pd->authtok == NULL) return ENOMEM;
- pd->authtok_size = len + 1;
- p += len;
-
- if (pd->cmd == SSS_PAM_CHAUTHTOK) {
- COPY_UINT32_CHECK(&len, buf + p, p, size);
-
- if ((p + len) > size) return EINVAL;
- pd->newauthtok = (uint8_t *)talloc_strndup(pd, (char *)(buf + p), len);
- if (pd->newauthtok == NULL) return ENOMEM;
- pd->newauthtok_size = len + 1;
- p += len;
- } else {
- pd->newauthtok = NULL;
- pd->newauthtok_size = 0;
- }
-
- return EOK;
-}
-
-static int krb5_cleanup(void *ptr)
-{
- struct krb5_req *kr = talloc_get_type(ptr, struct krb5_req);
- if (kr == NULL) return EOK;
-
- if (kr->options != NULL) {
- sss_krb5_get_init_creds_opt_free(kr->ctx, kr->options);
- }
-
- if (kr->creds != NULL) {
- krb5_free_cred_contents(kr->ctx, kr->creds);
- krb5_free_creds(kr->ctx, kr->creds);
- }
- if (kr->name != NULL)
- sss_krb5_free_unparsed_name(kr->ctx, kr->name);
- if (kr->princ != NULL)
- krb5_free_principal(kr->ctx, kr->princ);
- if (kr->ctx != NULL)
- krb5_free_context(kr->ctx);
-
- if (kr->krb5_ctx != NULL) {
- memset(kr->krb5_ctx, 0, sizeof(struct krb5_child_ctx));
- }
- memset(kr, 0, sizeof(struct krb5_req));
-
- return EOK;
-}
-
-static int krb5_setup(struct pam_data *pd, const char *user_princ_str,
- uint32_t offline, struct krb5_req **krb5_req)
-{
- struct krb5_req *kr = NULL;
- krb5_error_code kerr = 0;
-
- kr = talloc_zero(pd, struct krb5_req);
- if (kr == NULL) {
- DEBUG(1, ("talloc failed.\n"));
- kerr = ENOMEM;
- goto failed;
- }
- talloc_set_destructor((TALLOC_CTX *) kr, krb5_cleanup);
-
- kr->krb5_ctx = talloc_zero(kr, struct krb5_child_ctx);
- if (kr->krb5_ctx == NULL) {
- DEBUG(1, ("talloc failed.\n"));
- kerr = ENOMEM;
- goto failed;
- }
-
- kr->krb5_ctx->changepw_principle = getenv(SSSD_KRB5_CHANGEPW_PRINCIPLE);
- if (kr->krb5_ctx->changepw_principle == NULL) {
- DEBUG(1, ("Cannot read [%s] from environment.\n",
- SSSD_KRB5_CHANGEPW_PRINCIPLE));
- if (pd->cmd == SSS_PAM_CHAUTHTOK) {
- goto failed;
- }
- }
-
- kr->krb5_ctx->realm = getenv(SSSD_KRB5_REALM);
- if (kr->krb5_ctx->realm == NULL) {
- DEBUG(2, ("Cannot read [%s] from environment.\n", SSSD_KRB5_REALM));
- }
-
- kr->pd = pd;
-
- switch(pd->cmd) {
- case SSS_PAM_AUTHENTICATE:
- /* If we are offline, we need to create an empty ccache file */
- if (offline) {
- kr->child_req = create_empty_ccache;
- } else {
- kr->child_req = tgt_req_child;
- }
- break;
- case SSS_PAM_CHAUTHTOK:
- case SSS_PAM_CHAUTHTOK_PRELIM:
- kr->child_req = changepw_child;
- break;
- default:
- DEBUG(1, ("PAM command [%d] not supported.\n", pd->cmd));
- kerr = EINVAL;
- goto failed;
- }
-
- kerr = krb5_init_context(&kr->ctx);
- if (kerr != 0) {
- KRB5_DEBUG(1, kerr);
- goto failed;
- }
-
- kerr = krb5_parse_name(kr->ctx, user_princ_str, &kr->princ);
- if (kerr != 0) {
- KRB5_DEBUG(1, kerr);
- goto failed;
- }
-
- kerr = krb5_unparse_name(kr->ctx, kr->princ, &kr->name);
- if (kerr != 0) {
- KRB5_DEBUG(1, kerr);
- goto failed;
- }
-
- kr->creds = calloc(1, sizeof(krb5_creds));
- if (kr->creds == NULL) {
- DEBUG(1, ("talloc_zero failed.\n"));
- kerr = ENOMEM;
- goto failed;
- }
-
- kerr = sss_krb5_get_init_creds_opt_alloc(kr->ctx, &kr->options);
- if (kerr != 0) {
- KRB5_DEBUG(1, kerr);
- goto failed;
- }
-
-/* TODO: set options, e.g.
- * krb5_get_init_creds_opt_set_tkt_life
- * krb5_get_init_creds_opt_set_renew_life
- * krb5_get_init_creds_opt_set_forwardable
- * krb5_get_init_creds_opt_set_proxiable
- * krb5_get_init_creds_opt_set_etype_list
- * krb5_get_init_creds_opt_set_address_list
- * krb5_get_init_creds_opt_set_preauth_list
- * krb5_get_init_creds_opt_set_salt
- * krb5_get_init_creds_opt_set_change_password_prompt
- * krb5_get_init_creds_opt_set_pa
- */
-
- *krb5_req = kr;
- return EOK;
-
-failed:
- talloc_free(kr);
-
- return kerr;
-}
-
-int main(int argc, const char *argv[])
-{
- uint8_t *buf = NULL;
- int ret;
- ssize_t len = 0;
- struct pam_data *pd = NULL;
- struct krb5_req *kr = NULL;
- char *ccname;
- char *keytab;
- uint32_t validate;
- uint32_t offline;
- int opt;
- poptContext pc;
- int debug_fd = -1;
-
- struct poptOption long_options[] = {
- POPT_AUTOHELP
- {"debug-level", 'd', POPT_ARG_INT, &debug_level, 0,
- _("Debug level"), NULL},
- {"debug-timestamps", 0, POPT_ARG_INT, &debug_timestamps, 0,
- _("Add debug timestamps"), NULL},
- {"debug-fd", 0, POPT_ARG_INT, &debug_fd, 0,
- _("An open file descriptor for the debug logs"), NULL},
- POPT_TABLEEND
- };
-
-
- pc = poptGetContext(argv[0], argc, argv, long_options, 0);
- while((opt = poptGetNextOpt(pc)) != -1) {
- switch(opt) {
- default:
- fprintf(stderr, "\nInvalid option %s: %s\n\n",
- poptBadOption(pc, 0), poptStrerror(opt));
- poptPrintUsage(pc, stderr, 0);
- _exit(-1);
- }
- }
-
- poptFreeContext(pc);
-
- DEBUG(7, ("krb5_child started.\n"));
-
- pd = talloc(NULL, struct pam_data);
- if (pd == NULL) {
- DEBUG(1, ("malloc failed.\n"));
- _exit(-1);
- }
-
- debug_prg_name = talloc_asprintf(pd, "[sssd[krb5_child[%d]]]", getpid());
-
- if (debug_fd != -1) {
- ret = set_debug_file_from_fd(debug_fd);
- if (ret != EOK) {
- DEBUG(1, ("set_debug_file_from_fd failed.\n"));
- }
- }
-
- buf = talloc_size(pd, sizeof(uint8_t)*IN_BUF_SIZE);
- if (buf == NULL) {
- DEBUG(1, ("malloc failed.\n"));
- _exit(-1);
- }
-
- while ((ret = read(STDIN_FILENO, buf + len, IN_BUF_SIZE - len)) != 0) {
- if (ret == -1) {
- if (errno == EINTR || errno == EAGAIN) {
- continue;
- }
- DEBUG(1, ("read failed [%d][%s].\n", errno, strerror(errno)));
- goto fail;
- } else if (ret > 0) {
- len += ret;
- if (len > IN_BUF_SIZE) {
- DEBUG(1, ("read too much, this should never happen.\n"));
- goto fail;
- }
- continue;
- } else {
- DEBUG(1, ("unexpected return code of read [%d].\n", ret));
- goto fail;
- }
- }
- close(STDIN_FILENO);
-
- ret = unpack_buffer(buf, len, pd, &ccname, &keytab, &validate, &offline);
- if (ret != EOK) {
- DEBUG(1, ("unpack_buffer failed.\n"));
- goto fail;
- }
-
- ret = krb5_setup(pd, pd->upn, offline, &kr);
- if (ret != EOK) {
- DEBUG(1, ("krb5_setup failed.\n"));
- goto fail;
- }
- kr->ccname = ccname;
- kr->keytab = keytab;
- kr->validate = (validate == 0) ? false : true;
-
- ret = kr->child_req(STDOUT_FILENO, kr);
- if (ret != EOK) {
- DEBUG(1, ("Child request failed.\n"));
- goto fail;
- }
-
- close(STDOUT_FILENO);
- talloc_free(pd);
-
- return 0;
-
-fail:
- close(STDOUT_FILENO);
- talloc_free(pd);
- exit(-1);
-}
diff --git a/server/providers/krb5/krb5_common.c b/server/providers/krb5/krb5_common.c
deleted file mode 100644
index 86676f44c..000000000
--- a/server/providers/krb5/krb5_common.c
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- SSSD
-
- Kerberos Provider Common Functions
-
- Authors:
- Sumit Bose <sbose@redhat.com>
-
- Copyright (C) 2008-2009 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <netdb.h>
-
-#include "providers/dp_backend.h"
-#include "providers/krb5/krb5_common.h"
-
-struct dp_option default_krb5_opts[] = {
- { "krb5_kdcip", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "krb5_ccachedir", DP_OPT_STRING, { "/tmp" }, NULL_STRING },
- { "krb5_ccname_template", DP_OPT_STRING, { "FILE:%d/krb5cc_%U_XXXXXX" }, NULL_STRING},
- { "krb5_changepw_principal", DP_OPT_STRING, { "kadmin/changepw" }, NULL_STRING },
- { "krb5_auth_timeout", DP_OPT_NUMBER, { .number = 15 }, NULL_NUMBER },
- { "krb5_keytab", DP_OPT_STRING, { "/etc/krb5.keytab" }, NULL_STRING },
- { "krb5_validate", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }
-};
-
-errno_t check_and_export_options(struct dp_option *opts,
- struct sss_domain_info *dom)
-{
- int ret;
- char *value;
- const char *realm;
- const char *dummy;
- struct stat stat_buf;
- char **list;
-
- realm = dp_opt_get_cstring(opts, KRB5_REALM);
- if (realm == NULL) {
- ret = dp_opt_set_string(opts, KRB5_REALM, dom->name);
- if (ret != EOK) {
- DEBUG(1, ("dp_opt_set_string failed.\n"));
- return ret;
- }
- realm = dom->name;
- }
-
- ret = setenv(SSSD_KRB5_REALM, realm, 1);
- if (ret != EOK) {
- DEBUG(2, ("setenv %s failed, authentication might fail.\n",
- SSSD_KRB5_REALM));
- }
-
- dummy = dp_opt_get_cstring(opts, KRB5_KDC);
- if (dummy == NULL) {
- DEBUG(1, ("No KDC expicitly configured, using defaults"));
- } else {
- ret = split_on_separator(opts, dummy, ',', true, &list, NULL);
- if (ret != EOK) {
- DEBUG(1, ("Failed to parse server list!\n"));
- return ret;
- }
- ret = write_kdcinfo_file(realm, list[0]);
- if (ret != EOK) {
- DEBUG(1, ("write_kdcinfo_file failed, "
- "using kerberos defaults from /etc/krb5.conf"));
- }
- talloc_free(list);
- }
-
- dummy = dp_opt_get_cstring(opts, KRB5_CCACHEDIR);
- ret = lstat(dummy, &stat_buf);
- if (ret != EOK) {
- DEBUG(1, ("lstat for [%s] failed: [%d][%s].\n", dummy, errno,
- strerror(errno)));
- return ret;
- }
- if ( !S_ISDIR(stat_buf.st_mode) ) {
- DEBUG(1, ("Value of krb5ccache_dir [%s] is not a directory.\n", dummy));
- return EINVAL;
- }
-
- dummy = dp_opt_get_cstring(opts, KRB5_CCNAME_TMPL);
- if (dummy == NULL) {
- DEBUG(1, ("Missing credential cache name template.\n"));
- return EINVAL;
- }
- if (dummy[0] != '/' && strncmp(dummy, "FILE:", 5) != 0) {
- DEBUG(1, ("Currently only file based credential caches are supported "
- "and krb5ccname_template must start with '/' or 'FILE:'\n"));
- return EINVAL;
- }
-
- dummy = dp_opt_get_cstring(opts, KRB5_CHANGEPW_PRINC);
- if (dummy == NULL) {
- DEBUG(1, ("Missing change password principle.\n"));
- return EINVAL;
- }
- if (strchr(dummy, '@') == NULL) {
- value = talloc_asprintf(opts, "%s@%s", dummy, realm);
- if (value == NULL) {
- DEBUG(7, ("talloc_asprintf failed.\n"));
- return ENOMEM;
- }
- ret = dp_opt_set_string(opts, KRB5_CHANGEPW_PRINC, value);
- if (ret != EOK) {
- DEBUG(1, ("dp_opt_set_string failed.\n"));
- return ret;
- }
- dummy = value;
- }
-
- ret = setenv(SSSD_KRB5_CHANGEPW_PRINCIPLE, dummy, 1);
- if (ret != EOK) {
- DEBUG(2, ("setenv %s failed, password change might fail.\n",
- SSSD_KRB5_CHANGEPW_PRINCIPLE));
- }
-
- return EOK;
-}
-
-errno_t krb5_get_options(TALLOC_CTX *memctx, struct confdb_ctx *cdb,
- const char *conf_path, struct dp_option **_opts)
-{
- int ret;
- struct dp_option *opts;
-
- opts = talloc_zero(memctx, struct dp_option);
- if (opts == NULL) {
- DEBUG(1, ("talloc_zero failed.\n"));
- return ENOMEM;
- }
-
- ret = dp_get_options(opts, cdb, conf_path, default_krb5_opts,
- KRB5_OPTS, &opts);
- if (ret != EOK) {
- DEBUG(1, ("dp_get_options failed.\n"));
- goto done;
- }
-
- *_opts = opts;
- ret = EOK;
-
-done:
- if (ret != EOK) {
- talloc_zfree(opts);
- }
-
- return ret;
-}
-
-errno_t write_kdcinfo_file(const char *realm, const char *kdc)
-{
- int ret;
- int fd = -1;
- char *tmp_name = NULL;
- char *kdcinfo_name = NULL;
- TALLOC_CTX *tmp_ctx = NULL;
- int kdc_len;
-
- if (realm == NULL || *realm == '\0' || kdc == NULL || *kdc == '\0') {
- DEBUG(1, ("Missing or empty realm or kdc.\n"));
- return EINVAL;
- }
-
- kdc_len = strlen(kdc);
-
- tmp_ctx = talloc_new(NULL);
- if (tmp_ctx == NULL) {
- DEBUG(1, ("talloc_new failed.\n"));
- return ENOMEM;
- }
-
- tmp_name = talloc_asprintf(tmp_ctx, PUBCONF_PATH"/.kdcinfo_dummy_XXXXXX");
- if (tmp_name == NULL) {
- DEBUG(1, ("talloc_asprintf failed.\n"));
- ret = ENOMEM;
- goto done;
- }
-
- kdcinfo_name = talloc_asprintf(tmp_ctx, KDCINFO_TMPL, realm);
- if (kdcinfo_name == NULL) {
- DEBUG(1, ("talloc_asprintf failed.\n"));
- ret = ENOMEM;
- goto done;
- }
-
- fd = mkstemp(tmp_name);
- if (fd == -1) {
- DEBUG(1, ("mkstemp failed [%d][%s].\n", errno, strerror(errno)));
- ret = errno;
- goto done;
- }
-
- ret = write(fd, kdc, kdc_len);
- if (ret == -1) {
- DEBUG(1, ("write failed [%d][%s].\n", errno, strerror(errno)));
- goto done;
- }
- if (ret != kdc_len) {
- DEBUG(1, ("Partial write occured, this should never happen.\n"));
- ret = EINTR;
- goto done;
- }
-
- ret = fchmod(fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
- if (ret == -1) {
- DEBUG(1, ("fchmod failed [%d][%s].\n", errno, strerror(errno)));
- goto done;
- }
-
- ret = close(fd);
- if (ret == -1) {
- DEBUG(1, ("close failed [%d][%s].\n", errno, strerror(errno)));
- goto done;
- }
-
- ret = rename(tmp_name, kdcinfo_name);
- if (ret == -1) {
- DEBUG(1, ("rename failed [%d][%s].\n", errno, strerror(errno)));
- goto done;
- }
-
-done:
- talloc_free(tmp_ctx);
- return ret;
-}
-
-static void krb5_resolve_callback(void *private_data, struct fo_server *server)
-{
- struct krb5_service *krb5_service;
- struct hostent *srvaddr;
- char *address;
- int ret;
-
- krb5_service = talloc_get_type(private_data, struct krb5_service);
- if (!krb5_service) {
- DEBUG(1, ("FATAL: Bad private_data\n"));
- return;
- }
-
- srvaddr = fo_get_server_hostent(server);
- if (!srvaddr) {
- DEBUG(1, ("FATAL: No hostent available for server (%s)\n",
- fo_get_server_name(server)));
- return;
- }
-
- address = talloc_asprintf(krb5_service, "%s", srvaddr->h_name);
- if (!address) {
- DEBUG(1, ("Failed to copy address ...\n"));
- return;
- }
-
- talloc_zfree(krb5_service->address);
- krb5_service->address = address;
-
- ret = write_kdcinfo_file(krb5_service->realm, address);
- if (ret != EOK) {
- DEBUG(2, ("write_kdcinfo_file failed, authentication might fail.\n"));
- }
-
- return;
-}
-
-
-int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
- const char *service_name, const char *servers,
- const char *realm, struct krb5_service **_service)
-{
- TALLOC_CTX *tmp_ctx;
- struct krb5_service *service;
- char **list = NULL;
- int ret;
- int i;
-
- tmp_ctx = talloc_new(memctx);
- if (!tmp_ctx) {
- return ENOMEM;
- }
-
- service = talloc_zero(tmp_ctx, struct krb5_service);
- if (!service) {
- ret = ENOMEM;
- goto done;
- }
-
- ret = be_fo_add_service(ctx, service_name);
- if (ret != EOK) {
- DEBUG(1, ("Failed to create failover service!\n"));
- goto done;
- }
-
- service->name = talloc_strdup(service, service_name);
- if (!service->name) {
- ret = ENOMEM;
- goto done;
- }
-
- service->realm = talloc_strdup(service, realm);
- if (!service->realm) {
- ret = ENOMEM;
- goto done;
- }
-
- ret = split_on_separator(tmp_ctx, servers, ',', true, &list, NULL);
- if (ret != EOK) {
- DEBUG(1, ("Failed to parse server list!\n"));
- goto done;
- }
-
- for (i = 0; list[i]; i++) {
-
- talloc_steal(service, list[i]);
-
- ret = be_fo_add_server(ctx, service_name, list[i], 0, NULL);
- if (ret && ret != EEXIST) {
- DEBUG(0, ("Failed to add server\n"));
- goto done;
- }
-
- DEBUG(6, ("Added Server %s\n", list[i]));
- }
-
- ret = be_fo_service_add_callback(memctx, ctx, service_name,
- krb5_resolve_callback, service);
- if (ret != EOK) {
- DEBUG(1, ("Failed to add failover callback!\n"));
- goto done;
- }
-
- ret = EOK;
-
-done:
- if (ret == EOK) {
- *_service = talloc_steal(memctx, service);
- }
- talloc_zfree(tmp_ctx);
- return ret;
-}
-
diff --git a/server/providers/krb5/krb5_common.h b/server/providers/krb5/krb5_common.h
deleted file mode 100644
index 832ffcdd5..000000000
--- a/server/providers/krb5/krb5_common.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- SSSD
-
- Kerberos Backend, common header file
-
- Authors:
- Sumit Bose <sbose@redhat.com>
-
- Copyright (C) 2009 Red Hat
-
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __KRB5_COMMON_H__
-#define __KRB5_COMMON_H__
-
-#include "config.h"
-#include <stdbool.h>
-
-#include "providers/dp_backend.h"
-#include "util/util.h"
-#include "util/sss_krb5.h"
-
-#define SSSD_KRB5_KDC "SSSD_KRB5_KDC"
-#define SSSD_KRB5_REALM "SSSD_KRB5_REALM"
-#define SSSD_KRB5_CHANGEPW_PRINCIPLE "SSSD_KRB5_CHANGEPW_PRINCIPLE"
-
-#define KDCINFO_TMPL PUBCONF_PATH"/kdcinfo.%s"
-
-enum krb5_opts {
- KRB5_KDC = 0,
- KRB5_REALM,
- KRB5_CCACHEDIR,
- KRB5_CCNAME_TMPL,
- KRB5_CHANGEPW_PRINC,
- KRB5_AUTH_TIMEOUT,
- KRB5_KEYTAB,
- KRB5_VALIDATE,
-
- KRB5_OPTS
-};
-
-struct krb5_service {
- char *name;
- char *address;
- char *realm;
-};
-
-errno_t check_and_export_options(struct dp_option *opts,
- struct sss_domain_info *dom);
-
-errno_t krb5_get_options(TALLOC_CTX *memctx, struct confdb_ctx *cdb,
- const char *conf_path, struct dp_option **_opts);
-
-errno_t write_kdcinfo_file(const char *realm, const char *kdc);
-
-int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
- const char *service_name, const char *servers,
- const char *realm, struct krb5_service **_service);
-#endif /* __KRB5_COMMON_H__ */
diff --git a/server/providers/krb5/krb5_init.c b/server/providers/krb5/krb5_init.c
deleted file mode 100644
index 43cbc1bc7..000000000
--- a/server/providers/krb5/krb5_init.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- SSSD
-
- Kerberos 5 Backend Module
-
- Authors:
- Sumit Bose <sbose@redhat.com>
-
- Copyright (C) 2009 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <sys/types.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include "providers/child_common.h"
-#include "providers/krb5/krb5_auth.h"
-#include "providers/krb5/krb5_common.h"
-
-struct krb5_options {
- struct dp_option *opts;
- struct krb5_ctx *auth_ctx;
-};
-
-struct krb5_options *krb5_options = NULL;
-
-struct bet_ops krb5_auth_ops = {
- .handler = krb5_pam_handler,
- .finalize = NULL,
-};
-
-int sssm_krb5_auth_init(struct be_ctx *bectx,
- struct bet_ops **ops,
- void **pvt_auth_data)
-{
- struct krb5_ctx *ctx = NULL;
- int ret;
- struct tevent_signal *sige;
- unsigned v;
- FILE *debug_filep;
- const char *krb5_servers;
- const char *krb5_realm;
-
- if (krb5_options == NULL) {
- krb5_options = talloc_zero(bectx, struct krb5_options);
- if (krb5_options == NULL) {
- DEBUG(1, ("talloc_zero failed.\n"));
- return ENOMEM;
- }
- ret = krb5_get_options(krb5_options, bectx->cdb, bectx->conf_path,
- &krb5_options->opts);
- if (ret != EOK) {
- DEBUG(1, ("krb5_get_options failed.\n"));
- return ret;
- }
- }
-
- if (krb5_options->auth_ctx != NULL) {
- *ops = &krb5_auth_ops;
- *pvt_auth_data = krb5_options->auth_ctx;
- return EOK;
- }
-
- ctx = talloc_zero(bectx, struct krb5_ctx);
- if (!ctx) {
- DEBUG(1, ("talloc failed.\n"));
- return ENOMEM;
- }
-
- ctx->action = INIT_PW;
- ctx->opts = krb5_options->opts;
-
- krb5_servers = dp_opt_get_string(ctx->opts, KRB5_KDC);
- if (krb5_servers == NULL) {
- DEBUG(0, ("Missing krb5_kdcip option!\n"));
- return EINVAL;
- }
-
- krb5_realm = dp_opt_get_string(ctx->opts, KRB5_REALM);
- if (krb5_realm == NULL) {
- DEBUG(0, ("Missing krb5_realm option!\n"));
- return EINVAL;
- }
-
- ret = krb5_service_init(ctx, bectx, "KRB5", krb5_servers, krb5_realm,
- &ctx->service);
- if (ret != EOK) {
- DEBUG(0, ("Failed to init IPA failover service!\n"));
- return ret;
- }
-
- ret = check_and_export_options(ctx->opts, bectx->domain);
- if (ret != EOK) {
- DEBUG(1, ("check_and_export_options failed.\n"));
- goto fail;
- }
-
- sige = tevent_add_signal(bectx->ev, ctx, SIGCHLD, SA_SIGINFO,
- child_sig_handler, NULL);
- if (sige == NULL) {
- DEBUG(1, ("tevent_add_signal failed.\n"));
- ret = ENOMEM;
- goto fail;
- }
-
- if (debug_to_file != 0) {
- ret = open_debug_file_ex("krb5_child", &debug_filep);
- if (ret != EOK) {
- DEBUG(0, ("Error setting up logging (%d) [%s]\n",
- ret, strerror(ret)));
- goto fail;
- }
-
- ctx->child_debug_fd = fileno(debug_filep);
- if (ctx->child_debug_fd == -1) {
- DEBUG(0, ("fileno failed [%d][%s]\n", errno, strerror(errno)));
- ret = errno;
- goto fail;
- }
-
- v = fcntl(ctx->child_debug_fd, F_GETFD, 0);
- fcntl(ctx->child_debug_fd, F_SETFD, v & ~FD_CLOEXEC);
- }
-
- *ops = &krb5_auth_ops;
- *pvt_auth_data = ctx;
- return EOK;
-
-fail:
- talloc_free(ctx);
- return ret;
-}
-
-int sssm_krb5_chpass_init(struct be_ctx *bectx,
- struct bet_ops **ops,
- void **pvt_auth_data)
-{
- return sssm_krb5_auth_init(bectx, ops, pvt_auth_data);
-}
diff --git a/server/providers/krb5/krb5_utils.c b/server/providers/krb5/krb5_utils.c
deleted file mode 100644
index 489030af8..000000000
--- a/server/providers/krb5/krb5_utils.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- SSSD
-
- Kerberos 5 Backend Module -- Utilities
-
- Authors:
- Sumit Bose <sbose@redhat.com>
-
- Copyright (C) 2009 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-#include <string.h>
-#include <stdlib.h>
-
-#include "providers/krb5/krb5_utils.h"
-#include "providers/krb5/krb5_auth.h"
-#include "util/util.h"
-
-char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct krb5child_req *kr,
- const char *template)
-{
- char *copy;
- char *p;
- char *n;
- char *result = NULL;
- const char *dummy;
-
- if (template == NULL) {
- DEBUG(1, ("Missing template.\n"));
- return NULL;
- }
-
- copy = talloc_strdup(mem_ctx, template);
- if (copy == NULL) {
- DEBUG(1, ("talloc_strdup failed.\n"));
- return NULL;
- }
-
- result = talloc_strdup(mem_ctx, "");
- if (result == NULL) {
- DEBUG(1, ("talloc_strdup failed.\n"));
- return NULL;
- }
-
- p = copy;
- while ( (n = strchr(p, '%')) != NULL) {
- *n = '\0';
- n++;
- if ( *n == '\0' ) {
- DEBUG(1, ("format error, single %% at the end of the template.\n"));
- return NULL;
- }
-
- switch( *n ) {
- case 'u':
- if (kr->pd->user == NULL) {
- DEBUG(1, ("Cannot expand user name template "
- "because user name is empty.\n"));
- return NULL;
- }
- result = talloc_asprintf_append(result, "%s%s", p,
- kr->pd->user);
- break;
- case 'U':
- if (kr->pd->pw_uid <= 0) {
- DEBUG(1, ("Cannot expand uid template "
- "because uid is invalid.\n"));
- return NULL;
- }
- result = talloc_asprintf_append(result, "%s%d", p,
- kr->pd->pw_uid);
- break;
- case 'p':
- if (kr->pd->upn == NULL) {
- DEBUG(1, ("Cannot expand user principle name template "
- "because upn is empty.\n"));
- return NULL;
- }
- result = talloc_asprintf_append(result, "%s%s", p, kr->pd->upn);
- break;
- case '%':
- result = talloc_asprintf_append(result, "%s%%", p);
- break;
- case 'r':
- dummy = dp_opt_get_string(kr->krb5_ctx->opts, KRB5_REALM);
- if (dummy == NULL) {
- DEBUG(1, ("Missing kerberos realm.\n"));
- return NULL;
- }
- result = talloc_asprintf_append(result, "%s%s", p, dummy);
- break;
- case 'h':
- if (kr->homedir == NULL) {
- DEBUG(1, ("Cannot expand home directory template "
- "because the path is not available.\n"));
- return NULL;
- }
- result = talloc_asprintf_append(result, "%s%s", p, kr->homedir);
- break;
- case 'd':
- dummy = dp_opt_get_string(kr->krb5_ctx->opts, KRB5_CCACHEDIR);
- if (dummy == NULL) {
- DEBUG(1, ("Missing credential cache directory.\n"));
- return NULL;
- }
- result = talloc_asprintf_append(result, "%s%s", p, dummy);
- break;
- case 'P':
- if (kr->pd->cli_pid == 0) {
- DEBUG(1, ("Cannot expand PID template "
- "because PID is not available.\n"));
- return NULL;
- }
- result = talloc_asprintf_append(result, "%s%d", p,
- kr->pd->cli_pid);
- break;
- default:
- DEBUG(1, ("format error, unknown template [%%%c].\n", *n));
- return NULL;
- }
-
- if (result == NULL) {
- DEBUG(1, ("talloc_asprintf_append failed.\n"));
- return NULL;
- }
-
- p = n + 1;
- }
-
- result = talloc_asprintf_append(result, "%s", p);
-
- return result;
-}
diff --git a/server/providers/krb5/krb5_utils.h b/server/providers/krb5/krb5_utils.h
deleted file mode 100644
index 7637041a6..000000000
--- a/server/providers/krb5/krb5_utils.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- SSSD
-
- Kerberos Backend, header file for utilities
-
- Authors:
- Sumit Bose <sbose@redhat.com>
-
- Copyright (C) 2009 Red Hat
-
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __KRB5_UTILS_H__
-#define __KRB5_UTILS_H__
-
-#include <talloc.h>
-
-#include "providers/krb5/krb5_auth.h"
-#include "providers/data_provider.h"
-
-char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct krb5child_req *kr,
- const char *template);
-
-errno_t become_user(uid_t uid, gid_t gid);
-
-#endif /* __KRB5_UTILS_H__ */