summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2014-10-11 20:11:04 +0200
committerJakub Hrozek <jhrozek@redhat.com>2014-10-29 10:55:11 +0100
commit05176a0efd8ed7089432a92a9d310dfc019d1b88 (patch)
tree8d6676a94d1470be704610a02d2fca5630b64301
parentc4e278c2637547640d28bda007c9c38a17956fcc (diff)
downloadsssd-05176a0efd8ed7089432a92a9d310dfc019d1b88.tar.gz
sssd-05176a0efd8ed7089432a92a9d310dfc019d1b88.tar.xz
sssd-05176a0efd8ed7089432a92a9d310dfc019d1b88.zip
KRB5: Add utility function to get a list of principals from keytab
-rw-r--r--src/util/sss_krb5.c116
1 files changed, 115 insertions, 1 deletions
diff --git a/src/util/sss_krb5.c b/src/util/sss_krb5.c
index b4012593d..d9b076ebe 100644
--- a/src/util/sss_krb5.c
+++ b/src/util/sss_krb5.c
@@ -97,7 +97,9 @@ errno_t select_principal_from_keytab(TALLOC_CTX *mem_ctx,
NULL, NULL};
DEBUG(SSSDBG_FUNC_DATA,
- "trying to select the most appropriate principal from keytab\n");
+ "trying to select the most appropriate principal from "
+ "list of principals\n");
+
tmp_ctx = talloc_new(NULL);
if (!tmp_ctx) {
DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed\n");
@@ -404,6 +406,118 @@ done:
return ret;
}
+errno_t sss_read_keytab(TALLOC_CTX *mem_ctx,
+ const char *keytab_name,
+ char **_list_princs)
+{
+ krb5_context ctx = NULL;
+ krb5_keytab keytab = NULL;
+ TALLOC_CTX *tmp_ctx = NULL;
+ krb5_kt_cursor cursor;
+ krb5_error_code kerr;
+ krb5_keytab_entry entry;
+ errno_t ret;
+ char *str_princ;
+ size_t num_princs;
+ size_t pindex;
+ char **list_princs;
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed\n");
+ return ENOMEM;
+ }
+
+ kerr = krb5_init_context(&ctx);
+ if (kerr) {
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to init kerberos context\n");
+ ret = EFAULT;
+ goto done;
+ }
+
+ if (keytab_name != NULL) {
+ kerr = krb5_kt_resolve(ctx, keytab_name, &keytab);
+ } else {
+ kerr = krb5_kt_default(ctx, &keytab);
+ }
+ if (kerr) {
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ "Failed to read keytab [%s]: %s\n",
+ KEYTAB_CLEAN_NAME,
+ sss_krb5_get_error_message(ctx, kerr));
+ ret = EFAULT;
+ goto done;
+ }
+
+ memset(&cursor, 0, sizeof(cursor));
+ kerr = krb5_kt_start_seq_get(ctx, keytab, &cursor);
+ if (kerr != 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "krb5_kt_start_seq_get failed.\n");
+ ret = EFAULT;
+ goto done;
+ }
+
+ /* Get the number of entries first */
+ num_princs = 0;
+ while ((kerr = krb5_kt_next_entry(ctx, keytab, &entry, &cursor)) == 0) {
+ num_princs++;
+ }
+ memset(&entry, 0, sizeof(entry));
+
+ kerr = krb5_kt_end_seq_get(ctx, keytab, &cursor);
+ if (kerr != 0) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "krb5_kt_end_seq_get failed.\n");
+ /* Non-critical, just a memleak */
+ }
+
+ list_princs = talloc_zero_array(tmp_ctx, char *, num_princs + 1);
+ if (list_princs == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ /* Got the number of entries, let's read them */
+ memset(&cursor, 0, sizeof(cursor));
+ kerr = krb5_kt_start_seq_get(ctx, keytab, &cursor);
+ if (kerr != 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "krb5_kt_start_seq_get failed.\n");
+ ret = EFAULT;
+ goto done;
+ }
+
+ pindex = 0;
+ memset(&entry, 0, sizeof(entry));
+ while ((kerr = krb5_kt_next_entry(ctx, keytab, &entry, &cursor)) == 0) {
+ sss_krb5_unparse_name_flags(ctx, entry.principal, 0, &str_princ);
+ kerr = sss_krb5_free_keytab_entry_contents(ctx, &entry);
+ if (kerr != 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to free keytab entry.\n");
+ }
+ memset(&entry, 0, sizeof(entry));
+
+ list_princs[pindex] = talloc_strdup(list_princs, str_princ);
+ krb5_free_unparsed_name(ctx, str_princ);
+ if (list_princs[pindex] == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+ pindex++;
+ }
+
+ kerr = krb5_kt_end_seq_get(ctx, keytab, &cursor);
+ if (kerr != 0) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "krb5_kt_end_seq_get failed.\n");
+ /* Non-critical, just a memleak */
+ }
+
+ ret = 0;
+done:
+ if (keytab) krb5_kt_close(ctx, keytab);
+ if (ctx) krb5_free_context(ctx);
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
krb5_error_code find_principal_in_keytab(krb5_context ctx,
krb5_keytab keytab,
const char *pattern_primary,