|
|
905b4d |
From 7c20e30182e3b5f7f8ebcd8174bded4dcc2f89a8 Mon Sep 17 00:00:00 2001
|
|
|
905b4d |
From: Sumit Bose <sbose@redhat.com>
|
|
|
905b4d |
Date: Thu, 15 Jan 2015 10:38:33 +0100
|
|
|
905b4d |
Subject: [PATCH 169/169] krb5: fix entry order in MEMORY keytab
|
|
|
905b4d |
MIME-Version: 1.0
|
|
|
905b4d |
Content-Type: text/plain; charset=UTF-8
|
|
|
905b4d |
Content-Transfer-Encoding: 8bit
|
|
|
905b4d |
|
|
|
905b4d |
Since krb5_kt_add_entry() adds new entries at the beginning of a MEMORY
|
|
|
905b4d |
type keytab and not at the end a simple copy into a MEMORY type keytab
|
|
|
905b4d |
will revert the order of the keytab entries. Since e.g. the sssd_krb5
|
|
|
905b4d |
man page give hints about where to add entries into keytab files to help
|
|
|
905b4d |
SSSD to find a right entry we have to keep the order when coping a
|
|
|
905b4d |
keytab into a MEMORY type keytab. This patch fixes this by doing a
|
|
|
905b4d |
second copy to retain the original order.
|
|
|
905b4d |
|
|
|
905b4d |
Resolves https://fedorahosted.org/sssd/ticket/2557
|
|
|
905b4d |
|
|
|
905b4d |
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
|
|
905b4d |
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
905b4d |
|
|
|
905b4d |
(cherry picked from commit 24df1487413d13248dcc70d2548a763930da4c65)
|
|
|
905b4d |
---
|
|
|
905b4d |
src/providers/krb5/krb5_keytab.c | 118 +++++++++++++++++++++++++++++----------
|
|
|
905b4d |
1 file changed, 90 insertions(+), 28 deletions(-)
|
|
|
905b4d |
|
|
|
905b4d |
diff --git a/src/providers/krb5/krb5_keytab.c b/src/providers/krb5/krb5_keytab.c
|
|
|
905b4d |
index 855f69419611b863a7aea79e2788272f819b0736..ec8d6502d89c0d7f75c28b151523d235b6bc131d 100644
|
|
|
905b4d |
--- a/src/providers/krb5/krb5_keytab.c
|
|
|
905b4d |
+++ b/src/providers/krb5/krb5_keytab.c
|
|
|
905b4d |
@@ -25,20 +25,78 @@
|
|
|
905b4d |
#include "util/util.h"
|
|
|
905b4d |
#include "util/sss_krb5.h"
|
|
|
905b4d |
|
|
|
905b4d |
+static krb5_error_code do_keytab_copy(krb5_context kctx, krb5_keytab s_keytab,
|
|
|
905b4d |
+ krb5_keytab d_keytab)
|
|
|
905b4d |
+{
|
|
|
905b4d |
+ krb5_error_code kerr;
|
|
|
905b4d |
+ krb5_error_code kt_err;
|
|
|
905b4d |
+ krb5_kt_cursor cursor;
|
|
|
905b4d |
+ krb5_keytab_entry entry;
|
|
|
905b4d |
+
|
|
|
905b4d |
+ memset(&cursor, 0, sizeof(cursor));
|
|
|
905b4d |
+ kerr = krb5_kt_start_seq_get(kctx, s_keytab, &cursor);
|
|
|
905b4d |
+ if (kerr != 0) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_CRIT_FAILURE, "error reading keytab.\n");
|
|
|
905b4d |
+ return kerr;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ memset(&entry, 0, sizeof(entry));
|
|
|
905b4d |
+ while ((kt_err = krb5_kt_next_entry(kctx, s_keytab, &entry,
|
|
|
905b4d |
+ &cursor)) == 0) {
|
|
|
905b4d |
+ kerr = krb5_kt_add_entry(kctx, d_keytab, &entry);
|
|
|
905b4d |
+ if (kerr != 0) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_OP_FAILURE, "krb5_kt_add_entry failed.\n");
|
|
|
905b4d |
+ kt_err = krb5_kt_end_seq_get(kctx, s_keytab, &cursor);
|
|
|
905b4d |
+ if (kt_err != 0) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_TRACE_ALL,
|
|
|
905b4d |
+ "krb5_kt_end_seq_get failed with [%d], ignored.\n",
|
|
|
905b4d |
+ kt_err);
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+ return kerr;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ kerr = sss_krb5_free_keytab_entry_contents(kctx, &entry);
|
|
|
905b4d |
+ if (kerr != 0) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_MINOR_FAILURE, "Failed to free keytab entry.\n");
|
|
|
905b4d |
+ kt_err = krb5_kt_end_seq_get(kctx, s_keytab, &cursor);
|
|
|
905b4d |
+ if (kt_err != 0) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_TRACE_ALL,
|
|
|
905b4d |
+ "krb5_kt_end_seq_get failed with [%d], ignored.\n",
|
|
|
905b4d |
+ kt_err);
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+ return kerr;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+ memset(&entry, 0, sizeof(entry));
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ kerr = krb5_kt_end_seq_get(kctx, s_keytab, &cursor);
|
|
|
905b4d |
+ if (kerr != 0) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_CRIT_FAILURE, "krb5_kt_end_seq_get failed.\n");
|
|
|
905b4d |
+ return kerr;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ /* check if we got any errors from krb5_kt_next_entry */
|
|
|
905b4d |
+ if (kt_err != 0 && kt_err != KRB5_KT_END) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_CRIT_FAILURE, "error reading keytab.\n");
|
|
|
905b4d |
+ return kt_err;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ return 0;
|
|
|
905b4d |
+}
|
|
|
905b4d |
+
|
|
|
905b4d |
krb5_error_code copy_keytab_into_memory(TALLOC_CTX *mem_ctx, krb5_context kctx,
|
|
|
905b4d |
char *inp_keytab_file,
|
|
|
905b4d |
char **_mem_name,
|
|
|
905b4d |
krb5_keytab *_mem_keytab)
|
|
|
905b4d |
{
|
|
|
905b4d |
krb5_error_code kerr;
|
|
|
905b4d |
- krb5_error_code kt_err;
|
|
|
905b4d |
krb5_keytab keytab = NULL;
|
|
|
905b4d |
krb5_keytab mem_keytab = NULL;
|
|
|
905b4d |
- krb5_kt_cursor cursor;
|
|
|
905b4d |
- krb5_keytab_entry entry;
|
|
|
905b4d |
+ krb5_keytab tmp_mem_keytab = NULL;
|
|
|
905b4d |
char keytab_name[MAX_KEYTAB_NAME_LEN];
|
|
|
905b4d |
char *sep;
|
|
|
905b4d |
char *mem_name = NULL;
|
|
|
905b4d |
+ char *tmp_mem_name = NULL;
|
|
|
905b4d |
char *keytab_file;
|
|
|
905b4d |
char default_keytab_name[MAX_KEYTAB_NAME_LEN];
|
|
|
905b4d |
|
|
|
905b4d |
@@ -103,6 +161,13 @@ krb5_error_code copy_keytab_into_memory(TALLOC_CTX *mem_ctx, krb5_context kctx,
|
|
|
905b4d |
goto done;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
+ tmp_mem_name = talloc_asprintf(mem_ctx, "MEMORY:%s.tmp", sep + 1);
|
|
|
905b4d |
+ if (tmp_mem_name == NULL) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
|
|
|
905b4d |
+ kerr = KRB5KRB_ERR_GENERIC;
|
|
|
905b4d |
+ goto done;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
kerr = krb5_kt_resolve(kctx, mem_name, &mem_keytab);
|
|
|
905b4d |
if (kerr != 0) {
|
|
|
905b4d |
DEBUG(SSSDBG_CRIT_FAILURE, "error resolving keytab [%s].\n",
|
|
|
905b4d |
@@ -110,38 +175,29 @@ krb5_error_code copy_keytab_into_memory(TALLOC_CTX *mem_ctx, krb5_context kctx,
|
|
|
905b4d |
goto done;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
- memset(&cursor, 0, sizeof(cursor));
|
|
|
905b4d |
- kerr = krb5_kt_start_seq_get(kctx, keytab, &cursor);
|
|
|
905b4d |
+ kerr = krb5_kt_resolve(kctx, tmp_mem_name, &tmp_mem_keytab);
|
|
|
905b4d |
if (kerr != 0) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "error reading keytab [%s].\n", keytab_file);
|
|
|
905b4d |
+ DEBUG(SSSDBG_CRIT_FAILURE, "error resolving keytab [%s].\n",
|
|
|
905b4d |
+ tmp_mem_name);
|
|
|
905b4d |
goto done;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
- memset(&entry, 0, sizeof(entry));
|
|
|
905b4d |
- while ((kt_err = krb5_kt_next_entry(kctx, keytab, &entry, &cursor)) == 0) {
|
|
|
905b4d |
- kerr = krb5_kt_add_entry(kctx, mem_keytab, &entry);
|
|
|
905b4d |
- if (kerr != 0) {
|
|
|
905b4d |
- DEBUG(SSSDBG_OP_FAILURE, "krb5_kt_add_entry failed.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = sss_krb5_free_keytab_entry_contents(kctx, &entry);
|
|
|
905b4d |
- if (kerr != 0) {
|
|
|
905b4d |
- DEBUG(SSSDBG_MINOR_FAILURE, "Failed to free keytab entry.\n");
|
|
|
905b4d |
- }
|
|
|
905b4d |
- memset(&entry, 0, sizeof(entry));
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- kerr = krb5_kt_end_seq_get(kctx, keytab, &cursor);
|
|
|
905b4d |
+ kerr = do_keytab_copy(kctx, keytab, tmp_mem_keytab);
|
|
|
905b4d |
if (kerr != 0) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "krb5_kt_end_seq_get failed.\n");
|
|
|
905b4d |
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy keytab [%s] into [%s].\n",
|
|
|
905b4d |
+ keytab_file, tmp_mem_name);
|
|
|
905b4d |
goto done;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
- /* check if we got any errors from krb5_kt_next_entry */
|
|
|
905b4d |
- if (kt_err != 0 && kt_err != KRB5_KT_END) {
|
|
|
905b4d |
- DEBUG(SSSDBG_CRIT_FAILURE, "error reading keytab [%s].\n", keytab_file);
|
|
|
905b4d |
- kerr = KRB5KRB_ERR_GENERIC;
|
|
|
905b4d |
+ /* krb5_kt_add_entry() adds new entries into MEMORY keytabs at the
|
|
|
905b4d |
+ * beginning and not at the end as for FILE keytabs. Since we want to keep
|
|
|
905b4d |
+ * the processing order we have to copy the MEMORY keytab again to retain
|
|
|
905b4d |
+ * the order from the FILE keytab. */
|
|
|
905b4d |
+
|
|
|
905b4d |
+ kerr = do_keytab_copy(kctx, tmp_mem_keytab, mem_keytab);
|
|
|
905b4d |
+ if (kerr != 0) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy keytab [%s] into [%s].\n",
|
|
|
905b4d |
+ tmp_mem_name, mem_name);
|
|
|
905b4d |
goto done;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
@@ -153,12 +209,18 @@ krb5_error_code copy_keytab_into_memory(TALLOC_CTX *mem_ctx, krb5_context kctx,
|
|
|
905b4d |
kerr = 0;
|
|
|
905b4d |
done:
|
|
|
905b4d |
|
|
|
905b4d |
+ talloc_free(tmp_mem_name);
|
|
|
905b4d |
+
|
|
|
905b4d |
if (kerr != 0) {
|
|
|
905b4d |
talloc_free(mem_name);
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
+ if (tmp_mem_keytab != NULL && krb5_kt_close(kctx, tmp_mem_keytab) != 0) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_MINOR_FAILURE, "krb5_kt_close failed.\n");
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
if (keytab != NULL && krb5_kt_close(kctx, keytab) != 0) {
|
|
|
905b4d |
- DEBUG(SSSDBG_MINOR_FAILURE, "krb5_kt_close failed");
|
|
|
905b4d |
+ DEBUG(SSSDBG_MINOR_FAILURE, "krb5_kt_close failed.\n");
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
return kerr;
|
|
|
905b4d |
--
|
|
|
905b4d |
2.1.0
|
|
|
905b4d |
|