Windows: NPLogonNotify provide password in all cases
[openafs.git] / src / WINNT / afsd / afslogon.c
index 5a5ff56..e2c89c0 100644 (file)
@@ -1,12 +1,16 @@
 /*
  * Copyright 2000, International Business Machines Corporation and others.
  * All Rights Reserved.
- * 
+ *
  * This software has been released under the terms of the IBM Public
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
  */
 
+#include <afsconfig.h>
+#include <afs/param.h>
+#include <roken.h>
+
 #include "afslogon.h"
 
 #include <io.h>
@@ -18,7 +22,6 @@
 #include <lm.h>
 #include <nb30.h>
 
-#include <afs/param.h>
 #include <afs/stds.h>
 #include <afs/pioctl_nt.h>
 #include <afs/kautils.h>
 #include "afskfw.h"
 #include "lanahelper.h"
 
+/* Allocated in Windows Driver Kit */
+#ifndef WNNC_NET_OPENAFS
+#define WNNC_NET_OPENAFS     0x00390000
+#endif
+
 #include <WINNT\afsreg.h>
 
 DWORD TraceOption = 0;
@@ -37,21 +45,23 @@ HANDLE hDLL;
 
 #define AFS_LOGON_EVENT_NAME TEXT("AFS Logon")
 
-void DebugEvent0(char *a) 
+void DebugEvent0(char *a)
 {
     HANDLE h; char *ptbuf[1];
-    
+
     if (!ISLOGONTRACE(TraceOption))
         return;
-    
+
     h = RegisterEventSource(NULL, AFS_LOGON_EVENT_NAME);
-    ptbuf[0] = a;
-    ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);
-    DeregisterEventSource(h);
+    if (h != INVALID_HANDLE_VALUE) {
+        ptbuf[0] = a;
+        ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 1008, NULL, 1, 0, (const char **)ptbuf, NULL);
+        DeregisterEventSource(h);
+    }
 }
 
 #define MAXBUF_ 512
-void DebugEvent(char *b,...) 
+void DebugEvent(char *b,...)
 {
     HANDLE h; char *ptbuf[1],buf[MAXBUF_+1];
     va_list marker;
@@ -60,13 +70,15 @@ void DebugEvent(char *b,...)
         return;
 
     h = RegisterEventSource(NULL, AFS_LOGON_EVENT_NAME);
-    va_start(marker,b);
-    StringCbVPrintf(buf, MAXBUF_+1,b,marker);
-    buf[MAXBUF_] = '\0';
-    ptbuf[0] = buf;
-    ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);
-    DeregisterEventSource(h);
-    va_end(marker);
+    if (h != INVALID_HANDLE_VALUE) {
+        va_start(marker,b);
+        StringCbVPrintf(buf, MAXBUF_+1,b,marker);
+        buf[MAXBUF_] = '\0';
+        ptbuf[0] = buf;
+        ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 1008, NULL, 1, 0, (const char **)ptbuf, NULL);
+        DeregisterEventSource(h);
+        va_end(marker);
+    }
 }
 
 static HANDLE hInitMutex = NULL;
