From 86887fddd5c90982414d15795a3d259d253bdd41 Mon Sep 17 00:00:00 2001 From: Danilo Almeida Date: Wed, 16 Jun 1999 05:43:46 +0000 Subject: [PATCH] For profile name, enhance win32 heuristics to use environment variable (like Unix) and registry. Also try executable's dir before windows dir if not secure. For ccname, enhance win32 heuristics to use registry properly. Default to API:krb5cc properly, and to use temp dirs before the windows dir. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@11516 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb5/os/ChangeLog | 11 ++ src/lib/krb5/os/ccdefname.c | 103 +++++++++++++--- src/lib/krb5/os/init_os_ctx.c | 217 ++++++++++++++++++++++++++++------ 3 files changed, 281 insertions(+), 50 deletions(-) diff --git a/src/lib/krb5/os/ChangeLog b/src/lib/krb5/os/ChangeLog index 0db5a426d..fa8e7f03b 100644 --- a/src/lib/krb5/os/ChangeLog +++ b/src/lib/krb5/os/ChangeLog @@ -1,3 +1,14 @@ +1999-06-16 Danilo Almeida + + * init_os_ctx.c (os_init_paths): Enhance win32 heuristics to use + environment variable (like Unix) and to use the registry + too. Will try executable's dir before windows dir if + not secure. + + * ccdefname.c (get_from_os): Enhance win32 heuristics to use + registry properly, default to API: properly, + and to use temp dirs before the windows dir. + 1999-06-11 Miro Jurisic * init_os_ctx.c (os_init_paths): added NRL config file name correctly diff --git a/src/lib/krb5/os/ccdefname.c b/src/lib/krb5/os/ccdefname.c index d2bba7dfc..9cae686e1 100644 --- a/src/lib/krb5/os/ccdefname.c +++ b/src/lib/krb5/os/ccdefname.c @@ -33,7 +33,7 @@ #endif #if defined(_WIN32) -static int get_from_registry(char *name_buf, int name_size) +static int get_from_registry_indirect(char *name_buf, int name_size) { /* If the RegKRB5CCNAME variable is set, it will point to * the registry key that has the name of the cache to use. @@ -48,7 +48,6 @@ static int get_from_registry(char *name_buf, int name_size) LONG name_buf_size; HKEY hkey; - DWORD ipType; int found = 0; char *cp; @@ -69,34 +68,108 @@ static int get_from_registry(char *name_buf, int name_size) return 0; name_buf_size = name_size; - if (RegQueryValueEx(hkey, cp, 0, &ipType, + if (RegQueryValueEx(hkey, cp, 0, 0, name_buf, &name_buf_size) != ERROR_SUCCESS) - return 0; - + { + RegCloseKey(hkey); + return 0; + } + + RegCloseKey(hkey); return 1; } + +/* + * get_from_registry + * + * This will find the ccname in the registry. Returns 0 on error, non-zero + * on success. + */ + +static int +get_from_registry( + HKEY hBaseKey, + char *name_buf, + int name_size + ) +{ + HKEY hKey; + DWORD name_buf_size = (DWORD)name_size; + const char *key_path = "Software\\MIT\\Kerberos5"; + const char *value_name = "ccname"; + + if (RegOpenKeyEx(hBaseKey, key_path, 0, KEY_QUERY_VALUE, + &hKey) != ERROR_SUCCESS) + return 0; + if (RegQueryValueEx(hKey, value_name, 0, 0, + name_buf, &name_buf_size) != ERROR_SUCCESS) + { + RegCloseKey(hKey); + return 0; + } + RegCloseKey(hKey); + return 1; +} + +static int +try_dir( + char* dir, + char* buffer, + int buf_len + ) +{ + 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) + strncpy(buffer, dir, buf_len); + strncat(buffer, APPEND_KRB5CC, buf_len); + return 1; +} #endif #if defined(_MSDOS) || defined(_WIN32) static krb5_error_code get_from_os(char *name_buf, int name_size) { - char defname[160]; /* Default value */ char *prefix = krb5_cc_dfl_ops->prefix; int len; + char *p; + + if (get_from_registry(HKEY_CURRENT_USER, + name_buf, name_size) != 0) + return 0; + + if (get_from_registry(HKEY_LOCAL_MACHINE, + name_buf, name_size) != 0) + return 0; - if (get_from_registry(name_buf, name_size) != 0) + if (get_from_registry_indirect(name_buf, name_size) != 0) return 0; - if (!strcmp(prefix, "FILE") || !strcmp(prefix, "STDIO")) { - GetWindowsDirectory (defname, sizeof(defname)-7); - strcat (defname, "\\krb5cc"); + strncpy(name_buf, prefix, name_size); + strncat(name_buf, ":", name_size); + name_buf[name_size - 1] = 0; + len = strlen(name_buf); + p = name_buf + len; + len = name_size - len; + if (!strcmp(prefix, "API")) { + strncpy(p, "krb5cc", len); + } else if (!strcmp(prefix, "FILE") || !strcmp(prefix, "STDIO")) { + if (!try_dir(getenv("TEMP"), p, len) && + !try_dir(getenv("TMP"), p, len)) + { + GetWindowsDirectory(p, len); + strncat(p, "\\krb5cc", len); + } } else { - strcpy (defname, "default_cache_name"); + strncpy(p, "default_cache_name", len); } - sprintf(name_buf, "%s:", prefix); - len = strlen(name_buf); - GetPrivateProfileString(INI_FILES, INI_KRB_CCACHE, defname, - name_buf+len, name_size-len, KERBEROS_INI); + name_buf[name_size - 1] = 0; return 0; } #endif diff --git a/src/lib/krb5/os/init_os_ctx.c b/src/lib/krb5/os/init_os_ctx.c index 324e3c09b..fa185838f 100644 --- a/src/lib/krb5/os/init_os_ctx.c +++ b/src/lib/krb5/os/init_os_ctx.c @@ -26,6 +26,23 @@ #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; @@ -93,7 +110,169 @@ char pathbuf[255]; GetPathname(&krbSpec, &pathbuf); return strdup(pathbuf); } -#endif +#endif /* macintosh */ + +#if defined(_MSDOS) || defined(_WIN32) + +/* + * get_from_registry + * + * This will find a profile in the registry. *pbuffer != 0 if we + * found something. Make sure to free(*pbuffer) when done. It will + * return an error code if there is an error the user should know + * about. We maintain the invariant: return value != 0 => + * *pbuffer == 0. + */ + +static krb5_error_code +get_from_registry( + char** pbuffer, + HKEY hBaseKey + ) +{ + HKEY hKey = 0; + DWORD size = 0; + krb5_error_code retval = 0; + const char *key_path = "Software\\MIT\\Kerberos5"; + const char *value_name = "config"; + + /* a wannabe assertion */ + if (!pbuffer) + { + /* + * We have a programming error! For now, we segfault :) + * There is no good mechanism to deal. + */ + } + *pbuffer = 0; + + if (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) + { + /* not a real error */ + goto cleanup; + } + *pbuffer = malloc(size); + if (!*pbuffer) + { + retval = ENOMEM; + goto cleanup; + } + if (RegQueryValueEx(hKey, value_name, 0, 0, *pbuffer, &size) != + ERROR_SUCCESS) + { + /* + * Let's not call it a real error in case it disappears, but + * we need to free so that we say we did not find anything. + */ + free(*pbuffer); + *pbuffer = 0; + goto cleanup; + } + cleanup: + if (hKey) + RegCloseKey(hKey); + if (retval && *pbuffer) + { + free(*pbuffer); + /* Let's say we did not find anything: */ + *pbuffer = 0; + } + return retval; +} + +static krb5_error_code +os_init_paths(ctx, secure) + krb5_context ctx; + krb5_boolean secure; +{ + krb5_error_code retval = 0; + char *name = 0; + + ctx->profile_secure = secure; + + if (!secure) name = getenv("KRB5_CONFIG"); + if (!name && !secure) + { + /* HKCU */ + retval = get_from_registry(&name, HKEY_CURRENT_USER); + if (retval) + goto cleanup; + } + if (!name) + { + /* HKLM */ + retval = get_from_registry(&name, HKEY_LOCAL_MACHINE); + if (retval) + goto cleanup; + } + 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; + } + } + 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; + } + } + /* Invariant: name || retval */ + if (!retval) + { + const char *filenames[2]; + filenames[0] = name; + filenames[1] = 0; + retval = profile_init(filenames, &ctx->profile); + } + cleanup: + if (name) + free(name); + + return fixup_os_init_paths_retval(retval); +} + +#else /* Set the profile paths in the context. If secure is set to TRUE then do not include user paths (from environment variables, etc.) @@ -108,31 +287,9 @@ os_init_paths(ctx, secure) #if defined(macintosh) const char *filenames[3]; -#elif defined(_MSDOS) || defined(_WIN32) - const char *filenames[2]; #endif - ctx->profile_secure = secure; -#if defined(_MSDOS) || defined(_WIN32) - { - char defname[160]; /* Default value */ - char krb5conf[160]; /* Actual value */ - - GetWindowsDirectory(defname, sizeof(defname) - 10); - strcat (defname, "\\"); - strcat (defname, DEFAULT_PROFILE_FILENAME); - GetPrivateProfileString(INI_FILES, INI_KRB5_CONF, defname, - krb5conf, sizeof(krb5conf), KERBEROS_INI); - name = krb5conf; - - filenames[0] = name; - filenames[1] = 0; - } - - retval = profile_init(filenames, &ctx->profile); - -#else /* _MSDOS || _WIN32 */ #ifdef macintosh filenames[0] = GetMacProfilePathName("\pkrb Configuration"); filenames[1] = GetMacProfilePathName("\pkrb5.ini"); @@ -148,23 +305,13 @@ os_init_paths(ctx, secure) retval = profile_init_path(name, &ctx->profile); #endif /* macintosh */ -#endif /* _MSDOS || _WIN32 */ if (retval) ctx->profile = 0; - if (retval == ENOENT) - retval = 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; + return fixup_os_init_paths_retval(retval); } +#endif /* _MSDOS || _WIN32 */ krb5_error_code krb5_os_init_context(ctx) -- 2.26.2