Correct Heimdal conversion of libadmin/adminutil

Patchset 4251e386aa 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 <jaltman@openafs.org>
Tested-by: Jeffrey Altman <jaltman@openafs.org>
This commit is contained in:
Jeffrey Altman 2011-10-08 10:01:07 +02:00 committed by Jeffrey Altman
parent df3e4145e7
commit a453f21521
4 changed files with 40 additions and 42 deletions

View File

@ -16,6 +16,11 @@
#include <rx/rx.h>
#include <rx/rxstat.h>
#ifdef AFS_NT40_ENV
# include <winsock2.h>
# include <afs/krb5_nt.h>
#endif
#include <afs/afs_Admin.h>
#include <afs/pthread_glock.h>
#include <afs/cellconfig.h>
@ -29,12 +34,6 @@
#include <afs/volser.h>
#include <afs/afscbint.h>
#ifdef AFS_NT40_ENV
# define EncryptionKey Krb5EncryptionKey
# include <krb5/krb5.h>
# 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;

View File

@ -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 \

View File

@ -26,28 +26,26 @@
#include <afsconfig.h>
#include <afs/param.h>
#include <roken.h>
#include <windows.h>
#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 <krb5\krb5.h>
# include <com_err.h>
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;
}

View File

@ -26,10 +26,7 @@
#ifdef AFS_NT40_ENV
# include <krb5\krb5.h>
# include <com_err.h>
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 */