@@ -74,20 +86,20 @@ static BOOL bInit = FALSE;
 
 BOOLEAN APIENTRY DllEntryPoint(HANDLE dll, DWORD reason, PVOID reserved)
 {
+    WSADATA wsaData;
     hDLL = dll;
+
     switch (reason) {
     case DLL_PROCESS_ATTACH:
-        /* Initialization Mutex */
-       if (!bInit) {
+       /* Initialization Mutex */
+       if (!hInitMutex)
            hInitMutex = CreateMutex(NULL, FALSE, NULL);
-           SetEnvironmentVariable(DO_NOT_REGISTER_VARNAME, "");
-       }
+
+       WSAStartup( MAKEWORD(2,2), &wsaData );
         break;
 
     case DLL_PROCESS_DETACH:
-       /* do nothing on unload because we might 
-        * be reloaded.
-        */
+       WSACleanup();
        CloseHandle(hInitMutex);
        hInitMutex = NULL;
        bInit = FALSE;
@@ -107,21 +119,21 @@ void AfsLogonInit(void)
 {
     if ( bInit == FALSE ) {
         if ( WaitForSingleObject( hInitMutex, INFINITE ) == WAIT_OBJECT_0 ) {
-           /* initAFSDirPath() initializes an array and sets a 
+           /* initAFSDirPath() initializes an array and sets a
             * flag so that the initialization can only occur
-            * once.  No cleanup will be done when the DLL is 
-            * unloaded so the initialization will not be 
+            * once.  No cleanup will be done when the DLL is
+            * unloaded so the initialization will not be
             * performed again on a subsequent reload
             */
            initAFSDirPath();
 
            /* ka_Init initializes a number of error tables.
-            * and then calls ka_CellConfig() which grabs 
+            * and then calls ka_CellConfig() which grabs
             * an afsconf_dir structure via afsconf_Open().
             * Upon a second attempt to call ka_CellConfig()
             * the structure will be released with afsconf_Close()
             * and then re-opened.  Could this corrupt memory?
-            * 
+            *
             * We only need this if we are not using KFW.
             */
            if (!KFW_is_available())
@@ -213,7 +225,7 @@ DWORD APIENTRY NPGetCaps(DWORD index)
     switch (index) {
     case WNNC_NET_TYPE:
         /* Don't have our own type; use somebody else's. */
-        return WNNC_NET_SUN_PC_NFS;
+        return WNNC_NET_OPENAFS;
 
     case WNNC_START:
         /* Say we are already started, even though we might wait after we receive NPLogonNotify */
@@ -222,10 +234,10 @@ DWORD APIENTRY NPGetCaps(DWORD index)
     default:
         return 0;
     }
-}       
+}
 
-NET_API_STATUS 
-NetUserGetProfilePath( LPCWSTR Domain, LPCWSTR UserName, char * profilePath, 
+NET_API_STATUS
+NetUserGetProfilePath( LPCWSTR Domain, LPCWSTR UserName, char * profilePath,
                        DWORD profilePathLen )
 {
     NET_API_STATUS code;
@@ -234,7 +246,7 @@ NetUserGetProfilePath( LPCWSTR Domain, LPCWSTR UserName, char * profilePath,
 
     NetGetAnyDCName(NULL, Domain, (LPBYTE *)&ServerName);
     /* if NetGetAnyDCName fails, ServerName == NULL
-     * NetUserGetInfo will obtain local user information 
+     * NetUserGetInfo will obtain local user information
      */
     code = NetUserGetInfo(ServerName, UserName, 3, (LPBYTE *)&p3);
     if (code == NERR_Success)
@@ -254,7 +266,7 @@ NetUserGetProfilePath( LPCWSTR Domain, LPCWSTR UserName, char * profilePath,
             NetApiBufferFree(p3);
         }
     }
-    if (ServerName) 
+    if (ServerName)
         NetApiBufferFree(ServerName);
     return code;
 }
@@ -279,7 +291,7 @@ BOOL IsServiceRunning (void)
     }
     DebugEvent("AFS AfsLogon - Test Service Running Return Code[%x] ?Running[%d]",Status.dwCurrentState,(Status.dwCurrentState == SERVICE_RUNNING));
     return (Status.dwCurrentState == SERVICE_RUNNING);
-}   
+}
 
 BOOL IsServiceStartPending (void)
 {
@@ -301,7 +313,7 @@ BOOL IsServiceStartPending (void)
     }
     DebugEvent("AFS AfsLogon - Test Service Start Pending Return Code[%x] ?Start Pending[%d]",Status.dwCurrentState,(Status.dwCurrentState == SERVICE_START_PENDING));
     return (Status.dwCurrentState == SERVICE_START_PENDING);
-}   
+}
 
 /* LOOKUPKEYCHAIN: macro to look up the value in the list of keys in order until it's found
    v:variable to receive value (reference type)
@@ -315,28 +327,31 @@ BOOL IsServiceStartPending (void)
                if(hkDom) { \
                        dwSize = sizeof(v); \
                        rv = RegQueryValueEx(hkDom, n, 0, &dwType, (LPBYTE) &(v), &dwSize); \
-                       if(rv == ERROR_SUCCESS) DebugEvent(#v " found in hkDom with type [%d]", dwType); \
+                       if(rv == ERROR_SUCCESS || rv == ERROR_MORE_DATA) \
+                            DebugEvent(#v " found in hkDom with type [%d]", dwType); \
                } \
-               if(hkDoms && (rv != ERROR_SUCCESS || dwType != t)) { \
+               if(hkDoms && ((rv != ERROR_SUCCESS && rv != ERROR_MORE_DATA) || dwType != t)) { \
                        dwSize = sizeof(v); \
                        rv = RegQueryValueEx(hkDoms, n, 0, &dwType, (LPBYTE) &(v), &dwSize); \
-                       if(rv == ERROR_SUCCESS) DebugEvent(#v " found in hkDoms with type [%d]", dwType); \
+                       if(rv == ERROR_SUCCESS || rv == ERROR_MORE_DATA) \
+                            DebugEvent(#v " found in hkDoms with type [%d]", dwType); \
                } \
-               if(hkNp && (rv != ERROR_SUCCESS || dwType != t)) { \
+               if(hkNp && ((rv != ERROR_SUCCESS && rv != ERROR_MORE_DATA) || dwType != t)) { \
                        dwSize = sizeof(v); \
                        rv = RegQueryValueEx(hkNp, n, 0, &dwType, (LPBYTE) &(v), &dwSize); \
-                       if(rv == ERROR_SUCCESS) DebugEvent(#v " found in hkNp with type [%d]", dwType); \
+                       if(rv == ERROR_SUCCESS || rv == ERROR_MORE_DATA) \
+                            DebugEvent(#v " found in hkNp with type [%d]", dwType); \
                } \
-               if(rv != ERROR_SUCCESS || dwType != t) { \
+               if((rv != ERROR_SUCCESS && rv != ERROR_MORE_DATA) || dwType != t) { \
                        v = d; \
-                       DebugEvent(#v " being set to default"); \
+                       DebugEvent0(#v " being set to default"); \
                } \
        } while(0)
 
 /* Get domain specific configuration info.  We are returning void because if anything goes wrong
    we just return defaults.
  */
