From 65dcd0a7dabea704973d7f67c1733d2a47559f1b Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sat, 6 Mar 2010 17:32:57 -0500 Subject: [PATCH] afsadminutil: translate krb5 error messages on Windows util_AdminErrorCodeTranslate() is used to translate error code messages within the libadmin library set and is used by translate_et. This has in the past not translated krb5 error codes. This patchset conditionally adds support for using krb5_get_error_message() or error_message() on the Windows platform if KFW is installed. This is accomplished by adding new functions to afsutil.lib: initialize_krb5() fetch_krb5_error_message() which are used within util_AdminErrorCodeTranslate() only if AFS_KRB5_ERROR_ENV is defined. Support for Unix is not provided at the present time because doing this "right" will lead to a dependence on kerberos libraries from this library, which we might want to avoid. Change-Id: I7caf7b8e41cfd806f4defc175aa45afb165ec244 Reviewed-on: http://gerrit.openafs.org/1531 Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- src/config/param.amd64_w2k.h | 1 + src/config/param.i386_nt40.h | 1 + src/config/param.i386_w2k.h | 1 + src/libadmin/adminutil/NTMakefile | 17 +++++- src/libadmin/adminutil/afs_utilAdmin.c | 12 +++- src/util/NTMakefile | 4 ++ src/util/krb5_nt.c | 80 ++++++++++++++++++++++++++ src/util/krb5_nt.h | 35 +++++++++++ 8 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 src/util/krb5_nt.c create mode 100644 src/util/krb5_nt.h diff --git a/src/config/param.amd64_w2k.h b/src/config/param.amd64_w2k.h index 3b7eb7684..242bfda47 100644 --- a/src/config/param.amd64_w2k.h +++ b/src/config/param.amd64_w2k.h @@ -19,6 +19,7 @@ #define AFS_64BIT_IOPS_ENV 1 #define AFS_NAMEI_ENV 1 /* User space interface to file system */ #define AFS_HAVE_STATVFS 0 /* System doesn't support statvfs */ +#define AFS_KRB5_ERROR_ENV 1 /* fetch_krb5_error_message() available in afsutil.lib */ #include #define SYS_NAME_ID SYS_NAME_ID_amd64_w2k diff --git a/src/config/param.i386_nt40.h b/src/config/param.i386_nt40.h index 5d93ddbd3..e2df99012 100644 --- a/src/config/param.i386_nt40.h +++ b/src/config/param.i386_nt40.h @@ -19,6 +19,7 @@ #define AFS_64BIT_IOPS_ENV 1 #define AFS_NAMEI_ENV 1 /* User space interface to file system */ #define AFS_HAVE_STATVFS 0 /* System doesn't support statvfs */ +#define AFS_KRB5_ERROR_ENV 1 /* fetch_krb5_error_message() available in afsutil.lib */ #include #define SYS_NAME_ID SYS_NAME_ID_i386_nt35 diff --git a/src/config/param.i386_w2k.h b/src/config/param.i386_w2k.h index b0d60792c..309c0aca8 100644 --- a/src/config/param.i386_w2k.h +++ b/src/config/param.i386_w2k.h @@ -19,6 +19,7 @@ #define AFS_64BIT_IOPS_ENV 1 #define AFS_NAMEI_ENV 1 /* User space interface to file system */ #define AFS_HAVE_STATVFS 0 /* System doesn't support statvfs */ +#define AFS_KRB5_ERROR_ENV 1 /* fetch_krb5_error_message() available in afsutil.lib */ #include #define SYS_NAME_ID SYS_NAME_ID_i386_w2k diff --git a/src/libadmin/adminutil/NTMakefile b/src/libadmin/adminutil/NTMakefile index a55bf3ffe..64d35430e 100644 --- a/src/libadmin/adminutil/NTMakefile +++ b/src/libadmin/adminutil/NTMakefile @@ -142,8 +142,23 @@ DLLLIBS =\ $(DESTDIR)\lib\afsauthent.lib \ $(DESTDIR)\lib\afs\afsreg.lib +!IF "$(CPU)" == "IA64" || "$(CPU)" == "AMD64" || "$(CPU)" == "ALPHA64" +KFWLIBS = \ + $(AFSROOT)\src\WINNT\kfw\lib\$(CPU)\krb5_64.lib \ + $(AFSROOT)\src\WINNT\kfw\lib\$(CPU)\comerr64.lib \ + dnsapi.lib mpr.lib delayimp.lib shell32.lib +LINKOPTS = /DELAYLOAD:krb5_64.dll /DELAYLOAD:comerr64.dll +!else +KFWLIBS = \ + $(AFSROOT)\src\WINNT\kfw\lib\$(CPU)\krb5_32.lib \ + $(AFSROOT)\src\WINNT\kfw\lib\$(CPU)\comerr32.lib \ + dnsapi.lib mpr.lib delayimp.lib shell32.lib +LINKOPTS = /DELAYLOAD:krb5_32.dll /DELAYLOAD:comerr32.dll +!endif +afscflags = -I$(AFSROOT)\src\WINNT\kfw\inc\krb5 $(afscflags) + $(DLLFILE): $(DLLOBJS) $(DLLLIBS) - $(DLLCONLINK) /DEF:afsadminutil.def shell32.lib + $(DLLCONLINK) /DEF:afsadminutil.def $(KFWLIBS) $(_VC_MANIFEST_EMBED_DLL) $(DLLPREP) $(CODESIGN_USERLAND) diff --git a/src/libadmin/adminutil/afs_utilAdmin.c b/src/libadmin/adminutil/afs_utilAdmin.c index f13294e00..643ebba88 100644 --- a/src/libadmin/adminutil/afs_utilAdmin.c +++ b/src/libadmin/adminutil/afs_utilAdmin.c @@ -31,7 +31,8 @@ #include #include #ifdef AFS_NT40_ENV -#include +# include +# include #else #include #include @@ -79,6 +80,9 @@ 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; } @@ -103,6 +107,12 @@ util_AdminErrorCodeTranslate(afs_status_t errorCode, int langId, pthread_once(&error_init_once, init_once); code = (afs_int32) errorCode; *errorTextP = afs_error_message(code); +#ifdef AFS_KRB5_ERROR_ENV + if (strncmp(*errorTextP, "unknown", strlen("unknown")) == 0) { + const char *msg = fetch_krb5_error_message(NULL, code); + *errorTextP = msg ? msg : error_message(code); + } +#endif rc = 1; fail_util_AdminErrorCodeTranslate: diff --git a/src/util/NTMakefile b/src/util/NTMakefile index 6cd906366..9e705bc17 100644 --- a/src/util/NTMakefile +++ b/src/util/NTMakefile @@ -7,6 +7,7 @@ # General AFS utilities. +AFSDEV_AUXCDEFINES = $(AFSDEV_AUXCDEFINES) -I..\WINNT\kfw\inc\krb5 RELDIR=util !INCLUDE ..\config\NTMakefile.$(SYS_NAME) @@ -24,6 +25,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 \ @@ -47,6 +49,7 @@ LIBOBJS = \ $(OUT)\get_krbrlm.obj \ $(OUT)\hostparse.obj \ $(OUT)\isathing.obj \ + $(OUT)\krb5_nt.obj \ $(OUT)\kreltime.obj \ $(OUT)\ktime.obj \ $(OUT)\netutils.obj \ @@ -72,6 +75,7 @@ MT_LIBOBJS = \ $(OUT)\get_krbrlm.obj \ $(OUT)\hostparse.obj \ $(OUT)\isathing.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 new file mode 100644 index 000000000..61d6b39be --- /dev/null +++ b/src/util/krb5_nt.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2010 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Neither the name of Your File System, Inc. nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission from Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + #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 + + +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. + * + * On Unix, the MIT krb5 error table will be initialized + * by the library on first use. + * + * 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"); + } +} + +const char * +fetch_krb5_error_message(krb5_context context, krb5_error_code code) +{ + static char errorText[1024]; + + if (pkrb5_get_error_message) { + char *msg = pkrb5_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; + } + } + return NULL; +} diff --git a/src/util/krb5_nt.h b/src/util/krb5_nt.h new file mode 100644 index 000000000..f1e68c3a5 --- /dev/null +++ b/src/util/krb5_nt.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Neither the name of Your File System, Inc. nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission from Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef AFS_NT40_ENV + +# include +# include + +extern void initialize_krb5(void); +extern const char * fetch_krb5_error_message(krb5_context, krb5_error_code); + +#endif /* AFS_NT40_ENV */ \ No newline at end of file -- 2.39.5