For profile name, enhance win32 heuristics to use environment variable
authorDanilo Almeida <dalmeida@mit.edu>
Wed, 16 Jun 1999 05:43:46 +0000 (05:43 +0000)
committerDanilo Almeida <dalmeida@mit.edu>
Wed, 16 Jun 1999 05:43:46 +0000 (05:43 +0000)
(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
src/lib/krb5/os/ccdefname.c
src/lib/krb5/os/init_os_ctx.c

index 0db5a426d826bdacb949a3ef73983750d2dda1fa..fa8e7f03b1a79ae1f94dfb5832c8c032b9d35e7e 100644 (file)
@@ -1,3 +1,14 @@
+1999-06-16  Danilo Almeida  <dalmeida@mit.edu>
+
+       * 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  <meeroh@mit.edu>
 
        * init_os_ctx.c (os_init_paths): added NRL config file name correctly
index d2bba7dfcf84d94c41e3ed6bef09f15407edb7d2..9cae686e1cac5f80a628bc83ad41bdbfc28cd998 100644 (file)
@@ -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
index 324e3c09b448acbc2aec077a4f237f31db0bc06a..fa185838fd8970ac70590b92b63479e6cd829302 100644 (file)
 #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)