diff --git a/include/config.h.w32 b/include/config.h.w32 index c6c71d537..04eb469ed 100644 --- a/include/config.h.w32 +++ b/include/config.h.w32 @@ -41,6 +41,10 @@ static const char *const rcsid[] = { (const char *)rcsid, "@(#)" msg } with anything other than the version macros. */ #ifndef RC_INVOKED +#if defined(_MSC_VER) +#define inline __inline +#endif + #define MaxHostNameLen (64+4) #define MaxPathLen MAX_PATH diff --git a/include/heim_threads.h b/include/heim_threads.h index f337ac167..3ed06d926 100644 --- a/include/heim_threads.h +++ b/include/heim_threads.h @@ -46,6 +46,8 @@ #ifndef HEIM_THREADS_H #define HEIM_THREADS_H 1 +#include + #ifdef _MSC_VER #define HEIMDAL_THREAD_LOCAL __declspec(thread) diff --git a/kdc/cjwt_token_validator.c b/kdc/cjwt_token_validator.c index ea76b8706..68fe01594 100644 --- a/kdc/cjwt_token_validator.c +++ b/kdc/cjwt_token_validator.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -325,7 +326,7 @@ hcjwt_get_instance(const char *libname) krb5_plugin_load_ft kdc_token_validator_plugin_load; krb5_error_code KRB5_CALLCONV -kdc_token_validator_plugin_load(krb5_context context, +kdc_token_validator_plugin_load(heim_pcontext context, krb5_get_instance_func_t *get_instance, size_t *num_plugins, krb5_plugin_common_ftable_cp **plugins) diff --git a/kdc/csr_authorizer.c b/kdc/csr_authorizer.c index f8456daf7..4d930f01a 100644 --- a/kdc/csr_authorizer.c +++ b/kdc/csr_authorizer.c @@ -53,7 +53,7 @@ plcallback(krb5_context context, const void *plug, void *plugctx, void *userctx) static const char *plugin_deps[] = { "krb5", NULL }; -static struct krb5_plugin_data csr_authorizer_data = { +static struct heim_plugin_data csr_authorizer_data = { "kdc", KDC_CSR_AUTHORIZER, 1, diff --git a/kdc/ipc_csr_authorizer.c b/kdc/ipc_csr_authorizer.c index d271e3ee1..654084f4e 100644 --- a/kdc/ipc_csr_authorizer.c +++ b/kdc/ipc_csr_authorizer.c @@ -431,7 +431,7 @@ ipc_csr_authorizer_get_instance(const char *libname) krb5_plugin_load_ft kdc_csr_authorizer_plugin_load; krb5_error_code KRB5_CALLCONV -kdc_csr_authorizer_plugin_load(krb5_context context, +kdc_csr_authorizer_plugin_load(heim_pcontext context, krb5_get_instance_func_t *get_instance, size_t *num_plugins, krb5_plugin_common_ftable_cp **plugins) diff --git a/kdc/negotiate_token_validator.c b/kdc/negotiate_token_validator.c index 64294b746..df6ccdbde 100644 --- a/kdc/negotiate_token_validator.c +++ b/kdc/negotiate_token_validator.c @@ -42,7 +42,7 @@ #define _DEFAULT_SOURCE #define _BSD_SOURCE -#define _GNU_SOURCE +#define _GNU_SOURCE 1 #include #include @@ -56,6 +56,7 @@ #include #include +#include #include #include #include @@ -310,7 +311,7 @@ negotiate_get_instance(const char *libname) krb5_plugin_load_ft kdc_token_validator_plugin_load; krb5_error_code KRB5_CALLCONV -kdc_token_validator_plugin_load(krb5_context context, +kdc_token_validator_plugin_load(heim_pcontext context, krb5_get_instance_func_t *get_instance, size_t *num_plugins, krb5_plugin_common_ftable_cp **plugins) diff --git a/kdc/simple_csr_authorizer.c b/kdc/simple_csr_authorizer.c index b723a795a..412389100 100644 --- a/kdc/simple_csr_authorizer.c +++ b/kdc/simple_csr_authorizer.c @@ -325,7 +325,7 @@ simple_csr_authorizer_get_instance(const char *libname) krb5_plugin_load_ft kdc_csr_authorizer_plugin_load; krb5_error_code KRB5_CALLCONV -kdc_csr_authorizer_plugin_load(krb5_context context, +kdc_csr_authorizer_plugin_load(heim_pcontext context, krb5_get_instance_func_t *get_instance, size_t *num_plugins, krb5_plugin_common_ftable_cp **plugins) diff --git a/kdc/token_validator.c b/kdc/token_validator.c index d3ee8752a..cdb50e477 100644 --- a/kdc/token_validator.c +++ b/kdc/token_validator.c @@ -66,7 +66,7 @@ plcallback(krb5_context context, const void *plug, void *plugctx, void *userctx) static const char *plugin_deps[] = { "krb5", NULL }; -static struct krb5_plugin_data token_validator_data = { +static struct heim_plugin_data token_validator_data = { "kdc", KDC_PLUGIN_BEARER, 1, diff --git a/kdc/windc.c b/kdc/windc.c index 84419275e..05c59caf2 100644 --- a/kdc/windc.c +++ b/kdc/windc.c @@ -46,7 +46,7 @@ static const char *windc_plugin_deps[] = { NULL }; -static struct krb5_plugin_data windc_plugin_data = { +static struct heim_plugin_data windc_plugin_data = { "krb5", "windc", KRB5_WINDC_PLUGIN_MINOR, diff --git a/lib/Makefile.am b/lib/Makefile.am index 5f34eee6b..78a661bc3 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -26,10 +26,10 @@ endif SUBDIRS = \ roken \ - base \ vers \ - $(dir_editline) \ $(dir_com_err) \ + base \ + $(dir_editline) \ sl \ wind \ asn1 \ diff --git a/lib/NTMakefile b/lib/NTMakefile index d5150b0b6..fdb0261fe 100644 --- a/lib/NTMakefile +++ b/lib/NTMakefile @@ -50,7 +50,7 @@ assembly=..\thirdparty\assembly assembly=..\packages\windows\assembly !endif -SUBDIRS = roken base vers com_err sl wind asn1 sqlite \ +SUBDIRS = roken vers com_err base sl wind asn1 sqlite \ hcrypto hx509 krb5 heimdal ntlm kafs gssapi hdb \ kadm5 $(dir_otp) $(dir_dce) $(plugin) $(assembly) diff --git a/lib/base/Makefile.am b/lib/base/Makefile.am index da91c76ce..9483a72e7 100644 --- a/lib/base/Makefile.am +++ b/lib/base/Makefile.am @@ -11,42 +11,67 @@ IMPLEMENT_TLS += dll.c AM_CPPFLAGS += -DHEIM_BASE_MAINTAINER endif -AM_CPPFLAGS += $(ROKEN_RENAME) +AM_CPPFLAGS += $(ROKEN_RENAME) -I../com_err -I$(srcdir)/../com_err lib_LTLIBRARIES = libheimbase.la check_PROGRAMS = test_base libheimbase_la_LDFLAGS = -version-info 1:0:0 +if FRAMEWORK_COREFOUNDATION +libheimbase_la_LDFLAGS += -framework CoreFoundation +endif + TESTS = test_base if versionscript libheimbase_la_LDFLAGS += $(LDFLAGS_VERSION_SCRIPT)$(srcdir)/version-script.map endif -libheimbase_la_LIBADD = $(PTHREAD_LIBADD) +libheimbase_la_LIBADD = $(PTHREAD_LIBADD) $(LIB_dlopen) $(LIB_com_err) -include_HEADERS = heimbase.h +include_HEADERS = heimbase.h common_plugin.h + +ERR_FILES = heim_err.c dist_libheimbase_la_SOURCES = \ array.c \ baselocl.h \ bsearch.c \ bool.c \ + common_plugin.h \ + config_file.c \ + context.c \ data.c \ db.c \ dict.c \ $(IMPLEMENT_TLS) \ error.c \ + expand_path.c \ heimbase.c \ heimbasepriv.h \ json.c \ + log.c \ null.c \ number.c \ + plugin.c \ roken_rename.h \ - string.c + string.c \ + warn.c -nodist_libheimbase_la_SOURCES = $(ES) +nodist_libheimbase_la_SOURCES = $(ES) $(ERR_FILES) + +$(libheimbase_la_OBJECTS): $(srcdir)/heimbase-protos.h heim_err.h + +$(srcdir)/heimbase-protos.h: $(dist_libheimbase_la_SOURCES) + cd $(srcdir) && \ + perl ../../cf/make-proto.pl -q -P comment -o heimbase-protos.h $(dist_libheimbase_la_SOURCES) || \ + rm -f heimbase-protos.h + +$(srcdir)/heimbase-private.h: $(dist_libheimbase_la_SOURCES) + cd $(srcdir) && \ + perl ../../cf/make-proto.pl -q -P comment -p heimbase-private.h $(dist_libheimbase_la_SOURCES) || \ + rm -f heimbase-private.h # install these? @@ -54,9 +79,15 @@ libheimbase_la_DEPENDENCIES = version-script.map test_base_LDADD = libheimbase.la $(LIB_roken) -CLEANFILES = base64.c test_db.json +CLEANFILES = base64.c test_db.json heim_err.c heim_err.h -EXTRA_DIST = NTMakefile version-script.map +EXTRA_DIST = NTMakefile version-script.map config_reg.c heim_err.et + +dist_include_HEADERS = heimbase-protos.h + +nodist_include_HEADERS = heim_err.h + +heim_err.h: heim_err.et base64.c: rm -f base64.c diff --git a/lib/base/NTMakefile b/lib/base/NTMakefile index e5bda31dd..2f30d050e 100644 --- a/lib/base/NTMakefile +++ b/lib/base/NTMakefile @@ -35,31 +35,79 @@ intcflags=-I$(SRCDIR) -I$(OBJ) !include ../../windows/NTMakefile.w32 -INCFILES=$(INCDIR)\heimbase.h +INCFILES= \ + $(INCDIR)\heimbase.h \ + $(INCDIR)\heimbase-protos.h \ + $(INCDIR)\heim_err.h \ + $(INCDIR)\common_plugin.h test_binaries = $(OBJ)\test_base.exe +libheimbase_SOURCES = \ + array.c \ + bool.c \ + bsearch.c \ + config_file.c \ + config_reg.c \ + context.c \ + data.c \ + db.c \ + dict.c \ + dll.c \ + error.c \ + expand_path.c \ + heimbase.c \ + json.c \ + log.c \ + null.c \ + number.c \ + plugin.c \ + string.c \ + warn.c + libheimbase_OBJS = \ $(OBJ)\array.obj \ $(OBJ)\bool.obj \ $(OBJ)\bsearch.obj \ + $(OBJ)\config_file.obj \ + $(OBJ)\config_reg.obj \ + $(OBJ)\context.obj \ $(OBJ)\data.obj \ $(OBJ)\db.obj \ $(OBJ)\dict.obj \ $(OBJ)\dll.obj \ $(OBJ)\error.obj \ + $(OBJ)\expand_path.obj \ $(OBJ)\heimbase.obj \ $(OBJ)\json.obj \ + $(OBJ)\log.obj \ $(OBJ)\null.obj \ $(OBJ)\number.obj \ - $(OBJ)\string.obj + $(OBJ)\plugin.obj \ + $(OBJ)\string.obj \ + $(OBJ)\warn.obj -$(LIBHEIMBASE): $(libheimbase_OBJS) - $(LIBCON_C) -OUT:$@ $(LIBROKEN) @<< +libheimbase_gen_OBJS= $(OBJ)\heim_err.obj + +$(LIBHEIMBASE): $(libheimbase_OBJS) $(libheimbase_gen_OBJS) + $(LIBCON_C) -OUT:$@ $(LIBROKEN) $(PTHREAD_LIB) Secur32.lib Shell32.lib Advapi32.lib @<< $(libheimbase_OBJS: = ) +$(libheimbase_gen_OBJS: = +) << +$(OBJ)\heimbase-protos.h: $(libheimbase_SOURCES) + $(PERL) ..\..\cf\make-proto.pl -E KRB5_LIB -q -P remove -o $(OBJ)\heimbase-protos.h $(libheimbase_SOURCES) || $(RM) -f $(OBJ)\heimbase-protos.h + +$(OBJ)\heimbase-private.h: $(libheimbase_SOURCES) + $(PERL) ..\..\cf\make-proto.pl -q -P remove -p $(OBJ)\heimbase-private.h $(libheimbase_SOURCES) || $(RM) -f $(OBJ)\heimbase-private.h + +$(OBJ)\heim_err.c $(OBJ)\heim_err.h: heim_err.et + cd $(OBJ) + $(BINDIR)\compile_et.exe $(SRCDIR)\heim_err.et + cd $(SRCDIR) + test:: test-binaries test-run test-run: diff --git a/lib/base/baselocl.h b/lib/base/baselocl.h index ee61667af..7cc1734b6 100644 --- a/lib/base/baselocl.h +++ b/lib/base/baselocl.h @@ -37,6 +37,13 @@ #include +#define ISTILDE(x) (x == '~') +#ifdef _WIN32 +# define ISPATHSEP(x) (x == '/' || x =='\\') +#else +# define ISPATHSEP(x) (x == '/') +#endif + #ifdef HAVE_SYS_SELECT_H #include #endif diff --git a/lib/krb5/common_plugin.h b/lib/base/common_plugin.h similarity index 54% rename from lib/krb5/common_plugin.h rename to lib/base/common_plugin.h index 05f8b628f..c2e4440af 100644 --- a/lib/krb5/common_plugin.h +++ b/lib/base/common_plugin.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan + * Copyright (c) 2006 - 2020 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,37 +33,63 @@ * SUCH DAMAGE. */ -#ifndef HEIMDAL_KRB5_COMMON_PLUGIN_H -#define HEIMDAL_KRB5_COMMON_PLUGIN_H +#ifndef HEIMDAL_BASE_COMMON_PLUGIN_H +#define HEIMDAL_BASE_COMMON_PLUGIN_H + +#ifdef _WIN32 +#ifndef HEIM_CALLCONV +#define HEIM_CALLCONV __stdcall +#endif +#ifndef HEIM_LIB_CALL +#define HEIM_LIB_CALL __stdcall +#endif +#else +#ifndef HEIM_CALLCONV +#define HEIM_CALLCONV +#endif +#ifndef HEIM_LIB_CALL +#define HEIM_LIB_CALL +#endif +#endif + +/* For krb5 plugins, this is a krb5_context */ +typedef struct heim_pcontext_s *heim_pcontext; /* * All plugin function tables extend the following structure. */ -struct krb5_plugin_common_ftable_desc { +struct heim_plugin_common_ftable_desc { int version; - krb5_error_code (KRB5_LIB_CALL *init)(krb5_context, void **); - void (KRB5_LIB_CALL *fini)(void *); + int (HEIM_LIB_CALL *init)(heim_pcontext, void **); + void (HEIM_LIB_CALL *fini)(void *); }; -typedef struct krb5_plugin_common_ftable_desc krb5_plugin_common_ftable; -typedef struct krb5_plugin_common_ftable_desc *krb5_plugin_common_ftable_p; -typedef struct krb5_plugin_common_ftable_desc * const krb5_plugin_common_ftable_cp; +typedef struct heim_plugin_common_ftable_desc heim_plugin_common_ftable; +typedef struct heim_plugin_common_ftable_desc *heim_plugin_common_ftable_p; +typedef struct heim_plugin_common_ftable_desc * const heim_plugin_common_ftable_cp; -typedef krb5_error_code -(KRB5_CALLCONV krb5_plugin_load_ft)(krb5_context context, - krb5_get_instance_func_t *func, +typedef int +(HEIM_CALLCONV heim_plugin_load_ft)(heim_pcontext context, + heim_get_instance_func_t *func, size_t *n_ftables, - krb5_plugin_common_ftable_cp **ftables); + heim_plugin_common_ftable_cp **ftables); -typedef krb5_plugin_load_ft *krb5_plugin_load_t; +typedef heim_plugin_load_ft *heim_plugin_load_t; + +/* For source backwards-compatibility */ +typedef struct heim_plugin_common_ftable_desc krb5_plugin_common_ftable; +typedef struct heim_plugin_common_ftable_desc *krb5_plugin_common_ftable_p; +typedef struct heim_plugin_common_ftable_desc * const krb5_plugin_common_ftable_cp; +typedef heim_plugin_load_ft krb5_plugin_load_ft; +typedef heim_plugin_load_ft *krb5_plugin_load_t; /* * All plugins must export a function named "_plugin_load" with * a signature of: * - * krb5_error_code KRB5_CALLCONV - * _plugin_load(krb5_context context, - * krb5_get_instance_func_t *func, + * int HEIM_CALLCONV + * _plugin_load(heim_pcontext context, + * heim_get_instance_func_t *func, * size_t *n_ftables, - * const krb5_plugin_common_ftable *const **ftables); + * const heim_plugin_common_ftable *const **ftables); */ -#endif /* HEIMDAL_KRB5_COMMON_PLUGIN_H */ +#endif /* HEIMDAL_BASE_COMMON_PLUGIN_H */ diff --git a/lib/base/config_file.c b/lib/base/config_file.c index 6d66acf71..c41f4d624 100644 --- a/lib/base/config_file.c +++ b/lib/base/config_file.c @@ -33,7 +33,10 @@ * SUCH DAMAGE. */ -#include "krb5_locl.h" +#include "baselocl.h" +#include +#include +#include #if defined(HAVE_FRAMEWORK_COREFOUNDATION) #include @@ -41,7 +44,7 @@ /* Gaah! I want a portable funopen */ struct fileptr { - krb5_context context; + heim_context context; const char *s; FILE *f; }; @@ -52,56 +55,56 @@ config_fgets(char *str, size_t len, struct fileptr *ptr) /* XXX this is not correct, in that they don't do the same if the line is longer than len */ if(ptr->f != NULL) - return fgets(str, len, ptr->f); + return fgets(str, len, ptr->f); else { - /* this is almost strsep_copy */ - const char *p; - ssize_t l; - if(*ptr->s == '\0') - return NULL; - p = ptr->s + strcspn(ptr->s, "\n"); - if(*p == '\n') - p++; - l = min(len, (size_t)(p - ptr->s)); - if(len > 0) { - memcpy(str, ptr->s, l); - str[l] = '\0'; - } - ptr->s = p; - return str; + /* this is almost strsep_copy */ + const char *p; + ssize_t l; + if(*ptr->s == '\0') + return NULL; + p = ptr->s + strcspn(ptr->s, "\n"); + if(*p == '\n') + p++; + l = min(len, (size_t)(p - ptr->s)); + if(len > 0) { + memcpy(str, ptr->s, l); + str[l] = '\0'; + } + ptr->s = p; + return str; } } -static krb5_error_code parse_section(char *p, krb5_config_section **s, - krb5_config_section **res, - const char **err_message); -static krb5_error_code parse_binding(struct fileptr *f, unsigned *lineno, char *p, - krb5_config_binding **b, - krb5_config_binding **parent, - const char **err_message); -static krb5_error_code parse_list(struct fileptr *f, unsigned *lineno, - krb5_config_binding **parent, - const char **err_message); +static heim_error_code parse_section(char *p, heim_config_section **s, + heim_config_section **res, + const char **err_message); +static heim_error_code parse_binding(struct fileptr *f, unsigned *lineno, char *p, + heim_config_binding **b, + heim_config_binding **parent, + const char **err_message); +static heim_error_code parse_list(struct fileptr *f, unsigned *lineno, + heim_config_binding **parent, + const char **err_message); -KRB5_LIB_FUNCTION krb5_config_section * KRB5_LIB_CALL -_krb5_config_get_entry(krb5_config_section **parent, const char *name, int type) +heim_config_section * +heim_config_get_entry(heim_config_section **parent, const char *name, int type) { - krb5_config_section **q; + heim_config_section **q; - for(q = parent; *q != NULL; q = &(*q)->next) - if(type == krb5_config_list && - (unsigned)type == (*q)->type && - strcmp(name, (*q)->name) == 0) - return *q; + for (q = parent; *q != NULL; q = &(*q)->next) + if (type == heim_config_list && + (unsigned)type == (*q)->type && + strcmp(name, (*q)->name) == 0) + return *q; *q = calloc(1, sizeof(**q)); - if(*q == NULL) - return NULL; + if (*q == NULL) + return NULL; (*q)->name = strdup(name); (*q)->type = type; - if((*q)->name == NULL) { - free(*q); - *q = NULL; - return NULL; + if ((*q)->name == NULL) { + free(*q); + *q = NULL; + return NULL; } return *q; } @@ -110,10 +113,10 @@ _krb5_config_get_entry(krb5_config_section **parent, const char *name, int type) * Parse a section: * * [section] - * foo = bar - * b = { - * a - * } + * foo = bar + * b = { + * a + * } * ... * * starting at the line in `p', storing the resulting structure in @@ -121,23 +124,23 @@ _krb5_config_get_entry(krb5_config_section **parent, const char *name, int type) * Store the error message in `err_message'. */ -static krb5_error_code -parse_section(char *p, krb5_config_section **s, krb5_config_section **parent, - const char **err_message) +static heim_error_code +parse_section(char *p, heim_config_section **s, heim_config_section **parent, + const char **err_message) { char *p1; - krb5_config_section *tmp; + heim_config_section *tmp; p1 = strchr (p + 1, ']'); if (p1 == NULL) { - *err_message = "missing ]"; - return KRB5_CONFIG_BADFORMAT; + *err_message = "missing ]"; + return HEIM_ERR_CONFIG_BADFORMAT; } *p1 = '\0'; - tmp = _krb5_config_get_entry(parent, p + 1, krb5_config_list); + tmp = heim_config_get_entry(parent, p + 1, heim_config_list); if(tmp == NULL) { - *err_message = "out of memory"; - return KRB5_CONFIG_BADFORMAT; + *err_message = "out of memory"; + return HEIM_ERR_CONFIG_BADFORMAT; } *s = tmp; return 0; @@ -149,90 +152,90 @@ parse_section(char *p, krb5_config_section **s, krb5_config_section **parent, * Store the error message in `err_message'. */ -static krb5_error_code -parse_list(struct fileptr *f, unsigned *lineno, krb5_config_binding **parent, - const char **err_message) +static heim_error_code +parse_list(struct fileptr *f, unsigned *lineno, heim_config_binding **parent, + const char **err_message) { - char buf[KRB5_BUFSIZ]; - krb5_error_code ret; - krb5_config_binding *b = NULL; + char buf[2048]; + heim_error_code ret; + heim_config_binding *b = NULL; unsigned beg_lineno = *lineno; while(config_fgets(buf, sizeof(buf), f) != NULL) { - char *p; + char *p; - ++*lineno; - buf[strcspn(buf, "\r\n")] = '\0'; - p = buf; - while(isspace((unsigned char)*p)) - ++p; - if (*p == '#' || *p == ';' || *p == '\0') - continue; - while(isspace((unsigned char)*p)) - ++p; - if (*p == '}') - return 0; - if (*p == '\0') - continue; - ret = parse_binding (f, lineno, p, &b, parent, err_message); - if (ret) - return ret; + ++*lineno; + buf[strcspn(buf, "\r\n")] = '\0'; + p = buf; + while(isspace((unsigned char)*p)) + ++p; + if (*p == '#' || *p == ';' || *p == '\0') + continue; + while(isspace((unsigned char)*p)) + ++p; + if (*p == '}') + return 0; + if (*p == '\0') + continue; + ret = parse_binding (f, lineno, p, &b, parent, err_message); + if (ret) + return ret; } *lineno = beg_lineno; *err_message = "unclosed {"; - return KRB5_CONFIG_BADFORMAT; + return HEIM_ERR_CONFIG_BADFORMAT; } /* * */ -static krb5_error_code +static heim_error_code parse_binding(struct fileptr *f, unsigned *lineno, char *p, - krb5_config_binding **b, krb5_config_binding **parent, - const char **err_message) + heim_config_binding **b, heim_config_binding **parent, + const char **err_message) { - krb5_config_binding *tmp; + heim_config_binding *tmp; char *p1, *p2; - krb5_error_code ret = 0; + heim_error_code ret = 0; p1 = p; while (*p && *p != '=' && !isspace((unsigned char)*p)) - ++p; + ++p; if (*p == '\0') { - *err_message = "missing ="; - return KRB5_CONFIG_BADFORMAT; + *err_message = "missing ="; + return HEIM_ERR_CONFIG_BADFORMAT; } p2 = p; while (isspace((unsigned char)*p)) - ++p; + ++p; if (*p != '=') { - *err_message = "missing ="; - return KRB5_CONFIG_BADFORMAT; + *err_message = "missing ="; + return HEIM_ERR_CONFIG_BADFORMAT; } ++p; while(isspace((unsigned char)*p)) - ++p; + ++p; *p2 = '\0'; if (*p == '{') { - tmp = _krb5_config_get_entry(parent, p1, krb5_config_list); - if (tmp == NULL) { - *err_message = "out of memory"; - return KRB5_CONFIG_BADFORMAT; - } - ret = parse_list (f, lineno, &tmp->u.list, err_message); + tmp = heim_config_get_entry(parent, p1, heim_config_list); + if (tmp == NULL) { + *err_message = "out of memory"; + return HEIM_ERR_CONFIG_BADFORMAT; + } + ret = parse_list (f, lineno, &tmp->u.list, err_message); } else { - tmp = _krb5_config_get_entry(parent, p1, krb5_config_string); - if (tmp == NULL) { - *err_message = "out of memory"; - return KRB5_CONFIG_BADFORMAT; - } - p1 = p; - p = p1 + strlen(p1); - while(p > p1 && isspace((unsigned char)*(p-1))) - --p; - *p = '\0'; - tmp->u.string = strdup(p1); + tmp = heim_config_get_entry(parent, p1, heim_config_string); + if (tmp == NULL) { + *err_message = "out of memory"; + return HEIM_ERR_CONFIG_BADFORMAT; + } + p1 = p; + p = p1 + strlen(p1); + while(p > p1 && isspace((unsigned char)*(p-1))) + --p; + *p = '\0'; + tmp->u.string = strdup(p1); } *b = tmp; return ret; @@ -252,17 +255,17 @@ cfstring2cstring(CFStringRef string) str = (char *) CFStringGetCStringPtr(string, kCFStringEncodingUTF8); if (str) - return strdup(str); + return strdup(str); len = CFStringGetLength(string); len = 1 + CFStringGetMaximumSizeForEncoding(len, kCFStringEncodingUTF8); str = malloc(len); if (str == NULL) - return NULL; + return NULL; if (!CFStringGetCString (string, str, len, kCFStringEncodingUTF8)) { - free (str); - return NULL; + free (str); + return NULL; } return str; } @@ -270,52 +273,52 @@ cfstring2cstring(CFStringRef string) static void convert_content(const void *key, const void *value, void *context) { - krb5_config_section *tmp, **parent = context; + heim_config_section *tmp, **parent = context; char *k; if (CFGetTypeID(key) != CFStringGetTypeID()) - return; + return; k = cfstring2cstring(key); if (k == NULL) - return; + return; if (CFGetTypeID(value) == CFStringGetTypeID()) { - tmp = _krb5_config_get_entry(parent, k, krb5_config_string); - tmp->u.string = cfstring2cstring(value); + tmp = heim_config_get_entry(parent, k, heim_config_string); + tmp->u.string = cfstring2cstring(value); } else if (CFGetTypeID(value) == CFDictionaryGetTypeID()) { - tmp = _krb5_config_get_entry(parent, k, krb5_config_list); - CFDictionaryApplyFunction(value, convert_content, &tmp->u.list); + tmp = heim_config_get_entry(parent, k, heim_config_list); + CFDictionaryApplyFunction(value, convert_content, &tmp->u.list); } else { - /* log */ + /* log */ } free(k); } -static krb5_error_code -parse_plist_config(krb5_context context, const char *path, krb5_config_section **parent) +static heim_error_code +parse_plist_config(heim_context context, const char *path, heim_config_section **parent) { CFReadStreamRef s; CFDictionaryRef d; CFURLRef url; - url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (UInt8 *)path, strlen(path), FALSE); + url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (UInt8 *)path, strlen(path), 0); if (url == NULL) { - krb5_clear_error_message(context); - return ENOMEM; + heim_clear_error_message(context); + return ENOMEM; } s = CFReadStreamCreateWithFile(kCFAllocatorDefault, url); CFRelease(url); if (s == NULL) { - krb5_clear_error_message(context); - return ENOMEM; + heim_clear_error_message(context); + return ENOMEM; } if (!CFReadStreamOpen(s)) { - CFRelease(s); - krb5_clear_error_message(context); - return ENOENT; + CFRelease(s); + heim_clear_error_message(context); + return ENOENT; } #ifdef HAVE_CFPROPERTYLISTCREATEWITHSTREAM @@ -325,8 +328,8 @@ parse_plist_config(krb5_context context, const char *path, krb5_config_section * #endif CFRelease(s); if (d == NULL) { - krb5_clear_error_message(context); - return ENOENT; + heim_clear_error_message(context); + return ENOENT; } CFDictionaryApplyFunction(d, convert_content, parent); @@ -378,72 +381,72 @@ is_absolute_path(const char *path) * returning error messages in `err_message' */ -static krb5_error_code -krb5_config_parse_debug (struct fileptr *f, - krb5_config_section **res, - unsigned *lineno, - const char **err_message) +static heim_error_code +heim_config_parse_debug(struct fileptr *f, + heim_config_section **res, + unsigned *lineno, + const char **err_message) { - krb5_config_section *s = NULL; - krb5_config_binding *b = NULL; - char buf[KRB5_BUFSIZ]; - krb5_error_code ret; + heim_config_section *s = NULL; + heim_config_binding *b = NULL; + char buf[2048]; + heim_error_code ret; while (config_fgets(buf, sizeof(buf), f) != NULL) { - char *p; + char *p; - ++*lineno; - buf[strcspn(buf, "\r\n")] = '\0'; - p = buf; - while(isspace((unsigned char)*p)) - ++p; - if (*p == '#' || *p == ';') - continue; + ++*lineno; + buf[strcspn(buf, "\r\n")] = '\0'; + p = buf; + while(isspace((unsigned char)*p)) + ++p; + if (*p == '#' || *p == ';') + continue; if (*p == '[') { - ret = parse_section(p, &s, res, err_message); - if (ret) - return ret; - b = NULL; - } else if (*p == '}') { - *err_message = "unmatched }"; - return KRB5_CONFIG_BADFORMAT; + ret = parse_section(p, &s, res, err_message); + if (ret) + return ret; + b = NULL; + } else if (*p == '}') { + *err_message = "unmatched }"; + return 2048; } else if (strncmp(p, "include", sizeof("include") - 1) == 0 && isspace(p[sizeof("include") - 1])) { p += sizeof("include"); while (isspace(*p)) p++; if (!is_absolute_path(p)) { - krb5_set_error_message(f->context, EINVAL, + heim_set_error_message(f->context, HEIM_ERR_CONFIG_BADFORMAT, "Configuration include path must be " "absolute"); - return EINVAL; + return HEIM_ERR_CONFIG_BADFORMAT; } - ret = krb5_config_parse_file_multi(f->context, p, res); - if (ret) - return ret; + ret = heim_config_parse_file_multi(f->context, p, res); + if (ret) + return ret; } else if (strncmp(p, "includedir", sizeof("includedir") - 1) == 0 && isspace(p[sizeof("includedir") - 1])) { p += sizeof("includedir"); while (isspace(*p)) p++; if (!is_absolute_path(p)) { - krb5_set_error_message(f->context, EINVAL, + heim_set_error_message(f->context, HEIM_ERR_CONFIG_BADFORMAT, "Configuration includedir path must be " "absolute"); - return EINVAL; + return HEIM_ERR_CONFIG_BADFORMAT; } - ret = krb5_config_parse_dir_multi(f->context, p, res); - if (ret) - return ret; - } else if(*p != '\0') { - if (s == NULL) { - *err_message = "binding before section"; - return KRB5_CONFIG_BADFORMAT; - } - ret = parse_binding(f, lineno, p, &b, &s->u.list, err_message); - if (ret) - return ret; - } + ret = heim_config_parse_dir_multi(f->context, p, res); + if (ret) + return ret; + } else if(*p != '\0') { + if (s == NULL) { + *err_message = "binding before section"; + return 2048; + } + ret = parse_binding(f, lineno, p, &b, &s->u.list, err_message); + if (ret) + return ret; + } } return 0; } @@ -454,9 +457,9 @@ is_plist_file(const char *fname) size_t len = strlen(fname); char suffix[] = ".plist"; if (len < sizeof(suffix)) - return 0; + return 0; if (strcasecmp(&fname[len - (sizeof(suffix) - 1)], suffix) != 0) - return 0; + return 0; return 1; } @@ -467,23 +470,23 @@ is_plist_file(const char *fname) * ending in ".conf" will also be parsed. * * This interface can be used to parse several configuration directories - * into one resulting krb5_config_section by calling it repeatably. + * into one resulting heim_config_section by calling it repeatably. * * @param context a Kerberos 5 context. * @param dname a directory name to a Kerberos configuration file - * @param res the returned result, must be free with krb5_free_config_files(). - * @return Return an error code or 0, see krb5_get_error_message(). + * @param res the returned result, must be free with heim_free_config_files(). + * @return Return an error code or 0, see heim_get_error_message(). * - * @ingroup krb5_support + * @ingroup heim_support */ -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_config_parse_dir_multi(krb5_context context, +heim_error_code +heim_config_parse_dir_multi(heim_context context, const char *dname, - krb5_config_section **res) + heim_config_section **res) { struct dirent *entry; - krb5_error_code ret; + heim_error_code ret; DIR *d; if ((d = opendir(dname)) == NULL) @@ -496,7 +499,7 @@ krb5_config_parse_dir_multi(krb5_context context, while (*p) { /* - * Here be dragons. The call to krb5_config_parse_file_multi() + * Here be dragons. The call to heim_config_parse_file_multi() * below expands path tokens. Because of the limitations here * on file naming, we can't have path tokens in the file name, * so we're safe. Anyone changing this if condition here should @@ -515,13 +518,13 @@ krb5_config_parse_dir_multi(krb5_context context, if (asprintf(&path, "%s/%s", dname, entry->d_name) == -1 || path == NULL) { (void) closedir(d); - return krb5_enomem(context); + return heim_enomem(context); } - ret = krb5_config_parse_file_multi(context, path, res); + ret = heim_config_parse_file_multi(context, path, res); free(path); if (ret == ENOMEM) { (void) closedir(d); - return krb5_enomem(context);; + return heim_enomem(context); } /* Ignore malformed config files so we don't lock out admins, etc... */ } @@ -532,189 +535,193 @@ krb5_config_parse_dir_multi(krb5_context context, /** * Parse a configuration file and add the result into res. This * interface can be used to parse several configuration files into one - * resulting krb5_config_section by calling it repeatably. + * resulting heim_config_section by calling it repeatably. * * @param context a Kerberos 5 context. * @param fname a file name to a Kerberos configuration file - * @param res the returned result, must be free with krb5_free_config_files(). - * @return Return an error code or 0, see krb5_get_error_message(). + * @param res the returned result, must be free with heim_free_config_files(). + * @return Return an error code or 0, see heim_get_error_message(). * - * @ingroup krb5_support + * @ingroup heim_support */ -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_config_parse_file_multi (krb5_context context, - const char *fname, - krb5_config_section **res) +HEIMDAL_THREAD_LOCAL int config_include_depth = 0; + +heim_error_code +heim_config_parse_file_multi(heim_context context, + const char *fname, + heim_config_section **res) { const char *str; char *newfname = NULL; unsigned lineno = 0; - krb5_error_code ret; + heim_error_code ret; struct fileptr f; struct stat st; - if (context->config_include_depth > 5) { - krb5_warnx(context, "Maximum config file include depth reached; " + if (config_include_depth > 5) { + heim_warnx(context, "Maximum config file include depth reached; " "not including %s", fname); return 0; } - context->config_include_depth++; + config_include_depth++; /** * If the fname starts with "~/" parse configuration file in the * current users home directory. The behavior can be disabled and - * enabled by calling krb5_set_home_dir_access(). + * enabled by calling heim_set_home_dir_access(). */ if (ISTILDE(fname[0]) && ISPATHSEP(fname[1])) { #ifndef KRB5_USE_PATH_TOKENS - const char *home = NULL; + const char *home = NULL; char homebuf[MAX_PATH]; - if (!_krb5_homedir_access(context)) { - context->config_include_depth--; - krb5_set_error_message(context, EPERM, - "Access to home directory not allowed"); - return EPERM; - } + if (!heim_context_get_homedir_access(context)) { + config_include_depth--; + heim_set_error_message(context, EPERM, + "Access to home directory not allowed"); + return EPERM; + } home = roken_get_appdatadir(homebuf, sizeof(homebuf)); - if (home) { - int aret; + if (home) { + int aret; - aret = asprintf(&newfname, "%s%s", home, &fname[1]); - if (aret == -1 || newfname == NULL) { - context->config_include_depth--; - return krb5_enomem(context); + aret = asprintf(&newfname, "%s%s", home, &fname[1]); + if (aret == -1 || newfname == NULL) { + config_include_depth--; + return heim_enomem(context); } - fname = newfname; - } -#else /* KRB5_USE_PATH_TOKENS */ - if (asprintf(&newfname, "%%{USERCONFIG}%s", &fname[1]) < 0 || - newfname == NULL) { - context->config_include_depth--; - return krb5_enomem(context); + fname = newfname; } - fname = newfname; +#else /* KRB5_USE_PATH_TOKENS */ + /* + * Really, this is Windows, and on Windows we'd want to allow homedir + * access. We could refactor this a bit though. + */ + if (asprintf(&newfname, "%%{USERCONFIG}%s", &fname[1]) < 0 || + newfname == NULL) { + config_include_depth--; + return heim_enomem(context); + } + fname = newfname; #endif } if (is_plist_file(fname)) { - context->config_include_depth--; + config_include_depth--; #if defined(HAVE_FRAMEWORK_COREFOUNDATION) - ret = parse_plist_config(context, fname, res); - if (ret) { - krb5_set_error_message(context, ret, - "Failed to parse plist %s", fname); + ret = parse_plist_config(context, fname, res); + if (ret) { + heim_set_error_message(context, ret, + "Failed to parse plist %s", fname); free(newfname); - return ret; - } + return ret; + } #else - krb5_set_error_message(context, ENOENT, - "no support for plist configuration files"); - return ENOENT; + heim_set_error_message(context, ENOENT, + "no support for plist configuration files"); + return ENOENT; #endif } else { #ifdef KRB5_USE_PATH_TOKENS - char * exp_fname = NULL; + char * exp_fname = NULL; /* - * Note that krb5_config_parse_dir_multi() doesn't want tokens + * Note that heim_config_parse_dir_multi() doesn't want tokens * expanded here, but it happens to limit the names of files to * include such that there can be no tokens to expand. Don't * add token expansion for tokens using _, say. */ - ret = _krb5_expand_path_tokens(context, fname, 1, &exp_fname); - if (ret) { - context->config_include_depth--; + ret = heim_expand_path_tokens(context, fname, 1, &exp_fname, NULL); + if (ret) { + config_include_depth--; free(newfname); - return ret; - } + return ret; + } free(newfname); - fname = newfname = exp_fname; + fname = newfname = exp_fname; #endif f.context = context; - f.f = fopen(fname, "r"); - f.s = NULL; - if (f.f == NULL || fstat(fileno(f.f), &st) == -1) { + f.f = fopen(fname, "r"); + f.s = NULL; + if (f.f == NULL || fstat(fileno(f.f), &st) == -1) { if (f.f != NULL) (void) fclose(f.f); - context->config_include_depth--; - ret = errno; - krb5_set_error_message(context, ret, "open or stat %s: %s", - fname, strerror(ret)); + config_include_depth--; + ret = errno; + heim_set_error_message(context, ret, "open or stat %s: %s", + fname, strerror(ret)); free(newfname); - return ret; - } + return ret; + } if (!S_ISREG(st.st_mode)) { (void) fclose(f.f); - context->config_include_depth--; - krb5_set_error_message(context, EISDIR, "not a regular file %s: %s", - fname, strerror(EISDIR)); - free(newfname); - return EISDIR; + config_include_depth--; + heim_set_error_message(context, EISDIR, "not a regular file %s: %s", + fname, strerror(EISDIR)); + free(newfname); + return EISDIR; } - ret = krb5_config_parse_debug (&f, res, &lineno, &str); - context->config_include_depth--; - fclose(f.f); - if (ret) { - krb5_set_error_message (context, ret, "%s:%u: %s", - fname, lineno, str); + ret = heim_config_parse_debug(&f, res, &lineno, &str); + config_include_depth--; + fclose(f.f); + if (ret) { + heim_set_error_message(context, ret, "%s:%u: %s", + fname, lineno, str); free(newfname); - return ret; - } + return ret; + } } return 0; } -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_config_parse_file (krb5_context context, - const char *fname, - krb5_config_section **res) +heim_error_code +heim_config_parse_file(heim_context context, + const char *fname, + heim_config_section **res) { *res = NULL; - return krb5_config_parse_file_multi(context, fname, res); + return heim_config_parse_file_multi(context, fname, res); } static void -free_binding (krb5_context context, krb5_config_binding *b) +free_binding(heim_context context, heim_config_binding *b) { - krb5_config_binding *next_b; + heim_config_binding *next_b; while (b) { - free (b->name); - if (b->type == krb5_config_string) - free (b->u.string); - else if (b->type == krb5_config_list) - free_binding (context, b->u.list); - else - krb5_abortx(context, "unknown binding type (%d) in free_binding", - b->type); - next_b = b->next; - free (b); - b = next_b; + free (b->name); + assert(b->type == heim_config_string || b->type == heim_config_list); + if (b->type == heim_config_string) + free (b->u.string); + else + free_binding (context, b->u.list); + next_b = b->next; + free (b); + b = next_b; } } /** * Free configuration file section, the result of - * krb5_config_parse_file() and krb5_config_parse_file_multi(). + * heim_config_parse_file() and heim_config_parse_file_multi(). * * @param context A Kerberos 5 context * @param s the configuration section to free * * @return returns 0 on successes, otherwise an error code, see - * krb5_get_error_message() + * heim_get_error_message() * - * @ingroup krb5_support + * @ingroup heim_support */ -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_config_file_free (krb5_context context, krb5_config_section *s) +heim_error_code +heim_config_file_free(heim_context context, heim_config_section *s) { free_binding (context, s); return 0; @@ -722,142 +729,137 @@ krb5_config_file_free (krb5_context context, krb5_config_section *s) #ifndef HEIMDAL_SMALLER -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -_krb5_config_copy(krb5_context context, - krb5_config_section *c, - krb5_config_section **head) +heim_error_code +heim_config_copy(heim_context context, + heim_config_section *c, + heim_config_section **head) { - krb5_config_binding *d, *previous = NULL; + heim_config_binding *d, *previous = NULL; *head = NULL; while (c) { - d = calloc(1, sizeof(*d)); + d = calloc(1, sizeof(*d)); - if (*head == NULL) - *head = d; + if (*head == NULL) + *head = d; - d->name = strdup(c->name); - d->type = c->type; - if (d->type == krb5_config_string) - d->u.string = strdup(c->u.string); - else if (d->type == krb5_config_list) - _krb5_config_copy (context, c->u.list, &d->u.list); - else - krb5_abortx(context, - "unknown binding type (%d) in krb5_config_copy", - d->type); - if (previous) - previous->next = d; + d->name = strdup(c->name); + d->type = c->type; + assert(d->type == heim_config_string || d->type == heim_config_list); + if (d->type == heim_config_string) + d->u.string = strdup(c->u.string); + else + heim_config_copy (context, c->u.list, &d->u.list); + if (previous) + previous->next = d; - previous = d; - c = c->next; + previous = d; + c = c->next; } return 0; } #endif /* HEIMDAL_SMALLER */ -KRB5_LIB_FUNCTION const void * KRB5_LIB_CALL -_krb5_config_get_next (krb5_context context, - const krb5_config_section *c, - const krb5_config_binding **pointer, - int type, - ...) +const void * +heim_config_get_next(heim_context context, + const heim_config_section *c, + const heim_config_binding **pointer, + int type, + ...) { const char *ret; va_list args; va_start(args, type); - ret = _krb5_config_vget_next (context, c, pointer, type, args); + ret = heim_config_vget_next(context, c, pointer, type, args); va_end(args); return ret; } static const void * -vget_next(krb5_context context, - const krb5_config_binding *b, - const krb5_config_binding **pointer, - int type, - const char *name, - va_list args) +vget_next(heim_context context, + const heim_config_binding *b, + const heim_config_binding **pointer, + int type, + const char *name, + va_list args) { const char *p = va_arg(args, const char *); - while(b != NULL) { - if(strcmp(b->name, name) == 0) { - if(b->type == (unsigned)type && p == NULL) { - *pointer = b; - return b->u.generic; - } else if(b->type == krb5_config_list && p != NULL) { - return vget_next(context, b->u.list, pointer, type, p, args); - } - } - b = b->next; + + while (b != NULL) { + if (strcmp(b->name, name) == 0) { + if (b->type == (unsigned)type && p == NULL) { + *pointer = b; + return b->u.generic; + } else if (b->type == heim_config_list && p != NULL) { + return vget_next(context, b->u.list, pointer, type, p, args); + } + } + b = b->next; } return NULL; } -KRB5_LIB_FUNCTION const void * KRB5_LIB_CALL -_krb5_config_vget_next (krb5_context context, - const krb5_config_section *c, - const krb5_config_binding **pointer, - int type, - va_list args) +const void * +heim_config_vget_next(heim_context context, + const heim_config_section *c, + const heim_config_binding **pointer, + int type, + va_list args) { - const krb5_config_binding *b; + const heim_config_binding *b; const char *p; - if(c == NULL) - c = context->cf; - if (c == NULL) - return NULL; + return NULL; if (*pointer == NULL) { - /* first time here, walk down the tree looking for the right + /* first time here, walk down the tree looking for the right section */ - p = va_arg(args, const char *); - if (p == NULL) - return NULL; - return vget_next(context, c, pointer, type, p, args); + p = va_arg(args, const char *); + if (p == NULL) + return NULL; + return vget_next(context, c, pointer, type, p, args); } /* we were called again, so just look for more entries with the same name and type */ for (b = (*pointer)->next; b != NULL; b = b->next) { - if(strcmp(b->name, (*pointer)->name) == 0 && b->type == (unsigned)type) { - *pointer = b; - return b->u.generic; - } + if(strcmp(b->name, (*pointer)->name) == 0 && b->type == (unsigned)type) { + *pointer = b; + return b->u.generic; + } } return NULL; } -KRB5_LIB_FUNCTION const void * KRB5_LIB_CALL -_krb5_config_get (krb5_context context, - const krb5_config_section *c, - int type, - ...) +const void * +heim_config_get(heim_context context, + const heim_config_section *c, + int type, + ...) { const void *ret; va_list args; va_start(args, type); - ret = _krb5_config_vget (context, c, type, args); + ret = heim_config_vget(context, c, type, args); va_end(args); return ret; } -KRB5_LIB_FUNCTION const void * KRB5_LIB_CALL -_krb5_config_vget (krb5_context context, - const krb5_config_section *c, - int type, - va_list args) +const void * +heim_config_vget(heim_context context, + const heim_config_section *c, + int type, + va_list args) { - const krb5_config_binding *foo = NULL; + const heim_config_binding *foo = NULL; - return _krb5_config_vget_next (context, c, &foo, type, args); + return heim_config_vget_next(context, c, &foo, type, args); } /** @@ -869,19 +871,19 @@ _krb5_config_vget (krb5_context context, * * @return NULL if configuration list is not found, a list otherwise * - * @ingroup krb5_support + * @ingroup heim_support */ -KRB5_LIB_FUNCTION const krb5_config_binding * KRB5_LIB_CALL -krb5_config_get_list (krb5_context context, - const krb5_config_section *c, - ...) +const heim_config_binding * +heim_config_get_list(heim_context context, + const heim_config_section *c, + ...) { - const krb5_config_binding *ret; + const heim_config_binding *ret; va_list args; va_start(args, c); - ret = krb5_config_vget_list (context, c, args); + ret = heim_config_vget_list(context, c, args); va_end(args); return ret; } @@ -895,15 +897,15 @@ krb5_config_get_list (krb5_context context, * * @return NULL if configuration list is not found, a list otherwise * - * @ingroup krb5_support + * @ingroup heim_support */ -KRB5_LIB_FUNCTION const krb5_config_binding * KRB5_LIB_CALL -krb5_config_vget_list (krb5_context context, - const krb5_config_section *c, - va_list args) +const heim_config_binding * +heim_config_vget_list(heim_context context, + const heim_config_section *c, + va_list args) { - return _krb5_config_vget (context, c, krb5_config_list, args); + return heim_config_vget(context, c, heim_config_list, args); } /** @@ -918,25 +920,25 @@ krb5_config_vget_list (krb5_context context, * * @return NULL if configuration string not found, a string otherwise * - * @ingroup krb5_support + * @ingroup heim_support */ -KRB5_LIB_FUNCTION const char* KRB5_LIB_CALL -krb5_config_get_string (krb5_context context, - const krb5_config_section *c, - ...) +const char * +heim_config_get_string(heim_context context, + const heim_config_section *c, + ...) { const char *ret; va_list args; va_start(args, c); - ret = krb5_config_vget_string (context, c, args); + ret = heim_config_vget_string(context, c, args); va_end(args); return ret; } /** - * Like krb5_config_get_string(), but uses a va_list instead of ... + * Like heim_config_get_string(), but uses a va_list instead of ... * * @param context A Kerberos 5 context. * @param c a configuration section, or NULL to use the section from context @@ -944,19 +946,19 @@ krb5_config_get_string (krb5_context context, * * @return NULL if configuration string not found, a string otherwise * - * @ingroup krb5_support + * @ingroup heim_support */ -KRB5_LIB_FUNCTION const char* KRB5_LIB_CALL -krb5_config_vget_string (krb5_context context, - const krb5_config_section *c, - va_list args) +const char * +heim_config_vget_string(heim_context context, + const heim_config_section *c, + va_list args) { - return _krb5_config_vget (context, c, krb5_config_string, args); + return heim_config_vget(context, c, heim_config_string, args); } /** - * Like krb5_config_vget_string(), but instead of returning NULL, + * Like heim_config_vget_string(), but instead of returning NULL, * instead return a default value. * * @param context A Kerberos 5 context. @@ -967,25 +969,25 @@ krb5_config_vget_string (krb5_context context, * * @return a configuration string * - * @ingroup krb5_support + * @ingroup heim_support */ -KRB5_LIB_FUNCTION const char* KRB5_LIB_CALL -krb5_config_vget_string_default (krb5_context context, - const krb5_config_section *c, - const char *def_value, - va_list args) +const char * +heim_config_vget_string_default(heim_context context, + const heim_config_section *c, + const char *def_value, + va_list args) { const char *ret; - ret = krb5_config_vget_string (context, c, args); + ret = heim_config_vget_string(context, c, args); if (ret == NULL) - ret = def_value; + ret = def_value; return ret; } /** - * Like krb5_config_get_string(), but instead of returning NULL, + * Like heim_config_get_string(), but instead of returning NULL, * instead return a default value. * * @param context A Kerberos 5 context. @@ -996,20 +998,20 @@ krb5_config_vget_string_default (krb5_context context, * * @return a configuration string * - * @ingroup krb5_support + * @ingroup heim_support */ -KRB5_LIB_FUNCTION const char* KRB5_LIB_CALL -krb5_config_get_string_default (krb5_context context, - const krb5_config_section *c, - const char *def_value, - ...) +const char * +heim_config_get_string_default(heim_context context, + const heim_config_section *c, + const char *def_value, + ...) { const char *ret; va_list args; va_start(args, def_value); - ret = krb5_config_vget_string_default (context, c, def_value, args); + ret = heim_config_vget_string_default (context, c, def_value, args); va_end(args); return ret; } @@ -1060,7 +1062,7 @@ next_component_string(char * begin, const char * delims, char **state) /** * Get a list of configuration strings, free the result with - * krb5_config_free_strings(). + * heim_config_free_strings(). * * @param context A Kerberos 5 context. * @param c a configuration section, or NULL to use the section from context @@ -1068,55 +1070,55 @@ next_component_string(char * begin, const char * delims, char **state) * * @return TRUE or FALSE * - * @ingroup krb5_support + * @ingroup heim_support */ -KRB5_LIB_FUNCTION char ** KRB5_LIB_CALL -krb5_config_vget_strings(krb5_context context, - const krb5_config_section *c, - va_list args) +char ** +heim_config_vget_strings(heim_context context, + const heim_config_section *c, + va_list args) { char **strings = NULL; size_t nstr = 0; - const krb5_config_binding *b = NULL; + const heim_config_binding *b = NULL; const char *p; - while((p = _krb5_config_vget_next(context, c, &b, - krb5_config_string, args))) { - char *tmp = strdup(p); - char *pos = NULL; - char *s; - if(tmp == NULL) - goto cleanup; - s = next_component_string(tmp, " \t", &pos); - while(s){ - char **tmp2 = realloc(strings, (nstr + 1) * sizeof(*strings)); - if(tmp2 == NULL) { - free(tmp); - goto cleanup; - } - strings = tmp2; - strings[nstr] = strdup(s); - nstr++; - if(strings[nstr-1] == NULL) { - free(tmp); - goto cleanup; - } - s = next_component_string(NULL, " \t", &pos); - } - free(tmp); + while((p = heim_config_vget_next(context, c, &b, + heim_config_string, args))) { + char *tmp = strdup(p); + char *pos = NULL; + char *s; + if(tmp == NULL) + goto cleanup; + s = next_component_string(tmp, " \t", &pos); + while(s){ + char **tmp2 = realloc(strings, (nstr + 1) * sizeof(*strings)); + if(tmp2 == NULL) { + free(tmp); + goto cleanup; + } + strings = tmp2; + strings[nstr] = strdup(s); + nstr++; + if(strings[nstr-1] == NULL) { + free(tmp); + goto cleanup; + } + s = next_component_string(NULL, " \t", &pos); + } + free(tmp); } if(nstr){ - char **tmp = realloc(strings, (nstr + 1) * sizeof(*strings)); - if(tmp == NULL) - goto cleanup; - strings = tmp; - strings[nstr] = NULL; + char **tmp = realloc(strings, (nstr + 1) * sizeof(*strings)); + if(tmp == NULL) + goto cleanup; + strings = tmp; + strings[nstr] = NULL; } return strings; cleanup: while(nstr--) - free(strings[nstr]); + free(strings[nstr]); free(strings); return NULL; @@ -1124,7 +1126,7 @@ cleanup: /** * Get a list of configuration strings, free the result with - * krb5_config_free_strings(). + * heim_config_free_strings(). * * @param context A Kerberos 5 context. * @param c a configuration section, or NULL to use the section from context @@ -1132,44 +1134,45 @@ cleanup: * * @return TRUE or FALSE * - * @ingroup krb5_support + * @ingroup heim_support */ -KRB5_LIB_FUNCTION char** KRB5_LIB_CALL -krb5_config_get_strings(krb5_context context, - const krb5_config_section *c, - ...) +char ** +heim_config_get_strings(heim_context context, + const heim_config_section *c, + ...) { va_list ap; char **ret; va_start(ap, c); - ret = krb5_config_vget_strings(context, c, ap); + ret = heim_config_vget_strings(context, c, ap); va_end(ap); return ret; } /** - * Free the resulting strings from krb5_config-get_strings() and - * krb5_config_vget_strings(). + * Free the resulting strings from heim_config-get_strings() and + * heim_config_vget_strings(). * * @param strings strings to free * - * @ingroup krb5_support + * @ingroup heim_support */ -KRB5_LIB_FUNCTION void KRB5_LIB_CALL -krb5_config_free_strings(char **strings) +void +heim_config_free_strings(char **strings) { char **s = strings; - while(s && *s){ - free(*s); - s++; + + while (s && *s) { + free(*s); + s++; } free(strings); } /** - * Like krb5_config_get_bool_default() but with a va_list list of + * Like heim_config_get_bool_default() but with a va_list list of * configuration selection. * * Configuration value to a boolean value, where yes/true and any @@ -1183,27 +1186,26 @@ krb5_config_free_strings(char **strings) * * @return TRUE or FALSE * - * @ingroup krb5_support + * @ingroup heim_support */ -KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL -krb5_config_vget_bool_default (krb5_context context, - const krb5_config_section *c, - krb5_boolean def_value, - va_list args) +int +heim_config_vget_bool_default(heim_context context, + const heim_config_section *c, + int def_value, + va_list args) { const char *str; - str = krb5_config_vget_string (context, c, args); - if(str == NULL) - return def_value; - if(strcasecmp(str, "yes") == 0 || - strcasecmp(str, "true") == 0 || - atoi(str)) return TRUE; - return FALSE; + str = heim_config_vget_string(context, c, args); + if (str == NULL) + return def_value; + return !!(strcasecmp(str, "yes") == 0 || + strcasecmp(str, "true") == 0 || + atoi(str)); } /** - * krb5_config_get_bool() will convert the configuration + * heim_config_get_bool() will convert the configuration * option value to a boolean value, where yes/true and any non-zero * number means TRUE and other value is FALSE. * @@ -1213,19 +1215,19 @@ krb5_config_vget_bool_default (krb5_context context, * * @return TRUE or FALSE * - * @ingroup krb5_support + * @ingroup heim_support */ -KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL -krb5_config_vget_bool (krb5_context context, - const krb5_config_section *c, - va_list args) +int +heim_config_vget_bool(heim_context context, + const heim_config_section *c, + va_list args) { - return krb5_config_vget_bool_default (context, c, FALSE, args); + return heim_config_vget_bool_default(context, c, 0, args); } /** - * krb5_config_get_bool_default() will convert the configuration + * heim_config_get_bool_default() will convert the configuration * option value to a boolean value, where yes/true and any non-zero * number means TRUE and other value is FALSE. * @@ -1237,25 +1239,26 @@ krb5_config_vget_bool (krb5_context context, * * @return TRUE or FALSE * - * @ingroup krb5_support + * @ingroup heim_support */ -KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL -krb5_config_get_bool_default (krb5_context context, - const krb5_config_section *c, - krb5_boolean def_value, - ...) +int +heim_config_get_bool_default(heim_context context, + const heim_config_section *c, + int def_value, + ...) { va_list ap; - krb5_boolean ret; + int ret; + va_start(ap, def_value); - ret = krb5_config_vget_bool_default(context, c, def_value, ap); + ret = heim_config_vget_bool_default(context, c, def_value, ap); va_end(ap); return ret; } /** - * Like krb5_config_get_bool() but with a va_list list of + * Like heim_config_get_bool() but with a va_list list of * configuration selection. * * Configuration value to a boolean value, where yes/true and any @@ -1267,18 +1270,18 @@ krb5_config_get_bool_default (krb5_context context, * * @return TRUE or FALSE * - * @ingroup krb5_support + * @ingroup heim_support */ -KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL -krb5_config_get_bool (krb5_context context, - const krb5_config_section *c, - ...) +int +heim_config_get_bool(heim_context context, + const heim_config_section *c, + ...) { va_list ap; - krb5_boolean ret; + int ret; va_start(ap, c); - ret = krb5_config_vget_bool (context, c, ap); + ret = heim_config_vget_bool (context, c, ap); va_end(ap); return ret; } @@ -1286,7 +1289,7 @@ krb5_config_get_bool (krb5_context context, /** * Get the time from the configuration file using a relative time. * - * Like krb5_config_get_time_default() but with a va_list list of + * Like heim_config_get_time_default() but with a va_list list of * configuration selection. * * @param context A Kerberos 5 context. @@ -1297,24 +1300,21 @@ krb5_config_get_bool (krb5_context context, * * @return parsed the time (or def_value on parse error) * - * @ingroup krb5_support + * @ingroup heim_support */ -KRB5_LIB_FUNCTION int KRB5_LIB_CALL -krb5_config_vget_time_default (krb5_context context, - const krb5_config_section *c, - int def_value, - va_list args) +time_t +heim_config_vget_time_default(heim_context context, + const heim_config_section *c, + int def_value, + va_list args) { const char *str; - krb5_deltat t; + time_t t = -1; - str = krb5_config_vget_string (context, c, args); - if(str == NULL) - return def_value; - if (krb5_string_to_deltat(str, &t)) - return def_value; - return t; + if ((str = heim_config_vget_string(context, c, args))) + t = parse_time(str, "s"); + return t != -1 ? t : def_value; } /** @@ -1326,15 +1326,15 @@ krb5_config_vget_time_default (krb5_context context, * * @return parsed the time or -1 on error * - * @ingroup krb5_support + * @ingroup heim_support */ -KRB5_LIB_FUNCTION int KRB5_LIB_CALL -krb5_config_vget_time (krb5_context context, - const krb5_config_section *c, - va_list args) +time_t +heim_config_vget_time(heim_context context, + const heim_config_section *c, + va_list args) { - return krb5_config_vget_time_default (context, c, -1, args); + return heim_config_vget_time_default(context, c, -1, args); } /** @@ -1348,19 +1348,20 @@ krb5_config_vget_time (krb5_context context, * * @return parsed the time (or def_value on parse error) * - * @ingroup krb5_support + * @ingroup heim_support */ -KRB5_LIB_FUNCTION int KRB5_LIB_CALL -krb5_config_get_time_default (krb5_context context, - const krb5_config_section *c, - int def_value, - ...) +time_t +heim_config_get_time_default(heim_context context, + const heim_config_section *c, + int def_value, + ...) { va_list ap; - int ret; + time_t ret; + va_start(ap, def_value); - ret = krb5_config_vget_time_default(context, c, def_value, ap); + ret = heim_config_vget_time_default(context, c, def_value, ap); va_end(ap); return ret; } @@ -1374,110 +1375,101 @@ krb5_config_get_time_default (krb5_context context, * * @return parsed the time or -1 on error * - * @ingroup krb5_support + * @ingroup heim_support */ -KRB5_LIB_FUNCTION int KRB5_LIB_CALL -krb5_config_get_time (krb5_context context, - const krb5_config_section *c, - ...) +time_t +heim_config_get_time(heim_context context, + const heim_config_section *c, + ...) { va_list ap; int ret; va_start(ap, c); - ret = krb5_config_vget_time (context, c, ap); + ret = heim_config_vget_time(context, c, ap); va_end(ap); return ret; } -KRB5_LIB_FUNCTION int KRB5_LIB_CALL -krb5_config_vget_int_default (krb5_context context, - const krb5_config_section *c, - int def_value, - va_list args) +int +heim_config_vget_int_default(heim_context context, + const heim_config_section *c, + int def_value, + va_list args) { const char *str; - str = krb5_config_vget_string (context, c, args); + str = heim_config_vget_string (context, c, args); if(str == NULL) - return def_value; + return def_value; else { - char *endptr; - long l; - l = strtol(str, &endptr, 0); - if (endptr == str) - return def_value; - else - return l; + char *endptr; + long l; + l = strtol(str, &endptr, 0); + if (endptr == str) + return def_value; + else + return l; } } -KRB5_LIB_FUNCTION int KRB5_LIB_CALL -krb5_config_vget_int (krb5_context context, - const krb5_config_section *c, - va_list args) +int +heim_config_vget_int(heim_context context, + const heim_config_section *c, + va_list args) { - return krb5_config_vget_int_default (context, c, -1, args); + return heim_config_vget_int_default(context, c, -1, args); } -KRB5_LIB_FUNCTION int KRB5_LIB_CALL -krb5_config_get_int_default (krb5_context context, - const krb5_config_section *c, - int def_value, - ...) +int +heim_config_get_int_default(heim_context context, + const heim_config_section *c, + int def_value, + ...) { va_list ap; int ret; + va_start(ap, def_value); - ret = krb5_config_vget_int_default(context, c, def_value, ap); + ret = heim_config_vget_int_default(context, c, def_value, ap); va_end(ap); return ret; } -KRB5_LIB_FUNCTION int KRB5_LIB_CALL -krb5_config_get_int (krb5_context context, - const krb5_config_section *c, - ...) +int +heim_config_get_int(heim_context context, + const heim_config_section *c, + ...) { va_list ap; int ret; va_start(ap, c); - ret = krb5_config_vget_int (context, c, ap); + ret = heim_config_vget_int (context, c, ap); va_end(ap); return ret; } - #ifndef HEIMDAL_SMALLER - -/** - * Deprecated: configuration files are not strings - * - * @ingroup krb5_deprecated - */ - -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_config_parse_string_multi(krb5_context context, - const char *string, - krb5_config_section **res) - KRB5_DEPRECATED_FUNCTION("Use X instead") +heim_error_code +heim_config_parse_string_multi(heim_context context, + const char *string, + heim_config_section **res) { const char *str; unsigned lineno = 0; - krb5_error_code ret; + heim_error_code ret; struct fileptr f; f.context = context; f.f = NULL; f.s = string; - ret = krb5_config_parse_debug (&f, res, &lineno, &str); + ret = heim_config_parse_debug(&f, res, &lineno, &str); if (ret) { - krb5_set_error_message (context, ret, "%s:%u: %s", - "", lineno, str); - return ret; + heim_set_error_message(context, ret, "%s:%u: %s", + "", lineno, str); + return ret; } return 0; } - #endif diff --git a/lib/base/config_reg.c b/lib/base/config_reg.c index 6ee6a6496..78234ac04 100644 --- a/lib/base/config_reg.c +++ b/lib/base/config_reg.c @@ -29,7 +29,7 @@ * **********************************************************************/ -#include "krb5_locl.h" +#include "baselocl.h" #ifndef _WIN32 #error config_reg.c is only for Windows @@ -41,9 +41,6 @@ #define MAX_DWORD 0xFFFFFFFF #endif -#define REGPATH_KERBEROS "SOFTWARE\\Kerberos" -#define REGPATH_HEIMDAL "SOFTWARE\\Heimdal" - /** * Store a string as a registry value of the specified type * @@ -83,14 +80,14 @@ * * @retval 0 if success or non-zero on error. * If non-zero is returned, an error message has been set using - * krb5_set_error_message(). + * heim_set_error_message(). * */ -KRB5_LIB_FUNCTION int KRB5_LIB_CALL -_krb5_store_string_to_reg_value(krb5_context context, - HKEY key, const char * valuename, - DWORD type, const char *data, DWORD cb_data, - const char * separator) +int +heim_store_string_to_reg_value(heim_context context, + HKEY key, const char *valuename, + DWORD type, const char *data, DWORD cb_data, + const char *separator) { LONG rcode; DWORD dwData; @@ -100,7 +97,7 @@ _krb5_store_string_to_reg_value(krb5_context context, if (data == NULL) { if (context) - krb5_set_error_message(context, 0, + heim_set_error_message(context, 0, "'data' must not be NULL"); return -1; } @@ -113,7 +110,7 @@ _krb5_store_string_to_reg_value(krb5_context context, cb_data >= sizeof(static_buffer)) { if (context) - krb5_set_error_message(context, 0, "cb_data too big"); + heim_set_error_message(context, 0, "cb_data too big"); return -1; } else if (data[cb_data-1] != '\0') @@ -146,7 +143,7 @@ _krb5_store_string_to_reg_value(krb5_context context, if (rcode) { if (context) - krb5_set_error_message(context, 0, + heim_set_error_message(context, 0, "Unexpected error when setting registry value %s gle 0x%x", valuename, GetLastError()); @@ -171,7 +168,7 @@ _krb5_store_string_to_reg_value(krb5_context context, if (rcode) { if (context) - krb5_set_error_message(context, 0, + heim_set_error_message(context, 0, "Unexpected error when setting registry value %s gle 0x%x", valuename, GetLastError()); @@ -183,7 +180,7 @@ _krb5_store_string_to_reg_value(krb5_context context, if ( !StrToIntExA( data, STIF_SUPPORT_HEX, &dwData) ) { if (context) - krb5_set_error_message(context, 0, + heim_set_error_message(context, 0, "Unexpected error when parsing %s as number gle 0x%x", data, GetLastError()); @@ -193,7 +190,7 @@ _krb5_store_string_to_reg_value(krb5_context context, if (rcode) { if (context) - krb5_set_error_message(context, 0, + heim_set_error_message(context, 0, "Unexpected error when setting registry value %s gle 0x%x", valuename, GetLastError()); @@ -210,15 +207,15 @@ _krb5_store_string_to_reg_value(krb5_context context, /** * Parse a registry value as a string * - * @see _krb5_parse_reg_value_as_multi_string() + * @see heim_parse_reg_value_as_multi_string() */ -KRB5_LIB_FUNCTION char * KRB5_LIB_CALL -_krb5_parse_reg_value_as_string(krb5_context context, - HKEY key, const char * valuename, - DWORD type, DWORD cb_data) +char * +heim_parse_reg_value_as_string(heim_context context, + HKEY key, const char * valuename, + DWORD type, DWORD cb_data) { - return _krb5_parse_reg_value_as_multi_string(context, key, valuename, - type, cb_data, " "); + return heim_parse_reg_value_as_multi_string(context, key, valuename, + type, cb_data, " "); } /** @@ -249,12 +246,12 @@ _krb5_parse_reg_value_as_string(krb5_context context, * * @retval The registry value string, or NULL if there was an error. * If NULL is returned, an error message has been set using - * krb5_set_error_message(). + * heim_set_error_message(). */ -KRB5_LIB_FUNCTION char * KRB5_LIB_CALL -_krb5_parse_reg_value_as_multi_string(krb5_context context, - HKEY key, const char * valuename, - DWORD type, DWORD cb_data, char *separator) +char * +heim_parse_reg_value_as_multi_string(heim_context context, + HKEY key, const char * valuename, + DWORD type, DWORD cb_data, char *separator) { LONG rcode = ERROR_MORE_DATA; @@ -293,7 +290,7 @@ _krb5_parse_reg_value_as_multi_string(krb5_context context, case REG_DWORD: if (cb_data != sizeof(DWORD)) { if (context) - krb5_set_error_message(context, 0, + heim_set_error_message(context, 0, "Unexpected size while reading registry value %s", valuename); return NULL; @@ -322,7 +319,7 @@ _krb5_parse_reg_value_as_multi_string(krb5_context context, default: if (context) - krb5_set_error_message(context, 0, + heim_set_error_message(context, 0, "Unexpected type while reading registry value %s", valuename); return NULL; @@ -347,7 +344,7 @@ _krb5_parse_reg_value_as_multi_string(krb5_context context, * its value. Ideally we would retry the query in a loop. */ if (context) - krb5_set_error_message(context, 0, + heim_set_error_message(context, 0, "Unexpected error while reading registry value %s", valuename); goto done; @@ -355,7 +352,7 @@ _krb5_parse_reg_value_as_multi_string(krb5_context context, if (cb_data > cb_alloc || cb_data == 0) { if (context) - krb5_set_error_message(context, 0, + heim_set_error_message(context, 0, "Unexpected size while reading registry value %s", valuename); goto done; @@ -405,7 +402,7 @@ have_data: ret_string = strdup(expsz); } else { if (context) - krb5_set_error_message(context, 0, + heim_set_error_message(context, 0, "Overflow while expanding environment strings " "for registry value %s", valuename); } @@ -441,7 +438,7 @@ have_data: default: if (context) - krb5_set_error_message(context, 0, + heim_set_error_message(context, 0, "Unexpected type while reading registry value %s", valuename); } @@ -458,21 +455,21 @@ done: * * @see parse_reg_value_as_string() */ -static krb5_error_code -parse_reg_value(krb5_context context, +static heim_error_code +parse_reg_value(heim_context context, HKEY key, const char * valuename, - DWORD type, DWORD cbdata, krb5_config_section ** parent) + DWORD type, DWORD cbdata, heim_config_section ** parent) { char *reg_string = NULL; - krb5_config_section *value; - krb5_error_code code = 0; + heim_config_section *value; + heim_error_code code = 0; - reg_string = _krb5_parse_reg_value_as_string(context, key, valuename, type, cbdata); + reg_string = heim_parse_reg_value_as_string(context, key, valuename, type, cbdata); if (reg_string == NULL) - return KRB5_CONFIG_BADFORMAT; + return HEIM_ERR_CONFIG_BADFORMAT; - value = _krb5_config_get_entry(parent, valuename, krb5_config_string); + value = heim_config_get_entry(parent, valuename, heim_config_string); if (value == NULL) { code = ENOMEM; goto done; @@ -491,10 +488,10 @@ done: return code; } -static krb5_error_code -parse_reg_values(krb5_context context, +static heim_error_code +parse_reg_values(heim_context context, HKEY key, - krb5_config_section ** parent) + heim_config_section ** parent) { DWORD index; LONG rcode; @@ -504,7 +501,7 @@ parse_reg_values(krb5_context context, DWORD cch = sizeof(name)/sizeof(name[0]); DWORD type; DWORD cbdata = 0; - krb5_error_code code; + heim_error_code code; rcode = RegEnumValue(key, index, name, &cch, NULL, &type, NULL, &cbdata); @@ -522,10 +519,10 @@ parse_reg_values(krb5_context context, return 0; } -static krb5_error_code -parse_reg_subkeys(krb5_context context, +static heim_error_code +parse_reg_subkeys(heim_context context, HKEY key, - krb5_config_section ** parent) + heim_config_section ** parent) { DWORD index; LONG rcode; @@ -534,8 +531,8 @@ parse_reg_subkeys(krb5_context context, HKEY subkey = NULL; char name[256]; DWORD cch = sizeof(name)/sizeof(name[0]); - krb5_config_section *section = NULL; - krb5_error_code code; + heim_config_section *section = NULL; + heim_error_code code; rcode = RegEnumKeyEx(key, index, name, &cch, NULL, NULL, NULL, NULL); if (rcode != ERROR_SUCCESS) @@ -545,7 +542,7 @@ parse_reg_subkeys(krb5_context context, if (rcode != ERROR_SUCCESS) continue; - section = _krb5_config_get_entry(parent, name, krb5_config_list); + section = heim_config_get_entry(parent, name, heim_config_list); if (section == NULL) { RegCloseKey(subkey); return ENOMEM; @@ -569,17 +566,17 @@ parse_reg_subkeys(krb5_context context, return 0; } -static krb5_error_code -parse_reg_root(krb5_context context, +static heim_error_code +parse_reg_root(heim_context context, HKEY key, - krb5_config_section ** parent) + heim_config_section ** parent) { - krb5_config_section *libdefaults = NULL; - krb5_error_code code = 0; + heim_config_section *libdefaults = NULL; + heim_error_code code = 0; - libdefaults = _krb5_config_get_entry(parent, "libdefaults", krb5_config_list); + libdefaults = heim_config_get_entry(parent, "libdefaults", heim_config_list); if (libdefaults == NULL) - return krb5_enomem(context); + return heim_enomem(context); code = parse_reg_values(context, key, &libdefaults->u.list); if (code) @@ -588,15 +585,15 @@ parse_reg_root(krb5_context context, return parse_reg_subkeys(context, key, parent); } -static krb5_error_code -load_config_from_regpath(krb5_context context, +static heim_error_code +load_config_from_regpath(heim_context context, HKEY hk_root, const char* key_path, - krb5_config_section ** res) + heim_config_section ** res) { HKEY key = NULL; LONG rcode; - krb5_error_code code = 0; + heim_error_code code = 0; rcode = RegOpenKeyEx(hk_root, key_path, 0, KEY_READ, &key); if (rcode == ERROR_SUCCESS) { @@ -620,30 +617,43 @@ load_config_from_regpath(krb5_context context, * * @see parse_reg_value() for details about how each type of value is handled. */ -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -_krb5_load_config_from_registry(krb5_context context, - krb5_config_section ** res) +heim_error_code +heim_load_config_from_registry(heim_context context, + const char *path0, + const char *path1, + heim_config_section **res) { - krb5_error_code code; + heim_error_code code; - code = load_config_from_regpath(context, HKEY_LOCAL_MACHINE, - REGPATH_KERBEROS, res); - if (code) - return code; + if (!path0 && !path1) + return EINVAL; - code = load_config_from_regpath(context, HKEY_LOCAL_MACHINE, - REGPATH_HEIMDAL, res); - if (code) - return code; + if (path0) { + code = load_config_from_regpath(context, HKEY_LOCAL_MACHINE, + path0, res); + if (code) + return code; + } - code = load_config_from_regpath(context, HKEY_CURRENT_USER, - REGPATH_KERBEROS, res); - if (code) - return code; + if (path1) { + code = load_config_from_regpath(context, HKEY_LOCAL_MACHINE, + path1, res); + if (code) + return code; + } - code = load_config_from_regpath(context, HKEY_CURRENT_USER, - REGPATH_HEIMDAL, res); - if (code) - return code; + if (path0) { + code = load_config_from_regpath(context, HKEY_CURRENT_USER, + path0, res); + if (code) + return code; + } + + if (path0) { + code = load_config_from_regpath(context, HKEY_CURRENT_USER, + path1, res); + if (code) + return code; + } return 0; } diff --git a/lib/base/context.c b/lib/base/context.c new file mode 100644 index 000000000..1feabd8c6 --- /dev/null +++ b/lib/base/context.c @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2020 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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 "baselocl.h" + +#undef __attribute__ +#define __attribute__(X) + +struct heim_context_s { + heim_log_facility *warn_dest; /* XXX Move warn.c into lib/base as well */ + heim_log_facility *debug_dest; + char *time_fmt; + unsigned int log_utc:1; + unsigned int homedir_access:1; + heim_err_cb_context error_context; + heim_err_cb_clear_msg clear_error_message; + heim_err_cb_free_msg free_error_message; + heim_err_cb_get_msg get_error_message; + heim_err_cb_set_msg set_error_message; + const char *unknown_error; + const char *success; +}; + +heim_context +heim_context_init(void) +{ + heim_context context; + + if ((context = calloc(1, sizeof(*context))) == NULL) + return NULL; + + context->log_utc = 1; + context->clear_error_message = NULL; + context->free_error_message = NULL; + context->get_error_message = NULL; + context->set_error_message = NULL; + context->error_context = NULL; + context->unknown_error = "Unknown error"; + context->success = "Success"; + context->debug_dest = NULL; + context->warn_dest = NULL; + context->time_fmt = NULL; + return context; +} + +void +heim_context_free(heim_context *contextp) +{ + heim_context context = *contextp; + + *contextp = NULL; + if (!context) + return; + heim_closelog(context, context->debug_dest); + heim_closelog(context, context->warn_dest); + free(context->time_fmt); + free(context); +} + +void +heim_context_set_msg_cb(heim_context context, + heim_err_cb_context cb_context, + heim_err_cb_clear_msg cb_clear_msg, + heim_err_cb_free_msg cb_free_msg, + heim_err_cb_get_msg cb_get_msg, + heim_err_cb_set_msg cb_set_msg) +{ + context->error_context = cb_context; + context->clear_error_message = cb_clear_msg; + context->free_error_message = cb_free_msg; + context->set_error_message = cb_set_msg; + context->get_error_message = cb_get_msg; +} + +heim_error_code +heim_context_set_time_fmt(heim_context context, const char *fmt) +{ + char *s; + + if (fmt == NULL) { + free(context->time_fmt); + return 0; + } + if ((s = strdup(fmt)) == NULL) + return heim_enomem(context); + free(context->time_fmt); + context->time_fmt = s; + return 0; +} + +const char * +heim_context_get_time_fmt(heim_context context) +{ + return context->time_fmt ? context->time_fmt : "%Y-%m-%dT%H:%M:%S"; +} + +unsigned int +heim_context_set_log_utc(heim_context context, unsigned int log_utc) +{ + unsigned int old = context->log_utc; + + context->log_utc = log_utc ? 1 : 0; + return old; +} + +int +heim_context_get_log_utc(heim_context context) +{ + return context->log_utc; +} + +unsigned int +heim_context_set_homedir_access(heim_context context, unsigned int homedir_access) +{ + unsigned int old = context->homedir_access; + + context->homedir_access = homedir_access ? 1 : 0; + return old; +} + +unsigned int +heim_context_get_homedir_access(heim_context context) +{ + return context->homedir_access; +} + +void +heim_clear_error_message(heim_context context) +{ + if (context != NULL && context->clear_error_message != NULL) + context->clear_error_message(context->error_context); +} + +void +heim_free_error_message(heim_context context, const char *msg) +{ + if (context != NULL && context->free_error_message != NULL && + msg != context->unknown_error && msg != context->success) + context->free_error_message(context->error_context, msg); +} + +const char * +heim_get_error_message(heim_context context, heim_error_code ret) +{ + if (context != NULL && context->get_error_message != NULL) + return context->get_error_message(context->error_context, ret); + if (ret) + return context->unknown_error; + return context->success; +} + +void +heim_set_error_message(heim_context context, heim_error_code ret, + const char *fmt, ...) + __attribute__ ((__format__ (__printf__, 3, 4))) +{ + va_list ap; + + va_start(ap, fmt); + heim_vset_error_message(context, ret, fmt, ap); + va_end(ap); +} + +void +heim_vset_error_message(heim_context context, heim_error_code ret, + const char *fmt, va_list args) + __attribute__ ((__format__ (__printf__, 3, 0))) +{ + if (context != NULL && context->set_error_message != NULL) + context->set_error_message(context->error_context, ret, fmt, args); +} + +heim_error_code +heim_enomem(heim_context context) +{ + heim_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; +} + +heim_log_facility * +heim_get_warn_dest(heim_context context) +{ + return context->warn_dest; +} + +heim_log_facility * +heim_get_debug_dest(heim_context context) +{ + return context->debug_dest; +} + +heim_error_code +heim_set_warn_dest(heim_context context, heim_log_facility *fac) +{ + context->warn_dest = fac; + return 0; +} + +heim_error_code +heim_set_debug_dest(heim_context context, heim_log_facility *fac) +{ + context->debug_dest = fac; + return 0; +} diff --git a/lib/base/expand_path.c b/lib/base/expand_path.c index 1e70ec91a..e934b7b30 100644 --- a/lib/base/expand_path.c +++ b/lib/base/expand_path.c @@ -1,6 +1,6 @@ /*********************************************************************** - * Copyright (c) 2009, Secure Endpoints Inc. + * Copyright (c) 2009-2020, Secure Endpoints Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,7 +30,7 @@ * **********************************************************************/ -#include "krb5_locl.h" +#include "baselocl.h" #include @@ -51,35 +51,35 @@ typedef int PTYPE; * temporary directory until the user profile is loaded. In addition, * the returned path may or may not exist. */ -static krb5_error_code -_expand_temp_folder(krb5_context context, PTYPE param, const char *postfix, - const char *arg, char **ret) +static heim_error_code +expand_temp_folder(heim_context context, PTYPE param, const char *postfix, + const char *arg, char **ret) { TCHAR tpath[MAX_PATH]; size_t len; if (!GetTempPath(sizeof(tpath)/sizeof(tpath[0]), tpath)) { - if (context) - krb5_set_error_message(context, EINVAL, - "Failed to get temporary path (GLE=%d)", - GetLastError()); - return EINVAL; + if (context) + heim_set_error_message(context, EINVAL, + "Failed to get temporary path (GLE=%d)", + GetLastError()); + return EINVAL; } len = strlen(tpath); if (len > 0 && tpath[len - 1] == '\\') - tpath[len - 1] = '\0'; + tpath[len - 1] = '\0'; *ret = strdup(tpath); if (*ret == NULL) - return krb5_enomem(context); + return heim_enomem(context); return 0; } -extern HINSTANCE _krb5_hInstance; +EXTERN_C IMAGE_DOS_HEADER __ImageBase; /* * Expand a %{BINDIR} token @@ -87,40 +87,41 @@ extern HINSTANCE _krb5_hInstance; * This is also used to expand a few other tokens on Windows, since * most of the executable binaries end up in the same directory. The * "bin" directory is considered to be the directory in which the - * krb5.dll is located. + * containing DLL is located. */ -static krb5_error_code -_expand_bin_dir(krb5_context context, PTYPE param, const char *postfix, - const char *arg, char **ret) +static heim_error_code +expand_bin_dir(heim_context context, PTYPE param, const char *postfix, + const char *arg, char **ret) { TCHAR path[MAX_PATH]; TCHAR *lastSlash; DWORD nc; - nc = GetModuleFileName(_krb5_hInstance, path, sizeof(path)/sizeof(path[0])); + nc = GetModuleFileName((HINSTANCE)&__ImageBase, path, + sizeof(path)/sizeof(path[0])); if (nc == 0 || - nc == sizeof(path)/sizeof(path[0])) { - return EINVAL; + nc == sizeof(path)/sizeof(path[0])) { + return EINVAL; } lastSlash = strrchr(path, '\\'); if (lastSlash != NULL) { - TCHAR *fslash = strrchr(lastSlash, '/'); + TCHAR *fslash = strrchr(lastSlash, '/'); - if (fslash != NULL) - lastSlash = fslash; + if (fslash != NULL) + lastSlash = fslash; - *lastSlash = '\0'; + *lastSlash = '\0'; } if (postfix) { - if (strlcat(path, postfix, sizeof(path)/sizeof(path[0])) >= sizeof(path)/sizeof(path[0])) - return EINVAL; + if (strlcat(path, postfix, sizeof(path)/sizeof(path[0])) >= sizeof(path)/sizeof(path[0])) + return EINVAL; } *ret = strdup(path); if (*ret == NULL) - return krb5_enomem(context); + return heim_enomem(context); return 0; } @@ -140,9 +141,9 @@ _expand_bin_dir(krb5_context context, PTYPE param, const char *postfix, * SecurityIdentification level the call will fail. * */ -static krb5_error_code -_expand_userid(krb5_context context, PTYPE param, const char *postfix, - const char *arg, char **ret) +static heim_error_code +expand_userid(heim_context context, PTYPE param, const char *postfix, + const char *arg, char **ret) { int rv = EINVAL; HANDLE hThread = NULL; @@ -154,83 +155,83 @@ _expand_userid(krb5_context context, PTYPE param, const char *postfix, hThread = GetCurrentThread(); if (!OpenThreadToken(hThread, TOKEN_QUERY, - FALSE, /* Open the thread token as the - current thread user. */ - &hToken)) { + FALSE, /* Open the thread token as the + current thread user. */ + &hToken)) { - DWORD le = GetLastError(); + DWORD le = GetLastError(); - if (le == ERROR_NO_TOKEN) { - HANDLE hProcess = GetCurrentProcess(); + if (le == ERROR_NO_TOKEN) { + HANDLE hProcess = GetCurrentProcess(); - le = 0; - if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) - le = GetLastError(); - } + le = 0; + if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) + le = GetLastError(); + } - if (le != 0) { - if (context) - krb5_set_error_message(context, rv, - "Can't open thread token (GLE=%d)", le); - goto _exit; - } + if (le != 0) { + if (context) + heim_set_error_message(context, rv, + "Can't open thread token (GLE=%d)", le); + goto _exit; + } } if (!GetTokenInformation(hToken, TokenOwner, NULL, 0, &len)) { - if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { - if (context) - krb5_set_error_message(context, rv, - "Unexpected error reading token information (GLE=%d)", - GetLastError()); - goto _exit; - } + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + if (context) + heim_set_error_message(context, rv, + "Unexpected error reading token information (GLE=%d)", + GetLastError()); + goto _exit; + } - if (len == 0) { - if (context) - krb5_set_error_message(context, rv, - "GetTokenInformation() returned truncated buffer"); - goto _exit; - } + if (len == 0) { + if (context) + heim_set_error_message(context, rv, + "GetTokenInformation() returned truncated buffer"); + goto _exit; + } - pOwner = malloc(len); - if (pOwner == NULL) { - if (context) - krb5_set_error_message(context, rv, "Out of memory"); - goto _exit; - } + pOwner = malloc(len); + if (pOwner == NULL) { + if (context) + heim_set_error_message(context, rv, "Out of memory"); + goto _exit; + } } else { - if (context) - krb5_set_error_message(context, rv, "GetTokenInformation() returned truncated buffer"); - goto _exit; + if (context) + heim_set_error_message(context, rv, "GetTokenInformation() returned truncated buffer"); + goto _exit; } if (!GetTokenInformation(hToken, TokenOwner, pOwner, len, &len)) { - if (context) - krb5_set_error_message(context, rv, "GetTokenInformation() failed. GLE=%d", GetLastError()); - goto _exit; + if (context) + heim_set_error_message(context, rv, "GetTokenInformation() failed. GLE=%d", GetLastError()); + goto _exit; } if (!ConvertSidToStringSid(pOwner->Owner, &strSid)) { - if (context) - krb5_set_error_message(context, rv, "Can't convert SID to string. GLE=%d", GetLastError()); - goto _exit; + if (context) + heim_set_error_message(context, rv, "Can't convert SID to string. GLE=%d", GetLastError()); + goto _exit; } *ret = strdup(strSid); if (*ret == NULL && context) - krb5_set_error_message(context, rv, "Out of memory"); + heim_set_error_message(context, rv, "Out of memory"); rv = 0; _exit: if (hToken != NULL) - CloseHandle(hToken); + CloseHandle(hToken); if (pOwner != NULL) - free (pOwner); + free (pOwner); if (strSid != NULL) - LocalFree(strSid); + LocalFree(strSid); return rv; } @@ -239,129 +240,129 @@ _expand_userid(krb5_context context, PTYPE param, const char *postfix, * Expand a folder identified by a CSIDL */ -static krb5_error_code -_expand_csidl(krb5_context context, PTYPE folder, const char *postfix, - const char *arg, char **ret) +static heim_error_code +expand_csidl(heim_context context, PTYPE folder, const char *postfix, + const char *arg, char **ret) { TCHAR path[MAX_PATH]; size_t len; if (SHGetFolderPath(NULL, folder, NULL, SHGFP_TYPE_CURRENT, path) != S_OK) { - if (context) - krb5_set_error_message(context, EINVAL, "Unable to determine folder path"); - return EINVAL; + if (context) + heim_set_error_message(context, EINVAL, "Unable to determine folder path"); + return EINVAL; } len = strlen(path); if (len > 0 && path[len - 1] == '\\') - path[len - 1] = '\0'; + path[len - 1] = '\0'; if (postfix && - strlcat(path, postfix, sizeof(path)/sizeof(path[0])) >= sizeof(path)/sizeof(path[0])) - return krb5_enomem(context); + strlcat(path, postfix, sizeof(path)/sizeof(path[0])) >= sizeof(path)/sizeof(path[0])) + return heim_enomem(context); *ret = strdup(path); if (*ret == NULL) - return krb5_enomem(context); + return heim_enomem(context); return 0; } #else -static krb5_error_code -_expand_path(krb5_context context, PTYPE param, const char *postfix, - const char *arg, char **ret) +static heim_error_code +expand_path(heim_context context, PTYPE param, const char *postfix, + const char *arg, char **ret) { *ret = strdup(postfix); if (*ret == NULL) - return krb5_enomem(context); + return heim_enomem(context); return 0; } -static krb5_error_code -_expand_temp_folder(krb5_context context, PTYPE param, const char *postfix, - const char *arg, char **ret) +static heim_error_code +expand_temp_folder(heim_context context, PTYPE param, const char *postfix, + const char *arg, char **ret) { const char *p = NULL; p = secure_getenv("TEMP"); if (p) - *ret = strdup(p); + *ret = strdup(p); else - *ret = strdup("/tmp"); + *ret = strdup("/tmp"); if (*ret == NULL) - return krb5_enomem(context); + return heim_enomem(context); return 0; } -static krb5_error_code -_expand_userid(krb5_context context, PTYPE param, const char *postfix, - const char *arg, char **str) +static heim_error_code +expand_userid(heim_context context, PTYPE param, const char *postfix, + const char *arg, char **str) { int ret = asprintf(str, "%ld", (unsigned long)getuid()); if (ret < 0 || *str == NULL) - return krb5_enomem(context); + return heim_enomem(context); return 0; } -static krb5_error_code -_expand_euid(krb5_context context, PTYPE param, const char *postfix, - const char *arg, char **str) +static heim_error_code +expand_euid(heim_context context, PTYPE param, const char *postfix, + const char *arg, char **str) { int ret = asprintf(str, "%ld", (unsigned long)geteuid()); if (ret < 0 || *str == NULL) - return krb5_enomem(context); + return heim_enomem(context); return 0; } #endif /* _WIN32 */ -static krb5_error_code -_expand_username(krb5_context context, PTYPE param, const char *postfix, - const char *arg, char **str) +static heim_error_code +expand_username(heim_context context, PTYPE param, const char *postfix, + const char *arg, char **str) { char user[128]; const char *username = roken_get_username(user, sizeof(user)); if (username == NULL) { - krb5_set_error_message(context, ENOTTY, - N_("unable to figure out current principal", - "")); - return ENOTTY; /* XXX */ + heim_set_error_message(context, ENOTTY, + N_("unable to figure out current principal", + "")); + return ENOTTY; /* XXX */ } *str = strdup(username); if (*str == NULL) - return krb5_enomem(context); + return heim_enomem(context); return 0; } -static krb5_error_code -_expand_loginname(krb5_context context, PTYPE param, const char *postfix, - const char *arg, char **str) +static heim_error_code +expand_loginname(heim_context context, PTYPE param, const char *postfix, + const char *arg, char **str) { char user[128]; const char *username = roken_get_loginname(user, sizeof(user)); if (username == NULL) { - krb5_set_error_message(context, ENOTTY, - N_("unable to figure out current principal", - "")); - return ENOTTY; /* XXX */ + heim_set_error_message(context, ENOTTY, + N_("unable to figure out current principal", + "")); + return ENOTTY; /* XXX */ } *str = strdup(username); if (*str == NULL) - return krb5_enomem(context); + return heim_enomem(context); return 0; } -static krb5_error_code -_expand_strftime(krb5_context context, PTYPE param, const char *postfix, - const char *arg, char **ret) +static heim_error_code +expand_strftime(heim_context context, PTYPE param, const char *postfix, + const char *arg, char **ret) { size_t len; time_t t; @@ -370,7 +371,7 @@ _expand_strftime(krb5_context context, PTYPE param, const char *postfix, t = time(NULL); len = strftime(buf, sizeof(buf), arg, localtime(&t)); if (len == 0 || len >= sizeof(buf)) - return ENOMEM; + return ENOMEM; *ret = strdup(buf); return 0; } @@ -379,12 +380,12 @@ _expand_strftime(krb5_context context, PTYPE param, const char *postfix, * Expand an extra token */ -static krb5_error_code -_expand_extra_token(krb5_context context, const char *value, char **ret) +static heim_error_code +expand_extra_token(heim_context context, const char *value, char **ret) { *ret = strdup(value); if (*ret == NULL) - return krb5_enomem(context); + return heim_enomem(context); return 0; } @@ -394,13 +395,13 @@ _expand_extra_token(krb5_context context, const char *value, char **ret) * The expansion of a %{null} token is always the empty string. */ -static krb5_error_code -_expand_null(krb5_context context, PTYPE param, const char *postfix, - const char *arg, char **ret) +static heim_error_code +expand_null(heim_context context, PTYPE param, const char *postfix, + const char *arg, char **ret) { *ret = strdup(""); if (*ret == NULL) - return krb5_enomem(context); + return heim_enomem(context); return 0; } @@ -414,14 +415,14 @@ static const struct { PTYPE param; const char * postfix; - int (*exp_func)(krb5_context, PTYPE, const char *, const char *, char **); + int (*exp_func)(heim_context, PTYPE, const char *, const char *, char **); #define SPECIALP(f, P) FTYPE_SPECIAL, 0, P, f #define SPECIAL(f) SPECIALP(f, NULL) } tokens[] = { #ifdef _WIN32 -#define CSIDLP(C,P) FTYPE_CSIDL, C, P, _expand_csidl +#define CSIDLP(C,P) FTYPE_CSIDL, C, P, expand_csidl #define CSIDL(C) CSIDLP(C, NULL) {"APPDATA", CSIDL(CSIDL_APPDATA)}, /* Roaming application data (for current user) */ @@ -431,36 +432,36 @@ static const struct { {"WINDOWS", CSIDL(CSIDL_WINDOWS)}, /* Windows folder */ {"USERCONFIG", CSIDLP(CSIDL_APPDATA, "\\" PACKAGE)}, /* Per user Heimdal configuration file path */ {"COMMONCONFIG", CSIDLP(CSIDL_COMMON_APPDATA, "\\" PACKAGE)}, /* Common Heimdal configuration file path */ - {"LIBDIR", SPECIAL(_expand_bin_dir)}, - {"BINDIR", SPECIAL(_expand_bin_dir)}, - {"LIBEXEC", SPECIAL(_expand_bin_dir)}, - {"SBINDIR", SPECIAL(_expand_bin_dir)}, + {"LIBDIR", SPECIAL(expand_bin_dir)}, + {"BINDIR", SPECIAL(expand_bin_dir)}, + {"LIBEXEC", SPECIAL(expand_bin_dir)}, + {"SBINDIR", SPECIAL(expand_bin_dir)}, #else - {"LOCALSTATEDIR", FTYPE_SPECIAL, 0, LOCALSTATEDIR, _expand_path}, - {"LIBDIR", FTYPE_SPECIAL, 0, LIBDIR, _expand_path}, - {"BINDIR", FTYPE_SPECIAL, 0, BINDIR, _expand_path}, - {"LIBEXEC", FTYPE_SPECIAL, 0, LIBEXECDIR, _expand_path}, - {"SBINDIR", FTYPE_SPECIAL, 0, SBINDIR, _expand_path}, - {"euid", SPECIAL(_expand_euid)}, - {"ruid", SPECIAL(_expand_userid)}, - {"loginname", SPECIAL(_expand_loginname)}, + {"LOCALSTATEDIR", FTYPE_SPECIAL, 0, LOCALSTATEDIR, expand_path}, + {"LIBDIR", FTYPE_SPECIAL, 0, LIBDIR, expand_path}, + {"BINDIR", FTYPE_SPECIAL, 0, BINDIR, expand_path}, + {"LIBEXEC", FTYPE_SPECIAL, 0, LIBEXECDIR, expand_path}, + {"SBINDIR", FTYPE_SPECIAL, 0, SBINDIR, expand_path}, + {"euid", SPECIAL(expand_euid)}, + {"ruid", SPECIAL(expand_userid)}, + {"loginname", SPECIAL(expand_loginname)}, #endif - {"username", SPECIAL(_expand_username)}, - {"TEMP", SPECIAL(_expand_temp_folder)}, - {"USERID", SPECIAL(_expand_userid)}, - {"uid", SPECIAL(_expand_userid)}, - {"null", SPECIAL(_expand_null)}, - {"strftime", SPECIAL(_expand_strftime)} + {"username", SPECIAL(expand_username)}, + {"TEMP", SPECIAL(expand_temp_folder)}, + {"USERID", SPECIAL(expand_userid)}, + {"uid", SPECIAL(expand_userid)}, + {"null", SPECIAL(expand_null)}, + {"strftime", SPECIAL(expand_strftime)} }; -static krb5_error_code -_expand_token(krb5_context context, - const char *token, - const char *token_end, - char **extra_tokens, - char **ret) +static heim_error_code +expand_token(heim_context context, + const char *token, + const char *token_end, + char **extra_tokens, + char **ret) { - krb5_error_code errcode; + heim_error_code errcode; size_t i; char **p; const char *colon; @@ -468,62 +469,70 @@ _expand_token(krb5_context context, *ret = NULL; if (token[0] != '%' || token[1] != '{' || token_end[0] != '}' || - token_end - token <= 2) { - if (context) - krb5_set_error_message(context, EINVAL,"Invalid token."); - return EINVAL; + token_end - token <= 2) { + if (context) + heim_set_error_message(context, EINVAL,"Invalid token."); + return EINVAL; } for (p = extra_tokens; p && p[0]; p += 2) { - if (strncmp(token+2, p[0], (token_end - token) - 2) == 0) - return _expand_extra_token(context, p[1], ret); + if (strncmp(token+2, p[0], (token_end - token) - 2) == 0) + return expand_extra_token(context, p[1], ret); } for (colon=token+2; colon < token_end; colon++) - if (*colon == ':') - break; + if (*colon == ':') + break; for (i = 0; i < sizeof(tokens)/sizeof(tokens[0]); i++) - if (!strncmp(token+2, tokens[i].tok, (colon - token) - 2)) { - char *arg = NULL; + if (!strncmp(token+2, tokens[i].tok, (colon - token) - 2)) { + char *arg = NULL; - errcode = 0; - if (*colon == ':') { - asprintf(&arg, "%.*s", (int)(token_end - colon - 1), colon + 1); - if (!arg) - errcode = ENOMEM; - } - if (!errcode) - errcode = tokens[i].exp_func(context, tokens[i].param, - tokens[i].postfix, arg, ret); - free(arg); - return errcode; - } + errcode = 0; + if (*colon == ':') { + asprintf(&arg, "%.*s", (int)(token_end - colon - 1), colon + 1); + if (!arg) + errcode = ENOMEM; + } + if (!errcode) + errcode = tokens[i].exp_func(context, tokens[i].param, + tokens[i].postfix, arg, ret); + free(arg); + return errcode; + } if (context) - krb5_set_error_message(context, EINVAL, "Invalid token."); + heim_set_error_message(context, EINVAL, "Invalid token."); return EINVAL; } /** * Internal function to expand tokens in paths. * - * Inputs: + * Params: * - * @context A krb5_context + * @context A heim_context * @path_in The path to expand tokens from - * - * Outputs: - * - * @ppath_out Path with expanded tokens (caller must free() this) + * @ppath_out The expanded path + * @... Variable number of pairs of strings, the first of each + * being a token (e.g., "luser") and the second a string to + * replace it with. The list is terminated by a NULL. */ -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -_krb5_expand_path_tokens(krb5_context context, - const char *path_in, - int filepath, - char **ppath_out) +heim_error_code +heim_expand_path_tokens(heim_context context, + const char *path_in, + int filepath, + char **ppath_out, + ...) { - return _krb5_expand_path_tokensv(context, path_in, filepath, ppath_out, NULL); + heim_error_code ret; + va_list ap; + + va_start(ap, ppath_out); + ret = heim_expand_path_tokensv(context, path_in, filepath, ppath_out, ap); + va_end(ap); + + return ret; } static void @@ -532,7 +541,7 @@ free_extra_tokens(char **extra_tokens) char **p; for (p = extra_tokens; p && *p; p++) - free(*p); + free(*p); free(extra_tokens); } @@ -541,29 +550,29 @@ free_extra_tokens(char **extra_tokens) * * Inputs: * - * @context A krb5_context + * @context A heim_context * @path_in The path to expand tokens from * @ppath_out The expanded path - * @... Variable number of pairs of strings, the first of each - * being a token (e.g., "luser") and the second a string to - * replace it with. The list is terminated by a NULL. + * @ap A NULL-terminated va_list of pairs of strings, the first of each + * being a token (e.g., "luser") and the second a string to replace + * it with. * * Outputs: * * @ppath_out Path with expanded tokens (caller must free() this) */ -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -_krb5_expand_path_tokensv(krb5_context context, - const char *path_in, - int filepath, - char **ppath_out, ...) +heim_error_code +heim_expand_path_tokensv(heim_context context, + const char *path_in, + int filepath, + char **ppath_out, va_list ap) { char *tok_begin, *tok_end, *append; char **extra_tokens = NULL; const char *path_left; size_t nargs = 0; size_t len = 0; - va_list ap; + va_list ap2; if (path_in == NULL || *path_in == '\0') { *ppath_out = strdup(""); @@ -572,126 +581,128 @@ _krb5_expand_path_tokensv(krb5_context context, *ppath_out = NULL; - va_start(ap, ppath_out); - while (va_arg(ap, const char *)) { - nargs++; - va_arg(ap, const char *); +#if defined(_MSC_VER) + ap2 = ap; /* Come on! See SO #558223 */ +#else + va_copy(ap2, ap); +#endif + while (va_arg(ap2, const char *)) { + nargs++; + va_arg(ap2, const char *); } - va_end(ap); + va_end(ap2); nargs *= 2; /* Get extra tokens */ if (nargs) { - size_t i; + size_t i; - extra_tokens = calloc(nargs + 1, sizeof (*extra_tokens)); - if (extra_tokens == NULL) - return krb5_enomem(context); - va_start(ap, ppath_out); - for (i = 0; i < nargs; i++) { - const char *s = va_arg(ap, const char *); /* token key */ - if (s == NULL) - break; - extra_tokens[i] = strdup(s); - if (extra_tokens[i++] == NULL) { - va_end(ap); - free_extra_tokens(extra_tokens); - return krb5_enomem(context); - } - s = va_arg(ap, const char *); /* token value */ - if (s == NULL) - s = ""; - extra_tokens[i] = strdup(s); - if (extra_tokens[i] == NULL) { - va_end(ap); - free_extra_tokens(extra_tokens); - return krb5_enomem(context); - } - } - va_end(ap); + extra_tokens = calloc(nargs + 1, sizeof (*extra_tokens)); + if (extra_tokens == NULL) + return heim_enomem(context); + for (i = 0; i < nargs; i++) { + const char *s = va_arg(ap, const char *); /* token key */ + if (s == NULL) + break; + extra_tokens[i] = strdup(s); + if (extra_tokens[i++] == NULL) { + va_end(ap); + free_extra_tokens(extra_tokens); + return heim_enomem(context); + } + s = va_arg(ap, const char *); /* token value */ + if (s == NULL) + s = ""; + extra_tokens[i] = strdup(s); + if (extra_tokens[i] == NULL) { + va_end(ap); + free_extra_tokens(extra_tokens); + return heim_enomem(context); + } + } } for (path_left = path_in; path_left && *path_left; ) { - tok_begin = strstr(path_left, "%{"); + tok_begin = strstr(path_left, "%{"); - if (tok_begin && tok_begin != path_left) { + if (tok_begin && tok_begin != path_left) { - append = malloc((tok_begin - path_left) + 1); - if (append) { - memcpy(append, path_left, tok_begin - path_left); - append[tok_begin - path_left] = '\0'; - } - path_left = tok_begin; + append = malloc((tok_begin - path_left) + 1); + if (append) { + memcpy(append, path_left, tok_begin - path_left); + append[tok_begin - path_left] = '\0'; + } + path_left = tok_begin; - } else if (tok_begin) { + } else if (tok_begin) { - tok_end = strchr(tok_begin, '}'); - if (tok_end == NULL) { - free_extra_tokens(extra_tokens); - if (*ppath_out) - free(*ppath_out); - *ppath_out = NULL; - if (context) - krb5_set_error_message(context, EINVAL, "variable missing }"); - return EINVAL; - } + tok_end = strchr(tok_begin, '}'); + if (tok_end == NULL) { + free_extra_tokens(extra_tokens); + if (*ppath_out) + free(*ppath_out); + *ppath_out = NULL; + if (context) + heim_set_error_message(context, EINVAL, "variable missing }"); + return EINVAL; + } - if (_expand_token(context, tok_begin, tok_end, extra_tokens, - &append)) { - free_extra_tokens(extra_tokens); - if (*ppath_out) - free(*ppath_out); - *ppath_out = NULL; - return EINVAL; - } + if (expand_token(context, tok_begin, tok_end, extra_tokens, + &append)) { + free_extra_tokens(extra_tokens); + if (*ppath_out) + free(*ppath_out); + *ppath_out = NULL; + return EINVAL; + } - path_left = tok_end + 1; - } else { + path_left = tok_end + 1; + } else { - append = strdup(path_left); - path_left = NULL; + append = strdup(path_left); + path_left = NULL; - } + } - if (append == NULL) { + if (append == NULL) { - free_extra_tokens(extra_tokens); - if (*ppath_out) - free(*ppath_out); - *ppath_out = NULL; - return krb5_enomem(context); + free_extra_tokens(extra_tokens); + if (*ppath_out) + free(*ppath_out); + *ppath_out = NULL; + return heim_enomem(context); - } + } - { - size_t append_len = strlen(append); - char * new_str = realloc(*ppath_out, len + append_len + 1); + { + size_t append_len = strlen(append); + char * new_str = realloc(*ppath_out, len + append_len + 1); - if (new_str == NULL) { - free_extra_tokens(extra_tokens); - free(append); - if (*ppath_out) - free(*ppath_out); - *ppath_out = NULL; - return krb5_enomem(context); - } + if (new_str == NULL) { + free_extra_tokens(extra_tokens); + free(append); + if (*ppath_out) + free(*ppath_out); + *ppath_out = NULL; + return heim_enomem(context); + } - *ppath_out = new_str; - memcpy(*ppath_out + len, append, append_len + 1); - len = len + append_len; - free(append); - } + *ppath_out = new_str; + memcpy(*ppath_out + len, append, append_len + 1); + len = len + append_len; + free(append); + } } #ifdef _WIN32 /* Also deal with slashes */ if (filepath && *ppath_out) { - char * c; + char * c; - for (c = *ppath_out; *c; c++) - if (*c == '/') - *c = '\\'; + for (c = *ppath_out; *c; c++) + if (*c == '/') + *c = '\\'; } #endif diff --git a/lib/krb5/heim_err.et b/lib/base/heim_err.et similarity index 96% rename from lib/krb5/heim_err.et rename to lib/base/heim_err.et index 69039bb4d..02f21b027 100644 --- a/lib/krb5/heim_err.et +++ b/lib/base/heim_err.et @@ -21,6 +21,7 @@ error_code NOT_SEEKABLE, "File descriptor not seekable" error_code TOO_BIG, "Offset too large" error_code BAD_HDBENT_ENCODING, "Invalid HDB entry encoding" error_code RANDOM_OFFLINE, "No random source available" +error_code CONFIG_BADFORMAT, "Improper format of configuration file" index 64 prefix HEIM_PKINIT diff --git a/lib/base/heimbase.h b/lib/base/heimbase.h index 45b7ee097..d0d397c28 100644 --- a/lib/base/heimbase.h +++ b/lib/base/heimbase.h @@ -55,8 +55,89 @@ #endif #endif +#include + +#include + +#ifdef _WIN32 +#define HEIM_CALLCONV __stdcall +#define HEIM_LIB_CALL __stdcall +#else +#define HEIM_CALLCONV +#define HEIM_LIB_CALL +#endif + +#if !defined(__GNUC__) && !defined(__attribute__) +#define __attribute__(x) +#endif + #define HEIM_BASE_API_VERSION 20130210 +typedef int32_t heim_error_code; +typedef struct heim_context_s *heim_context; +typedef struct heim_pcontext_s *heim_pcontext; + +typedef void (HEIM_CALLCONV *heim_log_log_func_t)(heim_context, + const char *, + const char *, + void *); +typedef void (HEIM_CALLCONV *heim_log_close_func_t)(void *); + +struct heim_log_facility_internal { + int min; + int max; + heim_log_log_func_t log_func; + heim_log_close_func_t close_func; + void *data; +}; + + +typedef struct heim_log_facility_s { + char *program; + int len; + struct heim_log_facility_internal *val; +} heim_log_facility; + +typedef uintptr_t +(HEIM_LIB_CALL *heim_get_instance_func_t)(const char *); + +#define HEIM_PLUGIN_INVOKE_ALL 1 + +struct heim_plugin_data { + const char *module; + const char *name; + int min_version; + const char **deps; + heim_get_instance_func_t get_instance; +}; + +typedef struct heim_err_cb_context_s *heim_err_cb_context; +typedef void (*heim_err_cb_clear_msg)(heim_err_cb_context); +typedef void (*heim_err_cb_free_msg)(heim_err_cb_context, const char *); +typedef const char * (*heim_err_cb_get_msg)(heim_err_cb_context, int32_t); +typedef void (*heim_err_cb_set_msg)(heim_err_cb_context, int32_t, + const char *, va_list) + __attribute__ ((__format__ (__printf__, 3, 0))); + +typedef struct heim_config_binding heim_config_binding; +struct heim_config_binding { + enum { + heim_config_string, + heim_config_list, + /* For compatibility in krb5 code */ + krb5_config_string = heim_config_string, + krb5_config_list = heim_config_list, + } type; + char *name; + struct heim_config_binding *next; + union { + char *string; + struct heim_config_binding *list; + void *generic; + } u; +}; +typedef struct heim_config_binding heim_config_section; + typedef void * heim_object_t; typedef unsigned int heim_tid_t; typedef heim_object_t heim_bool_t; @@ -572,4 +653,7 @@ heim_base_exchange_pointer(void *target, void *value) #error set SIZEOF_TIME_T for your platform #endif +#include +#include + #endif /* HEIM_BASE_H */ diff --git a/lib/base/log.c b/lib/base/log.c index a3913e907..a1ac76052 100644 --- a/lib/base/log.c +++ b/lib/base/log.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2006 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2020 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,25 +33,19 @@ * SUCH DAMAGE. */ -#include "krb5_locl.h" +#include "baselocl.h" +#include "heim_threads.h" #include +#include #include -struct facility { - int min; - int max; - krb5_log_log_func_t log_func; - krb5_log_close_func_t close_func; - void *data; -}; - -static struct facility* -log_realloc(krb5_log_facility *f) +static struct heim_log_facility_internal * +log_realloc(heim_log_facility *f) { - struct facility *fp; + struct heim_log_facility_internal *fp; fp = realloc(f->val, (f->len + 1) * sizeof(*f->val)); - if(fp == NULL) - return NULL; + if (fp == NULL) + return NULL; f->len++; f->val = fp; fp += f->len - 1; @@ -111,40 +105,40 @@ static struct s2i syslogvals[] = { static int find_value(const char *s, struct s2i *table) { - while(table->s && strcasecmp(table->s, s)) - table++; + while (table->s && strcasecmp(table->s, s)) + table++; return table->val; } -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_initlog(krb5_context context, - const char *program, - krb5_log_facility **fac) +heim_error_code +heim_initlog(heim_context context, + const char *program, + heim_log_facility **fac) { - krb5_log_facility *f = calloc(1, sizeof(*f)); + heim_log_facility *f = calloc(1, sizeof(*f)); if (f == NULL) - return krb5_enomem(context); + return heim_enomem(context); f->program = strdup(program); - if(f->program == NULL){ - free(f); - return krb5_enomem(context); + if (f->program == NULL) { + free(f); + return heim_enomem(context); } *fac = f; return 0; } -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_addlog_func(krb5_context context, - krb5_log_facility *fac, - int min, - int max, - krb5_log_log_func_t log_func, - krb5_log_close_func_t close_func, - void *data) +heim_error_code +heim_addlog_func(heim_context context, + heim_log_facility *fac, + int min, + int max, + heim_log_log_func_t log_func, + heim_log_close_func_t close_func, + void *data) { - struct facility *fp = log_realloc(fac); + struct heim_log_facility_internal *fp = log_realloc(fac); if (fp == NULL) - return krb5_enomem(context); + return heim_enomem(context); fp->min = min; fp->max = max; fp->log_func = log_func; @@ -158,42 +152,42 @@ struct _heimdal_syslog_data{ int priority; }; -static void KRB5_CALLCONV -log_syslog(krb5_context context, const char *timestr, - const char *msg, void *data) +static void +log_syslog(heim_context context, const char *timestr, + const char *msg, void *data) { struct _heimdal_syslog_data *s = data; syslog(s->priority, "%s", msg); } -static void KRB5_CALLCONV +static void close_syslog(void *data) { free(data); closelog(); } -static krb5_error_code -open_syslog(krb5_context context, - krb5_log_facility *facility, int min, int max, - const char *sev, const char *fac) +static heim_error_code +open_syslog(heim_context context, + heim_log_facility *facility, int min, int max, + const char *sev, const char *fac) { struct _heimdal_syslog_data *sd = malloc(sizeof(*sd)); int i; if (sd == NULL) - return krb5_enomem(context); + return heim_enomem(context); i = find_value(sev, syslogvals); - if(i == -1) - i = LOG_ERR; + if (i == -1) + i = LOG_ERR; sd->priority = i; i = find_value(fac, syslogvals); - if(i == -1) - i = LOG_AUTH; + if (i == -1) + i = LOG_AUTH; sd->priority |= i; roken_openlog(facility->program, LOG_PID | LOG_NDELAY, i); - return krb5_addlog_func(context, facility, min, max, - log_syslog, close_syslog, sd); + return heim_addlog_func(context, facility, min, max, + log_syslog, close_syslog, sd); } struct file_data { @@ -202,14 +196,14 @@ struct file_data { struct timeval tv; FILE *fd; int disp; -#define FILEDISP_KEEPOPEN 0x1 -#define FILEDISP_REOPEN 0x2 -#define FILEDISP_IFEXISTS 0x3 +#define FILEDISP_KEEPOPEN 0x1 +#define FILEDISP_REOPEN 0x2 +#define FILEDISP_IFEXISTS 0x3 int freefilename; }; -static void KRB5_CALLCONV -log_file(krb5_context context, const char *timestr, const char *msg, void *data) +static void +log_file(heim_context context, const char *timestr, const char *msg, void *data) { struct timeval tv; struct file_data *f = data; @@ -218,38 +212,38 @@ log_file(krb5_context context, const char *timestr, const char *msg, void *data) size_t j; if (f->disp != FILEDISP_KEEPOPEN) { - char *filename; - int flags = -1; - int fd; + char *filename; + int flags = -1; + int fd; - if (f->mode[0] == 'w' && f->mode[1] == 0) - flags = O_WRONLY|O_TRUNC; - if (f->mode[0] == 'a' && f->mode[1] == 0) - flags = O_WRONLY|O_APPEND; - assert(flags != -1); + if (f->mode[0] == 'w' && f->mode[1] == 0) + flags = O_WRONLY|O_TRUNC; + if (f->mode[0] == 'a' && f->mode[1] == 0) + flags = O_WRONLY|O_APPEND; + assert(flags != -1); - if (f->disp == FILEDISP_IFEXISTS) { - /* Cache failure for 1s */ - gettimeofday(&tv, NULL); - if (tv.tv_sec == f->tv.tv_sec) - return; - } else { - flags |= O_CREAT; - } + if (f->disp == FILEDISP_IFEXISTS) { + /* Cache failure for 1s */ + gettimeofday(&tv, NULL); + if (tv.tv_sec == f->tv.tv_sec) + return; + } else { + flags |= O_CREAT; + } - if (_krb5_expand_path_tokens(context, f->filename, 1, &filename)) - return; - fd = open(filename, flags, 0666); - if (fd == -1) { - if (f->disp == FILEDISP_IFEXISTS) - gettimeofday(&f->tv, NULL); - return; - } - f->fd = fdopen(fd, f->mode); - free(filename); + if (heim_expand_path_tokens(context, f->filename, 1, &filename, NULL)) + return; + fd = open(filename, flags, 0666); + if (fd == -1) { + if (f->disp == FILEDISP_IFEXISTS) + gettimeofday(&f->tv, NULL); + return; + } + f->fd = fdopen(fd, f->mode); + free(filename); } - if(f->fd == NULL) - return; + if (f->fd == NULL) + return; /* * make sure the log doesn't contain special chars: * we used to use strvisx(3) to encode the log, but this is @@ -260,40 +254,40 @@ log_file(krb5_context context, const char *timestr, const char *msg, void *data) */ msgclean = strdup(msg); if (msgclean == NULL) - goto out; + goto out; for (i=0, j=0; msg[i]; i++) - if (msg[i] >= 32 || msg[i] == '\t') - msgclean[j++] = msg[i]; + if (msg[i] >= 32 || msg[i] == '\t') + msgclean[j++] = msg[i]; fprintf(f->fd, "%s %s\n", timestr, msgclean); free(msgclean); - out: - if(f->disp != FILEDISP_KEEPOPEN) { - fclose(f->fd); - f->fd = NULL; +out: + if (f->disp != FILEDISP_KEEPOPEN) { + fclose(f->fd); + f->fd = NULL; } } -static void KRB5_CALLCONV +static void close_file(void *data) { struct file_data *f = data; - if(f->disp == FILEDISP_KEEPOPEN && f->filename) - fclose(f->fd); + if (f->disp == FILEDISP_KEEPOPEN && f->filename) + fclose(f->fd); if (f->filename && f->freefilename) - free((char *)f->filename); + free((char *)f->filename); free(data); } -static krb5_error_code -open_file(krb5_context context, krb5_log_facility *fac, int min, int max, - const char *filename, const char *mode, FILE *f, int disp, - int freefilename) +static heim_error_code +open_file(heim_context context, heim_log_facility *fac, int min, int max, + const char *filename, const char *mode, FILE *f, int disp, + int freefilename) { struct file_data *fd = malloc(sizeof(*fd)); if (fd == NULL) { - if (freefilename && filename) - free((char *)filename); - return krb5_enomem(context); + if (freefilename && filename) + free((char *)filename); + return heim_enomem(context); } fd->filename = filename; fd->mode = mode; @@ -301,15 +295,13 @@ open_file(krb5_context context, krb5_log_facility *fac, int min, int max, fd->disp = disp; fd->freefilename = freefilename; - return krb5_addlog_func(context, fac, min, max, log_file, close_file, fd); + return heim_addlog_func(context, fac, min, max, log_file, close_file, fd); } - - -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *orig) +heim_error_code +heim_addlog_dest(heim_context context, heim_log_facility *f, const char *orig) { - krb5_error_code ret = 0; + heim_error_code ret = 0; int min = 0, max = 3, n; char c; const char *p = orig; @@ -318,149 +310,158 @@ krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *orig) #endif n = sscanf(p, "%d%c%d/", &min, &c, &max); - if(n == 2){ - if(ISPATHSEP(c)) { - if(min < 0){ - max = -min; - min = 0; - }else{ - max = min; - } - } - if (c == '-') - max = -1; + if (n == 2) { + if (ISPATHSEP(c)) { + if (min < 0) { + max = -min; + min = 0; + } else { + max = min; + } + } + if (c == '-') + max = -1; } - if(n){ + if (n) { #ifdef _WIN32 - q = strrchr(p, '\\'); - if (q != NULL) - p = q; - else + q = strrchr(p, '\\'); + if (q != NULL) + p = q; + else #endif - p = strchr(p, '/'); - if(p == NULL) { - krb5_set_error_message(context, HEIM_ERR_LOG_PARSE, - N_("failed to parse \"%s\"", ""), orig); - return HEIM_ERR_LOG_PARSE; - } - p++; + p = strchr(p, '/'); + if (p == NULL) { + heim_set_error_message(context, EINVAL /*XXX HEIM_ERR_LOG_PARSE*/, + N_("failed to parse \"%s\"", ""), orig); + return EINVAL /*XXX HEIM_ERR_LOG_PARSE*/; + } + p++; } - if(strcmp(p, "STDERR") == 0){ - ret = open_file(context, f, min, max, NULL, NULL, stderr, 1, 0); - }else if(strcmp(p, "CONSOLE") == 0){ - ret = open_file(context, f, min, max, "/dev/console", "w", NULL, - FILEDISP_REOPEN, 0); - }else if (strncmp(p, "EFILE", 5) == 0 && p[5] == ':') { - ret = open_file(context, f, min, max, strdup(p+6), "a", NULL, - FILEDISP_IFEXISTS, 1); - }else if(strncmp(p, "FILE", 4) == 0 && (p[4] == ':' || p[4] == '=')){ - char *fn; - FILE *file = NULL; - int disp = FILEDISP_REOPEN; - fn = strdup(p + 5); - if (fn == NULL) - return krb5_enomem(context); - if(p[4] == '='){ - int i = open(fn, O_WRONLY | O_CREAT | - O_TRUNC | O_APPEND, 0666); - if(i < 0) { - ret = errno; - krb5_set_error_message(context, ret, - N_("open(%s) logfile: %s", ""), fn, - strerror(ret)); - free(fn); - return ret; - } - rk_cloexec(i); - file = fdopen(i, "a"); - if(file == NULL){ - ret = errno; - close(i); - krb5_set_error_message(context, ret, - N_("fdopen(%s) logfile: %s", ""), - fn, strerror(ret)); - free(fn); - return ret; - } - disp = FILEDISP_KEEPOPEN; - } - ret = open_file(context, f, min, max, fn, "a", file, disp, 1); - }else if(strncmp(p, "DEVICE", 6) == 0 && (p[6] == ':' || p[6] == '=')){ - ret = open_file(context, f, min, max, strdup(p + 7), "w", NULL, - FILEDISP_REOPEN, 1); - }else if(strncmp(p, "SYSLOG", 6) == 0 && (p[6] == '\0' || p[6] == ':')){ - char severity[128] = ""; - char facility[128] = ""; - p += 6; - if(*p != '\0') - p++; - if(strsep_copy(&p, ":", severity, sizeof(severity)) != -1) - strsep_copy(&p, ":", facility, sizeof(facility)); - if(*severity == '\0') - strlcpy(severity, "ERR", sizeof(severity)); - if(*facility == '\0') - strlcpy(facility, "AUTH", sizeof(facility)); - ret = open_syslog(context, f, min, max, severity, facility); - }else{ - ret = HEIM_ERR_LOG_PARSE; /* XXX */ - krb5_set_error_message (context, ret, - N_("unknown log type: %s", ""), p); + if (strcmp(p, "STDERR") == 0) { + ret = open_file(context, f, min, max, NULL, NULL, stderr, 1, 0); + } else if (strcmp(p, "CONSOLE") == 0) { + ret = open_file(context, f, min, max, "/dev/console", "w", NULL, + FILEDISP_REOPEN, 0); + } else if (strncmp(p, "EFILE", 5) == 0 && p[5] == ':') { + ret = open_file(context, f, min, max, strdup(p+6), "a", NULL, + FILEDISP_IFEXISTS, 1); + } else if (strncmp(p, "FILE", 4) == 0 && (p[4] == ':' || p[4] == '=')) { + char *fn; + FILE *file = NULL; + int disp = FILEDISP_REOPEN; + fn = strdup(p + 5); + if (fn == NULL) + return heim_enomem(context); + if (p[4] == '=') { + int i = open(fn, O_WRONLY | O_CREAT | + O_TRUNC | O_APPEND, 0666); + if (i < 0) { + ret = errno; + heim_set_error_message(context, ret, + N_("open(%s) logfile: %s", ""), fn, + strerror(ret)); + free(fn); + return ret; + } + rk_cloexec(i); + file = fdopen(i, "a"); + if (file == NULL) { + ret = errno; + close(i); + heim_set_error_message(context, ret, + N_("fdopen(%s) logfile: %s", ""), + fn, strerror(ret)); + free(fn); + return ret; + } + disp = FILEDISP_KEEPOPEN; + } + ret = open_file(context, f, min, max, fn, "a", file, disp, 1); + } else if (strncmp(p, "DEVICE", 6) == 0 && (p[6] == ':' || p[6] == '=')) { + ret = open_file(context, f, min, max, strdup(p + 7), "w", NULL, + FILEDISP_REOPEN, 1); + } else if (strncmp(p, "SYSLOG", 6) == 0 && (p[6] == '\0' || p[6] == ':')) { + char severity[128] = ""; + char facility[128] = ""; + p += 6; + if (*p != '\0') + p++; + if (strsep_copy(&p, ":", severity, sizeof(severity)) != -1) + strsep_copy(&p, ":", facility, sizeof(facility)); + if (*severity == '\0') + strlcpy(severity, "ERR", sizeof(severity)); + if (*facility == '\0') + strlcpy(facility, "AUTH", sizeof(facility)); + ret = open_syslog(context, f, min, max, severity, facility); + } else { + ret = EINVAL; /*XXX HEIM_ERR_LOG_PARSE*/ + heim_set_error_message(context, ret, + N_("unknown log type: %s", ""), p); } return ret; } - -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_openlog(krb5_context context, - const char *program, - krb5_log_facility **fac) +heim_error_code +heim_openlog(heim_context context, + const char *program, + const char **specs, + heim_log_facility **fac) { - krb5_error_code ret; - char **p, **q; + heim_error_code ret; - ret = krb5_initlog(context, program, fac); - if(ret) - return ret; + ret = heim_initlog(context, program, fac); + if (ret) + return ret; - p = krb5_config_get_strings(context, NULL, "logging", program, NULL); - if(p == NULL) - p = krb5_config_get_strings(context, NULL, "logging", "default", NULL); - if(p){ - for(q = p; *q && ret == 0; q++) - ret = krb5_addlog_dest(context, *fac, *q); - krb5_config_free_strings(p); - }else - ret = krb5_addlog_dest(context, *fac, "SYSLOG"); + if (specs) { + size_t i; + for (i = 0; specs[i] && ret == 0; i++) + ret = heim_addlog_dest(context, *fac, specs[i]); + } else { + ret = heim_addlog_dest(context, *fac, "SYSLOG"); + } return ret; } -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_closelog(krb5_context context, - krb5_log_facility *fac) +void +heim_closelog(heim_context context, heim_log_facility *fac) { int i; - for(i = 0; i < fac->len; i++) - (*fac->val[i].close_func)(fac->val[i].data); + + if (!fac) + return; + for (i = 0; i < fac->len; i++) + (*fac->val[i].close_func)(fac->val[i].data); free(fac->val); free(fac->program); fac->val = NULL; fac->len = 0; fac->program = NULL; free(fac); - return 0; + return; +} + +static void +format_time(heim_context context, time_t t, char *s, size_t len) +{ + struct tm *tm = heim_context_get_log_utc(context) ? + gmtime(&t) : localtime(&t); + if (tm && strftime(s, len, heim_context_get_time_fmt(context), tm)) + return; + snprintf(s, len, "%ld", (long)t); } #undef __attribute__ #define __attribute__(X) -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_vlog_msg(krb5_context context, - krb5_log_facility *fac, - char **reply, - int level, - const char *fmt, - va_list ap) - __attribute__ ((__format__ (__printf__, 5, 0))) +heim_error_code +heim_vlog_msg(heim_context context, + heim_log_facility *fac, + char **reply, + int level, + const char *fmt, + va_list ap) +__attribute__ ((__format__ (__printf__, 5, 0))) { char *msg = NULL; @@ -469,114 +470,156 @@ krb5_vlog_msg(krb5_context context, time_t t = 0; int i; - for(i = 0; fac && i < fac->len; i++) - if(fac->val[i].min <= level && - (fac->val[i].max < 0 || fac->val[i].max >= level)) { - if(t == 0) { - t = time(NULL); - krb5_format_time(context, t, buf, sizeof(buf), TRUE); - } - if(actual == NULL) { - int ret = vasprintf(&msg, fmt, ap); - if(ret < 0 || msg == NULL) - actual = fmt; - else - actual = msg; - } - (*fac->val[i].log_func)(context, buf, actual, fac->val[i].data); - } - if(reply == NULL) - free(msg); + for (i = 0; fac && i < fac->len; i++) + if (fac->val[i].min <= level && + (fac->val[i].max < 0 || fac->val[i].max >= level)) { + if (t == 0) { + t = time(NULL); + format_time(context, t, buf, sizeof(buf)); + } + if (actual == NULL) { + int ret = vasprintf(&msg, fmt, ap); + if (ret < 0 || msg == NULL) + actual = fmt; + else + actual = msg; + } + (*fac->val[i].log_func)(context, buf, actual, fac->val[i].data); + } + if (reply == NULL) + free(msg); else - *reply = msg; + *reply = msg; return 0; } -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_vlog(krb5_context context, - krb5_log_facility *fac, - int level, - const char *fmt, - va_list ap) - __attribute__ ((__format__ (__printf__, 4, 0))) +heim_error_code +heim_vlog(heim_context context, + heim_log_facility *fac, + int level, + const char *fmt, + va_list ap) +__attribute__ ((__format__ (__printf__, 4, 0))) { - return krb5_vlog_msg(context, fac, NULL, level, fmt, ap); + return heim_vlog_msg(context, fac, NULL, level, fmt, ap); } -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_log_msg(krb5_context context, - krb5_log_facility *fac, - int level, - char **reply, - const char *fmt, - ...) - __attribute__ ((__format__ (__printf__, 5, 6))) +heim_error_code +heim_log_msg(heim_context context, + heim_log_facility *fac, + int level, + char **reply, + const char *fmt, + ...) +__attribute__ ((__format__ (__printf__, 5, 6))) { va_list ap; - krb5_error_code ret; + heim_error_code ret; va_start(ap, fmt); - ret = krb5_vlog_msg(context, fac, reply, level, fmt, ap); + ret = heim_vlog_msg(context, fac, reply, level, fmt, ap); va_end(ap); return ret; } -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_log(krb5_context context, - krb5_log_facility *fac, - int level, - const char *fmt, - ...) - __attribute__ ((__format__ (__printf__, 4, 5))) +heim_error_code +heim_log(heim_context context, + heim_log_facility *fac, + int level, + const char *fmt, + ...) +__attribute__ ((__format__ (__printf__, 4, 5))) { va_list ap; - krb5_error_code ret; + heim_error_code ret; va_start(ap, fmt); - ret = krb5_vlog(context, fac, level, fmt, ap); + ret = heim_vlog(context, fac, level, fmt, ap); va_end(ap); return ret; } -void KRB5_LIB_FUNCTION -_krb5_debug(krb5_context context, - int level, - const char *fmt, - ...) - __attribute__ ((__format__ (__printf__, 3, 4))) +void +heim_debug(heim_context context, + int level, + const char *fmt, + ...) +__attribute__ ((__format__ (__printf__, 3, 4))) { + heim_log_facility *fac; va_list ap; - if (context == NULL || context->debug_dest == NULL) - return; + if (context == NULL || + (fac = heim_get_debug_dest(context)) == NULL) + return; va_start(ap, fmt); - krb5_vlog(context, context->debug_dest, level, fmt, ap); + heim_vlog(context, fac, level, fmt, ap); va_end(ap); } -KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL -_krb5_have_debug(krb5_context context, int level) +void +heim_vdebug(heim_context context, + int level, + const char *fmt, + va_list ap) +__attribute__ ((__format__ (__printf__, 3, 0))) { - if (context == NULL || context->debug_dest == NULL) - return 0 ; - return 1; + heim_log_facility *fac; + + if (context == NULL || + (fac = heim_get_debug_dest(context)) == NULL) + return; + + heim_vlog(context, fac, level, fmt, ap); } -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_set_debug_dest(krb5_context context, const char *program, - const char *log_spec) +heim_error_code +heim_have_debug(heim_context context, int level) { - krb5_error_code ret; + heim_log_facility *fac; - if (context->debug_dest == NULL) { - ret = krb5_initlog(context, program, &context->debug_dest); + return (context != NULL && + (fac = heim_get_debug_dest(context)) != NULL); +} + +heim_error_code +heim_add_warn_dest(heim_context context, const char *program, + const char *log_spec) +{ + heim_log_facility *fac; + + heim_error_code ret; + + if ((fac = heim_get_warn_dest(context)) == NULL) { + ret = heim_initlog(context, program, &fac); if (ret) return ret; + heim_set_warn_dest(context, fac); } - ret = krb5_addlog_dest(context, context->debug_dest, log_spec); + ret = heim_addlog_dest(context, fac, log_spec); + if (ret) + return ret; + return 0; +} + +heim_error_code +heim_add_debug_dest(heim_context context, const char *program, + const char *log_spec) +{ + heim_log_facility *fac; + heim_error_code ret; + + if ((fac = heim_get_debug_dest(context)) == NULL) { + ret = heim_initlog(context, program, &fac); + if (ret) + return ret; + heim_set_debug_dest(context, fac); + } + + ret = heim_addlog_dest(context, fac, log_spec); if (ret) return ret; return 0; diff --git a/lib/base/plugin.c b/lib/base/plugin.c index 5730f7ca0..03a6e9612 100644 --- a/lib/base/plugin.c +++ b/lib/base/plugin.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan + * Copyright (c) 2006 - 2020 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,30 +33,31 @@ * SUCH DAMAGE. */ -#include "krb5_locl.h" +#include "baselocl.h" #include "common_plugin.h" +/* + * Documentation for the Heimdal plugin system is in lib/krb5/plugin.c and + * lib/krb5/krb5-plugin.7. + */ + /* * Definitions: * - * module - a category of plugin module, identified by subsystem - * (typically "krb5") - * dso - a library for a module containing a map of plugin - * types to plugins (e.g. "service_locator") - * plugin - a set of callbacks and state that follows the - * common plugin module definition (version, init, fini) + * module - a category of plugin module, identified by subsystem + * (e.g., "krb5") + * dso - a library for a module containing a map of plugin + * types to plugins (e.g. "service_locator") + * plugin - a set of callbacks and state that follows the + * common plugin module definition (version, init, fini) * * Obviously it would have been clearer to use the term "module" rather than * "DSO" given there is an internal "DSO", but "module" was already taken... * - * modules := { module: dsos } - * dsos := { path, dsohandle, plugins-by-name } - * plugins-by-name := { plugin-name: [plug] } - * plug := { ftable, ctx } - * - * Some existing plugin consumers outside libkrb5 use the "krb5" module - * namespace, but going forward the module should match the consumer library - * name (e.g. libhdb should use the "hdb" module rather than "krb5"). + * modules := { module: dsos } + * dsos := { path, dsohandle, plugins-by-name } + * plugins-by-name := { plugin-name: [plug] } + * plug := { ftable, ctx } */ /* global module use, use copy_modules() accessor to access */ @@ -94,8 +95,8 @@ copy_module(const char *name) module = heim_dict_copy_value(modules, module_name); if (module == NULL) { - module = heim_dict_create(11); - heim_dict_set_value(modules, module_name, module); + module = heim_dict_create(11); + heim_dict_set_value(modules, module_name, module); } heim_release(modules); @@ -105,7 +106,7 @@ copy_module(const char *name) } /* DSO helpers */ -struct krb5_dso { +struct heim_dso { heim_string_t path; heim_dict_t plugins_by_name; void *dsohandle; @@ -114,35 +115,35 @@ struct krb5_dso { static void dso_dealloc(void *ptr) { - struct krb5_dso *p = ptr; + struct heim_dso *p = ptr; heim_release(p->path); heim_release(p->plugins_by_name); #ifdef HAVE_DLOPEN if (p->dsohandle) - dlclose(p->dsohandle); + dlclose(p->dsohandle); #endif } /* returns internal "DSO" for name, refcount +1 */ -static struct krb5_dso * +static struct heim_dso * copy_internal_dso(const char *name) { heim_string_t dso_name = HSTR("__HEIMDAL_INTERNAL_DSO__"); heim_dict_t module = copy_module(name); - struct krb5_dso *dso; + struct heim_dso *dso; if (module == NULL) - return NULL; + return NULL; dso = heim_dict_copy_value(module, dso_name); if (dso == NULL) { - dso = heim_alloc(sizeof(*dso), "krb5-dso", dso_dealloc); + dso = heim_alloc(sizeof(*dso), "heim-dso", dso_dealloc); - dso->path = dso_name; - dso->plugins_by_name = heim_dict_create(11); + dso->path = dso_name; + dso->plugins_by_name = heim_dict_create(11); - heim_dict_set_value(module, dso_name, dso); + heim_dict_set_value(module, dso_name, dso); } heim_release(module); @@ -150,21 +151,21 @@ copy_internal_dso(const char *name) return dso; } -struct krb5_plugin { - krb5_plugin_common_ftable_p ftable; +struct heim_plugin { + heim_plugin_common_ftable_p ftable; void *ctx; }; static void plugin_free(void *ptr) { - struct krb5_plugin *pl = ptr; + struct heim_plugin *pl = ptr; if (pl->ftable && pl->ftable->fini) - pl->ftable->fini(pl->ctx); + pl->ftable->fini(pl->ctx); } -struct krb5_plugin_register_ctx { +struct heim_plugin_register_ctx { void *symbol; int is_dup; }; @@ -172,82 +173,73 @@ struct krb5_plugin_register_ctx { static void plugin_register_check_dup(heim_object_t value, void *ctx, int *stop) { - struct krb5_plugin_register_ctx *pc = ctx; - struct krb5_plugin *pl = value; + struct heim_plugin_register_ctx *pc = ctx; + struct heim_plugin *pl = value; if (pl->ftable == pc->symbol) { - pc->is_dup = 1; - *stop = 1; + pc->is_dup = 1; + *stop = 1; } } /** * Register a plugin symbol name of specific type. * @param context a Keberos context - * @param type type of plugin symbol - * @param name name of plugin symbol - * @param symbol a pointer to the named symbol + * @param module name of plugin module (e.g., "krb5") + * @param name name of plugin symbol (e.g., "krb5_plugin_kuserok") + * @param ftable a pointer to a function pointer table * @return In case of error a non zero error com_err error is returned * and the Kerberos error string is set. * - * @ingroup krb5_support + * @ingroup heim_support */ -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_plugin_register(krb5_context context, - enum krb5_plugin_type type, - const char *name, - void *symbol) +heim_error_code +heim_plugin_register(heim_context context, + heim_pcontext pcontext, + const char *module, + const char *name, + void *ftable) { - krb5_error_code ret; + heim_error_code ret; heim_array_t plugins; heim_string_t hname; - struct krb5_dso *dso; - struct krb5_plugin_register_ctx ctx; + struct heim_dso *dso; + struct heim_plugin_register_ctx ctx; - ctx.symbol = symbol; + ctx.symbol = ftable; ctx.is_dup = 0; - /* - * It's not clear that PLUGIN_TYPE_FUNC was ever used or supported. It likely - * would have caused _krb5_plugin_run_f() to crash as the previous implementation - * assumed PLUGIN_TYPE_DATA. - */ - if (type != PLUGIN_TYPE_DATA) { - krb5_warnx(context, "krb5_plugin_register: PLUGIN_TYPE_DATA no longer supported"); - return EINVAL; - } - HEIMDAL_MUTEX_lock(&modules_mutex); - dso = copy_internal_dso("krb5"); + dso = copy_internal_dso(module); hname = heim_string_create(name); plugins = heim_dict_copy_value(dso->plugins_by_name, hname); if (plugins != NULL) - heim_array_iterate_f(plugins, &ctx, plugin_register_check_dup); + heim_array_iterate_f(plugins, &ctx, plugin_register_check_dup); else { - plugins = heim_array_create(); - heim_dict_set_value(dso->plugins_by_name, hname, plugins); + plugins = heim_array_create(); + heim_dict_set_value(dso->plugins_by_name, hname, plugins); } + ret = 0; if (!ctx.is_dup) { - /* Note: refactored plugin API only supports common plugin layout */ - struct krb5_plugin *pl; + /* Note: refactored plugin API only supports common plugin layout */ + struct heim_plugin *pl; - pl = heim_alloc(sizeof(*pl), "krb5-plugin", plugin_free); - if (pl == NULL) { - ret = krb5_enomem(context); - } else { - pl->ftable = symbol; - ret = pl->ftable->init(context, &pl->ctx); - if (ret == 0) { - heim_array_append_value(plugins, pl); - _krb5_debug(context, 5, "Registered %s plugin", name); - } - heim_release(pl); - } - } else - ret = 0; /* ignore duplicates to match previous behavior */ + pl = heim_alloc(sizeof(*pl), "heim-plugin", plugin_free); + if (pl == NULL) { + ret = heim_enomem(context); + } else { + pl->ftable = ftable; + ret = pl->ftable->init(pcontext, &pl->ctx); + if (ret == 0) { + heim_array_append_value(plugins, pl); + heim_debug(context, 5, "Registered %s plugin", name); + } + heim_release(pl); + } + } HEIMDAL_MUTEX_unlock(&modules_mutex); @@ -261,32 +253,34 @@ krb5_plugin_register(krb5_context context, #ifdef HAVE_DLOPEN static char * -resolve_origin(const char *di) +resolve_origin(const char *di, const char *module) { #ifdef HAVE_DLADDR Dl_info dl_info; const char *dname; char *path, *p; -#endif if (strncmp(di, "$ORIGIN/", sizeof("$ORIGIN/") - 1) && strcmp(di, "$ORIGIN")) return strdup(di); -#ifndef HAVE_DLADDR - return strdup(LIBDIR "/plugin/krb5"); -#else /* !HAVE_DLADDR */ di += sizeof("$ORIGIN") - 1; - if (dladdr(_krb5_load_plugins, &dl_info) == 0) - return strdup(LIBDIR "/plugin/krb5"); + if (dladdr(heim_plugin_register, &dl_info) == 0) { + char *s = NULL; + + /* dladdr() failed */ + if (asprintf(&s, LIBDIR "/plugin/%s", module) == -1) + return NULL; + return s; + } dname = dl_info.dli_fname; #ifdef _WIN32 p = strrchr(dname, '\\'); if (p == NULL) #endif - p = strrchr(dname, '/'); + p = strrchr(dname, '/'); if (p) { if (asprintf(&path, "%.*s%s", (int) (p - dname), dname, di) == -1) return NULL; @@ -296,29 +290,40 @@ resolve_origin(const char *di) } return path; -#endif /* !HAVE_DLADDR */ +#else + char *s = NULL; + + if (strncmp(di, "$ORIGIN/", sizeof("$ORIGIN/") - 1) && + strcmp(di, "$ORIGIN")) + return strdup(di); + if (asprintf(&s, LIBDIR "/plugin/%s", module) == -1) + return NULL; + return s; +#endif /* HAVE_DLADDR */ } #endif /* HAVE_DLOPEN */ /** - * Load plugins (new system) for the given module @name (typically - * "krb5") from the given directory @paths. + * Load plugins (new system) for the given module @module from the given + * directory @paths. * * Inputs: * - * @context A krb5_context - * @name Name of plugin module (typically "krb5") - * @paths Array of directory paths where to look + * @context A heim_context + * @module Name of plugin module (typically "krb5") + * @paths Array of directory paths where to look */ -KRB5_LIB_FUNCTION void KRB5_LIB_CALL -_krb5_load_plugins(krb5_context context, const char *name, const char **paths) +void +heim_load_plugins(heim_context context, + const char *module, + const char **paths) { #ifdef HAVE_DLOPEN - heim_string_t s = heim_string_create(name); - heim_dict_t module, modules; + heim_string_t s = heim_string_create(module); + heim_dict_t mod, modules; struct dirent *entry; - krb5_error_code ret; + heim_error_code ret; const char **di; char *dirname = NULL; DIR *d; @@ -326,8 +331,8 @@ _krb5_load_plugins(krb5_context context, const char *name, const char **paths) char *plugin_prefix; size_t plugin_prefix_len; - if (asprintf(&plugin_prefix, "plugin_%s_", name) == -1) - return; + if (asprintf(&plugin_prefix, "plugin_%s_", module) == -1) + return; plugin_prefix_len = (plugin_prefix ? strlen(plugin_prefix) : 0); #endif @@ -335,115 +340,119 @@ _krb5_load_plugins(krb5_context context, const char *name, const char **paths) modules = copy_modules(); - module = heim_dict_copy_value(modules, s); - if (module == NULL) { - module = heim_dict_create(11); - if (module == NULL) { - HEIMDAL_MUTEX_unlock(&modules_mutex); - heim_release(s); - heim_release(modules); - return; - } - heim_dict_set_value(modules, s, module); + mod = heim_dict_copy_value(modules, s); + if (mod == NULL) { + mod = heim_dict_create(11); + if (mod == NULL) { + HEIMDAL_MUTEX_unlock(&modules_mutex); + heim_release(s); + heim_release(modules); + return; + } + heim_dict_set_value(modules, s, mod); } heim_release(s); heim_release(modules); for (di = paths; *di != NULL; di++) { free(dirname); - dirname = resolve_origin(*di); + dirname = resolve_origin(*di, module); if (dirname == NULL) continue; - d = opendir(dirname); - if (d == NULL) - continue; - rk_cloexec_dir(d); + d = opendir(dirname); + if (d == NULL) + continue; + rk_cloexec_dir(d); - while ((entry = readdir(d)) != NULL) { - char *n = entry->d_name; - char *path = NULL; - heim_string_t spath; - struct krb5_dso *p; + while ((entry = readdir(d)) != NULL) { + char *n = entry->d_name; + char *path = NULL; + heim_string_t spath; + struct heim_dso *p; - /* skip . and .. */ - if (n[0] == '.' && (n[1] == '\0' || (n[1] == '.' && n[2] == '\0'))) - continue; + /* skip . and .. */ + if (n[0] == '.' && (n[1] == '\0' || (n[1] == '.' && n[2] == '\0'))) + continue; - ret = 0; + ret = 0; #ifdef _WIN32 - /* - * On Windows, plugins must be loaded from the same directory as - * heimdal.dll (typically the assembly directory) and must have - * the name form "plugin__.dll". - */ - { - char *ext; + /* + * On Windows, plugins must be loaded from the same directory as + * heimdal.dll (typically the assembly directory) and must have + * the name form "plugin__.dll". + */ + { + char *ext; - if (strnicmp(n, plugin_prefix, plugin_prefix_len)) - continue; - ext = strrchr(n, '.'); - if (ext == NULL || stricmp(ext, ".dll")) - continue; + if (strnicmp(n, plugin_prefix, plugin_prefix_len)) + continue; + ext = strrchr(n, '.'); + if (ext == NULL || stricmp(ext, ".dll")) + continue; - ret = asprintf(&path, "%s\\%s", dirname, n); - if (ret < 0 || path == NULL) - continue; - } + ret = asprintf(&path, "%s\\%s", dirname, n); + if (ret < 0 || path == NULL) + continue; + } #endif #ifdef __APPLE__ - { /* support loading bundles on MacOS */ - size_t len = strlen(n); - if (len > 7 && strcmp(&n[len - 7], ".bundle") == 0) - ret = asprintf(&path, "%s/%s/Contents/MacOS/%.*s", dirname, n, (int)(len - 7), n); - } + { /* support loading bundles on MacOS */ + size_t len = strlen(n); + if (len > 7 && strcmp(&n[len - 7], ".bundle") == 0) + ret = asprintf(&path, "%s/%s/Contents/MacOS/%.*s", dirname, n, (int)(len - 7), n); + } #endif - if (ret < 0 || path == NULL) - ret = asprintf(&path, "%s/%s", dirname, n); + if (ret < 0 || path == NULL) + ret = asprintf(&path, "%s/%s", dirname, n); - if (ret < 0 || path == NULL) - continue; + if (ret < 0 || path == NULL) + continue; - spath = heim_string_create(n); - if (spath == NULL) { - free(path); - continue; - } + spath = heim_string_create(n); + if (spath == NULL) { + free(path); + continue; + } - /* check if already cached */ - p = heim_dict_copy_value(module, spath); - if (p == NULL) { - p = heim_alloc(sizeof(*p), "krb5-dso", dso_dealloc); - if (p) - p->dsohandle = dlopen(path, RTLD_LOCAL|RTLD_LAZY|RTLD_GROUP); - if (p && p->dsohandle) { - p->path = heim_retain(spath); - p->plugins_by_name = heim_dict_create(11); - heim_dict_set_value(module, spath, p); - } - } + /* check if already cached */ + p = heim_dict_copy_value(mod, spath); + if (p == NULL) { + p = heim_alloc(sizeof(*p), "heim-dso", dso_dealloc); + if (p) + p->dsohandle = dlopen(path, RTLD_LOCAL|RTLD_LAZY|RTLD_GROUP); + if (p && p->dsohandle) { + p->path = heim_retain(spath); + p->plugins_by_name = heim_dict_create(11); + heim_dict_set_value(mod, spath, p); + } + } heim_release(p); - heim_release(spath); - free(path); - } - closedir(d); + heim_release(spath); + free(path); + } + closedir(d); } free(dirname); HEIMDAL_MUTEX_unlock(&modules_mutex); - heim_release(module); + heim_release(mod); #ifdef _WIN32 if (plugin_prefix) - free(plugin_prefix); + free(plugin_prefix); #endif #endif /* HAVE_DLOPEN */ } /** - * Unload plugins (new system) + * Unload plugins of the given @module name. + * + * Params: + * + * @module Name of module whose plusins to unload. */ -KRB5_LIB_FUNCTION void KRB5_LIB_CALL -_krb5_unload_plugins(krb5_context context, const char *name) +void +heim_unload_plugins(heim_context context, const char *module) { - heim_string_t sname = heim_string_create(name); + heim_string_t sname = heim_string_create(module); heim_dict_t modules; HEIMDAL_MUTEX_lock(&modules_mutex); @@ -458,14 +467,16 @@ _krb5_unload_plugins(krb5_context context, const char *name) } struct iter_ctx { - krb5_context context; + heim_context context; + heim_pcontext pcontext; heim_string_t n; - struct krb5_plugin_data *caller; + struct heim_plugin_data *caller; int flags; heim_array_t result; - krb5_error_code (KRB5_LIB_CALL *func)(krb5_context, const void *, void *, void *); + int32_t (HEIM_LIB_CALL *func)(void *, const void *, void *, void *); void *userctx; - krb5_error_code ret; + int32_t ret; + int32_t plugin_no_handle_retval; }; #ifdef HAVE_DLOPEN @@ -476,33 +487,34 @@ struct iter_ctx { * instance validation. */ static heim_array_t -add_dso_plugin_struct(krb5_context context, - const char *dsopath, - void *dsohandle, - const char *name) +add_dso_plugin_struct(heim_context context, + heim_pcontext pcontext, + const char *dsopath, + void *dsohandle, + const char *name) { - krb5_error_code ret; - krb5_plugin_common_ftable_p cpm; - struct krb5_plugin *pl; + heim_error_code ret; + heim_plugin_common_ftable_p cpm; + struct heim_plugin *pl; heim_array_t plugins; if (dsohandle == NULL) - return NULL; + return NULL; /* suppress error here because we may be looking for a different plugin type */ - cpm = (krb5_plugin_common_ftable_p)dlsym(dsohandle, name); + cpm = (heim_plugin_common_ftable_p)dlsym(dsohandle, name); if (cpm == NULL) - return NULL; + return NULL; - krb5_warnx(context, "plugin %s uses deprecated loading mechanism", dsopath); + heim_warnx(context, "plugin %s uses deprecated loading mechanism", dsopath); - pl = heim_alloc(sizeof(*pl), "krb5-plugin", plugin_free); + pl = heim_alloc(sizeof(*pl), "heim-plugin", plugin_free); - ret = cpm->init(context, &pl->ctx); + ret = cpm->init(pcontext, &pl->ctx); if (ret) { - krb5_warn(context, ret, "plugin %s failed to initialize", dsopath); - heim_release(pl); - return NULL; + heim_warn(context, ret, "plugin %s failed to initialize", dsopath); + heim_release(pl); + return NULL; } pl->ftable = cpm; @@ -514,38 +526,38 @@ add_dso_plugin_struct(krb5_context context, return plugins; } -static krb5_boolean -validate_plugin_deps(krb5_context context, - struct krb5_plugin_data *caller, - const char *dsopath, - krb5_get_instance_func_t get_instance) +static int +validate_plugin_deps(heim_context context, + struct heim_plugin_data *caller, + const char *dsopath, + heim_get_instance_func_t get_instance) { size_t i; if (get_instance == NULL) { - krb5_warnx(context, "plugin %s omitted instance callback", - dsopath); - return FALSE; + heim_warnx(context, "plugin %s omitted instance callback", + dsopath); + return FALSE; } for (i = 0; caller->deps[i] != NULL; i++) { - uintptr_t heim_instance, plugin_instance; + uintptr_t heim_instance, plugin_instance; - heim_instance = caller->get_instance(caller->deps[i]); - plugin_instance = get_instance(caller->deps[i]); + heim_instance = caller->get_instance(caller->deps[i]); + plugin_instance = get_instance(caller->deps[i]); - if (heim_instance == 0 || plugin_instance == 0) - continue; + if (heim_instance == 0 || plugin_instance == 0) + continue; - if (heim_instance != plugin_instance) { - krb5_warnx(context, "plugin %s library %s linked against different " - "instance of Heimdal (got %zu, us %zu)", - dsopath, caller->deps[i], - plugin_instance, heim_instance); - return FALSE; - } - _krb5_debug(context, 10, "Validated plugin library dependency %s for %s", - caller->deps[i], dsopath); + if (heim_instance != plugin_instance) { + heim_warnx(context, "plugin %s library %s linked against different " + "instance of Heimdal (got %zu, us %zu)", + dsopath, caller->deps[i], + plugin_instance, heim_instance); + return FALSE; + } + heim_debug(context, 10, "Validated plugin library dependency %s for %s", + caller->deps[i], dsopath); } return TRUE; @@ -553,62 +565,63 @@ validate_plugin_deps(krb5_context context, /* * New interface from Heimdal 8 where a DSO can export a load function - * that can return both a libkrb5 instance identifier along with an array - * of plugins. + * that can return both a Heimdal instance identifier along with an + * array of plugins. */ static heim_array_t -add_dso_plugins_load_fn(krb5_context context, - struct krb5_plugin_data *caller, - const char *dsopath, - void *dsohandle) +add_dso_plugins_load_fn(heim_context context, + heim_pcontext pcontext, + struct heim_plugin_data *caller, + const char *dsopath, + void *dsohandle) { - krb5_error_code ret; + heim_error_code ret; heim_array_t plugins; - krb5_plugin_load_t load_fn; + heim_plugin_load_t load_fn; char *sym; size_t i; - krb5_get_instance_func_t get_instance; + heim_get_instance_func_t get_instance; size_t n_ftables; - krb5_plugin_common_ftable_cp *ftables; + heim_plugin_common_ftable_cp *ftables; if (asprintf(&sym, "%s_plugin_load", caller->name) == -1) - return NULL; + return NULL; /* suppress error here because we may be looking for a different plugin type */ - load_fn = (krb5_plugin_load_t)dlsym(dsohandle, sym); + load_fn = (heim_plugin_load_t)dlsym(dsohandle, sym); free(sym); if (load_fn == NULL) - return NULL; + return NULL; - ret = load_fn(context, &get_instance, &n_ftables, &ftables); + ret = load_fn(pcontext, &get_instance, &n_ftables, &ftables); if (ret) { - krb5_warn(context, ret, "plugin %s failed to load", dsopath); + heim_warn(context, ret, "plugin %s failed to load", dsopath); - /* fallback to loading structure directly */ - return add_dso_plugin_struct(context, dsopath, - dsohandle, caller->name); + /* fallback to loading structure directly */ + return add_dso_plugin_struct(context, pcontext, dsopath, + dsohandle, caller->name); } if (!validate_plugin_deps(context, caller, dsopath, get_instance)) - return NULL; + return NULL; plugins = heim_array_create(); for (i = 0; i < n_ftables; i++) { - krb5_plugin_common_ftable_cp cpm = ftables[i]; - struct krb5_plugin *pl; + heim_plugin_common_ftable_cp cpm = ftables[i]; + struct heim_plugin *pl; - pl = heim_alloc(sizeof(*pl), "krb5-plugin", plugin_free); + pl = heim_alloc(sizeof(*pl), "heim-plugin", plugin_free); - ret = cpm->init(context, &pl->ctx); - if (ret) { - krb5_warn(context, ret, "plugin %s[%zu] failed to initialize", - dsopath, i); - } else { - pl->ftable = rk_UNCONST(cpm); - heim_array_append_value(plugins, pl); - } - heim_release(pl); + ret = cpm->init(pcontext, &pl->ctx); + if (ret) { + heim_warn(context, ret, "plugin %s[%zu] failed to initialize", + dsopath, i); + } else { + pl->ftable = rk_UNCONST(cpm); + heim_array_append_value(plugins, pl); + } + heim_release(pl); } return plugins; @@ -619,56 +632,57 @@ static void reduce_by_version(heim_object_t value, void *ctx, int *stop) { struct iter_ctx *s = ctx; - struct krb5_plugin *pl = value; + struct heim_plugin *pl = value; if (pl->ftable && pl->ftable->version >= s->caller->min_version) - heim_array_append_value(s->result, pl); + heim_array_append_value(s->result, pl); } static void search_modules(heim_object_t key, heim_object_t value, void *ctx) { struct iter_ctx *s = ctx; - struct krb5_dso *p = value; + struct heim_dso *p = value; heim_array_t plugins = heim_dict_copy_value(p->plugins_by_name, s->n); #ifdef HAVE_DLOPEN if (plugins == NULL && p->dsohandle) { - const char *path = heim_string_get_utf8(p->path); + const char *path = heim_string_get_utf8(p->path); - plugins = add_dso_plugins_load_fn(s->context, - s->caller, - path, - p->dsohandle); - if (plugins) { - heim_dict_set_value(p->plugins_by_name, s->n, plugins); - _krb5_debug(s->context, 5, "Loaded %zu %s %s plugin%s from %s", - heim_array_get_length(plugins), - s->caller->module, s->caller->name, - heim_array_get_length(plugins) > 1 ? "s" : "", - path); - } + plugins = add_dso_plugins_load_fn(s->context, + s->pcontext, + s->caller, + path, + p->dsohandle); + if (plugins) { + heim_dict_set_value(p->plugins_by_name, s->n, plugins); + heim_debug(s->context, 5, "Loaded %zu %s %s plugin%s from %s", + heim_array_get_length(plugins), + s->caller->module, s->caller->name, + heim_array_get_length(plugins) > 1 ? "s" : "", + path); + } } #endif /* HAVE_DLOPEN */ if (plugins) { - heim_array_iterate_f(plugins, s, reduce_by_version); - heim_release(plugins); + heim_array_iterate_f(plugins, s, reduce_by_version); + heim_release(plugins); } } static void eval_results(heim_object_t value, void *ctx, int *stop) { - struct krb5_plugin *pl = value; + struct heim_plugin *pl = value; struct iter_ctx *s = ctx; - if (s->ret != KRB5_PLUGIN_NO_HANDLE) - return; + if (s->ret != s->plugin_no_handle_retval) + return; - s->ret = s->func(s->context, pl->ftable, pl->ctx, s->userctx); - if (s->ret != KRB5_PLUGIN_NO_HANDLE - && !(s->flags & KRB5_PLUGIN_INVOKE_ALL)) + s->ret = s->func(s->pcontext, pl->ftable, pl->ctx, s->userctx); + if (s->ret != s->plugin_no_handle_retval + && !(s->flags & HEIM_PLUGIN_INVOKE_ALL)) *stop = 1; } @@ -684,42 +698,47 @@ eval_results(heim_object_t value, void *ctx, int *stop) * outputs, if any, in @userctx. * * All loaded and registered plugins are invoked via @func until @func - * returns something other than KRB5_PLUGIN_NO_HANDLE. Plugins that - * have nothing to do for the given arguments should return - * KRB5_PLUGIN_NO_HANDLE. + * returns something other than @nohandle. Plugins that have nothing to + * do for the given arguments should return the same value as @nohandle. * * Inputs: * - * @context A krb5_context + * @context A heim_context + * @pcontext A context for the plugin, such as a krb5_context * @module Name of module (typically "krb5") * @name Name of pluggable interface (e.g., "kuserok") * @min_version Lowest acceptable plugin minor version number * @flags Flags (none defined at this time) + * @nohandle Flags (none defined at this time) * @userctx Callback data for the callback function @func * @func A callback function, invoked once per-plugin * * Outputs: None, other than the return value and such outputs as are * gathered by @func. */ -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -_krb5_plugin_run_f(krb5_context context, - struct krb5_plugin_data *caller, - int flags, - void *userctx, - krb5_error_code (KRB5_LIB_CALL *func)(krb5_context, const void *, void *, void *)) +heim_error_code +heim_plugin_run_f(heim_context context, + heim_pcontext pcontext, + struct heim_plugin_data *caller, + int flags, + int32_t nohandle, + void *userctx, + int32_t (HEIM_LIB_CALL *func)(void *, const void *, void *, void *)) { heim_string_t m = heim_string_create(caller->module); heim_dict_t modules, dict = NULL; struct iter_ctx s; s.context = context; + s.pcontext = pcontext; s.caller = caller; s.n = heim_string_create(caller->name); s.flags = flags; s.result = heim_array_create(); s.func = func; s.userctx = userctx; - s.ret = KRB5_PLUGIN_NO_HANDLE; + s.plugin_no_handle_retval = nohandle; + s.ret = nohandle; HEIMDAL_MUTEX_lock(&modules_mutex); @@ -729,7 +748,7 @@ _krb5_plugin_run_f(krb5_context context, /* Add loaded plugins to s.result array */ if (dict) - heim_dict_iterate_f(dict, &s, search_modules); + heim_dict_iterate_f(dict, &s, search_modules); /* We don't need to hold modules_mutex during plugin invocation */ HEIMDAL_MUTEX_unlock(&modules_mutex); @@ -745,27 +764,3 @@ _krb5_plugin_run_f(krb5_context context, return s.ret; } - -/** - * Return a cookie identifying this instance of a library. - * - * Inputs: - * - * @context A krb5_context - * @module Our library name or a library we depend on - * - * Outputs: The instance cookie - * - * @ingroup krb5_support - */ - -KRB5_LIB_FUNCTION uintptr_t KRB5_LIB_CALL -krb5_get_instance(const char *libname) -{ - static const char *instance = "libkrb5"; - - if (strcmp(libname, "krb5") == 0) - return (uintptr_t)instance; - - return 0; -} diff --git a/lib/base/version-script.map b/lib/base/version-script.map index 656277e37..2d10bab6c 100644 --- a/lib/base/version-script.map +++ b/lib/base/version-script.map @@ -6,11 +6,16 @@ HEIMDAL_BASE_1.0 { _bsearch_file_info; _bsearch_file_open; _bsearch_text; - __heim_string_constant; DllMain; + et_heim_error_table; heim_abort; heim_abortv; + heim_add_debug_dest; + heim_addlog_dest; + heim_addlog_func; + heim_add_warn_dest; heim_alloc; + _heim_alloc_object; heim_array_append_value; heim_array_copy_value; heim_array_create; @@ -19,9 +24,9 @@ HEIMDAL_BASE_1.0 { heim_array_get_length; heim_array_get_type_id; heim_array_get_value; + heim_array_insert_value; heim_array_iterate_f; heim_array_iterate_reverse_f; - heim_array_insert_value; heim_array_set_value; heim_auto_release; heim_auto_release_create; @@ -29,25 +34,72 @@ HEIMDAL_BASE_1.0 { heim_base_once_f; heim_bool_create; heim_bool_val; + heim_clear_error_message; + heim_closelog; heim_cmp; + heim_config_copy; + heim_config_file_free; + heim_config_free_strings; + heim_config_get; + heim_config_get_bool; + heim_config_get_bool_default; + heim_config_get_entry; + heim_config_get_int; + heim_config_get_int_default; + heim_config_get_list; + heim_config_get_next; + heim_config_get_string; + heim_config_get_string_default; + heim_config_get_strings; + heim_config_get_time; + heim_config_get_time_default; + heim_config_parse_dir_multi; + heim_config_parse_file; + heim_config_parse_file_multi; + heim_config_parse_string_multi; + heim_config_vget; + heim_config_vget_bool; + heim_config_vget_bool_default; + heim_config_vget_int; + heim_config_vget_int_default; + heim_config_vget_list; + heim_config_vget_next; + heim_config_vget_string; + heim_config_vget_string_default; + heim_config_vget_strings; + heim_config_vget_time; + heim_config_vget_time_default; + heim_context_free; + heim_context_get_homedir_access; + heim_context_get_log_utc; + heim_context_get_time_fmt; + heim_context_init; + heim_context_set_homedir_access; + heim_context_set_log_utc; + heim_context_set_msg_cb; + heim_context_set_time_fmt; + _heim_create_type; heim_data_create; - heim_data_ref_create; heim_data_get_data; heim_data_get_length; heim_data_get_ptr; heim_data_get_type_id; + heim_data_ref_create; heim_data_ref_get_type_id; heim_db_begin; heim_db_clone; heim_db_commit; heim_db_copy_value; + heim_db_create; heim_db_delete_key; heim_db_get_type_id; + _heim_db_get_value; heim_db_iterate_f; - heim_db_create; heim_db_register; heim_db_rollback; heim_db_set_value; + heim_debug; + heim_description; heim_dict_copy_value; heim_dict_create; heim_dict_delete_key; @@ -55,40 +107,81 @@ HEIMDAL_BASE_1.0 { heim_dict_get_value; heim_dict_iterate_f; heim_dict_set_value; + heim_enomem; heim_error_append; heim_error_copy_string; - heim_error_create_opt; heim_error_create; - heim_error_createv; heim_error_create_enomem; + heim_error_create_opt; + heim_error_createv; heim_error_get_code; + heim_expand_path_tokens; + heim_expand_path_tokensv; + heim_free_error_message; + heim_get_debug_dest; + heim_get_error_message; heim_get_hash; + _heim_get_isa; + _heim_get_isaextra; heim_get_tid; + heim_get_warn_dest; + heim_have_debug; + heim_initlog; + heim_json_copy_serialize; heim_json_create; heim_json_create_with_bytes; - heim_json_copy_serialize; + heim_load_plugins; + heim_log; + heim_log_msg; + _heim_make_permanent; heim_null_create; heim_number_create; heim_number_get_int; heim_number_get_type_id; + heim_openlog; + heim_path_copy; heim_path_create; heim_path_delete; heim_path_get; - heim_path_copy; + heim_path_vcopy; heim_path_vcreate; heim_path_vdelete; heim_path_vget; - heim_path_vcopy; + heim_plugin_register; + heim_plugin_run_f; + heim_prepend_error_message; heim_release; heim_retain; + heim_set_debug_dest; + heim_set_error_message; + heim_set_warn_dest; heim_show; heim_sorted_text_file_dbtype; + __heim_string_constant; heim_string_create; heim_string_create_with_bytes; heim_string_create_with_format; heim_string_get_type_id; heim_string_get_utf8; heim_string_ref_create; + _heim_type_get_tid; + heim_unload_plugins; + heim_vdebug; + heim_vlog; + heim_vlog_msg; + heim_vprepend_error_message; + heim_vset_error_message; + heim_vwarn; + heim_vwarnx; + heim_w32_delete_key; + heim_w32_getspecific; + heim_w32_key_create; + heim_w32_service_thread_detach; + heim_w32_setspecific; + heim_warn; + heim_warnx; + initialize_heim_error_table; + initialize_heim_error_table_r; local: *; }; diff --git a/lib/base/warn.c b/lib/base/warn.c index 84e04155b..2376a518e 100644 --- a/lib/base/warn.c +++ b/lib/base/warn.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2020 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -36,22 +36,22 @@ # pragma warning(disable: 4716) #endif -#include "krb5_locl.h" +#include "baselocl.h" #include -static krb5_error_code _warnerr(krb5_context context, int do_errtext, - krb5_error_code code, int level, const char *fmt, va_list ap) +static heim_error_code _warnerr(heim_context context, int do_errtext, + heim_error_code code, int level, const char *fmt, va_list ap) __attribute__ ((__format__ (__printf__, 5, 0))); -static krb5_error_code -_warnerr(krb5_context context, int do_errtext, - krb5_error_code code, int level, const char *fmt, va_list ap) +static heim_error_code +_warnerr(heim_context context, int do_errtext, + heim_error_code code, int level, const char *fmt, va_list ap) { char xfmt[7] = ""; const char *args[2], **arg; char *msg = NULL; const char *err_str = NULL; - krb5_error_code ret; + heim_error_code ret; args[0] = args[1] = NULL; arg = args; @@ -64,10 +64,10 @@ _warnerr(krb5_context context, int do_errtext, return ENOMEM; *arg++ = msg; } - if(context && do_errtext){ + if (context && do_errtext) { strlcat(xfmt, "%s", sizeof(xfmt)); - err_str = krb5_get_error_message(context, code); + err_str = heim_get_error_message(context, code); if (err_str != NULL) { *arg = err_str; } else { @@ -75,28 +75,23 @@ _warnerr(krb5_context context, int do_errtext, } } - if(context && context->warn_dest) - krb5_log(context, context->warn_dest, level, xfmt, args[0], args[1]); + if (context && heim_get_warn_dest(context)) + heim_log(context, heim_get_warn_dest(context), level, xfmt, args[0], + args[1]); else warnx(xfmt, args[0], args[1]); free(msg); - krb5_free_error_message(context, err_str); + heim_free_error_message(context, err_str); return 0; } #define FUNC(ETEXT, CODE, LEVEL) \ - krb5_error_code ret; \ + heim_error_code ret; \ va_list ap; \ va_start(ap, fmt); \ ret = _warnerr(context, ETEXT, CODE, LEVEL, fmt, ap); \ va_end(ap); -#define FUNC_NORET(ETEXT, CODE, LEVEL) \ - va_list ap; \ - va_start(ap, fmt); \ - (void) _warnerr(context, ETEXT, CODE, LEVEL, fmt, ap); \ - va_end(ap); - #undef __attribute__ #define __attribute__(X) @@ -109,11 +104,11 @@ _warnerr(krb5_context context, int do_errtext, * @param fmt message to print * @param ap arguments * - * @ingroup krb5_error + * @ingroup heim_error */ -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_vwarn(krb5_context context, krb5_error_code code, +heim_error_code +heim_vwarn(heim_context context, heim_error_code code, const char *fmt, va_list ap) __attribute__ ((__format__ (__printf__, 3, 0))) { @@ -128,11 +123,11 @@ krb5_vwarn(krb5_context context, krb5_error_code code, * @param code error code of the last error * @param fmt message to print * - * @ingroup krb5_error + * @ingroup heim_error */ -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_warn(krb5_context context, krb5_error_code code, const char *fmt, ...) +heim_error_code +heim_warn(heim_context context, heim_error_code code, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 3, 4))) { FUNC(1, code, 1); @@ -146,11 +141,11 @@ krb5_warn(krb5_context context, krb5_error_code code, const char *fmt, ...) * @param fmt message to print * @param ap arguments * - * @ingroup krb5_error + * @ingroup heim_error */ -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_vwarnx(krb5_context context, const char *fmt, va_list ap) +heim_error_code +heim_vwarnx(heim_context context, const char *fmt, va_list ap) __attribute__ ((__format__ (__printf__, 2, 0))) { return _warnerr(context, 0, 0, 1, fmt, ap); @@ -162,198 +157,13 @@ krb5_vwarnx(krb5_context context, const char *fmt, va_list ap) * @param context A Kerberos 5 context. * @param fmt message to print * - * @ingroup krb5_error + * @ingroup heim_error */ -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_warnx(krb5_context context, const char *fmt, ...) +heim_error_code +heim_warnx(heim_context context, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 2, 3))) { FUNC(0, 0, 1); return ret; } - -/** - * Log a warning to the log, default stderr, include bthe error from - * the last failure and then exit. - * - * @param context A Kerberos 5 context - * @param eval the exit code to exit with - * @param code error code of the last error - * @param fmt message to print - * @param ap arguments - * - * @ingroup krb5_error - */ - -KRB5_LIB_NORETURN_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_verr(krb5_context context, int eval, krb5_error_code code, - const char *fmt, va_list ap) - __attribute__ ((__noreturn__, __format__ (__printf__, 4, 0))) -{ - _warnerr(context, 1, code, 0, fmt, ap); - exit(eval); - UNREACHABLE(return 0); -} - -/** - * Log a warning to the log, default stderr, include bthe error from - * the last failure and then exit. - * - * @param context A Kerberos 5 context - * @param eval the exit code to exit with - * @param code error code of the last error - * @param fmt message to print - * - * @ingroup krb5_error - */ - -KRB5_LIB_NORETURN_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_err(krb5_context context, int eval, krb5_error_code code, - const char *fmt, ...) - __attribute__ ((__noreturn__, __format__ (__printf__, 4, 5))) -{ - FUNC_NORET(1, code, 0); - exit(eval); - UNREACHABLE(return 0); -} - -/** - * Log a warning to the log, default stderr, and then exit. - * - * @param context A Kerberos 5 context - * @param eval the exit code to exit with - * @param fmt message to print - * @param ap arguments - * - * @ingroup krb5_error - */ - -KRB5_LIB_NORETURN_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_verrx(krb5_context context, int eval, const char *fmt, va_list ap) - __attribute__ ((__noreturn__, __format__ (__printf__, 3, 0))) -{ - _warnerr(context, 0, 0, 0, fmt, ap); - exit(eval); - UNREACHABLE(return 0); -} - -/** - * Log a warning to the log, default stderr, and then exit. - * - * @param context A Kerberos 5 context - * @param eval the exit code to exit with - * @param fmt message to print - * - * @ingroup krb5_error - */ - -KRB5_LIB_NORETURN_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_errx(krb5_context context, int eval, const char *fmt, ...) - __attribute__ ((__noreturn__, __format__ (__printf__, 3, 4))) -{ - FUNC_NORET(0, 0, 0); - exit(eval); - UNREACHABLE(return 0); -} - -/** - * Log a warning to the log, default stderr, include bthe error from - * the last failure and then abort. - * - * @param context A Kerberos 5 context - * @param code error code of the last error - * @param fmt message to print - * @param ap arguments - * - * @ingroup krb5_error - */ - -KRB5_LIB_NORETURN_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_vabort(krb5_context context, krb5_error_code code, - const char *fmt, va_list ap) - __attribute__ ((__noreturn__, __format__ (__printf__, 3, 0))) -{ - _warnerr(context, 1, code, 0, fmt, ap); - abort(); - UNREACHABLE(return 0); -} - -/** - * Log a warning to the log, default stderr, include the error from - * the last failure and then abort. - * - * @param context A Kerberos 5 context - * @param code error code of the last error - * @param fmt message to print - * @param ... arguments for format string - * - * @ingroup krb5_error - */ - -KRB5_LIB_NORETURN_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_abort(krb5_context context, krb5_error_code code, const char *fmt, ...) - __attribute__ ((__noreturn__, __format__ (__printf__, 3, 4))) -{ - FUNC_NORET(1, code, 0); - abort(); - UNREACHABLE(return 0); -} - -KRB5_LIB_NORETURN_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_vabortx(krb5_context context, const char *fmt, va_list ap) - __attribute__ ((__noreturn__, __format__ (__printf__, 2, 0))) -{ - _warnerr(context, 0, 0, 0, fmt, ap); - abort(); - UNREACHABLE(return 0); -} - -/** - * Log a warning to the log, default stderr, and then abort. - * - * @param context A Kerberos 5 context - * @param fmt printf format string of message to print - * @param ... arguments for format string - * - * @ingroup krb5_error - */ - -KRB5_LIB_NORETURN_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_abortx(krb5_context context, const char *fmt, ...) - __attribute__ ((__noreturn__, __format__ (__printf__, 2, 3))) -{ - FUNC_NORET(0, 0, 0); - abort(); - UNREACHABLE(return 0); -} - -/** - * Set the default logging facility. - * - * @param context A Kerberos 5 context - * @param fac Facility to use for logging. - * - * @ingroup krb5_error - */ - -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_set_warn_dest(krb5_context context, krb5_log_facility *fac) -{ - context->warn_dest = fac; - return 0; -} - -/** - * Get the default logging facility. - * - * @param context A Kerberos 5 context - * - * @ingroup krb5_error - */ - -KRB5_LIB_FUNCTION krb5_log_facility * KRB5_LIB_CALL -krb5_get_warn_dest(krb5_context context) -{ - return context->warn_dest; -} diff --git a/lib/gssapi/NTMakefile b/lib/gssapi/NTMakefile index 7d20d8ebc..5093b9867 100644 --- a/lib/gssapi/NTMakefile +++ b/lib/gssapi/NTMakefile @@ -526,7 +526,8 @@ LIBGSSAPI_LIBS=\ $(LIBCOMERR) LIBGSSAPI_SDKLIBS=\ - $(PTHREAD_LIB) + $(PTHREAD_LIB) \ + Secur32.lib Shell32.lib Advapi32.lib !ifndef STATICLIBS diff --git a/lib/gssapi/mech/context.c b/lib/gssapi/mech/context.c index 5a029b79a..1e608cd82 100644 --- a/lib/gssapi/mech/context.c +++ b/lib/gssapi/mech/context.c @@ -271,7 +271,8 @@ _gss_mg_log(int level, const char *fmt, ...) if (mg->context && _krb5_have_debug(mg->context, level)) { va_start(ap, fmt); - krb5_vlog(mg->context, mg->context->debug_dest, level, fmt, ap); + krb5_vlog(mg->context, heim_get_debug_dest(mg->context->hcontext), + level, fmt, ap); va_end(ap); } diff --git a/lib/hdb/hdb.c b/lib/hdb/hdb.c index c88ad68e8..e55968568 100644 --- a/lib/hdb/hdb.c +++ b/lib/hdb/hdb.c @@ -416,7 +416,7 @@ hdb_list_builtin(krb5_context context, char **list) if (h->create == NULL) { struct cb_s cb_ctx; char *f; - struct krb5_plugin_data hdb_plugin_data; + struct heim_plugin_data hdb_plugin_data; hdb_plugin_data.module = "krb5"; hdb_plugin_data.min_version = HDB_INTERFACE_VERSION; @@ -489,7 +489,7 @@ hdb_create(krb5_context context, HDB **db, const char *filename) cb_ctx.filename = filename; if (cb_ctx.h == NULL || cb_ctx.h->create == NULL) { - struct krb5_plugin_data hdb_plugin_data; + struct heim_plugin_data hdb_plugin_data; hdb_plugin_data.module = "krb5"; hdb_plugin_data.min_version = HDB_INTERFACE_VERSION; diff --git a/lib/kadm5/private.h b/lib/kadm5/private.h index 43b7cd2d1..719abff44 100644 --- a/lib/kadm5/private.h +++ b/lib/kadm5/private.h @@ -197,7 +197,7 @@ enum kadm_recover_mode { #define KADMIN_APPL_VERSION "KADM0.1" #define KADMIN_OLD_APPL_VERSION "KADM0.0" -extern struct krb5_plugin_data kadm5_hook_plugin_data; +extern struct heim_plugin_data kadm5_hook_plugin_data; #include "kadm5-private.h" diff --git a/lib/kadm5/server_hooks.c b/lib/kadm5/server_hooks.c index 79a4af126..0973382e4 100644 --- a/lib/kadm5/server_hooks.c +++ b/lib/kadm5/server_hooks.c @@ -37,7 +37,7 @@ static const char *kadm5_hook_plugin_deps[] = { NULL }; -struct krb5_plugin_data kadm5_hook_plugin_data = { +struct heim_plugin_data kadm5_hook_plugin_data = { "kadm5", "kadm5_hook", KADM5_HOOK_VERSION_V1, diff --git a/lib/krb5/Makefile.am b/lib/krb5/Makefile.am index c37f25116..e93184218 100644 --- a/lib/krb5/Makefile.am +++ b/lib/krb5/Makefile.am @@ -80,8 +80,7 @@ libkrb5_la_LIBADD = \ $(LIBADD_roken) \ $(PTHREAD_LIBADD) \ $(LIB_add_key) \ - $(LIB_door_create) \ - $(LIB_dlopen) + $(LIB_door_create) librfc3961_la_LIBADD = \ $(top_builddir)/lib/asn1/libasn1.la \ @@ -95,12 +94,11 @@ librfc3961_la_LIBADD = \ $(LIBADD_roken) \ $(PTHREAD_LIBADD) \ $(LIB_add_key) \ - $(LIB_door_create) \ - $(LIB_dlopen) + $(LIB_door_create) lib_LTLIBRARIES = libkrb5.la -ERR_FILES = krb5_err.c krb_err.c heim_err.c k524_err.c k5e1_err.c kx509_err.c +ERR_FILES = krb5_err.c krb_err.c k524_err.c k5e1_err.c kx509_err.c libkrb5_la_CPPFLAGS = \ -DBUILD_KRB5_LIB \ @@ -128,7 +126,6 @@ dist_libkrb5_la_SOURCES = \ ccache_plugin.h \ changepw.c \ codec.c \ - common_plugin.h \ config_file.c \ convert_creds.c \ constants.c \ @@ -283,7 +280,7 @@ ALL_OBJECTS += $(test_renew_OBJECTS) ALL_OBJECTS += $(test_rfc3961_OBJECTS) $(ALL_OBJECTS): $(srcdir)/krb5-protos.h $(srcdir)/krb5-private.h -$(ALL_OBJECTS): krb5_err.h heim_err.h k524_err.h k5e1_err.h \ +$(ALL_OBJECTS): krb5_err.h k524_err.h k5e1_err.h \ krb_err.h k524_err.h kx509_err.h librfc3961_la_SOURCES = \ @@ -388,14 +385,13 @@ dist_include_HEADERS = \ noinst_HEADERS = $(srcdir)/krb5-private.h -nodist_include_HEADERS = krb5_err.h heim_err.h k524_err.h k5e1_err.h kx509_err.h +nodist_include_HEADERS = krb5_err.h k524_err.h k5e1_err.h kx509_err.h # XXX use nobase_include_HEADERS = krb5/locate_plugin.h krb5dir = $(includedir)/krb5 krb5_HEADERS = \ an2ln_plugin.h \ ccache_plugin.h \ - common_plugin.h \ db_plugin.h \ kuserok_plugin.h \ locate_plugin.h \ @@ -410,25 +406,22 @@ CLEANFILES = \ test-store-data \ krb5_err.c krb5_err.h \ krb_err.c krb_err.h \ - heim_err.c heim_err.h \ k524_err.c k524_err.h \ k5e1_err.c k5e1_err.h \ kx509_err.c kx509_err.h -$(libkrb5_la_OBJECTS): krb5_err.h krb_err.h heim_err.h k524_err.h k5e1_err.h kx509_err.h +$(libkrb5_la_OBJECTS): krb5_err.h krb_err.h k524_err.h k5e1_err.h kx509_err.h test_config_strings.out: test_config_strings.cfg $(CP) $(srcdir)/test_config_strings.cfg test_config_strings.out EXTRA_DIST = \ NTMakefile \ - config_reg.c \ dll.c \ libkrb5-exports.def.in \ verify_krb5_conf-version.rc \ krb5_err.et \ krb_err.et \ - heim_err.et \ k524_err.et \ k5e1_err.et \ kx509_err.et \ @@ -445,8 +438,6 @@ krb5_err.h: krb5_err.et krb_err.h: krb_err.et -heim_err.h: heim_err.et - k524_err.h: k524_err.et k5e1_err.h: k5e1_err.et diff --git a/lib/krb5/NTMakefile b/lib/krb5/NTMakefile index 04310b1f0..d3eca00b6 100644 --- a/lib/krb5/NTMakefile +++ b/lib/krb5/NTMakefile @@ -48,7 +48,6 @@ libkrb5_OBJS = \ $(OBJ)\changepw.obj \ $(OBJ)\codec.obj \ $(OBJ)\config_file.obj \ - $(OBJ)\config_reg.obj \ $(OBJ)\constants.obj \ $(OBJ)\context.obj \ $(OBJ)\convert_creds.obj \ @@ -167,12 +166,10 @@ libkrb5_OBJS = \ libkrb5_gen_OBJS= \ $(OBJ)\krb5_err.obj \ $(OBJ)\krb_err.obj \ - $(OBJ)\heim_err.obj \ $(OBJ)\k524_err.obj \ $(OBJ)\k5e1_err.obj INCFILES= \ - $(INCDIR)\heim_err.h \ $(INCDIR)\k524_err.h \ $(INCDIR)\k5e1_err.h \ $(INCDIR)\kx509_err.h \ @@ -188,7 +185,6 @@ INCFILES= \ $(INCDIR)\crypto.h \ $(INCDIR)\an2ln_plugin.h \ $(INCDIR)\ccache_plugin.h \ - $(INCDIR)\common_plugin.h \ $(INCDIR)\db_plugin.h \ $(INCDIR)\kuserok_plugin.h \ $(INCDIR)\locate_plugin.h \ @@ -214,7 +210,6 @@ dist_libkrb5_la_SOURCES = \ changepw.c \ codec.c \ config_file.c \ - config_reg.c \ constants.c \ context.c \ copy_host_realm.c \ @@ -350,11 +345,6 @@ $(OBJ)\krb_err.c $(OBJ)\krb_err.h: krb_err.et $(BINDIR)\compile_et.exe $(SRCDIR)\krb_err.et cd $(SRCDIR) -$(OBJ)\heim_err.c $(OBJ)\heim_err.h: heim_err.et - cd $(OBJ) - $(BINDIR)\compile_et.exe $(SRCDIR)\heim_err.et - cd $(SRCDIR) - $(OBJ)\k524_err.c $(OBJ)\k524_err.h: k524_err.et cd $(OBJ) $(BINDIR)\compile_et.exe $(SRCDIR)\k524_err.et diff --git a/lib/krb5/aname_to_localname.c b/lib/krb5/aname_to_localname.c index b002b3982..11f270d49 100644 --- a/lib/krb5/aname_to_localname.c +++ b/lib/krb5/aname_to_localname.c @@ -82,7 +82,7 @@ plcallback(krb5_context context, static const char *an2ln_plugin_deps[] = { "krb5", NULL }; -static struct krb5_plugin_data +static struct heim_plugin_data an2ln_plugin_data = { "krb5", KRB5_PLUGIN_AN2LN, diff --git a/lib/krb5/cache.c b/lib/krb5/cache.c index 8c117d0d7..8a606529a 100644 --- a/lib/krb5/cache.c +++ b/lib/krb5/cache.c @@ -2022,8 +2022,8 @@ _get_default_cc_name_from_registry(krb5_context context, HKEY hkBase) if (code != ERROR_SUCCESS) return NULL; - ccname = _krb5_parse_reg_value_as_string(context, hk_k5, "ccname", - REG_NONE, 0); + ccname = heim_parse_reg_value_as_string(context, hk_k5, "ccname", + REG_NONE, 0); RegCloseKey(hk_k5); @@ -2062,8 +2062,8 @@ _krb5_set_default_cc_name_to_registry(krb5_context context, krb5_ccache id) if (ret < 0) goto cleanup; - ret = _krb5_store_string_to_reg_value(context, hk_k5, "ccname", - REG_SZ, ccname, -1, 0); + ret = heim_store_string_to_reg_value(context, hk_k5, "ccname", + REG_SZ, ccname, -1, 0); cleanup: diff --git a/lib/krb5/ccache_plugin.h b/lib/krb5/ccache_plugin.h index 11e8f61f9..e0fda4c94 100644 --- a/lib/krb5/ccache_plugin.h +++ b/lib/krb5/ccache_plugin.h @@ -41,6 +41,6 @@ krb5_error_code KRB5_CALLCONV ccache_ops_plugin_load(krb5_context context, krb5_get_instance_func_t *func, size_t *n_ftables, - krb5_plugin_common_ftable_p **ftables); + heim_plugin_common_ftable_p **ftables); #endif /* HEIMDAL_KRB5_CCACHE_PLUGIN_H */ diff --git a/lib/krb5/config_file.c b/lib/krb5/config_file.c new file mode 100644 index 000000000..dc6016b60 --- /dev/null +++ b/lib/krb5/config_file.c @@ -0,0 +1,691 @@ +/* + * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2009 Apple 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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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 "krb5_locl.h" + +#if defined(HAVE_FRAMEWORK_COREFOUNDATION) +#include +#endif + +/** + * Parse configuration files in the given directory and add the result + * into res. Only files whose names consist only of alphanumeric + * characters, hyphen, and underscore, will be parsed, though files + * ending in ".conf" will also be parsed. + * + * This interface can be used to parse several configuration directories + * into one resulting krb5_config_section by calling it repeatably. + * + * @param context a Kerberos 5 context. + * @param dname a directory name to a Kerberos configuration file + * @param res the returned result, must be free with krb5_free_config_files(). + * @return Return an error code or 0, see krb5_get_error_message(). + * + * @ingroup krb5_support + */ + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_config_parse_dir_multi(krb5_context context, + const char *dname, + krb5_config_section **res) +{ + krb5_error_code ret; + + if ((ret = heim_config_parse_dir_multi(context->hcontext, dname, + res)) == HEIM_ERR_CONFIG_BADFORMAT) + return KRB5_CONFIG_BADFORMAT; + return ret; +} + +/** + * Parse a configuration file and add the result into res. This + * interface can be used to parse several configuration files into one + * resulting krb5_config_section by calling it repeatably. + * + * @param context a Kerberos 5 context. + * @param fname a file name to a Kerberos configuration file + * @param res the returned result, must be free with krb5_free_config_files(). + * @return Return an error code or 0, see krb5_get_error_message(). + * + * @ingroup krb5_support + */ + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_config_parse_file_multi(krb5_context context, + const char *fname, + krb5_config_section **res) +{ + krb5_error_code ret; + + if ((ret = heim_config_parse_file_multi(context->hcontext, fname, + res)) == HEIM_ERR_CONFIG_BADFORMAT) + return KRB5_CONFIG_BADFORMAT; + return ret; +} + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_config_parse_file(krb5_context context, + const char *fname, + krb5_config_section **res) +{ + *res = NULL; + return krb5_config_parse_file_multi(context, fname, res); +} + +/** + * Free configuration file section, the result of + * krb5_config_parse_file() and krb5_config_parse_file_multi(). + * + * @param context A Kerberos 5 context + * @param s the configuration section to free + * + * @return returns 0 on successes, otherwise an error code, see + * krb5_get_error_message() + * + * @ingroup krb5_support + */ + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_config_file_free(krb5_context context, krb5_config_section *s) +{ + return heim_config_file_free(context->hcontext, s); +} + +#ifndef HEIMDAL_SMALLER + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +_krb5_config_copy(krb5_context context, + krb5_config_section *c, + krb5_config_section **head) +{ + return heim_config_copy(context->hcontext, c, head); +} + +#endif /* HEIMDAL_SMALLER */ + +KRB5_LIB_FUNCTION const void * KRB5_LIB_CALL +_krb5_config_get_next(krb5_context context, + const krb5_config_section *c, + const krb5_config_binding **pointer, + int type, + ...) +{ + const char *ret; + va_list args; + + va_start(args, type); + ret = heim_config_vget_next(context->hcontext, c ? c : context->cf, + pointer, type, args); + va_end(args); + return ret; +} + +KRB5_LIB_FUNCTION const void * KRB5_LIB_CALL +_krb5_config_vget_next(krb5_context context, + const krb5_config_section *c, + const krb5_config_binding **pointer, + int type, + va_list args) +{ + return heim_config_vget_next(context->hcontext, c ? c : context->cf, + pointer, type, args); +} + +KRB5_LIB_FUNCTION const void * KRB5_LIB_CALL +_krb5_config_get(krb5_context context, + const krb5_config_section *c, + int type, + ...) +{ + const void *ret; + va_list args; + + va_start(args, type); + ret = heim_config_vget(context->hcontext, c ? c : context->cf, type, args); + va_end(args); + return ret; +} + + +KRB5_LIB_FUNCTION const void * KRB5_LIB_CALL +_krb5_config_vget(krb5_context context, + const krb5_config_section *c, + int type, + va_list args) +{ + return heim_config_vget(context->hcontext, c ? c : context->cf, type, args); +} + +/** + * Get a list of configuration binding list for more processing + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param ... a list of names, terminated with NULL. + * + * @return NULL if configuration list is not found, a list otherwise + * + * @ingroup krb5_support + */ + +KRB5_LIB_FUNCTION const krb5_config_binding * KRB5_LIB_CALL +krb5_config_get_list(krb5_context context, + const krb5_config_section *c, + ...) +{ + const krb5_config_binding *ret; + va_list args; + + va_start(args, c); + ret = heim_config_vget_list(context->hcontext, c ? c : context->cf, args); + va_end(args); + return ret; +} + +/** + * Get a list of configuration binding list for more processing + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param args a va_list of arguments + * + * @return NULL if configuration list is not found, a list otherwise + * + * @ingroup krb5_support + */ + +KRB5_LIB_FUNCTION const krb5_config_binding * KRB5_LIB_CALL +krb5_config_vget_list(krb5_context context, + const krb5_config_section *c, + va_list args) +{ + return heim_config_vget_list(context->hcontext, c ? c : context->cf, args); +} + +/** + * Returns a "const char *" to a string in the configuration database. + * The string may not be valid after a reload of the configuration + * database so a caller should make a local copy if it needs to keep + * the string. + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param ... a list of names, terminated with NULL. + * + * @return NULL if configuration string not found, a string otherwise + * + * @ingroup krb5_support + */ + +KRB5_LIB_FUNCTION const char* KRB5_LIB_CALL +krb5_config_get_string(krb5_context context, + const krb5_config_section *c, + ...) +{ + const char *ret; + va_list args; + + va_start(args, c); + ret = heim_config_vget_string(context->hcontext, c ? c : context->cf, + args); + va_end(args); + return ret; +} + +/** + * Like krb5_config_get_string(), but uses a va_list instead of ... + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param args a va_list of arguments + * + * @return NULL if configuration string not found, a string otherwise + * + * @ingroup krb5_support + */ + +KRB5_LIB_FUNCTION const char* KRB5_LIB_CALL +krb5_config_vget_string(krb5_context context, + const krb5_config_section *c, + va_list args) +{ + return heim_config_vget_string(context->hcontext, c ? c : context->cf, + args); +} + +/** + * Like krb5_config_vget_string(), but instead of returning NULL, + * instead return a default value. + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param def_value the default value to return if no configuration + * found in the database. + * @param args a va_list of arguments + * + * @return a configuration string + * + * @ingroup krb5_support + */ + +KRB5_LIB_FUNCTION const char* KRB5_LIB_CALL +krb5_config_vget_string_default(krb5_context context, + const krb5_config_section *c, + const char *def_value, + va_list args) +{ + return heim_config_vget_string_default(context->hcontext, + c ? c : context->cf, def_value, + args); +} + +/** + * Like krb5_config_get_string(), but instead of returning NULL, + * instead return a default value. + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param def_value the default value to return if no configuration + * found in the database. + * @param ... a list of names, terminated with NULL. + * + * @return a configuration string + * + * @ingroup krb5_support + */ + +KRB5_LIB_FUNCTION const char* KRB5_LIB_CALL +krb5_config_get_string_default(krb5_context context, + const krb5_config_section *c, + const char *def_value, + ...) +{ + const char *ret; + va_list args; + + va_start(args, def_value); + ret = heim_config_vget_string_default(context->hcontext, + c ? c : context->cf, def_value, + args); + va_end(args); + return ret; +} + +/** + * Get a list of configuration strings, free the result with + * krb5_config_free_strings(). + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param args a va_list of arguments + * + * @return TRUE or FALSE + * + * @ingroup krb5_support + */ + +KRB5_LIB_FUNCTION char ** KRB5_LIB_CALL +krb5_config_vget_strings(krb5_context context, + const krb5_config_section *c, + va_list args) +{ + return heim_config_vget_strings(context->hcontext, + c ? c : context->cf, args); +} + +/** + * Get a list of configuration strings, free the result with + * krb5_config_free_strings(). + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param ... a list of names, terminated with NULL. + * + * @return TRUE or FALSE + * + * @ingroup krb5_support + */ + +KRB5_LIB_FUNCTION char** KRB5_LIB_CALL +krb5_config_get_strings(krb5_context context, + const krb5_config_section *c, + ...) +{ + va_list ap; + char **ret; + va_start(ap, c); + ret = heim_config_vget_strings(context->hcontext, c ? c : context->cf, ap); + va_end(ap); + return ret; +} + +/** + * Free the resulting strings from krb5_config-get_strings() and + * krb5_config_vget_strings(). + * + * @param strings strings to free + * + * @ingroup krb5_support + */ + +KRB5_LIB_FUNCTION void KRB5_LIB_CALL +krb5_config_free_strings(char **strings) +{ + heim_config_free_strings(strings); +} + +/** + * Like krb5_config_get_bool_default() but with a va_list list of + * configuration selection. + * + * Configuration value to a boolean value, where yes/true and any + * non-zero number means TRUE and other value is FALSE. + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param def_value the default value to return if no configuration + * found in the database. + * @param args a va_list of arguments + * + * @return TRUE or FALSE + * + * @ingroup krb5_support + */ + +KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL +krb5_config_vget_bool_default(krb5_context context, + const krb5_config_section *c, + krb5_boolean def_value, + va_list args) +{ + return heim_config_vget_bool_default(context->hcontext, + c ? c : context->cf, def_value, args); +} + +/** + * krb5_config_get_bool() will convert the configuration + * option value to a boolean value, where yes/true and any non-zero + * number means TRUE and other value is FALSE. + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param args a va_list of arguments + * + * @return TRUE or FALSE + * + * @ingroup krb5_support + */ + +KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL +krb5_config_vget_bool(krb5_context context, + const krb5_config_section *c, + va_list args) +{ + return heim_config_vget_bool_default(context->hcontext, c ? c : + context->cf, FALSE, args); +} + +/** + * krb5_config_get_bool_default() will convert the configuration + * option value to a boolean value, where yes/true and any non-zero + * number means TRUE and other value is FALSE. + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param def_value the default value to return if no configuration + * found in the database. + * @param ... a list of names, terminated with NULL. + * + * @return TRUE or FALSE + * + * @ingroup krb5_support + */ + +KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL +krb5_config_get_bool_default(krb5_context context, + const krb5_config_section *c, + krb5_boolean def_value, + ...) +{ + va_list ap; + krb5_boolean ret; + va_start(ap, def_value); + ret = heim_config_vget_bool_default(context->hcontext, c ? c : context->cf, + def_value, ap); + va_end(ap); + return ret; +} + +/** + * Like krb5_config_get_bool() but with a va_list list of + * configuration selection. + * + * Configuration value to a boolean value, where yes/true and any + * non-zero number means TRUE and other value is FALSE. + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param ... a list of names, terminated with NULL. + * + * @return TRUE or FALSE + * + * @ingroup krb5_support + */ + +KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL +krb5_config_get_bool (krb5_context context, + const krb5_config_section *c, + ...) +{ + va_list ap; + krb5_boolean ret; + va_start(ap, c); + ret = krb5_config_vget_bool (context, c, ap); + va_end(ap); + return ret; +} + +/** + * Get the time from the configuration file using a relative time. + * + * Like krb5_config_get_time_default() but with a va_list list of + * configuration selection. + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param def_value the default value to return if no configuration + * found in the database. + * @param args a va_list of arguments + * + * @return parsed the time (or def_value on parse error) + * + * @ingroup krb5_support + */ + +KRB5_LIB_FUNCTION int KRB5_LIB_CALL +krb5_config_vget_time_default(krb5_context context, + const krb5_config_section *c, + int def_value, + va_list args) +{ + return heim_config_vget_time_default(context->hcontext, c ? c : + context->cf, def_value, args); +} + +/** + * Get the time from the configuration file using a relative time, for example: 1h30s + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param args a va_list of arguments + * + * @return parsed the time or -1 on error + * + * @ingroup krb5_support + */ + +KRB5_LIB_FUNCTION int KRB5_LIB_CALL +krb5_config_vget_time(krb5_context context, + const krb5_config_section *c, + va_list args) +{ + return heim_config_vget_time_default(context->hcontext, + c ? c : context->cf, -1, args); +} + +/** + * Get the time from the configuration file using a relative time, for example: 1h30s + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param def_value the default value to return if no configuration + * found in the database. + * @param ... a list of names, terminated with NULL. + * + * @return parsed the time (or def_value on parse error) + * + * @ingroup krb5_support + */ + +KRB5_LIB_FUNCTION int KRB5_LIB_CALL +krb5_config_get_time_default(krb5_context context, + const krb5_config_section *c, + int def_value, + ...) +{ + va_list ap; + int ret; + va_start(ap, def_value); + ret = heim_config_vget_time_default(context->hcontext, c ? c : context->cf, + def_value, ap); + va_end(ap); + return ret; +} + +/** + * Get the time from the configuration file using a relative time, for example: 1h30s + * + * @param context A Kerberos 5 context. + * @param c a configuration section, or NULL to use the section from context + * @param ... a list of names, terminated with NULL. + * + * @return parsed the time or -1 on error + * + * @ingroup krb5_support + */ + +KRB5_LIB_FUNCTION int KRB5_LIB_CALL +krb5_config_get_time(krb5_context context, + const krb5_config_section *c, + ...) +{ + va_list ap; + int ret; + va_start(ap, c); + ret = heim_config_vget_time(context->hcontext, c ? c : context->cf, ap); + va_end(ap); + return ret; +} + + +KRB5_LIB_FUNCTION int KRB5_LIB_CALL +krb5_config_vget_int_default(krb5_context context, + const krb5_config_section *c, + int def_value, + va_list args) +{ + return heim_config_vget_int_default(context->hcontext, c ? c : context->cf, + def_value, args); +} + +KRB5_LIB_FUNCTION int KRB5_LIB_CALL +krb5_config_vget_int(krb5_context context, + const krb5_config_section *c, + va_list args) +{ + return heim_config_vget_int_default(context->hcontext, c ? c : context->cf, + -1, args); +} + +KRB5_LIB_FUNCTION int KRB5_LIB_CALL +krb5_config_get_int_default(krb5_context context, + const krb5_config_section *c, + int def_value, + ...) +{ + va_list ap; + int ret; + va_start(ap, def_value); + ret = heim_config_vget_int_default(context->hcontext, c ? c : context->cf, + def_value, ap); + va_end(ap); + return ret; +} + +KRB5_LIB_FUNCTION int KRB5_LIB_CALL +krb5_config_get_int(krb5_context context, + const krb5_config_section *c, + ...) +{ + va_list ap; + int ret; + va_start(ap, c); + ret = heim_config_vget_int(context->hcontext, c ? c : context->cf, ap); + va_end(ap); + return ret; +} + + +#ifndef HEIMDAL_SMALLER +/** + * Deprecated: configuration files are not strings + * + * @ingroup krb5_deprecated + */ + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_config_parse_string_multi(krb5_context context, + const char *string, + krb5_config_section **res) + KRB5_DEPRECATED_FUNCTION("Use X instead") +{ + krb5_error_code ret; + + ret = heim_config_parse_string_multi(context->hcontext, string, res); + if (ret == HEIM_ERR_CONFIG_BADFORMAT) + return KRB5_CONFIG_BADFORMAT; + return ret; +} +#endif diff --git a/lib/krb5/context.c b/lib/krb5/context.c index a5c9d8b7c..733497b3c 100644 --- a/lib/krb5/context.c +++ b/lib/krb5/context.c @@ -247,19 +247,14 @@ init_context_from_config_file(krb5_context context) if (tmp || s) { char **p; - if (context->debug_dest) - krb5_closelog(context, context->debug_dest); - - krb5_initlog(context, "libkrb5", &context->debug_dest); - if (s) { - for(p = s; *p; p++) - krb5_addlog_dest(context, context->debug_dest, *p); + for (p = s; *p; p++) + heim_add_debug_dest(context->hcontext, "libkrb5", *p); krb5_config_free_strings(s); } if (tmp) - krb5_addlog_dest(context, context->debug_dest, tmp); + heim_add_debug_dest(context->hcontext, "libkrb5", *p); } tmp = krb5_config_get_string(context, NULL, "libdefaults", @@ -409,6 +404,31 @@ init_context_once(void *ctx) bindtextdomain(HEIMDAL_TEXTDOMAIN, HEIMDAL_LOCALEDIR); } +static void +clear_error_message_cb(heim_err_cb_context ctx) +{ + krb5_clear_error_message((krb5_context)ctx); +} + +static void +free_error_message_cb(heim_err_cb_context ctx, const char *msg) +{ + krb5_free_error_message((krb5_context)ctx, msg); +} + +static const char * +get_error_message_cb(heim_err_cb_context ctx, int32_t ret) +{ + return krb5_get_error_message((krb5_context)ctx, ret); +} + +static void +set_error_message_cb(heim_err_cb_context ctx, int32_t ret, + const char *fmt, va_list args) +{ + krb5_vset_error_message((krb5_context)ctx, ret, fmt, args); +} + /** * Initializes the context structure and reads the configuration file @@ -455,6 +475,16 @@ krb5_init_context(krb5_context *context) return ENOMEM; HEIMDAL_MUTEX_init(&p->mutex); + if ((p->hcontext = heim_context_init()) == NULL) { + ret = ENOMEM; + goto out; + } + + heim_context_set_msg_cb(p->hcontext, (void *)p, + clear_error_message_cb, + free_error_message_cb, + get_error_message_cb, + set_error_message_cb); p->flags |= KRB5_CTX_F_HOMEDIR_ACCESS; @@ -483,9 +513,11 @@ krb5_init_context(krb5_context *context) p->flags |= KRB5_CTX_F_SOCKETS_INITIALIZED; out: - if(ret) { + if (ret) { krb5_free_context(p); p = NULL; + } else { + heim_context_set_log_utc(p->hcontext, p->log_utc); } *context = p; return ret; @@ -549,12 +581,35 @@ krb5_copy_context(krb5_context context, krb5_context *out) HEIMDAL_MUTEX_init(&p->mutex); - if (context->default_cc_name) - p->default_cc_name = strdup(context->default_cc_name); - if (context->default_cc_name_env) - p->default_cc_name_env = strdup(context->default_cc_name_env); - if (context->configured_default_cc_name) - p->configured_default_cc_name = strdup(context->configured_default_cc_name); + if ((p->hcontext = heim_context_init()) == NULL) { + ret = ENOMEM; + goto out; + } + + heim_context_set_log_utc(p->hcontext, context->log_utc); + heim_context_set_msg_cb(p->hcontext, (void *)p, + clear_error_message_cb, + free_error_message_cb, + get_error_message_cb, + set_error_message_cb); + + if (context->default_cc_name && + (p->default_cc_name = strdup(context->default_cc_name)) == NULL) { + ret = ENOMEM; + goto out; + } + if (context->default_cc_name_env && + (p->default_cc_name_env = + strdup(context->default_cc_name_env)) == NULL) { + ret = ENOMEM; + goto out; + } + if (context->configured_default_cc_name && + (p->configured_default_cc_name = + strdup(context->configured_default_cc_name)) == NULL) { + ret = ENOMEM; + goto out; + } if (context->etypes) { ret = copy_etypes(context, context->etypes, &p->etypes); @@ -589,13 +644,6 @@ krb5_copy_context(krb5_context context, krb5_context *out) cc_ops_copy(p, context); kt_ops_copy(p, context); -#if 0 /* XXX */ - if(context->warn_dest != NULL) - ; - if(context->debug_dest != NULL) - ; -#endif - ret = krb5_set_extra_addresses(p, context->extra_addresses); if (ret) goto out; @@ -648,10 +696,6 @@ krb5_free_context(krb5_context context) free(rk_UNCONST(context->cc_ops)); free(context->kt_types); krb5_clear_error_message(context); - if(context->warn_dest != NULL) - krb5_closelog(context, context->warn_dest); - if(context->debug_dest != NULL) - krb5_closelog(context, context->debug_dest); krb5_set_extra_addresses(context, NULL); krb5_set_ignore_addresses(context, NULL); krb5_set_send_to_kdc_func(context, NULL, NULL); @@ -666,10 +710,16 @@ krb5_free_context(krb5_context context) rk_SOCK_EXIT(); } + heim_context_free(&context->hcontext); memset(context, 0, sizeof(*context)); free(context); } +#ifdef _WIN32 +#define REGPATH_KERBEROS "SOFTWARE\\Kerberos" +#define REGPATH_HEIMDAL "SOFTWARE\\Heimdal" +#endif + /** * Reinit the context from a new set of filenames. * @@ -704,7 +754,8 @@ krb5_set_config_files(krb5_context context, char **filenames) #endif #ifdef _WIN32 - _krb5_load_config_from_registry(context, &tmp); + heim_load_config_from_registry(context->hcontext, REGPATH_KERBEROS, + REGPATH_HEIMDAL, &tmp); #endif krb5_config_file_free(context, context->cf); @@ -846,8 +897,8 @@ _krb5_get_default_config_config_files_from_registry() rcode = RegOpenKeyEx(HKEY_CURRENT_USER, KeyName, 0, KEY_READ, &key); if (rcode == ERROR_SUCCESS) { - config_file = _krb5_parse_reg_value_as_multi_string(NULL, key, "config", - REG_NONE, 0, PATH_SEP); + config_file = heim_parse_reg_value_as_multi_string(NULL, key, "config", + REG_NONE, 0, PATH_SEP); RegCloseKey(key); } @@ -856,8 +907,8 @@ _krb5_get_default_config_config_files_from_registry() rcode = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KeyName, 0, KEY_READ, &key); if (rcode == ERROR_SUCCESS) { - config_file = _krb5_parse_reg_value_as_multi_string(NULL, key, "config", - REG_NONE, 0, PATH_SEP); + config_file = heim_parse_reg_value_as_multi_string(NULL, key, "config", + REG_NONE, 0, PATH_SEP); RegCloseKey(key); } @@ -1587,12 +1638,14 @@ KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL krb5_set_home_dir_access(krb5_context context, krb5_boolean allow) { krb5_boolean old; + if (context) { old = (context->flags & KRB5_CTX_F_HOMEDIR_ACCESS) ? TRUE : FALSE; if (allow) context->flags |= KRB5_CTX_F_HOMEDIR_ACCESS; else context->flags &= ~KRB5_CTX_F_HOMEDIR_ACCESS; + heim_context_set_homedir_access(context->hcontext, allow ? 1 : 0); } else { HEIMDAL_MUTEX_lock(&homedir_mutex); old = allow_homedir; diff --git a/lib/krb5/db_plugin.c b/lib/krb5/db_plugin.c index 45f34ff06..2933bd8ff 100644 --- a/lib/krb5/db_plugin.c +++ b/lib/krb5/db_plugin.c @@ -16,7 +16,7 @@ db_plugins_plcallback(krb5_context context, const void *plug, void *plugctx, static const char *db_plugin_deps[] = { "krb5", NULL }; -static struct krb5_plugin_data +static struct heim_plugin_data db_plugin_data = { "krb5", KRB5_PLUGIN_DB, diff --git a/lib/krb5/expand_path.c b/lib/krb5/expand_path.c new file mode 100644 index 000000000..0b4c5e4a2 --- /dev/null +++ b/lib/krb5/expand_path.c @@ -0,0 +1,89 @@ + +/*********************************************************************** + * Copyright (c) 2009, Secure Endpoints 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. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 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 HOLDER 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 "krb5_locl.h" + +#include + +/** + * Internal function to expand tokens in paths. + * + * Inputs: + * + * @context A krb5_context + * @path_in The path to expand tokens from + * + * Outputs: + * + * @ppath_out Path with expanded tokens (caller must free() this) + */ +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +_krb5_expand_path_tokens(krb5_context context, + const char *path_in, + int filepath, + char **ppath_out) +{ + return heim_expand_path_tokens(context->hcontext, path_in, filepath, + ppath_out, NULL); +} + +/** + * Internal function to expand tokens in paths. + * + * Inputs: + * + * @context A krb5_context + * @path_in The path to expand tokens from + * @ppath_out The expanded path + * @... Variable number of pairs of strings, the first of each + * being a token (e.g., "luser") and the second a string to + * replace it with. The list is terminated by a NULL. + * + * Outputs: + * + * @ppath_out Path with expanded tokens (caller must free() this) + */ +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +_krb5_expand_path_tokensv(krb5_context context, + const char *path_in, + int filepath, + char **ppath_out, ...) +{ + krb5_error_code ret; + va_list ap; + + va_start(ap, ppath_out); + ret = heim_expand_path_tokensv(context->hcontext, path_in, filepath, ppath_out, ap); + va_end(ap); + + return ret; +} diff --git a/lib/krb5/krb5-plugin.7 b/lib/krb5/krb5-plugin.7 index a024bcc43..5f3e9d22b 100644 --- a/lib/krb5/krb5-plugin.7 +++ b/lib/krb5/krb5-plugin.7 @@ -63,21 +63,48 @@ associated header file with the string "plugin_load" (e.g. "krb5_plugin_kuserok_plugin_load" for the plugin for .Xr krb5_kuserok 3 ). -The plugin load function has the following signature: +The plugin load function must be of type +.Va heim_plugin_load_ft +which is: .Bd -literal -offset indent -krb5_error_code -krb5_plugin_kuserok_plugin_load( - krb5_context context, - krb5_get_instance_func_t *get_instance, - size_t *n_plugins, - const common_plugin_ftable *const **plugins); +krb5_error_code HEIM_CALLCONV +my_plugin_load(heim_pcontext context, + krb5_get_instance_func_t *get_instance, + size_t *num_plugins, + heim_plugin_common_ftable_cp **plugins); + +.Ed +where +.Va HEIM_CALLCONV +is +.Va __stdcall +on Windows. +.Pp +The plugin should set the get_instance output parameter to the a +function that will return the instances of its library +dependencies. For example: +.Bd -literal -offset indent +static uintptr_t HEIM_LIB_CALL +my_plugin_get_instance(const char *name) +{ + if (strcmp(name, "krb5") == 0) + return krb5_get_instance(name); + return 0; +} .Ed .Pp -The plugin should set the get_instance output parameter to the a function -that will return the instances of its library dependencies. The output -parameters n_plugins and plugins specify the number of plugins, and an array of -pointers to function tables, respectively. -.Ed +The +.Va get_instance +function is used to check that dynamically-linked plugins are +linked with the same Heimdal shared objects as the one loading +and running the plugin. +.Pp +The output parameters +.Va plugins +and +.Va n_plugins +output an array of pointers to function tabls, and the number of +those, respectively. .Pp The plugin structs for all plugin types always begin with the same three common fields: @@ -88,24 +115,41 @@ common fields: associated header file. .It .Va init -, a pointer to a function with two arguments, a krb5_context and a -void **, returning a krb5_error_code. This function will be called to -initialize a plugin-specific context in the form of a void * that will -be output through the init function's second argument. +, a pointer to a function with two arguments, a +.Va heim_pcontext +(which for krb5 plugins is actually a krb5_context), +and a +.Va void ** +, returning a heim_error_code. This function will be called to +initialize a plugin-specific context in the form of a +.Va void * +that will be output through the init function's second argument. .It .Va fini -, a pointer to a function of one argument, a void *, consisting of the -plugin's context to be destroyed, and returning void. +, a pointer to a function of one argument, a +.Va void * +, consisting of the plugin's context to be destroyed, and +returning +.Va void. .El .Pp -Each plugin type must add zero or more fields to this struct following -the above three. Plugins are typically invoked in no particular order -until one succeeds or fails, or all return a special return value such -as KRB5_PLUGIN_NO_HANDLE to indicate that the plugin was not applicable. -Most plugin types obtain deterministic plugin behavior in spite of the -non-deterministic invocation order by, for example, invoking all plugins -for each "rule" and passing the rule to each plugin with the expectation -that just one plugin will match any given rule. +Each plugin type may add fields to this struct following the above +three. Plugins are typically invoked in no particular order until one +succeeds or fails, or all return a special return value that indicates +that the plugin was not applicable. For krb5 plugins, +.Va KRB5_PLUGIN_NO_HANDLE +indicates that the plugin was not applicable. +.Pp +Heimdal plugin callers either invoke all plugins until one returns an +error or all return +.Va KRB5_PLUGIN_NO_HANDLE +, or invoke all plugins until one returns a value other than +.Va KRB5_PLUGIN_NO_HANDLE +with the expectation that only one plugin would return success and all +oters would return +.Va KRB5_PLUGIN_NO_HANDLE. +Thus Heimdal plugin invokation can be deterministic in spite of +non-deterministic invocation order. .Pp There is a database plugin system intended for many of the uses of databases in Heimdal. The plugin is expected to call @@ -185,8 +229,9 @@ follows: .Bd -literal -offset indent #include +/* Note that `context' here is actually a krb5_context value */ static krb5_error_code -nouser_plug_init(krb5_context context, void **ctx) +nouser_plug_init(heim_pcontext context, void **ctx) { *ctx = NULL; return 0; @@ -230,8 +275,9 @@ an2ln_get_instance(const char *libname) return 0; } +/* Note that `context' here is actually a krb5_context value */ krb5_error_code -an2ln_plugin_load(krb5_context context, +an2ln_plugin_load(heim_pcontext context, krb5_get_instance_func_t *get_instance, size_t *num_plugins, const krb5plugin_an2ln_ftable * const **pplugins) @@ -252,7 +298,7 @@ there exists a built-in plugin with this functionality; see #include static krb5_error_code -reject_plug_init(krb5_context context, void **ctx) +reject_plug_init(heim_context context, void **ctx) { *ctx = NULL; return 0; @@ -295,7 +341,7 @@ kuserok_get_instance(const char *libname) krb5_error_code krb5_plugin_kuserok_plugin_load( - krb5_context context, + heim_context context, krb5_get_instance_func_t *get_instance, size_t *num_plugins, const krb5plugin_kuserok_ftable * const **pplugins) diff --git a/lib/krb5/krb5.h b/lib/krb5/krb5.h index b73f4dc4d..44553386a 100644 --- a/lib/krb5/krb5.h +++ b/lib/krb5/krb5.h @@ -526,21 +526,7 @@ typedef struct krb5_cc_ops { krb5_error_code (KRB5_CALLCONV * get_kdc_offset)(krb5_context, krb5_ccache, krb5_deltat *); } krb5_cc_ops; -struct krb5_log_facility; - -struct krb5_config_binding { - enum { krb5_config_string, krb5_config_list } type; - char *name; - struct krb5_config_binding *next; - union { - char *string; - struct krb5_config_binding *list; - void *generic; - } u; -}; - -typedef struct krb5_config_binding krb5_config_binding; - +typedef struct heim_config_binding krb5_config_binding; typedef krb5_config_binding krb5_config_section; typedef struct krb5_ticket { @@ -684,11 +670,7 @@ typedef void (KRB5_CALLCONV * krb5_log_log_func_t)(krb5_context, void*); typedef void (KRB5_CALLCONV * krb5_log_close_func_t)(void*); -typedef struct krb5_log_facility { - char *program; - int len; - struct facility *val; -} krb5_log_facility; +typedef struct heim_log_facility_s krb5_log_facility; typedef EncAPRepPart krb5_ap_rep_enc_part; diff --git a/lib/krb5/krb5_locl.h b/lib/krb5/krb5_locl.h index 555d05b23..94370b447 100644 --- a/lib/krb5/krb5_locl.h +++ b/lib/krb5/krb5_locl.h @@ -134,7 +134,6 @@ struct ContentInfo; struct AlgorithmIdentifier; typedef struct krb5_pk_init_ctx_data *krb5_pk_init_ctx; struct krb5_dh_moduli; -struct krb5_plugin_data; /* v4 glue */ struct _krb5_krb_auth_data; @@ -234,6 +233,7 @@ typedef uint32_t krb5_enctype_set; * if plugins are not built with a matching version. */ typedef struct krb5_context_data { + heim_context hcontext; krb5_enctype *etypes; krb5_enctype *cfg_etypes; krb5_enctype *etypes_des;/* deprecated */ @@ -249,8 +249,6 @@ typedef struct krb5_context_data { int32_t kdc_usec_offset; krb5_config_section *cf; struct et_list *et_list; - struct krb5_log_facility *warn_dest; - struct krb5_log_facility *debug_dest; const krb5_cc_ops **cc_ops; int num_cc_ops; const char *http_proxy; @@ -399,12 +397,4 @@ struct krb5_pk_init_ctx_data { # define ISPATHSEP(x) (x == '/') #endif -struct krb5_plugin_data { - const char *module; - const char *name; - int min_version; - const char **deps; - krb5_get_instance_func_t get_instance; -}; - #endif /* __KRB5_LOCL_H__ */ diff --git a/lib/krb5/krbhst.c b/lib/krb5/krbhst.c index ea2cafac8..45ba6052b 100644 --- a/lib/krb5/krbhst.c +++ b/lib/krb5/krbhst.c @@ -676,7 +676,7 @@ plcallback(krb5_context context, static const char *locate_plugin_deps[] = { "krb5", NULL }; -static struct krb5_plugin_data +static struct heim_plugin_data locate_plugin_data = { "krb5", KRB5_PLUGIN_LOCATE, diff --git a/lib/krb5/kuserok.c b/lib/krb5/kuserok.c index 03d146436..9d689cae8 100644 --- a/lib/krb5/kuserok.c +++ b/lib/krb5/kuserok.c @@ -457,7 +457,7 @@ krb5_kuserok(krb5_context context, static const char *kuserok_plugin_deps[] = { "krb5", NULL }; -static struct krb5_plugin_data +static struct heim_plugin_data kuserok_plugin_data = { "krb5", KRB5_PLUGIN_KUSEROK, diff --git a/lib/krb5/log.c b/lib/krb5/log.c new file mode 100644 index 000000000..8b2c5433d --- /dev/null +++ b/lib/krb5/log.c @@ -0,0 +1,182 @@ +/* + * Copyright (c) 1997-2006 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2009 Apple 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: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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 "krb5_locl.h" +#include +#include + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_initlog(krb5_context context, + const char *program, + krb5_log_facility **fac) +{ + return heim_initlog(context->hcontext, program, fac); +} + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_addlog_func(krb5_context context, + krb5_log_facility *fac, + int min, + int max, + krb5_log_log_func_t log_func, + krb5_log_close_func_t close_func, + void *data) + KRB5_DEPRECATED_FUNCTION("Use X instead") +{ + return ENOTSUP; +} + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *orig) +{ + return heim_addlog_dest(context->hcontext, f, orig); +} + + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_openlog(krb5_context context, + const char *program, + krb5_log_facility **fac) +{ + krb5_error_code ret; + char **p; + + p = krb5_config_get_strings(context, NULL, "logging", program, NULL); + if (p == NULL) + p = krb5_config_get_strings(context, NULL, "logging", "default", NULL); + ret = heim_openlog(context->hcontext, program, (const char **)p, fac); + krb5_config_free_strings(p); + return ret; +} + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_closelog(krb5_context context, + krb5_log_facility *fac) +{ + heim_closelog(context->hcontext, fac); + return 0; +} + +#undef __attribute__ +#define __attribute__(X) + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_vlog_msg(krb5_context context, + krb5_log_facility *fac, + char **reply, + int level, + const char *fmt, + va_list ap) + __attribute__ ((__format__ (__printf__, 5, 0))) +{ + return heim_vlog_msg(context->hcontext, fac, reply, level, fmt, ap); +} + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_vlog(krb5_context context, + krb5_log_facility *fac, + int level, + const char *fmt, + va_list ap) + __attribute__ ((__format__ (__printf__, 4, 0))) +{ + return heim_vlog_msg(context->hcontext, fac, NULL, level, fmt, ap); +} + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_log_msg(krb5_context context, + krb5_log_facility *fac, + int level, + char **reply, + const char *fmt, + ...) + __attribute__ ((__format__ (__printf__, 5, 6))) +{ + va_list ap; + krb5_error_code ret; + + va_start(ap, fmt); + ret = heim_vlog_msg(context->hcontext, fac, reply, level, fmt, ap); + va_end(ap); + return ret; +} + + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_log(krb5_context context, + krb5_log_facility *fac, + int level, + const char *fmt, + ...) + __attribute__ ((__format__ (__printf__, 4, 5))) +{ + va_list ap; + krb5_error_code ret; + + va_start(ap, fmt); + ret = heim_vlog(context->hcontext, fac, level, fmt, ap); + va_end(ap); + return ret; +} + +void KRB5_LIB_FUNCTION +_krb5_debug(krb5_context context, + int level, + const char *fmt, + ...) + __attribute__ ((__format__ (__printf__, 3, 4))) +{ + va_list ap; + + va_start(ap, fmt); + if (context && context->hcontext) + heim_vdebug(context->hcontext, level, fmt, ap); + va_end(ap); +} + +KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL +_krb5_have_debug(krb5_context context, int level) +{ + if (context == NULL || context->hcontext == NULL) + return 0; + return heim_have_debug(context->hcontext, level); +} + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_set_debug_dest(krb5_context context, const char *program, + const char *log_spec) +{ + return heim_add_debug_dest(context->hcontext, program, log_spec); +} diff --git a/lib/krb5/pcache.c b/lib/krb5/pcache.c index 4c22abb7b..8fbe589d2 100644 --- a/lib/krb5/pcache.c +++ b/lib/krb5/pcache.c @@ -60,7 +60,7 @@ cc_plugin_register_to_context(krb5_context context, const void *plug, void *plug static const char *ccache_plugin_deps[] = { "krb5", NULL }; -static struct krb5_plugin_data +static struct heim_plugin_data ccache_plugin_data = { "krb5", KRB5_PLUGIN_CCACHE, diff --git a/lib/krb5/plugin.c b/lib/krb5/plugin.c new file mode 100644 index 000000000..c7e11f84b --- /dev/null +++ b/lib/krb5/plugin.c @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2018 AuriStor, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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 "krb5_locl.h" +#include "common_plugin.h" + +/* + * Definitions: + * + * module - a category of plugin module, identified by subsystem + * (typically "krb5") + * dso - a library for a module containing a map of plugin + * types to plugins (e.g. "service_locator") + * plugin - a set of callbacks and state that follows the + * common plugin module definition (version, init, fini) + * + * Obviously it would have been clearer to use the term "module" rather than + * "DSO" given there is an internal "DSO", but "module" was already taken... + * + * modules := { module: dsos } + * dsos := { path, dsohandle, plugins-by-name } + * plugins-by-name := { plugin-name: [plug] } + * plug := { ftable, ctx } + * + * Some existing plugin consumers outside libkrb5 use the "krb5" module + * namespace, but going forward the module should match the consumer library + * name (e.g. libhdb should use the "hdb" module rather than "krb5"). + */ + +/** + * Register a plugin symbol name of specific type. + * @param context a Keberos context + * @param type type of plugin symbol + * @param name name of plugin symbol + * @param symbol a pointer to the named symbol + * @return In case of error a non zero error com_err error is returned + * and the Kerberos error string is set. + * + * @ingroup krb5_support + */ + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_plugin_register(krb5_context context, + enum krb5_plugin_type type, + const char *name, + void *symbol) +{ + /* + * It's not clear that PLUGIN_TYPE_FUNC was ever used or supported. It likely + * would have caused _krb5_plugin_run_f() to crash as the previous implementation + * assumed PLUGIN_TYPE_DATA. + */ + if (type != PLUGIN_TYPE_DATA) { + krb5_warnx(context, "krb5_plugin_register: PLUGIN_TYPE_DATA no longer supported"); + return EINVAL; + } + + return heim_plugin_register(context->hcontext, (heim_pcontext)context, + "krb5", name, symbol); +} + +/** + * Load plugins (new system) for the given module @name (typically + * "krb5") from the given directory @paths. + * + * Inputs: + * + * @context A krb5_context + * @name Name of plugin module (typically "krb5") + * @paths Array of directory paths where to look + */ +KRB5_LIB_FUNCTION void KRB5_LIB_CALL +_krb5_load_plugins(krb5_context context, const char *name, const char **paths) +{ + return heim_load_plugins(context->hcontext, name, paths); +} + +/** + * Unload plugins (new system) + */ +KRB5_LIB_FUNCTION void KRB5_LIB_CALL +_krb5_unload_plugins(krb5_context context, const char *name) +{ + heim_unload_plugins(context->hcontext, name); +} + +/** + * Run plugins for the given @module (e.g., "krb5") and @name (e.g., + * "kuserok"). Specifically, the @func is invoked once per-plugin with + * four arguments: the @context, the plugin symbol value (a pointer to a + * struct whose first three fields are the same as common_plugin_ftable), + * a context value produced by the plugin's init method, and @userctx. + * + * @func should unpack arguments for a plugin function and invoke it + * with arguments taken from @userctx. @func should save plugin + * outputs, if any, in @userctx. + * + * All loaded and registered plugins are invoked via @func until @func + * returns something other than KRB5_PLUGIN_NO_HANDLE. Plugins that + * have nothing to do for the given arguments should return + * KRB5_PLUGIN_NO_HANDLE. + * + * Inputs: + * + * @context A krb5_context + * @module Name of module (typically "krb5") + * @name Name of pluggable interface (e.g., "kuserok") + * @min_version Lowest acceptable plugin minor version number + * @flags Flags (none defined at this time) + * @userctx Callback data for the callback function @func + * @func A callback function, invoked once per-plugin + * + * Outputs: None, other than the return value and such outputs as are + * gathered by @func. + */ +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +_krb5_plugin_run_f(krb5_context context, + struct heim_plugin_data *caller, + int flags, + void *userctx, + krb5_error_code (KRB5_LIB_CALL *func)(krb5_context, const void *, void *, void *)) +{ + int32_t (HEIM_LIB_CALL *func2)(void *, const void *, void *, void *) = (void *)func; + return heim_plugin_run_f(context->hcontext, (heim_pcontext)context, caller, + flags, KRB5_PLUGIN_NO_HANDLE, userctx, func2); +} + +/** + * Return a cookie identifying this instance of a library. + * + * Inputs: + * + * @context A krb5_context + * @module Our library name or a library we depend on + * + * Outputs: The instance cookie + * + * @ingroup krb5_support + */ + +KRB5_LIB_FUNCTION uintptr_t KRB5_LIB_CALL +krb5_get_instance(const char *libname) +{ + static const char *instance = "libkrb5"; + + if (strcmp(libname, "krb5") == 0) + return (uintptr_t)instance; + + return 0; +} diff --git a/lib/krb5/send_to_kdc.c b/lib/krb5/send_to_kdc.c index 7fff78ff6..2a18fab0e 100644 --- a/lib/krb5/send_to_kdc.c +++ b/lib/krb5/send_to_kdc.c @@ -98,7 +98,7 @@ realmcallback(krb5_context context, const void *plug, void *plugctx, void *userc static const char *send_to_kdc_plugin_deps[] = { "krb5", NULL }; -static struct krb5_plugin_data +static struct heim_plugin_data send_to_kdc_plugin_data = { "krb5", KRB5_PLUGIN_SEND_TO_KDC, diff --git a/lib/krb5/verify_krb5_conf.c b/lib/krb5/verify_krb5_conf.c index b481e127e..128ebb270 100644 --- a/lib/krb5/verify_krb5_conf.c +++ b/lib/krb5/verify_krb5_conf.c @@ -38,6 +38,9 @@ /* verify krb5.conf */ +#define krb5_config_string heim_config_string +#define krb5_config_list heim_config_list + static int dumpconfig_flag = 0; static int version_flag = 0; static int help_flag = 0; diff --git a/lib/krb5/warn.c b/lib/krb5/warn.c new file mode 100644 index 000000000..65a7db6b8 --- /dev/null +++ b/lib/krb5/warn.c @@ -0,0 +1,330 @@ +/* + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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. + */ + +#if defined(_MSC_VER) +# pragma warning(disable: 4646) +# pragma warning(disable: 4716) +#endif + +#include "krb5_locl.h" +#include + +static krb5_error_code _warnerr(krb5_context context, int do_errtext, + krb5_error_code code, int level, const char *fmt, va_list ap) + __attribute__ ((__format__ (__printf__, 5, 0))); + +static krb5_error_code +_warnerr(krb5_context context, int do_errtext, + krb5_error_code code, int level, const char *fmt, va_list ap) +{ + if (do_errtext) + return heim_vwarn(context ? context->hcontext : NULL, code, fmt, ap); + else + return heim_vwarnx(context ? context->hcontext : NULL, fmt, ap); +} + +#define FUNC_NORET(ETEXT, CODE, LEVEL) \ + va_list ap; \ + va_start(ap, fmt); \ + (void) _warnerr(context, ETEXT, CODE, LEVEL, fmt, ap); \ + va_end(ap); + +#undef __attribute__ +#define __attribute__(X) + +/** + * Log a warning to the log, default stderr, include the error from + * the last failure. + * + * @param context A Kerberos 5 context. + * @param code error code of the last error + * @param fmt message to print + * @param ap arguments + * + * @ingroup krb5_error + */ + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_vwarn(krb5_context context, krb5_error_code code, + const char *fmt, va_list ap) + __attribute__ ((__format__ (__printf__, 3, 0))) +{ + return heim_vwarn(context ? context->hcontext : NULL, code, fmt, ap); +} + +/** + * Log a warning to the log, default stderr, include the error from + * the last failure. + * + * @param context A Kerberos 5 context. + * @param code error code of the last error + * @param fmt message to print + * + * @ingroup krb5_error + */ + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_warn(krb5_context context, krb5_error_code code, const char *fmt, ...) + __attribute__ ((__format__ (__printf__, 3, 4))) +{ + krb5_error_code ret; + va_list ap; + + va_start(ap, fmt); + ret = krb5_vwarn(context, code, fmt, ap); + va_end(ap); + return ret; +} + +/** + * Log a warning to the log, default stderr. + * + * @param context A Kerberos 5 context. + * @param fmt message to print + * @param ap arguments + * + * @ingroup krb5_error + */ + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_vwarnx(krb5_context context, const char *fmt, va_list ap) + __attribute__ ((__format__ (__printf__, 2, 0))) +{ + return heim_vwarnx(context ? context->hcontext : NULL, fmt, ap); +} + +/** + * Log a warning to the log, default stderr. + * + * @param context A Kerberos 5 context. + * @param fmt message to print + * + * @ingroup krb5_error + */ + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_warnx(krb5_context context, const char *fmt, ...) + __attribute__ ((__format__ (__printf__, 2, 3))) +{ + krb5_error_code ret; + va_list ap; + + va_start(ap, fmt); + ret = krb5_vwarnx(context, fmt, ap); + va_end(ap); + return ret; +} + +/** + * Log a warning to the log, default stderr, include bthe error from + * the last failure and then exit. + * + * @param context A Kerberos 5 context + * @param eval the exit code to exit with + * @param code error code of the last error + * @param fmt message to print + * @param ap arguments + * + * @ingroup krb5_error + */ + +KRB5_LIB_NORETURN_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_verr(krb5_context context, int eval, krb5_error_code code, + const char *fmt, va_list ap) + __attribute__ ((__noreturn__, __format__ (__printf__, 4, 0))) +{ + _warnerr(context, 1, code, 0, fmt, ap); + exit(eval); + UNREACHABLE(return 0); +} + +/** + * Log a warning to the log, default stderr, include bthe error from + * the last failure and then exit. + * + * @param context A Kerberos 5 context + * @param eval the exit code to exit with + * @param code error code of the last error + * @param fmt message to print + * + * @ingroup krb5_error + */ + +KRB5_LIB_NORETURN_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_err(krb5_context context, int eval, krb5_error_code code, + const char *fmt, ...) + __attribute__ ((__noreturn__, __format__ (__printf__, 4, 5))) +{ + FUNC_NORET(1, code, 0); + exit(eval); + UNREACHABLE(return 0); +} + +/** + * Log a warning to the log, default stderr, and then exit. + * + * @param context A Kerberos 5 context + * @param eval the exit code to exit with + * @param fmt message to print + * @param ap arguments + * + * @ingroup krb5_error + */ + +KRB5_LIB_NORETURN_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_verrx(krb5_context context, int eval, const char *fmt, va_list ap) + __attribute__ ((__noreturn__, __format__ (__printf__, 3, 0))) +{ + _warnerr(context, 0, 0, 0, fmt, ap); + exit(eval); + UNREACHABLE(return 0); +} + +/** + * Log a warning to the log, default stderr, and then exit. + * + * @param context A Kerberos 5 context + * @param eval the exit code to exit with + * @param fmt message to print + * + * @ingroup krb5_error + */ + +KRB5_LIB_NORETURN_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_errx(krb5_context context, int eval, const char *fmt, ...) + __attribute__ ((__noreturn__, __format__ (__printf__, 3, 4))) +{ + FUNC_NORET(0, 0, 0); + exit(eval); + UNREACHABLE(return 0); +} + +/** + * Log a warning to the log, default stderr, include bthe error from + * the last failure and then abort. + * + * @param context A Kerberos 5 context + * @param code error code of the last error + * @param fmt message to print + * @param ap arguments + * + * @ingroup krb5_error + */ + +KRB5_LIB_NORETURN_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_vabort(krb5_context context, krb5_error_code code, + const char *fmt, va_list ap) + __attribute__ ((__noreturn__, __format__ (__printf__, 3, 0))) +{ + _warnerr(context, 1, code, 0, fmt, ap); + abort(); + UNREACHABLE(return 0); +} + +/** + * Log a warning to the log, default stderr, include the error from + * the last failure and then abort. + * + * @param context A Kerberos 5 context + * @param code error code of the last error + * @param fmt message to print + * @param ... arguments for format string + * + * @ingroup krb5_error + */ + +KRB5_LIB_NORETURN_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_abort(krb5_context context, krb5_error_code code, const char *fmt, ...) + __attribute__ ((__noreturn__, __format__ (__printf__, 3, 4))) +{ + FUNC_NORET(1, code, 0); + abort(); + UNREACHABLE(return 0); +} + +KRB5_LIB_NORETURN_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_vabortx(krb5_context context, const char *fmt, va_list ap) + __attribute__ ((__noreturn__, __format__ (__printf__, 2, 0))) +{ + _warnerr(context, 0, 0, 0, fmt, ap); + abort(); + UNREACHABLE(return 0); +} + +/** + * Log a warning to the log, default stderr, and then abort. + * + * @param context A Kerberos 5 context + * @param fmt printf format string of message to print + * @param ... arguments for format string + * + * @ingroup krb5_error + */ + +KRB5_LIB_NORETURN_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_abortx(krb5_context context, const char *fmt, ...) + __attribute__ ((__noreturn__, __format__ (__printf__, 2, 3))) +{ + FUNC_NORET(0, 0, 0); + abort(); + UNREACHABLE(return 0); +} + +/** + * Set the default logging facility. + * + * @param context A Kerberos 5 context + * @param fac Facility to use for logging. + * + * @ingroup krb5_error + */ + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_set_warn_dest(krb5_context context, krb5_log_facility *fac) +{ + return heim_set_warn_dest(context->hcontext, fac); +} + +/** + * Get the default logging facility. + * + * @param context A Kerberos 5 context + * + * @ingroup krb5_error + */ + +KRB5_LIB_FUNCTION krb5_log_facility * KRB5_LIB_CALL +krb5_get_warn_dest(krb5_context context) +{ + return heim_get_warn_dest(context->hcontext); +} diff --git a/windows/NTMakefile.w32 b/windows/NTMakefile.w32 index f63b46a3b..1cb646339 100644 --- a/windows/NTMakefile.w32 +++ b/windows/NTMakefile.w32 @@ -164,7 +164,7 @@ cdefines=$(cdefines) -DHAVE_CONFIG_H # Windows CNG provider cdefines=$(cdefines) -DHCRYPTO_DEF_PROVIDER=w32crypto cdebug=$(cdebug) /Zi -ldebug=$(ldebug) /DEBUG +ldebug=$(ldebug) /RELEASE localcflags=$(localcflags) /Oy- # Disable warnings: