hack to permit GetEnvironmentVariable usage without requiring getenv() conversion
authorJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 12 Feb 2007 14:54:28 +0000 (14:54 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 12 Feb 2007 14:54:28 +0000 (14:54 +0000)
Windows has a major flaw when it comes to the use of getenv/putenv.
getenv/putenv do not modify the actual environment of the process.
Instead, they modify a copy of the environment block at the time the
C Runtime Library was initialized for the current module.  In other
words, the C Runtime Library environment block for the executable
is not the same as the C Runtime Library environment block for the
krb5_32.dll library, etc.

This results in problems when a process wants to set the default
ccache name outside the krb5_context.  The krb5_context default ccname
disappears when the context is destroyed.  gss_acquire_cred() suffers
from the creation and destruction of krb5_contexts and therefore the
krb5_context default ccname cannot be used to set a default ccname.
Instead, the process environment must be used.

In order to modify the process environment, SetEnvironmentVariable()
must be used.  However, this does not result in the C Runtime Library
environment blocks being updated.  putenv() does not see the definition
of "KRB5CCNAME".

This patch modifies get_os_ccname() for Windows to check
GetEnvironmentVariable() before checking the registry.  This hack will
work as long as there is no "KRB5CCNAME" variable in the C Runtime
Library environment block.

The long term solution is to replace all calls to getenv and putenv
with GetEnvironmentVariable/SetEnvironmentVariable for Windows.

ticket: new
tags: pullup

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@19154 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/krb5/os/ccdefname.c

index 4a9d184cd7ec5a0ab00570bf77d0913dcf5d0307..e5059a5e675f0fc9e16cf2331361335b9ff9198b 100644 (file)
@@ -148,6 +148,15 @@ static krb5_error_code get_from_os(char *name_buf, int name_size)
        char *prefix = krb5_cc_dfl_ops->prefix;
         int size;
         char *p;
+        DWORD gle;
+
+       SetLastError(0);
+       GetEnvironmentVariable(KRB5_ENV_CCNAME, name_buf, name_size);
+       gle = GetLastError();
+       if (gle == 0)
+               return 0;
+       else if (gle != ERROR_ENVVAR_NOT_FOUND)
+               return ENOMEM;
 
        if (get_from_registry(HKEY_CURRENT_USER,
                               name_buf, name_size) != 0)