352 lines
9.9 KiB
Diff
352 lines
9.9 KiB
Diff
Adds an "ANY" keytab type which is a list of other keytab locations to search
|
|
when searching for a specific entry. When iterated through, it only presents
|
|
the contents of the first keytab.
|
|
|
|
diff -up /dev/null krb5-1.7/src/lib/krb5/keytab/kt_any.c
|
|
--- /dev/null 2009-06-04 10:34:55.169007373 -0400
|
|
+++ krb5-1.7/src/lib/krb5/keytab/kt_any.c 2009-06-04 13:54:36.000000000 -0400
|
|
@@ -0,0 +1,292 @@
|
|
+/*
|
|
+ * lib/krb5/keytab/kt_any.c
|
|
+ *
|
|
+ * Copyright 1998, 1999 by the Massachusetts Institute of Technology.
|
|
+ * All Rights Reserved.
|
|
+ *
|
|
+ * Export of this software from the United States of America may
|
|
+ * require a specific license from the United States Government.
|
|
+ * It is the responsibility of any person or organization contemplating
|
|
+ * export to obtain such a license before exporting.
|
|
+ *
|
|
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
|
|
+ * distribute this software and its documentation for any purpose and
|
|
+ * without fee is hereby granted, provided that the above copyright
|
|
+ * notice appear in all copies and that both that copyright notice and
|
|
+ * this permission notice appear in supporting documentation, and that
|
|
+ * the name of M.I.T. not be used in advertising or publicity pertaining
|
|
+ * to distribution of the software without specific, written prior
|
|
+ * permission. M.I.T. makes no representations about the suitability of
|
|
+ * this software for any purpose. It is provided "as is" without express
|
|
+ * or implied warranty.
|
|
+ *
|
|
+ *
|
|
+ * krb5_kta_ops
|
|
+ */
|
|
+
|
|
+#include "k5-int.h"
|
|
+
|
|
+typedef struct _krb5_ktany_data {
|
|
+ char *name;
|
|
+ krb5_keytab *choices;
|
|
+ int nchoices;
|
|
+} krb5_ktany_data;
|
|
+
|
|
+typedef struct _krb5_ktany_cursor_data {
|
|
+ int which;
|
|
+ krb5_kt_cursor cursor;
|
|
+} krb5_ktany_cursor_data;
|
|
+
|
|
+static krb5_error_code krb5_ktany_resolve
|
|
+ (krb5_context,
|
|
+ const char *,
|
|
+ krb5_keytab *);
|
|
+static krb5_error_code krb5_ktany_get_name
|
|
+ (krb5_context context,
|
|
+ krb5_keytab id,
|
|
+ char *name,
|
|
+ unsigned int len);
|
|
+static krb5_error_code krb5_ktany_close
|
|
+ (krb5_context context,
|
|
+ krb5_keytab id);
|
|
+static krb5_error_code krb5_ktany_get_entry
|
|
+ (krb5_context context,
|
|
+ krb5_keytab id,
|
|
+ krb5_const_principal principal,
|
|
+ krb5_kvno kvno,
|
|
+ krb5_enctype enctype,
|
|
+ krb5_keytab_entry *entry);
|
|
+static krb5_error_code krb5_ktany_start_seq_get
|
|
+ (krb5_context context,
|
|
+ krb5_keytab id,
|
|
+ krb5_kt_cursor *cursorp);
|
|
+static krb5_error_code krb5_ktany_next_entry
|
|
+ (krb5_context context,
|
|
+ krb5_keytab id,
|
|
+ krb5_keytab_entry *entry,
|
|
+ krb5_kt_cursor *cursor);
|
|
+static krb5_error_code krb5_ktany_end_seq_get
|
|
+ (krb5_context context,
|
|
+ krb5_keytab id,
|
|
+ krb5_kt_cursor *cursor);
|
|
+static void cleanup
|
|
+ (krb5_context context,
|
|
+ krb5_ktany_data *data,
|
|
+ int nchoices);
|
|
+
|
|
+struct _krb5_kt_ops krb5_kta_ops = {
|
|
+ 0,
|
|
+ "ANY", /* Prefix -- this string should not appear anywhere else! */
|
|
+ krb5_ktany_resolve,
|
|
+ krb5_ktany_get_name,
|
|
+ krb5_ktany_close,
|
|
+ krb5_ktany_get_entry,
|
|
+ krb5_ktany_start_seq_get,
|
|
+ krb5_ktany_next_entry,
|
|
+ krb5_ktany_end_seq_get,
|
|
+ NULL,
|
|
+ NULL,
|
|
+ NULL,
|
|
+};
|
|
+
|
|
+static krb5_error_code
|
|
+krb5_ktany_resolve(context, name, id)
|
|
+ krb5_context context;
|
|
+ const char *name;
|
|
+ krb5_keytab *id;
|
|
+{
|
|
+ const char *p, *q;
|
|
+ char *copy;
|
|
+ krb5_error_code kerror;
|
|
+ krb5_ktany_data *data;
|
|
+ int i;
|
|
+
|
|
+ /* Allocate space for our data and remember a copy of the name. */
|
|
+ if ((data = (krb5_ktany_data *)malloc(sizeof(krb5_ktany_data))) == NULL)
|
|
+ return(ENOMEM);
|
|
+ if ((data->name = (char *)malloc(strlen(name) + 1)) == NULL) {
|
|
+ free(data);
|
|
+ return(ENOMEM);
|
|
+ }
|
|
+ strcpy(data->name, name);
|
|
+
|
|
+ /* Count the number of choices and allocate memory for them. */
|
|
+ data->nchoices = 1;
|
|
+ for (p = name; (q = strchr(p, ',')) != NULL; p = q + 1)
|
|
+ data->nchoices++;
|
|
+ if ((data->choices = (krb5_keytab *)
|
|
+ malloc(data->nchoices * sizeof(krb5_keytab))) == NULL) {
|
|
+ free(data->name);
|
|
+ free(data);
|
|
+ return(ENOMEM);
|
|
+ }
|
|
+
|
|
+ /* Resolve each of the choices. */
|
|
+ i = 0;
|
|
+ for (p = name; (q = strchr(p, ',')) != NULL; p = q + 1) {
|
|
+ /* Make a copy of the choice name so we can terminate it. */
|
|
+ if ((copy = (char *)malloc(q - p + 1)) == NULL) {
|
|
+ cleanup(context, data, i);
|
|
+ return(ENOMEM);
|
|
+ }
|
|
+ memcpy(copy, p, q - p);
|
|
+ copy[q - p] = 0;
|
|
+
|
|
+ /* Try resolving the choice name. */
|
|
+ kerror = krb5_kt_resolve(context, copy, &data->choices[i]);
|
|
+ free(copy);
|
|
+ if (kerror) {
|
|
+ cleanup(context, data, i);
|
|
+ return(kerror);
|
|
+ }
|
|
+ i++;
|
|
+ }
|
|
+ if ((kerror = krb5_kt_resolve(context, p, &data->choices[i]))) {
|
|
+ cleanup(context, data, i);
|
|
+ return(kerror);
|
|
+ }
|
|
+
|
|
+ /* Allocate and fill in an ID for the caller. */
|
|
+ if ((*id = (krb5_keytab)malloc(sizeof(**id))) == NULL) {
|
|
+ cleanup(context, data, i);
|
|
+ return(ENOMEM);
|
|
+ }
|
|
+ (*id)->ops = &krb5_kta_ops;
|
|
+ (*id)->data = (krb5_pointer)data;
|
|
+ (*id)->magic = KV5M_KEYTAB;
|
|
+
|
|
+ return(0);
|
|
+}
|
|
+
|
|
+static krb5_error_code
|
|
+krb5_ktany_get_name(context, id, name, len)
|
|
+ krb5_context context;
|
|
+ krb5_keytab id;
|
|
+ char *name;
|
|
+ unsigned int len;
|
|
+{
|
|
+ krb5_ktany_data *data = (krb5_ktany_data *)id->data;
|
|
+
|
|
+ if (len < strlen(data->name) + 1)
|
|
+ return(KRB5_KT_NAME_TOOLONG);
|
|
+ strcpy(name, data->name);
|
|
+ return(0);
|
|
+}
|
|
+
|
|
+static krb5_error_code
|
|
+krb5_ktany_close(context, id)
|
|
+ krb5_context context;
|
|
+ krb5_keytab id;
|
|
+{
|
|
+ krb5_ktany_data *data = (krb5_ktany_data *)id->data;
|
|
+
|
|
+ cleanup(context, data, data->nchoices);
|
|
+ id->ops = 0;
|
|
+ free(id);
|
|
+ return(0);
|
|
+}
|
|
+
|
|
+static krb5_error_code
|
|
+krb5_ktany_get_entry(context, id, principal, kvno, enctype, entry)
|
|
+ krb5_context context;
|
|
+ krb5_keytab id;
|
|
+ krb5_const_principal principal;
|
|
+ krb5_kvno kvno;
|
|
+ krb5_enctype enctype;
|
|
+ krb5_keytab_entry *entry;
|
|
+{
|
|
+ krb5_ktany_data *data = (krb5_ktany_data *)id->data;
|
|
+ krb5_error_code kerror = KRB5_KT_NOTFOUND;
|
|
+ int i;
|
|
+
|
|
+ for (i = 0; i < data->nchoices; i++) {
|
|
+ if ((kerror = krb5_kt_get_entry(context, data->choices[i], principal,
|
|
+ kvno, enctype, entry)) != ENOENT)
|
|
+ return kerror;
|
|
+ }
|
|
+ return kerror;
|
|
+}
|
|
+
|
|
+static krb5_error_code
|
|
+krb5_ktany_start_seq_get(context, id, cursorp)
|
|
+ krb5_context context;
|
|
+ krb5_keytab id;
|
|
+ krb5_kt_cursor *cursorp;
|
|
+{
|
|
+ krb5_ktany_data *data = (krb5_ktany_data *)id->data;
|
|
+ krb5_ktany_cursor_data *cdata;
|
|
+ krb5_error_code kerror = ENOENT;
|
|
+ int i;
|
|
+
|
|
+ if ((cdata = (krb5_ktany_cursor_data *)
|
|
+ malloc(sizeof(krb5_ktany_cursor_data))) == NULL)
|
|
+ return(ENOMEM);
|
|
+
|
|
+ /* Find a choice which can handle the serialization request. */
|
|
+ for (i = 0; i < data->nchoices; i++) {
|
|
+ if ((kerror = krb5_kt_start_seq_get(context, data->choices[i],
|
|
+ &cdata->cursor)) == 0)
|
|
+ break;
|
|
+ else if (kerror != ENOENT) {
|
|
+ free(cdata);
|
|
+ return(kerror);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (i == data->nchoices) {
|
|
+ /* Everyone returned ENOENT, so no go. */
|
|
+ free(cdata);
|
|
+ return(kerror);
|
|
+ }
|
|
+
|
|
+ cdata->which = i;
|
|
+ *cursorp = (krb5_kt_cursor)cdata;
|
|
+ return(0);
|
|
+}
|
|
+
|
|
+static krb5_error_code
|
|
+krb5_ktany_next_entry(context, id, entry, cursor)
|
|
+ krb5_context context;
|
|
+ krb5_keytab id;
|
|
+ krb5_keytab_entry *entry;
|
|
+ krb5_kt_cursor *cursor;
|
|
+{
|
|
+ krb5_ktany_data *data = (krb5_ktany_data *)id->data;
|
|
+ krb5_ktany_cursor_data *cdata = (krb5_ktany_cursor_data *)*cursor;
|
|
+ krb5_keytab choice_id;
|
|
+
|
|
+ choice_id = data->choices[cdata->which];
|
|
+ return(krb5_kt_next_entry(context, choice_id, entry, &cdata->cursor));
|
|
+}
|
|
+
|
|
+static krb5_error_code
|
|
+krb5_ktany_end_seq_get(context, id, cursor)
|
|
+ krb5_context context;
|
|
+ krb5_keytab id;
|
|
+ krb5_kt_cursor *cursor;
|
|
+{
|
|
+ krb5_ktany_data *data = (krb5_ktany_data *)id->data;
|
|
+ krb5_ktany_cursor_data *cdata = (krb5_ktany_cursor_data *)*cursor;
|
|
+ krb5_keytab choice_id;
|
|
+ krb5_error_code kerror;
|
|
+
|
|
+ choice_id = data->choices[cdata->which];
|
|
+ kerror = krb5_kt_end_seq_get(context, choice_id, &cdata->cursor);
|
|
+ free(cdata);
|
|
+ return(kerror);
|
|
+}
|
|
+
|
|
+static void
|
|
+cleanup(context, data, nchoices)
|
|
+ krb5_context context;
|
|
+ krb5_ktany_data *data;
|
|
+ int nchoices;
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ free(data->name);
|
|
+ for (i = 0; i < nchoices; i++)
|
|
+ krb5_kt_close(context, data->choices[i]);
|
|
+ free(data->choices);
|
|
+ free(data);
|
|
+}
|
|
diff -up krb5-1.7/src/lib/krb5/keytab/ktbase.c krb5-1.7/src/lib/krb5/keytab/ktbase.c
|
|
--- krb5-1.7/src/lib/krb5/keytab/ktbase.c 2009-02-18 13:18:56.000000000 -0500
|
|
+++ krb5-1.7/src/lib/krb5/keytab/ktbase.c 2009-06-04 13:54:36.000000000 -0400
|
|
@@ -59,14 +59,19 @@ extern const krb5_kt_ops krb5_ktf_ops;
|
|
extern const krb5_kt_ops krb5_ktf_writable_ops;
|
|
extern const krb5_kt_ops krb5_kts_ops;
|
|
extern const krb5_kt_ops krb5_mkt_ops;
|
|
+extern const krb5_kt_ops krb5_kta_ops;
|
|
|
|
struct krb5_kt_typelist {
|
|
const krb5_kt_ops *ops;
|
|
const struct krb5_kt_typelist *next;
|
|
};
|
|
+static struct krb5_kt_typelist krb5_kt_typelist_any = {
|
|
+ &krb5_kta_ops,
|
|
+ NULL
|
|
+};
|
|
const static struct krb5_kt_typelist krb5_kt_typelist_srvtab = {
|
|
&krb5_kts_ops,
|
|
- NULL
|
|
+ &krb5_kt_typelist_any
|
|
};
|
|
const static struct krb5_kt_typelist krb5_kt_typelist_memory = {
|
|
&krb5_mkt_ops,
|
|
diff -up krb5-1.7/src/lib/krb5/keytab/Makefile.in krb5-1.7/src/lib/krb5/keytab/Makefile.in
|
|
--- krb5-1.7/src/lib/krb5/keytab/Makefile.in 2009-01-05 15:27:53.000000000 -0500
|
|
+++ krb5-1.7/src/lib/krb5/keytab/Makefile.in 2009-06-04 13:54:36.000000000 -0400
|
|
@@ -19,6 +19,7 @@ STLIBOBJS= \
|
|
ktfr_entry.o \
|
|
ktremove.o \
|
|
ktfns.o \
|
|
+ kt_any.o \
|
|
kt_file.o \
|
|
kt_memory.o \
|
|
kt_srvtab.o \
|
|
@@ -31,6 +32,7 @@ OBJS= \
|
|
$(OUTPRE)ktfr_entry.$(OBJEXT) \
|
|
$(OUTPRE)ktremove.$(OBJEXT) \
|
|
$(OUTPRE)ktfns.$(OBJEXT) \
|
|
+ $(OUTPRE)kt_any.$(OBJEXT) \
|
|
$(OUTPRE)kt_file.$(OBJEXT) \
|
|
$(OUTPRE)kt_memory.$(OBJEXT) \
|
|
$(OUTPRE)kt_srvtab.$(OBJEXT) \
|
|
@@ -43,6 +45,7 @@ SRCS= \
|
|
$(srcdir)/ktfr_entry.c \
|
|
$(srcdir)/ktremove.c \
|
|
$(srcdir)/ktfns.c \
|
|
+ $(srcdir)/kt_any.c \
|
|
$(srcdir)/kt_file.c \
|
|
$(srcdir)/kt_memory.c \
|
|
$(srcdir)/kt_srvtab.c \
|