From 6e717849a9115d6c489ec007d9e7eb38cb30ea1f Mon Sep 17 00:00:00 2001 From: Danilo Almeida Date: Thu, 17 Jun 1999 10:01:28 +0000 Subject: [PATCH] * ccdefname.c (get_from_registry_indirect, try_dir, get_from_os): Extra robustness to win32 code. * init_os_ctx.c (krb5_get_config_files, krb5_free_config_files): Add function to get config files being used for current context with corresponding free function. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@11520 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb5/os/ChangeLog | 9 ++ src/lib/krb5/os/ccdefname.c | 39 +++-- src/lib/krb5/os/init_os_ctx.c | 297 ++++++++++++++++++++++------------ 3 files changed, 225 insertions(+), 120 deletions(-) diff --git a/src/lib/krb5/os/ChangeLog b/src/lib/krb5/os/ChangeLog index fa8e7f03b..c493db665 100644 --- a/src/lib/krb5/os/ChangeLog +++ b/src/lib/krb5/os/ChangeLog @@ -1,3 +1,12 @@ +1999-06-16 Danilo Almeida + + * ccdefname.c (get_from_registry_indirect, try_dir, get_from_os): + Extra robustness to win32 code. + + * init_os_ctx.c (krb5_get_config_files, krb5_free_config_files): + Add function to get config files being used for current + context with corresponding free function. + 1999-06-16 Danilo Almeida * init_os_ctx.c (os_init_paths): Enhance win32 heuristics to use diff --git a/src/lib/krb5/os/ccdefname.c b/src/lib/krb5/os/ccdefname.c index 9cae686e1..11713e724 100644 --- a/src/lib/krb5/os/ccdefname.c +++ b/src/lib/krb5/os/ccdefname.c @@ -51,11 +51,13 @@ static int get_from_registry_indirect(char *name_buf, int name_size) int found = 0; char *cp; + newkey[0] = 0; GetPrivateProfileString(INI_FILES, "RegKRB5CCNAME", "", newkey, sizeof(newkey), KERBEROS_INI); if (!newkey[0]) return 0; + newkey[sizeof(newkey)-1] = 0; cp = strrchr(newkey,'\\'); if (cp) { *cp = '\0'; /* split the string */ @@ -111,6 +113,8 @@ get_from_registry( return 1; } +#define APPEND_KRB5CC "\\krb5cc" + static int try_dir( char* dir, @@ -119,16 +123,18 @@ try_dir( ) { struct _stat s; - static const char APPEND_KRB5CC[] = "\\krb5cc"; if (!dir) return 0; if (_stat(dir, &s)) return 0; if (!(s.st_mode & _S_IFDIR)) return 0; - if (buffer != dir) + if (buffer != dir) { strncpy(buffer, dir, buf_len); - strncat(buffer, APPEND_KRB5CC, buf_len); + buffer[buf_len-1]='\0'; + } + strncat(buffer, APPEND_KRB5CC, buf_len-strlen(buffer)); + buffer[buf_len-1] = '\0'; return 1; } #endif @@ -137,7 +143,7 @@ try_dir( static krb5_error_code get_from_os(char *name_buf, int name_size) { char *prefix = krb5_cc_dfl_ops->prefix; - int len; + int size; char *p; if (get_from_registry(HKEY_CURRENT_USER, @@ -151,23 +157,26 @@ static krb5_error_code get_from_os(char *name_buf, int name_size) if (get_from_registry_indirect(name_buf, name_size) != 0) return 0; - strncpy(name_buf, prefix, name_size); - strncat(name_buf, ":", name_size); + strncpy(name_buf, prefix, name_size); name_buf[name_size - 1] = 0; - len = strlen(name_buf); - p = name_buf + len; - len = name_size - len; + size = name_size - strlen(prefix); + if (size > 0) + strcat(name_buf, ":"); + size--; + p = name_buf + name_size - size; if (!strcmp(prefix, "API")) { - strncpy(p, "krb5cc", len); + strncpy(p, "krb5cc", size); } else if (!strcmp(prefix, "FILE") || !strcmp(prefix, "STDIO")) { - if (!try_dir(getenv("TEMP"), p, len) && - !try_dir(getenv("TMP"), p, len)) + if (!try_dir(getenv("TEMP"), p, size) && + !try_dir(getenv("TMP"), p, size)) { - GetWindowsDirectory(p, len); - strncat(p, "\\krb5cc", len); + int len = GetWindowsDirectory(p, size); + name_buf[name_size - 1] = 0; + if (len < size - sizeof(APPEND_KRB5CC)) + strcat(p, APPEND_KRB5CC); } } else { - strncpy(p, "default_cache_name", len); + strncpy(p, "default_cache_name", size); } name_buf[name_size - 1] = 0; return 0; diff --git a/src/lib/krb5/os/init_os_ctx.c b/src/lib/krb5/os/init_os_ctx.c index fa185838f..d513cba5c 100644 --- a/src/lib/krb5/os/init_os_ctx.c +++ b/src/lib/krb5/os/init_os_ctx.c @@ -26,23 +26,6 @@ #define NEED_WINDOWS #include "k5-int.h" -static krb5_error_code -fixup_os_init_paths_retval(retval) - krb5_error_code retval; -{ - if (retval == ENOENT) - return KRB5_CONFIG_CANTOPEN; - - if ((retval == PROF_SECTION_NOTOP) || - (retval == PROF_SECTION_SYNTAX) || - (retval == PROF_RELATION_SYNTAX) || - (retval == PROF_EXTRA_CBRACE) || - (retval == PROF_MISSING_OBRACE)) - return KRB5_CONFIG_BADFORMAT; - - return retval; -} - #ifdef macintosh static CInfoPBRec theCatInfo; static char *FileBuffer; @@ -114,6 +97,62 @@ char pathbuf[255]; #if defined(_MSDOS) || defined(_WIN32) +static krb5_error_code +get_from_windows_dir( + char **pname + ) +{ + UINT size = GetWindowsDirectory(0, 0); + *pname = malloc(size + 1 + + strlen(DEFAULT_PROFILE_FILENAME) + 1); + if (*pname) + { + GetWindowsDirectory(*pname, size); + strcat(*pname, "\\"); + strcat(*pname, DEFAULT_PROFILE_FILENAME); + return 0; + } else { + return KRB5_CONFIG_CANTOPEN; + } +} + +static krb5_error_code +get_from_module_dir( + char **pname + ) +{ + const DWORD size = 1024; /* fixed buffer */ + int found = 0; + char *p; + char *name; + struct _stat s; + + *pname = 0; + + name = malloc(size); + if (!name) + return ENOMEM; + + if (!GetModuleFileName(GetModuleHandle("krb5_32"), name, size)) + goto cleanup; + + p = name + strlen(name); + while ((p >= name) && (*p != '\\') && (*p != '/')) p--; + if (p < name) + goto cleanup; + p++; + strncpy(p, DEFAULT_PROFILE_FILENAME, size - (p - name)); + name[size - 1] = 0; + found = !_stat(name, &s); + + cleanup: + if (found) + *pname = name; + else + if (name) free(name); + return 0; +} + /* * get_from_registry * @@ -123,7 +162,6 @@ char pathbuf[255]; * about. We maintain the invariant: return value != 0 => * *pbuffer == 0. */ - static krb5_error_code get_from_registry( char** pbuffer, @@ -131,6 +169,7 @@ get_from_registry( ) { HKEY hKey = 0; + LONG rc = 0; DWORD size = 0; krb5_error_code retval = 0; const char *key_path = "Software\\MIT\\Kerberos5"; @@ -146,13 +185,14 @@ get_from_registry( } *pbuffer = 0; - if (RegOpenKeyEx(hBaseKey, key_path, 0, KEY_QUERY_VALUE, - &hKey) != ERROR_SUCCESS) + if ((rc = RegOpenKeyEx(hBaseKey, key_path, 0, KEY_QUERY_VALUE, + &hKey)) != ERROR_SUCCESS) { /* not a real error */ goto cleanup; } - if (RegQueryValueEx(hKey, value_name, 0, 0, 0, &size) != ERROR_MORE_DATA) + rc = RegQueryValueEx(hKey, value_name, 0, 0, 0, &size); + if ((rc != ERROR_SUCCESS) && (rc != ERROR_MORE_DATA)) { /* not a real error */ goto cleanup; @@ -163,7 +203,7 @@ get_from_registry( retval = ENOMEM; goto cleanup; } - if (RegQueryValueEx(hKey, value_name, 0, 0, *pbuffer, &size) != + if ((rc = RegQueryValueEx(hKey, value_name, 0, 0, *pbuffer, &size)) != ERROR_SUCCESS) { /* @@ -186,93 +226,126 @@ get_from_registry( return retval; } +#endif /* _MSDOS || _WIN32 */ + +static void +free_filenames(filenames) + char **filenames; +{ + char **cp; + + if (filenames == 0) + return; + + for (cp = filenames; *cp; cp++) + free(*cp); + free(filenames); +} + static krb5_error_code -os_init_paths(ctx, secure) - krb5_context ctx; +os_get_default_config_files(pfilenames, secure) + char ***pfilenames; krb5_boolean secure; { + char **filenames; +#ifdef macintosh + filenames = malloc(3 * sizeof(char *)); + filenames[0] = GetMacProfilePathName("\pkrb Configuration"); + filenames[1] = GetMacProfilePathName("\pkrb5.ini"); + filenames[2] = 0; +#else /* !macintosh */ +#if defined(_MSDOS) || defined(_WIN32) krb5_error_code retval = 0; char *name = 0; - ctx->profile_secure = secure; - - if (!secure) name = getenv("KRB5_CONFIG"); + if (!secure) + { + char *env = getenv("KRB5_CONFIG"); + if (env) + { + name = malloc(strlen(env) + 1); + if (!name) return ENOMEM; + strcpy(name, env); + } + } if (!name && !secure) { /* HKCU */ retval = get_from_registry(&name, HKEY_CURRENT_USER); - if (retval) - goto cleanup; + if (retval) return retval; } if (!name) { /* HKLM */ retval = get_from_registry(&name, HKEY_LOCAL_MACHINE); - if (retval) - goto cleanup; + if (retval) return retval; } if (!name && !secure) { /* module dir */ - const DWORD size = 1024; /* fixed buffer */ - int found = 0; - name = malloc(size); - if (!name) { - retval = ENOMEM; - goto cleanup; - } - if (GetModuleFileName(0, name, size)) - { - char *p = name + strlen(name); - while ((p >= name) && (*p != '\\') && (*p != '/')) p--; - if (p >= name) - { - struct _stat s; - p++; - strncpy(p, DEFAULT_PROFILE_FILENAME, size - (p - name)); - name[size - 1] = 0; - found = !_stat(name, &s); - } - } else { - /* Module name too long. Oh well. Keep trucking. */ - } - if (!found && name) - { - free(name); - name = 0; - } + retval = get_from_module_dir(&name); + if (retval) return retval; } if (!name) { /* windows dir */ - UINT size = GetWindowsDirectory(0, 0); - name = malloc(size + 1 + - strlen(DEFAULT_PROFILE_FILENAME) + 1); - if (name) - { - GetWindowsDirectory(name, size); - strcat(name, "\\"); - strcat(name, DEFAULT_PROFILE_FILENAME); - } else { - retval = KRB5_CONFIG_CANTOPEN; - } + retval = get_from_windows_dir(&name); } - /* Invariant: name || retval */ - if (!retval) - { - const char *filenames[2]; - filenames[0] = name; - filenames[1] = 0; - retval = profile_init(filenames, &ctx->profile); + if (retval) + return retval; + if (!name) + return KRB5_CONFIG_CANTOPEN; /* should never happen */ + + filenames = malloc(2 * sizeof(char *)); + filenames[0] = name; + filenames[1] = 0; +#else /* !_MSDOS && !_WIN32 */ + char* filepath = 0; + int n_entries, i; + int ent_len; + const char *s, *t; + errcode_t retval; + + if (!secure) filepath = getenv("KRB5_CONFIG"); + if (!filepath) filepath = DEFAULT_PROFILE_PATH; + + /* count the distinct filename components */ + for(s = filepath, n_entries = 1; *s; s++) { + if (*s == ':') + n_entries++; } - cleanup: - if (name) - free(name); - return fixup_os_init_paths_retval(retval); + /* the array is NULL terminated */ + filenames = (char**) malloc((n_entries+1) * sizeof(char*)); + if (filenames == 0) + return ENOMEM; + + /* measure, copy, and skip each one */ + for(s = filepath, i=0; (t = strchr(s, ':')) || (t=s+strlen(s)); s=t+1, i++) + { + ent_len = t-s; + filenames[i] = (char*) malloc(ent_len + 1); + if (filenames[i] == 0) { + /* if malloc fails, free the ones that worked */ + while(--i >= 0) free(filenames[i]); + free(filenames); + return ENOMEM; + } + strncpy(filenames[i], s, ent_len); + filenames[i][ent_len] = 0; + if (*t == 0) { + i++; + break; + } + } + /* cap the array */ + filenames[i] = 0; +#endif /* !_MSDOS && !_WIN32 */ +#endif /* !macintosh */ + *pfilenames = filenames; + return 0; } -#else /* Set the profile paths in the context. If secure is set to TRUE then do not include user paths (from environment variables, etc.) @@ -282,36 +355,34 @@ os_init_paths(ctx, secure) krb5_context ctx; krb5_boolean secure; { - krb5_error_code retval = 0; - char *name = 0; + krb5_error_code retval = 0; + char **filenames = 0; -#if defined(macintosh) - const char *filenames[3]; -#endif - ctx->profile_secure = secure; + ctx->profile_secure = secure; -#ifdef macintosh - filenames[0] = GetMacProfilePathName("\pkrb Configuration"); - filenames[1] = GetMacProfilePathName("\pkrb5.ini"); - filenames[2] = 0; - retval = profile_init(filenames, &ctx->profile); -#else - /* - * When the profile routines are later enhanced, we will try - * including a config file from user's home directory here. - */ - if (!secure) name = getenv("KRB5_CONFIG"); - if(!name) name = DEFAULT_PROFILE_PATH; + retval = os_get_default_config_files(&filenames, secure); - retval = profile_init_path(name, &ctx->profile); -#endif /* macintosh */ + if (!retval) + retval = profile_init(filenames, &ctx->profile); - if (retval) - ctx->profile = 0; + if (filenames) + free_filenames(filenames); + + if (retval) + ctx->profile = 0; + + if (retval == ENOENT) + return KRB5_CONFIG_CANTOPEN; + + if ((retval == PROF_SECTION_NOTOP) || + (retval == PROF_SECTION_SYNTAX) || + (retval == PROF_RELATION_SYNTAX) || + (retval == PROF_EXTRA_CBRACE) || + (retval == PROF_MISSING_OBRACE)) + return KRB5_CONFIG_BADFORMAT; - return fixup_os_init_paths_retval(retval); + return retval; } -#endif /* _MSDOS || _WIN32 */ krb5_error_code krb5_os_init_context(ctx) @@ -367,6 +438,22 @@ krb5_set_config_files(ctx, filenames) return 0; } +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5_get_default_config_files(pfilenames) + char ***pfilenames; +{ + if (!pfilenames) + return EINVAL; + return os_get_default_config_files(pfilenames, FALSE); +} + +KRB5_DLLIMP void KRB5_CALLCONV +krb5_free_config_files(filenames) + char **filenames; +{ + free_filenames(filenames); +} + krb5_error_code krb5_secure_config_files(ctx) krb5_context ctx; -- 2.26.2