a0ab15ceb80290db80c2052520830a95390de385Sumit Bose/*
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose SSSD
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose Kerberos 5 Backend Module -- keytab related utilities
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose Authors:
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose Sumit Bose <sbose@redhat.com>
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose Copyright (C) 2014 Red Hat
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose This program is free software; you can redistribute it and/or modify
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose it under the terms of the GNU General Public License as published by
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose the Free Software Foundation; either version 3 of the License, or
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose (at your option) any later version.
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose This program is distributed in the hope that it will be useful,
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose but WITHOUT ANY WARRANTY; without even the implied warranty of
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose GNU General Public License for more details.
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose You should have received a copy of the GNU General Public License
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose along with this program. If not, see <http://www.gnu.org/licenses/>.
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose*/
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose#include "util/util.h"
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose#include "util/sss_krb5.h"
41f13bb048dbc4241dcfc024cdc3ec535510ba6bLukas Slebodnik#include "providers/krb5/krb5_common.h"
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bosestatic krb5_error_code do_keytab_copy(krb5_context kctx, krb5_keytab s_keytab,
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose krb5_keytab d_keytab)
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose{
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose krb5_error_code kerr;
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose krb5_error_code kt_err;
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose krb5_kt_cursor cursor;
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose krb5_keytab_entry entry;
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose memset(&cursor, 0, sizeof(cursor));
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose kerr = krb5_kt_start_seq_get(kctx, s_keytab, &cursor);
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose if (kerr != 0) {
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "error reading keytab.\n");
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose return kerr;
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose }
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose memset(&entry, 0, sizeof(entry));
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose while ((kt_err = krb5_kt_next_entry(kctx, s_keytab, &entry,
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose &cursor)) == 0) {
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose kerr = krb5_kt_add_entry(kctx, d_keytab, &entry);
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose if (kerr != 0) {
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose DEBUG(SSSDBG_OP_FAILURE, "krb5_kt_add_entry failed.\n");
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose kt_err = krb5_kt_end_seq_get(kctx, s_keytab, &cursor);
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose if (kt_err != 0) {
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose DEBUG(SSSDBG_TRACE_ALL,
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose "krb5_kt_end_seq_get failed with [%d], ignored.\n",
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose kt_err);
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose }
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose return kerr;
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose }
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose kerr = sss_krb5_free_keytab_entry_contents(kctx, &entry);
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose if (kerr != 0) {
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose DEBUG(SSSDBG_MINOR_FAILURE, "Failed to free keytab entry.\n");
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose kt_err = krb5_kt_end_seq_get(kctx, s_keytab, &cursor);
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose if (kt_err != 0) {
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose DEBUG(SSSDBG_TRACE_ALL,
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose "krb5_kt_end_seq_get failed with [%d], ignored.\n",
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose kt_err);
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose }
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose return kerr;
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose }
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose memset(&entry, 0, sizeof(entry));
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose }
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose kerr = krb5_kt_end_seq_get(kctx, s_keytab, &cursor);
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose if (kerr != 0) {
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "krb5_kt_end_seq_get failed.\n");
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose return kerr;
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose }
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose /* check if we got any errors from krb5_kt_next_entry */
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose if (kt_err != 0 && kt_err != KRB5_KT_END) {
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "error reading keytab.\n");
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose return kt_err;
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose }
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose return 0;
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose}
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose
a0ab15ceb80290db80c2052520830a95390de385Sumit Bosekrb5_error_code copy_keytab_into_memory(TALLOC_CTX *mem_ctx, krb5_context kctx,
41f13bb048dbc4241dcfc024cdc3ec535510ba6bLukas Slebodnik const char *inp_keytab_file,
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose char **_mem_name,
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose krb5_keytab *_mem_keytab)
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose{
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose krb5_error_code kerr;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose krb5_keytab keytab = NULL;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose krb5_keytab mem_keytab = NULL;
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose krb5_keytab tmp_mem_keytab = NULL;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose char keytab_name[MAX_KEYTAB_NAME_LEN];
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose char *sep;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose char *mem_name = NULL;
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose char *tmp_mem_name = NULL;
41f13bb048dbc4241dcfc024cdc3ec535510ba6bLukas Slebodnik const char *keytab_file;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose char default_keytab_name[MAX_KEYTAB_NAME_LEN];
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose keytab_file = inp_keytab_file;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose if (keytab_file == NULL) {
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose kerr = krb5_kt_default_name(kctx, default_keytab_name,
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose sizeof(default_keytab_name));
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose if (kerr != 0) {
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "krb5_kt_default_name failed.\n");
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose return kerr;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose }
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose keytab_file = default_keytab_name;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose }
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose kerr = krb5_kt_resolve(kctx, keytab_file, &keytab);
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose if (kerr != 0) {
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "error resolving keytab [%s].\n",
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose keytab_file);
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose return kerr;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose }
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
5dcf3ffa3aa228701a79556dc0b889dba0aac535Sumit Bose kerr = sss_krb5_kt_have_content(kctx, keytab);
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose if (kerr != 0) {
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "keytab [%s] has not entries.\n",
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose keytab_file);
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose goto done;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose }
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose kerr = krb5_kt_get_name(kctx, keytab, keytab_name, sizeof(keytab_name));
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose if (kerr != 0) {
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "Failed to read name for keytab [%s].\n",
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose keytab_file);
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose goto done;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose }
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose sep = strchr(keytab_name, ':');
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose if (sep == NULL || sep[1] == '\0') {
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE,
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose "Keytab name [%s] does not have delimiter[:] .\n", keytab_name);
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose kerr = KRB5KRB_ERR_GENERIC;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose goto done;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose }
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose if (strncmp(keytab_name, "MEMORY:", sizeof("MEMORY:") -1) == 0) {
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose DEBUG(SSSDBG_TRACE_FUNC, "Keytab [%s] is already memory keytab.\n",
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose keytab_name);
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose *_mem_name = talloc_strdup(mem_ctx, keytab_name);
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose if(*_mem_name == NULL) {
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose kerr = KRB5KRB_ERR_GENERIC;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose goto done;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose }
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose kerr = 0;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose goto done;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose }
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose mem_name = talloc_asprintf(mem_ctx, "MEMORY:%s", sep + 1);
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose if (mem_name == NULL) {
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose kerr = KRB5KRB_ERR_GENERIC;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose goto done;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose }
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose tmp_mem_name = talloc_asprintf(mem_ctx, "MEMORY:%s.tmp", sep + 1);
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose if (tmp_mem_name == NULL) {
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose kerr = KRB5KRB_ERR_GENERIC;
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose goto done;
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose }
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose kerr = krb5_kt_resolve(kctx, mem_name, &mem_keytab);
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose if (kerr != 0) {
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "error resolving keytab [%s].\n",
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose mem_name);
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose goto done;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose }
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose kerr = krb5_kt_resolve(kctx, tmp_mem_name, &tmp_mem_keytab);
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose if (kerr != 0) {
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "error resolving keytab [%s].\n",
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose tmp_mem_name);
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose goto done;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose }
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose kerr = do_keytab_copy(kctx, keytab, tmp_mem_keytab);
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose if (kerr != 0) {
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy keytab [%s] into [%s].\n",
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose keytab_file, tmp_mem_name);
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose goto done;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose }
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose /* krb5_kt_add_entry() adds new entries into MEMORY keytabs at the
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * beginning and not at the end as for FILE keytabs. Since we want to keep
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * the processing order we have to copy the MEMORY keytab again to retain
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose * the order from the FILE keytab. */
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose kerr = do_keytab_copy(kctx, tmp_mem_keytab, mem_keytab);
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose if (kerr != 0) {
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy keytab [%s] into [%s].\n",
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose tmp_mem_name, mem_name);
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose goto done;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose }
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose *_mem_name = mem_name;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose if (_mem_keytab != NULL) {
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose *_mem_keytab = mem_keytab;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose }
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose kerr = 0;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bosedone:
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose talloc_free(tmp_mem_name);
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose if (kerr != 0) {
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose talloc_free(mem_name);
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose }
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose if (tmp_mem_keytab != NULL && krb5_kt_close(kctx, tmp_mem_keytab) != 0) {
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose DEBUG(SSSDBG_MINOR_FAILURE, "krb5_kt_close failed.\n");
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose }
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose if (keytab != NULL && krb5_kt_close(kctx, keytab) != 0) {
576ad637181b80d39a4e136c9afbf34c57f76156Sumit Bose DEBUG(SSSDBG_MINOR_FAILURE, "krb5_kt_close failed.\n");
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose }
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose return kerr;
a0ab15ceb80290db80c2052520830a95390de385Sumit Bose}