45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek/*
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek SSSD
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek Kerberos 5 Backend Module -- ccache related utilities
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek Authors:
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek Sumit Bose <sbose@redhat.com>
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek Jakub Hrozek <jhrozek@redhat.com>
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek Copyright (C) 2014 Red Hat
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek This program is free software; you can redistribute it and/or modify
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek it under the terms of the GNU General Public License as published by
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek the Free Software Foundation; either version 3 of the License, or
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek (at your option) any later version.
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek This program is distributed in the hope that it will be useful,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek but WITHOUT ANY WARRANTY; without even the implied warranty of
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek GNU General Public License for more details.
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek You should have received a copy of the GNU General Public License
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek along with this program. If not, see <http://www.gnu.org/licenses/>.
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek*/
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek#ifdef HAVE_KRB5_KRB5_H
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek#include <krb5/krb5.h>
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek#else
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek#include <krb5.h>
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek#endif
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek#include "providers/krb5/krb5_ccache.h"
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek#include "util/sss_krb5.h"
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek#include "util/util.h"
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstruct string_list {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct string_list *next;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct string_list *prev;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek char *s;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek};
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic errno_t find_ccdir_parent_data(TALLOC_CTX *mem_ctx,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek const char *ccdirname,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct stat *parent_stat,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct string_list **missing_parents)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek{
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek int ret = EFAULT;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek char *parent = NULL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek char *end;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct string_list *li;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = stat(ccdirname, parent_stat);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret == EOK) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if ( !S_ISDIR(parent_stat->st_mode) ) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek "[%s] is not a directory.\n", ccdirname);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return EINVAL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return EOK;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } else {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (errno != ENOENT) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = errno;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek "stat for [%s] failed: [%d][%s].\n", ccdirname, ret,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek strerror(ret));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ret;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek li = talloc_zero(mem_ctx, struct string_list);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (li == NULL) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek "talloc_zero failed.\n");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ENOMEM;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek li->s = talloc_strdup(li, ccdirname);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (li->s == NULL) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek "talloc_strdup failed.\n");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ENOMEM;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DLIST_ADD(*missing_parents, li);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek parent = talloc_strdup(mem_ctx, ccdirname);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (parent == NULL) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek "talloc_strdup failed.\n");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ENOMEM;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* We'll remove all trailing slashes from the back so that
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * we only pass /some/path to find_ccdir_parent_data, not
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * /some/path */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek do {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek end = strrchr(parent, '/');
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (end == NULL || end == parent) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek "Cannot find parent directory of [%s], / is not allowed.\n",
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ccdirname);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = EINVAL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek *end = '\0';
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } while (*(end+1) == '\0');
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = find_ccdir_parent_data(mem_ctx, parent, parent_stat, missing_parents);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekdone:
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek talloc_free(parent);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ret;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek}
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic errno_t check_parent_stat(struct stat *parent_stat, uid_t uid)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek{
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (parent_stat->st_uid != 0 && parent_stat->st_uid != uid) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek "Private directory can only be created below a directory "
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek "belonging to root or to [%"SPRIuid"].\n", uid);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return EINVAL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (parent_stat->st_uid == uid) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (!(parent_stat->st_mode & S_IXUSR)) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek "Parent directory does not have the search bit set for "
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek "the owner.\n");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return EINVAL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } else {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (!(parent_stat->st_mode & S_IXOTH)) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek "Parent directory does not have the search bit set for "
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek "others.\n");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return EINVAL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return EOK;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek}
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
7c5cd2e7711621af9163a41393e88896a91ac33bJakub Hrozekstatic errno_t create_ccache_dir(const char *ccdirname, uid_t uid, gid_t gid)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek{
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek int ret = EFAULT;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct stat parent_stat;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct string_list *missing_parents = NULL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct string_list *li = NULL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek mode_t old_umask;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek mode_t new_dir_mode;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek TALLOC_CTX *tmp_ctx = NULL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek tmp_ctx = talloc_new(NULL);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (tmp_ctx == NULL) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek "talloc_new failed.\n");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ENOMEM;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (*ccdirname != '/') {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek "Only absolute paths are allowed, not [%s] .\n", ccdirname);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = EINVAL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = find_ccdir_parent_data(tmp_ctx, ccdirname, &parent_stat,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek &missing_parents);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret != EOK) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek "find_ccdir_parent_data failed.\n");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = check_parent_stat(&parent_stat, uid);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret != EOK) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_FATAL_FAILURE,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek "Check the ownership and permissions of krb5_ccachedir: [%s].\n",
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ccdirname);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DLIST_FOR_EACH(li, missing_parents) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek "Creating directory [%s].\n", li->s);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek new_dir_mode = 0700;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek old_umask = umask(0000);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = mkdir(li->s, new_dir_mode);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek umask(old_umask);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret != EOK) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = errno;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek "mkdir [%s] failed: [%d][%s].\n", li->s, ret,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek strerror(ret));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = chown(li->s, uid, gid);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret != EOK) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = errno;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek "chown failed [%d][%s].\n", ret, strerror(ret));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = EOK;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekdone:
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek talloc_free(tmp_ctx);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ret;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek}
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
7c5cd2e7711621af9163a41393e88896a91ac33bJakub Hrozekerrno_t sss_krb5_precreate_ccache(const char *ccname, uid_t uid, gid_t gid)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek{
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek TALLOC_CTX *tmp_ctx = NULL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek const char *filename;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek char *ccdirname;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek char *end;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek errno_t ret;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ccname[0] == '/') {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek filename = ccname;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } else if (strncmp(ccname, "FILE:", 5) == 0) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek filename = ccname + 5;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } else if (strncmp(ccname, "DIR:", 4) == 0) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek filename = ccname + 4;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } else {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* only FILE and DIR types need precreation so far, we ignore any
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * other type */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return EOK;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek tmp_ctx = talloc_new(NULL);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (!tmp_ctx) return ENOMEM;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ccdirname = talloc_strdup(tmp_ctx, filename);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ccdirname == NULL) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = ENOMEM;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* We'll remove all trailing slashes from the back so that
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * we only pass /some/path to find_ccdir_parent_data, not
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * /some/path/ */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek do {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek end = strrchr(ccdirname, '/');
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (end == NULL || end == ccdirname) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find parent directory of [%s], "
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek "/ is not allowed.\n", ccdirname);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = EINVAL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek *end = '\0';
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } while (*(end+1) == '\0');
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
7c5cd2e7711621af9163a41393e88896a91ac33bJakub Hrozek ret = create_ccache_dir(ccdirname, uid, gid);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekdone:
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek talloc_free(tmp_ctx);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ret;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek}
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstruct sss_krb5_ccache {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sss_creds *creds;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_context context;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_ccache ccache;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek};
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic int sss_free_krb5_ccache(void *mem)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek{
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sss_krb5_ccache *cc = talloc_get_type(mem, struct sss_krb5_ccache);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (cc->ccache) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_cc_close(cc->context, cc->ccache);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_free_context(cc->context);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek restore_creds(cc->creds);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return 0;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek}
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic errno_t sss_open_ccache_as_user(TALLOC_CTX *mem_ctx,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek const char *ccname,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek uid_t uid, gid_t gid,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sss_krb5_ccache **ccache)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek{
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sss_krb5_ccache *cc;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_error_code kerr;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek errno_t ret;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek cc = talloc_zero(mem_ctx, struct sss_krb5_ccache);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (!cc) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ENOMEM;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek talloc_set_destructor((TALLOC_CTX *)cc, sss_free_krb5_ccache);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = switch_creds(cc, uid, gid, 0, NULL, &cc->creds);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
2c10819750a8d920ab755eba1278e6e20e684e93Sumit Bose kerr = sss_krb5_init_context(&cc->context);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (kerr) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = EIO;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek kerr = krb5_cc_resolve(cc->context, ccname, &cc->ccache);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (kerr == KRB5_FCC_NOFILE || cc->ccache == NULL) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, "ccache %s is missing or empty\n", ccname);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = ERR_NOT_FOUND;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } else if (kerr != 0) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek KRB5_DEBUG(SSSDBG_OP_FAILURE, cc->context, kerr);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_resolve failed.\n");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = ERR_INTERNAL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = EOK;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekdone:
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek talloc_free(cc);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } else {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek *ccache = cc;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ret;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek}
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic errno_t sss_destroy_ccache(struct sss_krb5_ccache *cc)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek{
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_error_code kerr;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek errno_t ret;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek kerr = krb5_cc_destroy(cc->context, cc->ccache);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (kerr) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek KRB5_DEBUG(SSSDBG_OP_FAILURE, cc->context, kerr);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_destroy failed.\n");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = EIO;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } else {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = EOK;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* krb5_cc_destroy frees cc->ccache in all events */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek cc->ccache = NULL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ret;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek}
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekerrno_t sss_krb5_cc_destroy(const char *ccname, uid_t uid, gid_t gid)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek{
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sss_krb5_ccache *cc = NULL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek TALLOC_CTX *tmp_ctx;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek errno_t ret;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
e693e9c67e0b4c5b38ba7ce7d04f718b2da2e2d0Lukas Slebodnik if (ccname == NULL) {
e693e9c67e0b4c5b38ba7ce7d04f718b2da2e2d0Lukas Slebodnik /* nothing to remove */
e693e9c67e0b4c5b38ba7ce7d04f718b2da2e2d0Lukas Slebodnik return EOK;
e693e9c67e0b4c5b38ba7ce7d04f718b2da2e2d0Lukas Slebodnik }
e693e9c67e0b4c5b38ba7ce7d04f718b2da2e2d0Lukas Slebodnik
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek tmp_ctx = talloc_new(NULL);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (tmp_ctx == NULL) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ENOMEM;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sss_open_ccache_as_user(tmp_ctx, ccname, uid, gid, &cc);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sss_destroy_ccache(cc);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekdone:
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek talloc_free(tmp_ctx);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ret;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek}
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek/* This function is called only as a way to validate that we have the
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * right cache */
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozekerrno_t sss_krb5_check_ccache_princ(krb5_context kctx,
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek const char *ccname,
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek krb5_principal user_princ)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek{
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek krb5_ccache kcc = NULL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_principal ccprinc = NULL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_error_code kerr;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek const char *cc_type;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek errno_t ret;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek kerr = krb5_cc_resolve(kctx, ccname, &kcc);
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek if (kerr) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = ERR_INTERNAL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek cc_type = krb5_cc_get_type(kctx, kcc);
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek kerr = krb5_cc_get_principal(kctx, kcc, &ccprinc);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (kerr != 0) {
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek KRB5_DEBUG(SSSDBG_OP_FAILURE, kctx, kerr);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_get_principal failed.\n");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ccprinc) {
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek if (krb5_principal_compare(kctx, user_princ, ccprinc) == TRUE) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* found in the primary ccache */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = EOK;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek#ifdef HAVE_KRB5_CC_COLLECTION
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek if (krb5_cc_support_switch(kctx, cc_type)) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek krb5_cc_close(kctx, kcc);
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek kcc = NULL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek kerr = krb5_cc_set_default_name(kctx, ccname);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (kerr != 0) {
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek KRB5_DEBUG(SSSDBG_MINOR_FAILURE, kctx, kerr);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* try to continue despite failure */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek kerr = krb5_cc_cache_match(kctx, user_princ, &kcc);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (kerr == 0) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = EOK;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek KRB5_DEBUG(SSSDBG_TRACE_INTERNAL, kctx, kerr);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek#endif /* HAVE_KRB5_CC_COLLECTION */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = ERR_NOT_FOUND;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekdone:
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek if (ccprinc) {
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek krb5_free_principal(kctx, ccprinc);
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek }
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek if (kcc) {
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek krb5_cc_close(kctx, kcc);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ret;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek}
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic errno_t sss_low_level_path_check(const char *ccname)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek{
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek const char *filename;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct stat buf;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek int ret;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ccname[0] == '/') {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek filename = ccname;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } else if (strncmp(ccname, "FILE:", 5) == 0) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek filename = ccname + 5;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } else if (strncmp(ccname, "DIR:", 4) == 0) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek filename = ccname + 4;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (filename[0] == ':') filename += 1;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } else {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* only FILE and DIR types need file checks so far, we ignore any
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * other type */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return EOK;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = stat(filename, &buf);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret == -1) return errno;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return EOK;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek}
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekerrno_t sss_krb5_cc_verify_ccache(const char *ccname, uid_t uid, gid_t gid,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek const char *realm, const char *principal)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek{
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct sss_krb5_ccache *cc = NULL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek TALLOC_CTX *tmp_ctx = NULL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_principal tgt_princ = NULL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_principal princ = NULL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek char *tgt_name;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_creds mcred = { 0 };
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_creds cred = { 0 };
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_error_code kerr;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek errno_t ret;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* first of all verify if the old ccache file/dir exists as we may be
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * trying to verify if an old ccache exists at all. If no file/dir
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * exists bail out immediately otherwise a following krb5_cc_resolve()
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * call may actually create paths and files we do not want to have
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * around */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sss_low_level_path_check(ccname);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ret;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek tmp_ctx = talloc_new(NULL);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (tmp_ctx == NULL) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ENOMEM;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sss_open_ccache_as_user(tmp_ctx, ccname, uid, gid, &cc);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ret) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek tgt_name = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s", realm, realm);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (!tgt_name) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = ENOMEM;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek kerr = krb5_parse_name(cc->context, tgt_name, &tgt_princ);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (kerr) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek KRB5_DEBUG(SSSDBG_CRIT_FAILURE, cc->context, kerr);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (kerr == KRB5_PARSE_MALFORMED) ret = EINVAL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek else ret = ERR_INTERNAL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek kerr = krb5_parse_name(cc->context, principal, &princ);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (kerr) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek KRB5_DEBUG(SSSDBG_CRIT_FAILURE, cc->context, kerr);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (kerr == KRB5_PARSE_MALFORMED) ret = EINVAL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek else ret = ERR_INTERNAL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek mcred.client = princ;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek mcred.server = tgt_princ;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek mcred.times.endtime = time(NULL);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek kerr = krb5_cc_retrieve_cred(cc->context, cc->ccache,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek KRB5_TC_MATCH_TIMES, &mcred, &cred);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (kerr) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (kerr == KRB5_CC_NOTFOUND || kerr == KRB5_FCC_NOFILE) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, "TGT not found or expired.\n");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = EINVAL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } else {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek KRB5_DEBUG(SSSDBG_CRIT_FAILURE, cc->context, kerr);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = ERR_INTERNAL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_free_cred_contents(cc->context, &cred);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekdone:
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (tgt_princ) krb5_free_principal(cc->context, tgt_princ);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (princ) krb5_free_principal(cc->context, princ);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek talloc_free(tmp_ctx);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return ret;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek}
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekerrno_t get_ccache_file_data(const char *ccache_file, const char *client_name,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct tgt_times *tgtt)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek{
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_error_code kerr;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_context ctx = NULL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_ccache cc = NULL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_principal client_princ = NULL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_principal server_princ = NULL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek char *server_name;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_creds mcred;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_creds cred;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek const char *realm_name;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek int realm_length;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
2c10819750a8d920ab755eba1278e6e20e684e93Sumit Bose kerr = sss_krb5_init_context(&ctx);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (kerr != 0) {
2c10819750a8d920ab755eba1278e6e20e684e93Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "sss_krb5_init_context failed.\n");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek kerr = krb5_parse_name(ctx, client_name, &client_princ);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (kerr != 0) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "krb5_parse_name failed.\n");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek sss_krb5_princ_realm(ctx, client_princ, &realm_name, &realm_length);
466f5a539be1e4c6e7cfb396a2f406e1eb8c428dLukas Slebodnik if (realm_length == 0) {
466f5a539be1e4c6e7cfb396a2f406e1eb8c428dLukas Slebodnik kerr = KRB5KRB_ERR_GENERIC;
466f5a539be1e4c6e7cfb396a2f406e1eb8c428dLukas Slebodnik DEBUG(SSSDBG_CRIT_FAILURE, "sss_krb5_princ_realm failed.\n");
466f5a539be1e4c6e7cfb396a2f406e1eb8c428dLukas Slebodnik goto done;
466f5a539be1e4c6e7cfb396a2f406e1eb8c428dLukas Slebodnik }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek server_name = talloc_asprintf(NULL, "krbtgt/%.*s@%.*s",
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek realm_length, realm_name,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek realm_length, realm_name);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (server_name == NULL) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek kerr = KRB5_CC_NOMEM;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek kerr = krb5_parse_name(ctx, server_name, &server_princ);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek talloc_free(server_name);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (kerr != 0) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "krb5_parse_name failed.\n");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek kerr = krb5_cc_resolve(ctx, ccache_file, &cc);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (kerr != 0) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_resolve failed.\n");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek memset(&mcred, 0, sizeof(mcred));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek memset(&cred, 0, sizeof(mcred));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek mcred.server = server_princ;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek mcred.client = client_princ;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek kerr = krb5_cc_retrieve_cred(ctx, cc, 0, &mcred, &cred);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (kerr != 0) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_retrieve_cred failed.\n");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek tgtt->authtime = cred.times.authtime;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek tgtt->starttime = cred.times.starttime;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek tgtt->endtime = cred.times.endtime;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek tgtt->renew_till = cred.times.renew_till;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_free_cred_contents(ctx, &cred);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek kerr = krb5_cc_close(ctx, cc);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (kerr != 0) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_close failed.\n");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek goto done;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek cc = NULL;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek kerr = 0;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekdone:
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (cc != NULL) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_cc_close(ctx, cc);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (client_princ != NULL) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_free_principal(ctx, client_princ);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (server_princ != NULL) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_free_principal(ctx, server_princ);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ctx != NULL) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek krb5_free_context(ctx);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (kerr != 0) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return EIO;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return EOK;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek}
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekerrno_t safe_remove_old_ccache_file(const char *old_ccache,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek const char *new_ccache,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek uid_t uid, gid_t gid)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek{
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if ((old_ccache == new_ccache)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek || (old_ccache && new_ccache
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek && (strcmp(old_ccache, new_ccache) == 0))) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, "New and old ccache file are the same, "
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek "none will be deleted.\n");
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return EOK;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek }
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek return sss_krb5_cc_destroy(old_ccache, uid, gid);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek}
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bosekrb5_error_code copy_ccache_into_memory(TALLOC_CTX *mem_ctx, krb5_context kctx,
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose const char *ccache_file,
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose char **_mem_name)
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose{
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose krb5_error_code kerr;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose krb5_ccache ccache;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose krb5_ccache mem_ccache = NULL;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose char *ccache_name = NULL;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose krb5_principal princ = NULL;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose char *mem_name = NULL;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose char *sep;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose kerr = krb5_cc_resolve(kctx, ccache_file, &ccache);
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose if (kerr != 0) {
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "error resolving ccache [%s].\n",
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose ccache_file);
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose return kerr;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose }
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose kerr = krb5_cc_get_full_name(kctx, ccache, &ccache_name);
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose if (kerr != 0) {
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "Failed to read name for ccache [%s].\n",
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose ccache_file);
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose goto done;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose }
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose sep = strchr(ccache_name, ':');
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose if (sep == NULL || sep[1] == '\0') {
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE,
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose "Ccache name [%s] does not have delimiter[:] .\n", ccache_name);
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose kerr = KRB5KRB_ERR_GENERIC;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose goto done;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose }
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose if (strncmp(ccache_name, "MEMORY:", sizeof("MEMORY:") -1) == 0) {
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose DEBUG(SSSDBG_TRACE_FUNC, "Ccache [%s] is already memory ccache.\n",
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose ccache_name);
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose *_mem_name = talloc_strdup(mem_ctx, ccache_name);
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose if(*_mem_name == NULL) {
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose kerr = KRB5KRB_ERR_GENERIC;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose goto done;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose }
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose kerr = 0;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose goto done;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose }
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose if (strncmp(ccache_name, "FILE:", sizeof("FILE:") -1) == 0) {
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose mem_name = talloc_asprintf(mem_ctx, "MEMORY:%s", sep + 1);
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose if (mem_name == NULL) {
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose kerr = KRB5KRB_ERR_GENERIC;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose goto done;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose }
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose } else {
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose DEBUG(SSSDBG_MINOR_FAILURE, "Unexpected ccache type for ccache [%s], " \
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose "currently only FILE is supported.\n",
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose ccache_name);
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose kerr = KRB5KRB_ERR_GENERIC;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose goto done;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose }
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose kerr = krb5_cc_resolve(kctx, mem_name, &mem_ccache);
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose if (kerr != 0) {
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "error resolving ccache [%s].\n", mem_name);
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose goto done;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose }
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose kerr = krb5_cc_get_principal(kctx, ccache, &princ);
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose if (kerr != 0) {
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE,
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose "error reading principal from ccache [%s].\n", ccache_name);
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose goto done;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose }
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose kerr = krb5_cc_initialize(kctx, mem_ccache, princ);
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose if (kerr != 0) {
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE,
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose "Failed to initialize ccache [%s].\n", mem_name);
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose goto done;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose }
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose kerr = krb5_cc_copy_creds(kctx, ccache, mem_ccache);
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose if (kerr != 0) {
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE,
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose "Failed to copy ccache [%s] to [%s].\n", ccache_name, mem_name);
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose goto done;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose }
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose *_mem_name = mem_name;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose kerr = 0;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bosedone:
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose if (kerr != 0) {
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose talloc_free(mem_name);
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose }
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose free(ccache_name);
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose krb5_free_principal(kctx, princ);
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose if (krb5_cc_close(kctx, ccache) != 0) {
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose DEBUG(SSSDBG_OP_FAILURE, "krb5_cc_close failed.\n");
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose }
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose if (krb5_cc_close(kctx, mem_ccache) != 0) {
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose DEBUG(SSSDBG_OP_FAILURE, "krb5_cc_close failed.\n");
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose }
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose return kerr;
802385896dc1c4e7b8bbd40dcfe3cd131f68e696Sumit Bose}