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 */
return 1;
}
+#define APPEND_KRB5CC "\\krb5cc"
+
static int
try_dir(
char* 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
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,
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;
#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;
#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
*
* about. We maintain the invariant: return value != 0 =>
* *pbuffer == 0.
*/
-
static krb5_error_code
get_from_registry(
char** pbuffer,
)
{
HKEY hKey = 0;
+ LONG rc = 0;
DWORD size = 0;
krb5_error_code retval = 0;
const char *key_path = "Software\\MIT\\Kerberos5";
}
*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;
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)
{
/*
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.)
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)
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;