-void 
+void
 GetDomainLogonOptions( PLUID lpLogonId, char * username, char * domain, LogonOptions_t *opt ) {
     HKEY hkParm = NULL; /* Service parameter */
     HKEY hkNp = NULL;   /* network provider key */
@@ -347,8 +362,8 @@ GetDomainLogonOptions( PLUID lpLogonId, char * username, char * domain, LogonOpt
     DWORD dwSize;
     DWORD dwType;
     DWORD dwDummy;
-    char computerName[MAX_COMPUTERNAME_LENGTH + 1];
-    char *effDomain;
+    char computerName[MAX_COMPUTERNAME_LENGTH + 1]="";
+    char *effDomain = NULL;
 
     memset(opt, 0, sizeof(LogonOptions_t));
 
@@ -356,17 +371,16 @@ GetDomainLogonOptions( PLUID lpLogonId, char * username, char * domain, LogonOpt
     /* If the domain is the same as the Netbios computer name, we use the LOCALHOST domain name*/
     opt->flags = LOGON_FLAG_REMOTE;
     if(domain) {
-        dwSize = MAX_COMPUTERNAME_LENGTH;
+        dwSize = MAX_COMPUTERNAME_LENGTH + 1;
         if(GetComputerName(computerName, &dwSize)) {
-            if(!stricmp(computerName, domain)) {
+            if(!cm_stricmp_utf8(computerName, domain)) {
                 effDomain = "LOCALHOST";
                 opt->flags = LOGON_FLAG_LOCAL;
             }
-            else
-                effDomain = domain;
         }
-    } else
-        effDomain = NULL;
+        if (effDomain == NULL)
+            effDomain = domain;
+    }
 
     rv = RegOpenKeyEx( HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY, 0, KEY_READ, &hkParm );
     if(rv != ERROR_SUCCESS) {
@@ -398,10 +412,10 @@ GetDomainLogonOptions( PLUID lpLogonId, char * username, char * domain, LogonOpt
             hkDoms = NULL;
         }
     } else
-        DebugEvent("Not opening domain key for [%s]", effDomain);
+        DebugEvent0("Not opening domain key");
 
     /* Each individual can either be specified on the domain key, the domains key or in the
-       net provider key.  They fail over in that order.  If none is found, we just use the 
+       net provider key.  They fail over in that order.  If none is found, we just use the
        defaults. */
 
     /* LogonOption */
@@ -412,7 +426,7 @@ GetDomainLogonOptions( PLUID lpLogonId, char * username, char * domain, LogonOpt
     rv = RegQueryValueEx(hkParm, REG_CLIENT_FAIL_SILENTLY_PARM, 0, &dwType, (LPBYTE) &dwDummy, &dwSize);
     if (rv != ERROR_SUCCESS)
         LOOKUPKEYCHAIN(dwDummy, REG_DWORD, DEFAULT_FAIL_SILENTLY, REG_CLIENT_FAIL_SILENTLY_PARM);
-    opt->failSilently = !!dwDummy;
+    opt->failSilently = dwDummy ? 1 :0;
 
     /* Retry interval */
     LOOKUPKEYCHAIN(opt->retryInterval, REG_DWORD, DEFAULT_RETRY_INTERVAL, REG_CLIENT_RETRY_INTERVAL_PARM);
@@ -420,29 +434,38 @@ GetDomainLogonOptions( PLUID lpLogonId, char * username, char * domain, LogonOpt
     /* Sleep interval */
     LOOKUPKEYCHAIN(opt->sleepInterval, REG_DWORD, DEFAULT_SLEEP_INTERVAL, REG_CLIENT_SLEEP_INTERVAL_PARM);
 
-    opt->logonScript = NULL;
-    opt->smbName = NULL;
-
     if(!ISLOGONINTEGRATED(opt->LogonOption)) {
+        DebugEvent0("Integrated logon disabled");
         goto cleanup; /* no need to lookup the logon script */
     }
 
     /* come up with SMB username */
     if(ISHIGHSECURITY(opt->LogonOption)) {
+        DebugEvent0("High Security Mode active");
         opt->smbName = malloc( MAXRANDOMNAMELEN );
+        if (opt->smbName == NULL)
+            goto cleanup;
         GenRandomName(opt->smbName);
     } else if (lpLogonId) {
         /* username and domain for logon session is not necessarily the same as
            username and domain passed into network provider. */
-        PSECURITY_LOGON_SESSION_DATA plsd;
-        char lsaUsername[MAX_USERNAME_LENGTH];
-        char lsaDomain[MAX_DOMAIN_LENGTH];
+        PSECURITY_LOGON_SESSION_DATA plsd=NULL;
+        char lsaUsername[MAX_USERNAME_LENGTH]="";
+        char lsaDomain[MAX_DOMAIN_LENGTH]="";
         size_t len, tlen;
+        NTSTATUS Status;
 
-        LsaGetLogonSessionData(lpLogonId, &plsd);
-        
-        UnicodeStringToANSI(plsd->UserName, lsaUsername, MAX_USERNAME_LENGTH);
-        UnicodeStringToANSI(plsd->LogonDomain, lsaDomain, MAX_DOMAIN_LENGTH);
+        Status = LsaGetLogonSessionData(lpLogonId, &plsd);
+        if ( FAILED(Status) || plsd == NULL ) {
+            DebugEvent("LsaGetLogonSessionData failed [0x%x]", Status);
+            goto bad_strings;
+        }
+
+        if (!UnicodeStringToANSI(plsd->UserName, lsaUsername, MAX_USERNAME_LENGTH))
+            goto bad_strings;
+
+        if (!UnicodeStringToANSI(plsd->LogonDomain, lsaDomain, MAX_DOMAIN_LENGTH))
+            goto bad_strings;
 
         DebugEvent("PLSD username[%s] domain[%s]",lsaUsername,lsaDomain);
 
@@ -459,6 +482,8 @@ GetDomainLogonOptions( PLUID lpLogonId, char * username, char * domain, LogonOpt
         len += 2;
 
         opt->smbName = malloc(len);
+        if (opt->smbName == NULL)
+            goto cleanup;
 
         StringCbCopy(opt->smbName, len, lsaDomain);
         StringCbCat(opt->smbName, len, "\\");
@@ -467,25 +492,29 @@ GetDomainLogonOptions( PLUID lpLogonId, char * username, char * domain, LogonOpt
         strlwr(opt->smbName);
 
       bad_strings:
-        LsaFreeReturnBuffer(plsd);
-    } else {
+        if (plsd)
+            LsaFreeReturnBuffer(plsd);
+    }
+    if (opt->smbName == NULL) {
         size_t len;
 
-        DebugEvent("No LUID given. Constructing username using [%s] and [%s]",
+        DebugEvent("Constructing username using [%s] and [%s]",
                    username, domain);
+
         len = strlen(username) + strlen(domain) + 2;
 
         opt->smbName = malloc(len);
+        if (opt->smbName == NULL)
+            goto cleanup;
 
-        StringCbCopy(opt->smbName, len, username);
+        StringCbCopy(opt->smbName, len, domain);
         StringCbCat(opt->smbName, len, "\\");
-        StringCbCat(opt->smbName, len, domain);
+        StringCbCat(opt->smbName, len, username);
 
         strlwr(opt->smbName);
     }
 
-    DebugEvent("Looking up logon script");
+    DebugEvent0("Looking up logon script");
     /* Logon script */
     /* First find out where the key is */
     hkTemp = NULL;
@@ -495,20 +524,22 @@ GetDomainLogonOptions( PLUID lpLogonId, char * username, char * domain, LogonOpt
         rv = RegQueryValueExW(hkDom, REG_CLIENT_LOGON_SCRIPT_PARMW, 0, &dwType, NULL, &dwSize);
     if(rv == ERROR_SUCCESS && (dwType == REG_SZ || dwType == REG_EXPAND_SZ)) {
         hkTemp = hkDom;
-        DebugEvent("Located logon script in hkDom");
+        DebugEvent0("Located logon script in hkDom");
     }
-    else if(hkDoms)
+    else if(hkDoms) {
         rv = RegQueryValueExW(hkDoms, REG_CLIENT_LOGON_SCRIPT_PARMW, 0, &dwType, NULL, &dwSize);
-    if(rv == ERROR_SUCCESS && !hkTemp && (dwType == REG_SZ || dwType == REG_EXPAND_SZ)) {
-        hkTemp = hkDoms;
-        DebugEvent("Located logon script in hkDoms");
-    }
-    /* Note that the LogonScript in the NP key is only used if we are doing high security. */
-    else if(hkNp && ISHIGHSECURITY(opt->LogonOption))
-        rv = RegQueryValueExW(hkNp, REG_CLIENT_LOGON_SCRIPT_PARMW, 0, &dwType, NULL, &dwSize);
-    if(rv == ERROR_SUCCESS && !hkTemp && (dwType == REG_SZ || dwType == REG_EXPAND_SZ)) {
-        hkTemp = hkNp;
-        DebugEvent("Located logon script in hkNp");
+        if(rv == ERROR_SUCCESS && !hkTemp && (dwType == REG_SZ || dwType == REG_EXPAND_SZ)) {
+            hkTemp = hkDoms;
+            DebugEvent0("Located logon script in hkDoms");
+        }
+        /* Note that the LogonScript in the NP key is only used if we are doing high security. */
+        else if(hkNp && ISHIGHSECURITY(opt->LogonOption)) {
+            rv = RegQueryValueExW(hkNp, REG_CLIENT_LOGON_SCRIPT_PARMW, 0, &dwType, NULL, &dwSize);
+            if(rv == ERROR_SUCCESS && !hkTemp && (dwType == REG_SZ || dwType == REG_EXPAND_SZ)) {
+                hkTemp = hkNp;
+                DebugEvent0("Located logon script in hkNp");
+            }
+        }
     }
 
     if(hkTemp) {
@@ -524,15 +555,19 @@ GetDomainLogonOptions( PLUID lpLogonId, char * username, char * domain, LogonOpt
         len ++;
 
         wuname = malloc(len * sizeof(WCHAR));
+        if (!wuname)
+            goto doneLogonScript;
         MultiByteToWideChar(CP_ACP,0,opt->smbName,-1,wuname,(int)(len*sizeof(WCHAR)));
 
         DebugEvent("Username is set for [%S]", wuname);
 
         /* dwSize still has the size of the required buffer in bytes. */
         regscript = malloc(dwSize);
+        if (!regscript)
+            goto doneLogonScript;
         rv = RegQueryValueExW(hkTemp, REG_CLIENT_LOGON_SCRIPT_PARMW, 0, &dwType, (LPBYTE) regscript, &dwSize);
         if(rv != ERROR_SUCCESS) {/* what the ..? */
-            DebugEvent("Can't look up logon script [%d]",rv);
+            DebugEvent("Can't look up logon script rv [%d] size [%d] gle %d",rv, dwSize, GetLastError());
             goto doneLogonScript;
         }
 
@@ -543,12 +578,14 @@ GetDomainLogonOptions( PLUID lpLogonId, char * username, char * domain, LogonOpt
 
             dwSize += MAX_PATH * sizeof(WCHAR);  /* make room for environment expansion. */
             regexscript = malloc(dwSize);
+            if (!regexscript)
+                goto doneLogonScript;
             dwReq = ExpandEnvironmentStringsW(regscript, regexscript, dwSize / sizeof(WCHAR));
             free(regscript);
             regscript = regexscript;
             regexscript = NULL;
             if(dwReq > (dwSize / sizeof(WCHAR))) {
-                DebugEvent("Overflow while expanding environment strings.");
+                DebugEvent0("Overflow while expanding environment strings.");
                 goto doneLogonScript;
             }
         }
@@ -558,9 +595,13 @@ GetDomainLogonOptions( PLUID lpLogonId, char * username, char * domain, LogonOpt
         if(wcsstr(regscript, L"%s")) {
             dwSize += (DWORD)(len * sizeof(WCHAR)); /* make room for username expansion */
             regexuscript = (WCHAR *) LocalAlloc(LMEM_FIXED, dwSize);
+            if (!regexuscript)
+                goto doneLogonScript;
             hr = StringCbPrintfW(regexuscript, dwSize, regscript, wuname);
         } else {
             regexuscript = (WCHAR *) LocalAlloc(LMEM_FIXED, dwSize);
+            if (!regexuscript)
+                goto doneLogonScript;
             hr = StringCbCopyW(regexuscript, dwSize, regscript);
         }
 
@@ -577,45 +618,107 @@ GetDomainLogonOptions( PLUID lpLogonId, char * username, char * domain, LogonOpt
         if(regexscript) free(regexscript);
     }
 
-    DebugEvent("Looking up TheseCells");
-    /* Logon script */
+    DebugEvent0("Looking up TheseCells");
+    /* TheseCells */
     /* First find out where the key is */
     hkTemp = NULL;
     rv = ~ERROR_SUCCESS;
-    dwType = 0;
+    dwSize = 0;
     if (hkDom)
         rv = RegQueryValueEx(hkDom, REG_CLIENT_THESE_CELLS_PARM, 0, &dwType, NULL, &dwSize);
     if (rv == ERROR_SUCCESS && dwType == REG_MULTI_SZ) {
         hkTemp = hkDom;
-        DebugEvent("Located TheseCells in hkDom");
-    } else if (hkDoms)
+        DebugEvent("Located TheseCells in hkDom size %d", dwSize);
+    } else if (hkDoms) {
         rv = RegQueryValueEx(hkDoms, REG_CLIENT_THESE_CELLS_PARM, 0, &dwType, NULL, &dwSize);
-    if (rv == ERROR_SUCCESS && !hkTemp && dwType == REG_MULTI_SZ) {
-        hkTemp = hkDoms;
-        DebugEvent("Located TheseCells in hkDoms");
-    } else if (hkNp)
-        rv = RegQueryValueEx(hkNp, REG_CLIENT_THESE_CELLS_PARM, 0, &dwType, NULL, &dwSize);
-    if (rv == ERROR_SUCCESS && !hkTemp && dwType == REG_MULTI_SZ) {
-        hkTemp = hkNp;
-        DebugEvent("Located TheseCells in hkNp");
+        if (rv == ERROR_SUCCESS && !hkTemp && dwType == REG_MULTI_SZ) {
+            hkTemp = hkDoms;
+            DebugEvent("Located TheseCells in hkDoms size %d", dwSize);
+        } else if (hkNp) {
+            rv = RegQueryValueEx(hkNp, REG_CLIENT_THESE_CELLS_PARM, 0, &dwType, NULL, &dwSize);
+            if (rv == ERROR_SUCCESS && !hkTemp && dwType == REG_MULTI_SZ) {
+                hkTemp = hkNp;
+                DebugEvent("Located TheseCells in hkNp size %d", dwSize);
+            }
+        }
     }
 
     if (hkTemp) {
-        CHAR * thesecells;
+        CHAR * thesecells = NULL, *p;
 
         /* dwSize still has the size of the required buffer in bytes. */
-        thesecells = malloc(dwSize);
-        rv = RegQueryValueEx(hkTemp, REG_CLIENT_THESE_CELLS_PARM, 0, &dwType, (LPBYTE) thesecells, &dwSize);
+        thesecells = malloc(dwSize*2);
+        if (!thesecells)
+            goto doneTheseCells;
+        dwSize *= 2;
+        SetLastError(0);
+        rv = RegQueryValueEx(hkTemp, REG_CLIENT_THESE_CELLS_PARM, 0, NULL, (LPBYTE) thesecells, &dwSize);
         if(rv != ERROR_SUCCESS) {/* what the ..? */
-            DebugEvent("Can't look up TheseCells [%d]",rv);
+            DebugEvent("Can't look up TheseCells rv [%d] size [%d] gle [%d]",rv, dwSize, GetLastError());
             goto doneTheseCells;
         }
 
-        DebugEvent("Found TheseCells [%s]", thesecells);
-        opt->theseCells = thesecells;
+        /* TheseCells is a REG_MULTI_SZ */
+        if ( thesecells && thesecells[0]) {
+            for ( p=thesecells; *p; p += (strlen(p) + 1)) {
+                DebugEvent("Found TheseCells [%s]", p);
+            }
+            opt->theseCells = thesecells;
+            thesecells = NULL;
+        } else {
+            DebugEvent("TheseCells [REG_MULTI_SZ] not found");
+        }
 
       doneTheseCells:
-        ;
+        if (thesecells) free(thesecells);
+    }
+
+    DebugEvent0("Looking up Realm");
+    /* Realm */
+    /* First find out where the key is */
+    hkTemp = NULL;
+    rv = ~ERROR_SUCCESS;
+    dwSize = 0;
+    if (hkDom)
+        rv = RegQueryValueEx(hkDom, REG_CLIENT_REALM_PARM, 0, &dwType, NULL, &dwSize);
+    if (rv == ERROR_SUCCESS && dwType == REG_SZ) {
+        hkTemp = hkDom;
+        DebugEvent("Located Realm in hkDom size %d", dwSize);
+    } else if (hkDoms) {
+        rv = RegQueryValueEx(hkDoms, REG_CLIENT_REALM_PARM, 0, &dwType, NULL, &dwSize);
+        if (rv == ERROR_SUCCESS && !hkTemp && dwType == REG_SZ) {
+            hkTemp = hkDoms;
+            DebugEvent("Located Realm in hkDoms size %d", dwSize);
+        } else if (hkNp) {
+            rv = RegQueryValueEx(hkNp, REG_CLIENT_REALM_PARM, 0, &dwType, NULL, &dwSize);
+            if (rv == ERROR_SUCCESS && !hkTemp && dwType == REG_SZ) {
+                hkTemp = hkNp;
+                DebugEvent("Located Realm in hkNp size %d", dwSize);
+            }
+        }
+    }
+
+    if (hkTemp) {
+        CHAR * realm = NULL;
+
+        /* dwSize still has the size of the required buffer in bytes. */
+        realm = malloc(dwSize*2);
+        if (!realm)
+            goto doneRealm;
+        dwSize *=2;
+        SetLastError(0);
+        rv = RegQueryValueEx(hkTemp, REG_CLIENT_REALM_PARM, 0, NULL, (LPBYTE) realm, &dwSize);
+        if(rv != ERROR_SUCCESS) {/* what the ..? */
+            DebugEvent("Can't look up Realm rv [%d] size [%d] gle [%d]",rv, dwSize, GetLastError());
+            goto doneRealm;
+        }
+
+        DebugEvent("Found Realm [%s]", realm);
+        opt->realm = realm;
+        realm = NULL;
+
+      doneRealm:
+        if (realm) free(realm);
     }
 
   cleanup:
@@ -623,7 +726,7 @@ GetDomainLogonOptions( PLUID lpLogonId, char * username, char * domain, LogonOpt
     if(hkDom) RegCloseKey(hkDom);
     if(hkDoms) RegCloseKey(hkDoms);
     if(hkParm) RegCloseKey(hkParm);
-}       
+}
 
 #undef LOOKUPKEYCHAIN
 
@@ -646,7 +749,7 @@ DWORD GetFileCellName(char * path, char * cell, size_t cellLen) {
         cell[cellLen - 1] = '\0';
     }
     return code;
-}       
+}
 
 
 static BOOL
@@ -660,7 +763,7 @@ UnicodeStringToANSI(UNICODE_STRING uInputString, LPSTR lpszOutputString, int nOu
     if (CodePageInfo.MaxCharSize > 1)
         // Only supporting non-Unicode strings
         return FALSE;
-    
+
     if (uInputString.Buffer && ((LPBYTE) uInputString.Buffer)[1] == '\0')
     {
         // Looks like unicode, better translate it
@@ -670,8 +773,8 @@ UnicodeStringToANSI(UNICODE_STRING uInputString, LPSTR lpszOutputString, int nOu
         lpszOutputString[min(uInputString.Length/2,nOutStringLen-1)] = '\0';
         return TRUE;
     }
-    else
-        lpszOutputString[0] = '\0';
+
+    lpszOutputString[0] = '\0';
     return FALSE;
 }  // UnicodeStringToANSI
 
@@ -715,6 +818,15 @@ DWORD APIENTRY NPLogonNotify(
     int retryInterval;
     int sleepInterval;
 
+    /* Are we interactive? */
+    interactive = (wcsicmp(lpStationName, L"WinSta0") == 0);
+
+#ifdef DISABLE_NON_INTERACTIVE
+    /* Do not do anything if the logon session is not interactive. */
+    if (!interactive)
+       return 0;
+#endif
+
     (void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
                          0, KEY_QUERY_VALUE, &NPKey);
     LSPsize=sizeof(TraceOption);
@@ -730,12 +842,12 @@ DWORD APIENTRY NPLogonNotify(
 
     /* Initialize Logon Script to none */
     *lpLogonScript=NULL;
-    
+
     /* MSV1_0_INTERACTIVE_LOGON and KERB_INTERACTIVE_LOGON are equivalent for
      * our purposes */
 
-    if ( wcscmp(lpAuthentInfoType,L"MSV1_0:Interactive") && 
-         wcscmp(lpAuthentInfoType,L"Kerberos:Interactive") )
+    if ( wcsicmp(lpAuthentInfoType,L"MSV1_0:Interactive") &&
+         wcsicmp(lpAuthentInfoType,L"Kerberos:Interactive") )
     {
         DebugEvent("Unsupported Authentication Info Type: %S",
                    lpAuthentInfoType);
@@ -744,19 +856,22 @@ DWORD APIENTRY NPLogonNotify(
 
     IL = (MSV1_0_INTERACTIVE_LOGON *) lpAuthentInfo;
 
-    /* Are we interactive? */
-    interactive = (wcscmp(lpStationName, L"WinSta0") == 0);
-
     /* Convert from Unicode to ANSI */
 
     /*TODO: Use SecureZeroMemory to erase passwords */
-    UnicodeStringToANSI(IL->UserName, uname, MAX_USERNAME_LENGTH);
-    UnicodeStringToANSI(IL->Password, password, MAX_PASSWORD_LENGTH);
-    UnicodeStringToANSI(IL->LogonDomainName, logonDomain, MAX_DOMAIN_LENGTH);
+    if (!UnicodeStringToANSI(IL->UserName, uname, MAX_USERNAME_LENGTH) ||
+        !UnicodeStringToANSI(IL->Password, password, MAX_PASSWORD_LENGTH) ||
+        !UnicodeStringToANSI(IL->LogonDomainName, logonDomain, MAX_DOMAIN_LENGTH))
+       return 0;
 
-    /* Make sure AD-DOMANS sent from login that is sent to us is striped */
+    /* Make sure AD-DOMAINS sent from login that is sent to us is stripped */
     ctemp = strchr(uname, '@');
-    if (ctemp) *ctemp = 0;
+    if (ctemp) {
+        *ctemp = 0;
+        ctemp++;
+        if ( logonDomain[0] == '\0' )
+            StringCchCopy(logonDomain, MAX_DOMAIN_LENGTH, ctemp);
+    }
 
     /* is the name all lowercase? */
     for ( ctemp = uname; *ctemp ; ctemp++) {
@@ -778,41 +893,41 @@ DWORD APIENTRY NPLogonNotify(
     if (retryInterval < sleepInterval)
         sleepInterval = retryInterval;
 
-    DebugEvent("Got logon script: %S",opt.logonScript);
+    DebugEvent("Got logon script: [%S]", opt.logonScript);
 
     afsWillAutoStart = AFSWillAutoStart();
 
     DebugEvent("LogonOption[%x], Service AutoStart[%d]",
                 opt.LogonOption,afsWillAutoStart);
-    
+
     /* Check for zero length password if integrated logon*/
     if ( ISLOGONINTEGRATED(opt.LogonOption) )  {
         if ( password[0] == 0 ) {
-            DebugEvent("Password is the empty string");
+            DebugEvent0("Password is the empty string");
             code = GT_PW_NULL;
             reason = "zero length password is illegal";
             code=0;
         }
 
-        /* Get cell name if doing integrated logon.  
+        /* Get cell name if doing integrated logon.
            We might overwrite this if we are logging into an AD realm and we find out that
            the user's home dir is in some other cell. */
-        DebugEvent("About to call cm_GetRootCellName(%s)",cell);
+        DebugEvent("About to call cm_GetRootCellName()");
         code = cm_GetRootCellName(cell);
-        if (code < 0) { 
-            DebugEvent("Unable to obtain Root Cell");
+        if (code < 0) {
+            DebugEvent0("Unable to obtain Root Cell");
             code = KTC_NOCELL;
             reason = "unknown cell";
             code=0;
         } else {
-            DebugEvent("Cell is %s",cell);
-        }       
+            DebugEvent("Default cell is %s", cell);
+        }
 
         /* We get the user's home directory path, if applicable, though we can't lookup the
            cell right away because the client service may not have started yet. This call
            also sets the AD_REALM flag in opt.flags if applicable. */
         if (ISREMOTE(opt.flags)) {
-            DebugEvent("Is Remote");
+            DebugEvent0("Is Remote");
             GetAdHomePath(homePath,MAX_PATH,lpLogonId,&opt);
         }
     }
@@ -829,23 +944,21 @@ DWORD APIENTRY NPLogonNotify(
                    DebugEvent("profile path [%s] is in cell [%s]",homePath,cell);
                }
                /* Don't bail out if GetFileCellName failed.
-                * The home dir may not be in AFS after all. 
+                * The home dir may not be in AFS after all.
                 */
            } else
                code=0;
-               
+
            /* if Integrated Logon  */
            if (ISLOGONINTEGRATED(opt.LogonOption))
-           {                   
+           {
                if ( KFW_is_available() ) {
-                   code = KFW_AFS_get_cred(uname, cell, password, 0, opt.smbName, &reason);
-                   DebugEvent("KFW_AFS_get_cred  uname=[%s] smbname=[%s] cell=[%s] code=[%d]",
-                               uname,opt.smbName,cell,code);
-                   if (code == 0 && opt.theseCells) { 
+                   SetEnvironmentVariable(DO_NOT_REGISTER_VARNAME, "");
+                    if (opt.realm) {
                        char * principal, *p;
                        size_t len, tlen;
 
-                       StringCchLength(cell, MAX_DOMAIN_LENGTH, &tlen);
+                       StringCchLength(opt.realm, MAX_DOMAIN_LENGTH, &tlen);
                        len = tlen;
                        StringCchLength(uname, MAX_USERNAME_LENGTH, &tlen);
                        len += tlen + 2;
@@ -856,16 +969,50 @@ DWORD APIENTRY NPLogonNotify(
                            StringCchCopy(principal, len, uname);
                            p = principal + tlen;
                            *p++ = '@';
-                           StringCchCopy(p, len - tlen - 1, cell);
-                           for ( ;*p; p++) {
-                               *p = toupper(*p);
-                           }
+                            StringCchCopy(p, len - tlen -1, opt.realm);
+                            code = KFW_AFS_get_cred(principal, cell, password, 0, opt.smbName, &reason);
+                            DebugEvent("KFW_AFS_get_cred  uname=[%s] smbname=[%s] cell=[%s] code=[%d]",
+                                           principal,opt.smbName,cell,code);
+                           free(principal);
+                       }
+                    } else {
+                        code = KFW_AFS_get_cred(uname, cell, password, 0, opt.smbName, &reason);
+                        DebugEvent("KFW_AFS_get_cred  uname=[%s] smbname=[%s] cell=[%s] code=[%d]",
+                                    uname,opt.smbName,cell,code);
+                    }
+                   SetEnvironmentVariable(DO_NOT_REGISTER_VARNAME, NULL);
+                   if (code == 0 && opt.theseCells) {
+                       char * principal, *p;
+                       size_t len, tlen;
 
+                       StringCchLength(opt.realm ? opt.realm : cell, MAX_DOMAIN_LENGTH, &tlen);
+                       len = tlen;
+                       StringCchLength(uname, MAX_USERNAME_LENGTH, &tlen);
+                       len += tlen + 2;
+
+                       /* tlen is now the length of uname in characters */
+                       principal = (char *)malloc(len * sizeof(char));
+                       if ( principal ) {
+                           StringCchCopy(principal, len, uname);
+                           p = principal + tlen;
+                           *p++ = '@';
+                            if (opt.realm) {
+                                StringCchCopy(p, len - tlen -1, opt.realm);
+                            } else {
+                                StringCchCopy(p, len - tlen - 1, cell);
+                                for ( ;*p; p++) {
+                                    *p = toupper(*p);
+                                }
+                            }
                            p = opt.theseCells;
                            while ( *p ) {
-                               code2 = KFW_AFS_get_cred(principal, p, 0, 0, opt.smbName, &reason);
-                               DebugEvent("KFW_AFS_get_cred  uname=[%s] smbname=[%s] cell=[%s] code=[%d]",
-                                           principal,opt.smbName,p,code2);
+                                if ( cm_stricmp_utf8(p, cell) ) {
+                                    SetEnvironmentVariable(DO_NOT_REGISTER_VARNAME, "");
+                                    code2 = KFW_AFS_get_cred(principal, p, password, 0, opt.smbName, &reason);
+                                    SetEnvironmentVariable(DO_NOT_REGISTER_VARNAME, NULL);
+                                    DebugEvent("KFW_AFS_get_cred  uname=[%s] smbname=[%s] cell=[%s] code=[%d]",
+                                               principal,opt.smbName,p,code2);
+                                }
                                p += strlen(p) + 1;
                            }
                            free(principal);
@@ -877,7 +1024,7 @@ DWORD APIENTRY NPLogonNotify(
                                                        &reason);
                    DebugEvent("AFS AfsLogon - (INTEGRATED only)ka_UserAuthenticateGeneral2 Code[%x] uname[%s] smbname=[%s] Cell[%s] PwExp=[%d] Reason=[%s]",
                                code,uname,opt.smbName,cell,pw_exp,reason?reason:"");
-               }       
+               }
                if ( code && code != KTC_NOCM && code != KTC_NOCMRPC && !lowercased_name ) {
                    for ( ctemp = uname; *ctemp ; ctemp++) {
                        *ctemp = tolower(*ctemp);
@@ -890,12 +1037,12 @@ DWORD APIENTRY NPLogonNotify(
 
                /* If we've failed because the client isn't running yet and the
                 * client is set to autostart (and therefore it makes sense for
-                * us to wait for it to start) then sleep a while and try again. 
+                * us to wait for it to start) then sleep a while and try again.
                 * If the error was something else, then give up. */
                if (code != KTC_NOCM && code != KTC_NOCMRPC)
                    break;
            }
-           else {  
+           else {
                /*JUST check to see if its running*/
                if (IsServiceRunning())
                    break;
@@ -930,14 +1077,17 @@ DWORD APIENTRY NPLogonNotify(
            retryInterval -= sleepInterval;
        }
     }
-    DebugEvent("while loop exited");
+    DebugEvent0("while loop exited");
+
     /* remove any kerberos 5 tickets currently held by the SYSTEM account
-     * for this user 
+     * for this user
      */
+
     if (ISLOGONINTEGRATED(opt.LogonOption) && KFW_is_available()) {
+#ifdef KFW_LOGON
        sprintf(szLogonId,"%d.%d",lpLogonId->HighPart, lpLogonId->LowPart);
        KFW_AFS_copy_cache_to_system_file(uname, szLogonId);
-
+#endif
        KFW_AFS_destroy_tickets_for_principal(uname);
     }
 
@@ -956,7 +1106,7 @@ DWORD APIENTRY NPLogonNotify(
        ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1008, NULL,
                     1, 0, ptbuf, NULL);
        DeregisterEventSource(h);
-           
+
         code = MapAuthError(code);
         SetLastError(code);
 
@@ -972,10 +1122,11 @@ DWORD APIENTRY NPLogonNotify(
 
     if (opt.theseCells) free(opt.theseCells);
     if (opt.smbName) free(opt.smbName);
+    if (opt.realm) free(opt.realm);
 
     DebugEvent("AFS AfsLogon - Exit","Return Code[%x]",code);
     return code;
-}       
+}
 
 DWORD APIENTRY NPPasswordChangeNotify(
        LPCWSTR lpAuthentInfoType,
@@ -986,6 +1137,15 @@ DWORD APIENTRY NPPasswordChangeNotify(
        LPVOID StationHandle,
        DWORD dwChangeInfo)
 {
+    BOOLEAN interactive;
+
+    /* Are we interactive? */
+    interactive = (wcsicmp(lpStationName, L"WinSta0") == 0);
+
+    /* Do not do anything if the logon session is not interactive. */
+    if (!interactive)
+       return 0;
+
     /* Make sure the AFS Libraries are initialized */
     AfsLogonInit();
 
@@ -1015,14 +1175,14 @@ BOOL IsPathInAfs(const CHAR *strPath)
 }
 
 #ifdef COMMENT
-typedef struct _WLX_NOTIFICATION_INFO {  
-    ULONG Size;  
-    ULONG Flags;  
-    PWSTR UserName;  
-    PWSTR Domain;  
-    PWSTR WindowStation;  
-    HANDLE hToken;  
-    HDESK hDesktop;  
+typedef struct _WLX_NOTIFICATION_INFO {
+    ULONG Size;
+    ULONG Flags;
+    PWSTR UserName;
+    PWSTR Domain;
+    PWSTR WindowStation;
+    HANDLE hToken;
+    HDESK hDesktop;
     PFNMSGECALLBACK pStatusCallback;
 } WLX_NOTIFICATION_INFO, *PWLX_NOTIFICATION_INFO;
 #endif
@@ -1101,10 +1261,10 @@ VOID AFS_Logoff_Event( PWLX_NOTIFICATION_INFO pInfo )
                }
            }
 
-           /* We can't use pInfo->Domain for the domain since in the cross realm case 
+           /* We can't use pInfo->Domain for the domain since in the cross realm case
             * this is source domain and not the destination domain.
             */
-           if (QueryAdHomePathFromSid( profileDir, sizeof(profileDir), tokenUser->User.Sid, pInfo->Domain)) {
+           if (tokenUser && QueryAdHomePathFromSid( profileDir, sizeof(profileDir), tokenUser->User.Sid, pInfo->Domain)) {
                WCHAR Domain[64]=L"";
                GetLocalShortDomain(Domain, sizeof(Domain));
                if (QueryAdHomePathFromSid( profileDir, sizeof(profileDir), tokenUser->User.Sid, Domain)) {
@@ -1141,7 +1301,7 @@ VOID AFS_Logoff_Event( PWLX_NOTIFICATION_INFO pInfo )
     }
 
     DebugEvent0("AFS_Logoff_Event - End");
-}   
+}
 
 VOID AFS_Logon_Event( PWLX_NOTIFICATION_INFO pInfo )
 {
@@ -1177,7 +1337,7 @@ VOID AFS_Logon_Event( PWLX_NOTIFICATION_INFO pInfo )
         StringCchLengthW(pInfo->UserName, MAX_USERNAME_LENGTH, &szlen);
         WideCharToMultiByte(CP_UTF8, 0, pInfo->UserName, szlen,
                             username, sizeof(username), NULL, NULL);
-        
+
         StringCchLengthW(pInfo->Domain, MAX_DOMAIN_LENGTH, &szlen);
         WideCharToMultiByte(CP_UTF8, 0, pInfo->Domain, szlen,
                             domain, sizeof(domain), NULL, NULL);
@@ -1191,7 +1351,7 @@ VOID AFS_Logon_Event( PWLX_NOTIFICATION_INFO pInfo )
            DebugEvent0("AFS_Logon_Event - No pInfo->Domain");
     }
 
-    DebugEvent("AFS_Logon_Event - opt.LogonOption = %lX opt.flags = %lX", 
+    DebugEvent("AFS_Logon_Event - opt.LogonOption = %lX opt.flags = %lX",
                opt.LogonOption, opt.flags);
 
     if (!ISLOGONINTEGRATED(opt.LogonOption) || !ISREMOTE(opt.flags)) {
@@ -1213,10 +1373,10 @@ VOID AFS_Logon_Event( PWLX_NOTIFICATION_INFO pInfo )
         }
     }
 
-    /* We can't use pInfo->Domain for the domain since in the cross realm case 
+    /* We can't use pInfo->Domain for the domain since in the cross realm case
      * this is source domain and not the destination domain.
      */
-    if (QueryAdHomePathFromSid( profileDir, sizeof(profileDir), tokenUser->User.Sid, pInfo->Domain)) {
+    if (tokenUser && QueryAdHomePathFromSid( profileDir, sizeof(profileDir), tokenUser->User.Sid, pInfo->Domain)) {
         WCHAR Domain[64]=L"";
         GetLocalShortDomain(Domain, sizeof(Domain));
         if (QueryAdHomePathFromSid( profileDir, sizeof(profileDir), tokenUser->User.Sid, Domain)) {
@@ -1224,7 +1384,7 @@ VOID AFS_Logon_Event( PWLX_NOTIFICATION_INFO pInfo )
                 GetUserProfileDirectory(pInfo->hToken, profileDir, &len);
         }
     }
-    
+
     if (strlen(profileDir)) {
         DebugEvent("AFS_Logon_Event - Profile Directory: %s", profileDir);
     } else {
@@ -1255,7 +1415,7 @@ VOID AFS_Logon_Event( PWLX_NOTIFICATION_INFO pInfo )
                         szPath, szUserA,res);
         else
             DebugEvent0("AFS_Logon_Event - WNetAddConnection2() succeeded");
-    } else 
+    } else
         DebugEvent("AFS_Logon_Event - User name conversion failed: GLE = 0x%X",GetLastError());
 
     if ( tokenUser )
@@ -1289,15 +1449,18 @@ GetSecurityLogonSessionData(HANDLE hToken, PSECURITY_LOGON_SESSION_DATA * ppSess
 
 VOID KFW_Logon_Event( PWLX_NOTIFICATION_INFO pInfo )
 {
+#ifdef KFW_LOGON
     WCHAR szUserW[128] = L"";
     char  szUserA[128] = "";
     char szPath[MAX_PATH] = "";
     char szLogonId[128] = "";
     DWORD count;
-    char filename[256];
-    char commandline[512];
+    char filename[MAX_PATH] = "";
+    char newfilename[MAX_PATH] = "";
+    char commandline[MAX_PATH+256] = "";
     STARTUPINFO startupinfo;
     PROCESS_INFORMATION procinfo;
+    HANDLE hf = INVALID_HANDLE_VALUE;
 
     LUID LogonId = {0, 0};
     PSECURITY_LOGON_SESSION_DATA pLogonSessionData = NULL;
@@ -1327,14 +1490,56 @@ VOID KFW_Logon_Event( PWLX_NOTIFICATION_INFO pInfo )
         GetWindowsDirectory(filename, sizeof(filename));
     }
 
-    if ( strlen(filename) + strlen(szLogonId) + 2 <= sizeof(filename) ) {
-        strcat(filename, "\\");
-        strcat(filename, szLogonId);    
+    count = GetEnvironmentVariable("TEMP", filename, sizeof(filename));
+    if ( count > sizeof(filename) || count == 0 ) {
+        GetWindowsDirectory(filename, sizeof(filename));
+    }
 
-        sprintf(commandline, "afscpcc.exe \"%s\"", filename);
+    if ( strlen(filename) + strlen(szLogonId) + 2 > sizeof(filename) ) {
+        DebugEvent0("KFW_Logon_Event - filename too long");
+       return;
+    }
+
+    strcat(filename, "\\");
+    strcat(filename, szLogonId);
+
+    hf = CreateFile(filename, FILE_ALL_ACCESS, 0, NULL, OPEN_EXISTING,
+                    FILE_ATTRIBUTE_NORMAL, NULL);
+    if (hf == INVALID_HANDLE_VALUE) {
+       DebugEvent0("KFW_Logon_Event - file cannot be opened");
+       return;
+    }
+    CloseHandle(hf);
 
-        GetStartupInfo(&startupinfo);
-        if (CreateProcessAsUser( pInfo->hToken,
+    if (KFW_AFS_set_file_cache_dacl(filename, pInfo->hToken)) {
+       DebugEvent0("KFW_Logon_Event - unable to set dacl");
+       DeleteFile(filename);
+       return;
+    }
+
+    if (KFW_AFS_obtain_user_temp_directory(pInfo->hToken, newfilename, sizeof(newfilename))) {
+       DebugEvent0("KFW_Logon_Event - unable to obtain temp directory");
+       return;
+    }
+
+    if ( strlen(newfilename) + strlen(szLogonId) + 2 > sizeof(newfilename) ) {
+        DebugEvent0("KFW_Logon_Event - new filename too long");
+       return;
+    }
+
+    strcat(newfilename, "\\");
+    strcat(newfilename, szLogonId);
+
+    if (!MoveFileEx(filename, newfilename,
+                    MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) {
+        DebugEvent("KFW_Logon_Event - MoveFileEx failed GLE = 0x%x", GetLastError());
+       return;
+    }
+
+    sprintf(commandline, "afscpcc.exe \"%s\"", newfilename);
+
+    GetStartupInfo(&startupinfo);
+    if (CreateProcessAsUser( pInfo->hToken,
                              "afscpcc.exe",
                              commandline,
                              NULL,
@@ -1344,17 +1549,21 @@ VOID KFW_Logon_Event( PWLX_NOTIFICATION_INFO pInfo )
                              NULL,
                              NULL,
                              &startupinfo,
-                             &procinfo)) 
-        {
-            WaitForSingleObject(procinfo.hProcess, 30000);
+                             &procinfo))
+    {
+       DebugEvent("KFW_Logon_Event - CommandLine %s", commandline);
 
-            CloseHandle(procinfo.hThread);
-            CloseHandle(procinfo.hProcess);
-        }
+       WaitForSingleObject(procinfo.hProcess, 30000);
+
+       CloseHandle(procinfo.hThread);
+       CloseHandle(procinfo.hProcess);
+    } else {
+       DebugEvent0("KFW_Logon_Event - CreateProcessFailed");
     }
 
     DeleteFile(filename);
 
     DebugEvent0("KFW_Logon_Event - End");
+#endif
 }