From a453f2152145f242c7412c947aaebdd135cb9022 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sat, 8 Oct 2011 10:01:07 +0200 Subject: [PATCH] Correct Heimdal conversion of libadmin/adminutil Patchset 4251e386aa25bb3fc02fa255e92327fffc8b954d converts to using Heimdal. The conversion undid the introduction of the abstraction function fetch_krb5_error_message() which is implemented in src/util. Restore the use of fetch_krb5_error_message() and modify src/util/krb5_nt.c to use the Kerberos Compat SDK interface. Change-Id: I67fe7a309727f67a1da3705e1e485e64747c325c Reviewed-on: http://gerrit.openafs.org/5571 Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- src/libadmin/adminutil/afs_utilAdmin.c | 31 +++++++++---------- src/util/NTMakefile | 3 ++ src/util/krb5_nt.c | 43 +++++++++++++------------- src/util/krb5_nt.h | 5 +-- 4 files changed, 40 insertions(+), 42 deletions(-) diff --git a/src/libadmin/adminutil/afs_utilAdmin.c b/src/libadmin/adminutil/afs_utilAdmin.c index fd2ecc7876..eab3c8e4d9 100644 --- a/src/libadmin/adminutil/afs_utilAdmin.c +++ b/src/libadmin/adminutil/afs_utilAdmin.c @@ -16,6 +16,11 @@ #include #include +#ifdef AFS_NT40_ENV +# include +# include +#endif + #include #include #include @@ -29,12 +34,6 @@ #include #include -#ifdef AFS_NT40_ENV -# define EncryptionKey Krb5EncryptionKey -# include -# undef EncryptionKey -#endif - #include "afs_AdminInternal.h" #include "afs_utilAdmin.h" @@ -76,9 +75,15 @@ init_once(void) initialize_AU_error_table(); initialize_AV_error_table(); initialize_VOLS_error_table(); +#ifdef AFS_KRB5_ERROR_ENV + initialize_krb5(); +#endif error_init_done = 1; } +/* + * (*errorTextP) will not be freed by the caller. + */ int ADMINAPI util_AdminErrorCodeTranslate(afs_status_t errorCode, int langId, const char **errorTextP, afs_status_p st) @@ -102,17 +107,9 @@ util_AdminErrorCodeTranslate(afs_status_t errorCode, int langId, *errorTextP = afs_error_message(code); #ifdef AFS_KRB5_ERROR_ENV if (strncmp(*errorTextP, "unknown", strlen("unknown")) == 0) { - krb5_context context; - if (!krb5_init_context(&context)) - { - char *msg; - msg = krb5_get_error_message(context, code); - if (msg) { - *errorTextP = strdup(msg); - krb5_free_error_message(context, msg); - } - krb5_free_context(context); - } + const char *msg = fetch_krb5_error_message(code); + if (msg) + *errorTextP = msg; } #endif rc = 1; diff --git a/src/util/NTMakefile b/src/util/NTMakefile index 71a068f3cf..234c37635e 100644 --- a/src/util/NTMakefile +++ b/src/util/NTMakefile @@ -23,6 +23,7 @@ INCFILES =\ $(INCFILEDIR)\pthread_nosigs.h \ $(INCFILEDIR)\errmap_nt.h \ $(INCFILEDIR)\dirpath.h \ + $(INCFILEDIR)\krb5_nt.h \ $(INCFILEDIR)\ktime.h \ $(INCFILEDIR)\fileutil.h \ $(INCFILEDIR)\afsutil_prototypes.h \ @@ -43,6 +44,7 @@ LIBOBJS = \ $(OUT)\base32.obj \ $(OUT)\get_krbrlm.obj \ $(OUT)\hostparse.obj \ + $(OUT)\krb5_nt.obj \ $(OUT)\kreltime.obj \ $(OUT)\ktime.obj \ $(OUT)\netutils.obj \ @@ -61,6 +63,7 @@ MT_LIBOBJS = \ $(OUT)\base32.obj \ $(OUT)\get_krbrlm.obj \ $(OUT)\hostparse.obj \ + $(OUT)\krb5_nt.obj \ $(OUT)\kreltime.obj \ $(OUT)\ktime.obj \ $(OUT)\netutils.obj \ diff --git a/src/util/krb5_nt.c b/src/util/krb5_nt.c index ac215df425..47c3f639af 100644 --- a/src/util/krb5_nt.c +++ b/src/util/krb5_nt.c @@ -26,28 +26,26 @@ #include #include +#include #include #include "krb5_nt.h" -static char * (KRB5_CALLCONV *pkrb5_get_error_message)(krb5_context context, krb5_error_code code) = NULL; -static void (KRB5_CALLCONV *pkrb5_free_error_message)(krb5_context context, char *s) = NULL; - -# ifndef _WIN64 -# define KRB5LIB "krb5_32.dll" -# else -# define KRB5LIB "krb5_64.dll" -# endif +# include +# include +static int krb5_initialized = 0; void initialize_krb5(void) { /* * On Windows, the error table will be initialized when the - * krb5 library is loaded into the process. Since not all - * versions of krb5 contain krb5_{get,free}_error_message() - * we load them conditionally by function pointer. + * krb5 library is loaded into the process for MIT KFW but + * for Heimdal the error table is initialized when the + * krb5_init_context() call is issued. We always build + * against the Kerberos Compat SDK now so we do not have + * load by function pointer. Use DelayLoadHeimd * * On Unix, the MIT krb5 error table will be initialized * by the library on first use. @@ -55,26 +53,29 @@ initialize_krb5(void) * initialize_krb5_error_table is a macro substitution to * nothing. */ - HINSTANCE h = LoadLibrary(KRB5LIB); - if (h) { - (FARPROC)pkrb5_get_error_message = GetProcAddress(h, "krb5_get_error_message"); - (FARPROC)pkrb5_free_error_message = GetProcAddress(h, "krb5_free_error_message"); + if (!DelayLoadHeimdal()) { + fprintf(stderr, "Kerberos for Windows or Heimdal is not available.\n"); + } else { + krb5_initialized = 1; } } const char * -fetch_krb5_error_message(krb5_context context, krb5_error_code code) +fetch_krb5_error_message(afs_uint32 code) { static char errorText[1024]; + char *msg = NULL; + krb5_context context; - if (pkrb5_get_error_message) { - char *msg = pkrb5_get_error_message(context, code); + if (krb5_initialized && krb5_init_context(&context) == 0) { + msg = krb5_get_error_message(context, code); if (msg) { strncpy(errorText, msg, sizeof(errorText)); errorText[sizeof(errorText)-1]='\0'; - pkrb5_free_error_message(context, msg); - return errorText; + krb5_free_error_message(context, msg); + msg = errorText; } + krb5_free_context(context); } - return NULL; + return msg; } diff --git a/src/util/krb5_nt.h b/src/util/krb5_nt.h index f1e68c3a50..6d6888977e 100644 --- a/src/util/krb5_nt.h +++ b/src/util/krb5_nt.h @@ -26,10 +26,7 @@ #ifdef AFS_NT40_ENV -# include -# include - extern void initialize_krb5(void); -extern const char * fetch_krb5_error_message(krb5_context, krb5_error_code); +extern const char * fetch_krb5_error_message(afs_uint32); #endif /* AFS_NT40_ENV */ \ No newline at end of file