From 9ec76c542775ae58ff03f42ebfa1acc1a63a1bb1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?G=C3=BCnther=20Deschner?= Date: Mon, 23 Apr 2007 08:40:54 +0000 Subject: [PATCH] r22479: Add "net ads keytab list". Guenther --- source/configure.in | 46 +++++++++++++ source/include/includes.h | 4 ++ source/libads/kerberos_keytab.c | 112 ++++++++++++++++++++++++++++++++ source/libsmb/clikrb5.c | 47 ++++++++++++-- source/utils/net_ads.c | 10 ++- 5 files changed, 212 insertions(+), 7 deletions(-) diff --git a/source/configure.in b/source/configure.in index 2a60e4360..f9a5c1802 100644 --- a/source/configure.in +++ b/source/configure.in @@ -3640,6 +3640,7 @@ if test x"$with_ads_support" != x"no"; then AC_CHECK_FUNC_EXT(initialize_krb5_error_table, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_get_init_creds_opt_alloc, $KRB5_LIBS) AC_CHECK_FUNC_EXT(krb5_get_init_creds_opt_free, $KRB5_LIBS) + AC_CHECK_FUNC_EXT(krb5_enctype_to_string, $KRB5_LIBS) LIBS="$KRB5_LIBS $LIBS" @@ -4016,6 +4017,43 @@ if test x"$with_ads_support" != x"no"; then [whether krb5_mk_error takes 3 arguments MIT or 9 Heimdal]) fi + if test x"$ac_cv_func_ext_krb5_enctype_to_string" = x"yes"; then + AC_CACHE_CHECK([for krb5_error_code krb5_enctype_to_string(krb5_context context, krb5_enctype enctype, char **str)], + smb_krb5_enctype_to_string_takes_krb5_context_arg,[ + AC_TRY_RUN_STRICT([ + #include + int main(void) { + krb5_context context; + char *str = NULL; + krb5_enctype_to_string(context, 1, &str); + if (str) free (str); + } + ],[$Werror_FLAGS],[$CPPFLAGS],[$LDFLAGS], + smb_krb5_enctype_to_string_takes_krb5_context_arg=yes, + smb_krb5_enctype_to_string_takes_krb5_context_arg=no)]) + + if test x"$smb_krb5_enctype_to_string_takes_krb5_context_arg" = x"yes"; then + AC_DEFINE(HAVE_KRB5_ENCTYPE_TO_STRING_WITH_KRB5_CONTEXT_ARG,1, + [whether krb5_enctype_to_string takes krb5_context argument]) + fi + + AC_CACHE_CHECK([for krb5_error_code krb5_enctype_to_string(krb5_enctype enctype, char *str, size_t len)], + smb_krb5_enctype_to_string_takes_size_t_arg,[ + AC_TRY_RUN_STRICT([ + #include + int main(void) { + char buf[256]; + krb5_enctype_to_string(1, buf, 256); + } + ],[$Werror_FLAGS],[$CPPFLAGS],[$LDFLAGS], + smb_krb5_enctype_to_string_takes_size_t_arg=yes, + smb_krb5_enctype_to_string_takes_size_t_arg=no)]) + + if test x"$smb_krb5_enctype_to_string_takes_size_t_arg" = x"yes"; then + AC_DEFINE(HAVE_KRB5_ENCTYPE_TO_STRING_WITH_SIZE_T_ARG,1, + [whether krb5_enctype_to_string takes size_t argument]) + fi + fi # # @@ -5954,6 +5992,14 @@ if test x"$samba_cv_HAVE_PEERCRED" = x"yes"; then AC_DEFINE(HAVE_PEERCRED,1,[Whether we can use SO_PEERCRED to get socket credentials]) fi +AC_CHECK_FUNCS(getpeereid sendmsg) +AC_CHECK_HEADERS(sys/ucred.h) + +AC_CHECK_MEMBERS([struct msghdr.msg_accrightslen],,, + [#include ]) +AC_CHECK_MEMBERS([struct msghdr.msg_control],,, + [#include ]) + ################################################# # Check to see if we should use the included popt diff --git a/source/include/includes.h b/source/include/includes.h index b6b0d470d..9a368f808 100644 --- a/source/include/includes.h +++ b/source/include/includes.h @@ -1194,6 +1194,10 @@ krb5_error_code smb_krb5_mk_error(krb5_context context, krb5_error_code error_code, const krb5_principal server, krb5_data *reply); +krb5_enctype smb_get_enctype_from_kt_entry(const krb5_keytab_entry *kt_entry); +krb5_error_code smb_krb5_enctype_to_string(krb5_context context, + krb5_enctype enctype, + char **etype_s); #endif /* HAVE_KRB5 */ diff --git a/source/libads/kerberos_keytab.c b/source/libads/kerberos_keytab.c index 0ad225fbe..d99e322b9 100644 --- a/source/libads/kerberos_keytab.c +++ b/source/libads/kerberos_keytab.c @@ -691,4 +691,116 @@ done: } return ret; } + +/********************************************************************** + List system keytab. +***********************************************************************/ + +int ads_keytab_list(void) +{ + krb5_error_code ret = 0; + krb5_context context = NULL; + krb5_keytab keytab = NULL; + krb5_kt_cursor cursor; + krb5_keytab_entry kt_entry; + char keytab_name[MAX_KEYTAB_NAME_LEN]; + + ZERO_STRUCT(kt_entry); + ZERO_STRUCT(cursor); + + initialize_krb5_error_table(); + ret = krb5_init_context(&context); + if (ret) { + DEBUG(1,("ads_keytab_list: could not krb5_init_context: %s\n",error_message(ret))); + return ret; + } +#if 0 /* HAVE_WRFILE_KEYTAB */ + keytab_name[0] = 'W'; + keytab_name[1] = 'R'; + ret = krb5_kt_default_name(context, (char *) &keytab_name[2], MAX_KEYTAB_NAME_LEN - 4); +#else + ret = krb5_kt_default_name(context, (char *) &keytab_name[0], MAX_KEYTAB_NAME_LEN - 2); +#endif + if (ret) { + DEBUG(1,("ads_keytab_list: krb5_kt_default failed (%s)\n", error_message(ret))); + goto out; + } + DEBUG(3,("ads_keytab_list: Using default keytab: %s\n", (char *) &keytab_name)); + ret = krb5_kt_resolve(context, (char *) &keytab_name, &keytab); + if (ret) { + DEBUG(1,("ads_keytab_list: krb5_kt_resolve failed (%s)\n", error_message(ret))); + goto out; + } + + ret = krb5_kt_start_seq_get(context, keytab, &cursor); + if (ret) { + goto out; + } + + printf("Vno Type Principal\n"); + + while (krb5_kt_next_entry(context, keytab, &kt_entry, &cursor) == 0) { + + char *princ_s = NULL; + char *etype_s = NULL; + krb5_enctype enctype = 0; + + ret = smb_krb5_unparse_name(context, kt_entry.principal, &princ_s); + if (ret) { + goto out; + } + + enctype = smb_get_enctype_from_kt_entry(&kt_entry); + + ret = smb_krb5_enctype_to_string(context, enctype, &etype_s); + if (ret) { + SAFE_FREE(princ_s); + goto out; + } + + printf("%3d %s\t\t %s\n", kt_entry.vno, etype_s, princ_s); + + SAFE_FREE(princ_s); + SAFE_FREE(etype_s); + + ret = smb_krb5_kt_free_entry(context, &kt_entry); + if (ret) { + goto out; + } + } + + ret = krb5_kt_end_seq_get(context, keytab, &cursor); + if (ret) { + goto out; + } + + /* Ensure we don't double free. */ + ZERO_STRUCT(kt_entry); + ZERO_STRUCT(cursor); +out: + + { + krb5_keytab_entry zero_kt_entry; + ZERO_STRUCT(zero_kt_entry); + if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) { + smb_krb5_kt_free_entry(context, &kt_entry); + } + } + { + krb5_kt_cursor zero_csr; + ZERO_STRUCT(zero_csr); + if ((memcmp(&cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) { + krb5_kt_end_seq_get(context, keytab, &cursor); + } + } + + if (keytab) { + krb5_kt_close(context, keytab); + } + if (context) { + krb5_free_context(context); + } + return ret; +} + #endif /* HAVE_KRB5 */ diff --git a/source/libsmb/clikrb5.c b/source/libsmb/clikrb5.c index 7043a2640..474c6823e 100644 --- a/source/libsmb/clikrb5.c +++ b/source/libsmb/clikrb5.c @@ -28,11 +28,11 @@ #ifdef HAVE_KRB5 -#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE -#define KRB5_KEY_TYPE(k) ((k)->keytype) +#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE /* Heimdal */ +#define KRB5_KEY_TYPE(k) ((k)->keytype) #define KRB5_KEY_LENGTH(k) ((k)->keyvalue.length) #define KRB5_KEY_DATA(k) ((k)->keyvalue.data) -#else +#else /* MIT */ #define KRB5_KEY_TYPE(k) ((k)->enctype) #define KRB5_KEY_LENGTH(k) ((k)->length) #define KRB5_KEY_DATA(k) ((k)->contents) @@ -1216,7 +1216,7 @@ out: krb5_free_creds(context, creds); } #else -#error No suitable krb5 ticket renew function available +#error NO_SUITABKE_KRB5_TICKET_RENEW_FUNCTION_AVAILABLE #endif @@ -1428,18 +1428,53 @@ done: #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_FREE #ifdef KRB5_CREDS_OPT_FREE_REQUIRES_CONTEXT - /* Modern MIT version */ + /* Modern MIT or Heimdal version */ krb5_get_init_creds_opt_free(context, opt); #else /* Heimdal version */ krb5_get_init_creds_opt_free(opt); -#endif +#endif /* KRB5_CREDS_OPT_FREE_REQUIRES_CONTEXT */ #else /* HAVE_KRB5_GET_INIT_CREDS_OPT_FREE */ /* Historical MIT version */ SAFE_FREE(opt); opt = NULL; #endif /* HAVE_KRB5_GET_INIT_CREDS_OPT_FREE */ +} + + krb5_enctype smb_get_enctype_from_kt_entry(const krb5_keytab_entry *kt_entry) +{ +#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEY /* MIT */ + return kt_entry->key.enctype; +#elif defined(HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK) /* Heimdal */ + return kt_entry->keyblock.keytype; +#else +#error UNKNOWN_KRB5_KEYTAB_ENTRY_KEYBLOCK_FORMAT +#endif +} + + +/* caller needs to free etype_s */ + krb5_error_code smb_krb5_enctype_to_string(krb5_context context, + krb5_enctype enctype, + char **etype_s) +{ +#ifdef HAVE_KRB5_ENCTYPE_TO_STRING_WITH_KRB5_CONTEXT_ARG + return krb5_enctype_to_string(context, enctype, etype_s); /* Heimdal */ +#elif defined(HAVE_KRB5_ENCTYPE_TO_STRING_WITH_SIZE_T_ARG) + char buf[256]; + krb5_error_code ret = krb5_enctype_to_string(enctype, buf, 256); /* MIT */ + if (ret) { + return ret; + } + *etype_s = SMB_STRDUP(buf); + if (!*etype_s) { + return ENOMEM; + } + return ret; +#else +#error UNKNOWN_KRB5_ENCTYPE_TO_STRING_FUNCTION +#endif } krb5_error_code smb_krb5_mk_error(krb5_context context, diff --git a/source/utils/net_ads.c b/source/utils/net_ads.c index f5a3c3626..37ede28a9 100644 --- a/source/utils/net_ads.c +++ b/source/utils/net_ads.c @@ -2397,10 +2397,11 @@ static int net_ads_keytab_usage(int argc, const char **argv) d_printf( "net ads keytab \n"\ " can be either:\n"\ -" CREATE Creates a fresh keytab\n"\ " ADD Adds new service principal\n"\ +" CREATE Creates a fresh keytab\n"\ " FLUSH Flushes out all keytab entries\n"\ " HELP Prints this help message\n"\ +" LIST List the keytab\n"\ "The ADD command will take arguments, the other commands\n"\ "will not take any arguments. The arguments given to ADD\n"\ "should be a list of principals to add. For example, \n"\ @@ -2455,6 +2456,12 @@ static int net_ads_keytab_create(int argc, const char **argv) return ret; } +static int net_ads_keytab_list(int argc, const char **argv) +{ + return ads_keytab_list(); +} + + int net_ads_keytab(int argc, const char **argv) { struct functable func[] = { @@ -2462,6 +2469,7 @@ int net_ads_keytab(int argc, const char **argv) {"ADD", net_ads_keytab_add}, {"FLUSH", net_ads_keytab_flush}, {"HELP", net_ads_keytab_usage}, + {"LIST", net_ads_keytab_list}, {NULL, NULL} }; -- 2.34.1