windows-logon-20050630
[openafs.git] / src / WINNT / afsd / afslogon.c
index 7f6b4e1..506ea71 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <winsock2.h>
 #include <lm.h>
+#include <nb30.h>
 
 #include <afs/param.h>
 #include <afs/stds.h>
@@ -26,6 +27,9 @@
 #include "cm_config.h"
 #include "krb.h"
 #include "afskfw.h"
+#include "lanahelper.h"
+
+#include <WINNT\afsreg.h>
 
 DWORD TraceOption = 0;
 
@@ -37,8 +41,10 @@ WSADATA WSAjunk;
 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);
@@ -254,6 +260,28 @@ BOOL IsServiceRunning (void)
     return (Status.dwCurrentState == SERVICE_RUNNING);
 }   
 
+BOOL IsServiceStartPending (void)
+{
+    SERVICE_STATUS Status;
+    SC_HANDLE hManager;
+    memset (&Status, 0x00, sizeof(Status));
+    Status.dwCurrentState = SERVICE_STOPPED;
+
+    if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
+    {
+        SC_HANDLE hService;
+        if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
+        {
+            QueryServiceStatus (hService, &Status);
+            CloseServiceHandle (hService);
+        }
+
+        CloseServiceHandle (hManager);
+    }
+    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)
    t:type
@@ -301,6 +329,8 @@ GetDomainLogonOptions( PLUID lpLogonId, char * username, char * domain, LogonOpt
     char computerName[MAX_COMPUTERNAME_LENGTH + 1];
     char *effDomain;
 
+    memset(opt, 0, sizeof(LogonOptions_t));
+
     DebugEvent("In GetDomainLogonOptions for user [%s] in domain [%s]", username, domain);
     /* If the domain is the same as the Netbios computer name, we use the LOCALHOST domain name*/
     opt->flags = LOGON_FLAG_REMOTE;
@@ -317,13 +347,13 @@ GetDomainLogonOptions( PLUID lpLogonId, char * username, char * domain, LogonOpt
     } else
         effDomain = NULL;
 
-    rv = RegOpenKeyEx( HKEY_LOCAL_MACHINE, REG_CLIENT_PARMS_KEY, 0, KEY_READ, &hkParm );
+    rv = RegOpenKeyEx( HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY, 0, KEY_READ, &hkParm );
     if(rv != ERROR_SUCCESS) {
         hkParm = NULL;
         DebugEvent("GetDomainLogonOption: Can't open parms key [%d]", rv);
     }
 
-    rv = RegOpenKeyEx( HKEY_LOCAL_MACHINE, REG_CLIENT_PROVIDER_KEY, 0, KEY_READ, &hkNp );
+    rv = RegOpenKeyEx( HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PROVIDER_SUBKEY, 0, KEY_READ, &hkNp );
     if(rv != ERROR_SUCCESS) {
         hkNp = NULL;
         DebugEvent("GetDomainLogonOptions: Can't open NP key [%d]", rv);
@@ -511,6 +541,46 @@ GetDomainLogonOptions( PLUID lpLogonId, char * username, char * domain, LogonOpt
         if(regexscript) free(regexscript);
     }
 
+    DebugEvent("Looking up TheseCells");
+    /* Logon script */
+    /* First find out where the key is */
+    hkTemp = NULL;
+    rv = ~ERROR_SUCCESS;
+    dwType = 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)
+        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 (hkTemp) {
+        CHAR * thesecells;
+
+        /* 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);
+        if(rv != ERROR_SUCCESS) {/* what the ..? */
+            DebugEvent("Can't look up TheseCells [%d]",rv);
+            goto doneTheseCells;
+        }
+
+        DebugEvent("Found TheseCells [%s]", thesecells);
+        opt->theseCells = thesecells;
+
+      doneTheseCells:;
+    }
+
   cleanup:
     if(hkNp) RegCloseKey(hkNp);
     if(hkDom) RegCloseKey(hkDom);
@@ -583,10 +653,11 @@ DWORD APIENTRY NPLogonNotify(
     char logonDomain[MAX_DOMAIN_LENGTH]="";
     char cell[256]="<non-integrated logon>";
     char homePath[MAX_PATH]="";
+    char szLogonId[128] = "";
 
     MSV1_0_INTERACTIVE_LOGON *IL;
 
-    DWORD code;
+    DWORD code, code2;
 
     int pw_exp;
     char *reason;
@@ -601,21 +672,39 @@ DWORD APIENTRY NPLogonNotify(
 
     BOOLEAN afsWillAutoStart;
 
-    BOOLEAN uppercased_name = TRUE;
+    BOOLEAN lowercased_name = TRUE;
 
     LogonOptions_t opt; /* domain specific logon options */
     int retryInterval;
     int sleepInterval;
 
+    (void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
+                         0, KEY_QUERY_VALUE, &NPKey);
+    LSPsize=sizeof(TraceOption);
+    RegQueryValueEx(NPKey, REG_CLIENT_TRACE_OPTION_PARM, NULL,
+                     &LSPtype, (LPBYTE)&TraceOption, &LSPsize);
+
+    RegCloseKey (NPKey);
+
+    DebugEvent("NPLogonNotify - LoginId(%d,%d)", lpLogonId->HighPart, lpLogonId->LowPart);
+
     /* Make sure the AFS Libraries are initialized */
     AfsLogonInit();
 
     /* Initialize Logon Script to none */
     *lpLogonScript=NULL;
     
-    /* TODO: We should check the value of lpAuthentInfoType before assuming that it is
-       MSV1_0_INTERACTIVE_LOGON though for our purposes KERB_INTERACTIVE_LOGON is
-       co-incidentally equivalent. */
+    /* 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") )
+    {
+        DebugEvent("Unsupported Authentication Info Type: %S",
+                   lpAuthentInfoType);
+        return 0;
+    }
+
     IL = (MSV1_0_INTERACTIVE_LOGON *) lpAuthentInfo;
 
     /* Are we interactive? */
@@ -632,22 +721,14 @@ DWORD APIENTRY NPLogonNotify(
     ctemp = strchr(uname, '@');
     if (ctemp) *ctemp = 0;
 
-    /* is the name all uppercase? */
+    /* is the name all lowercase? */
     for ( ctemp = uname; *ctemp ; ctemp++) {
-        if ( islower(*ctemp) ) {
-            uppercased_name = FALSE;
+        if ( !islower(*ctemp) ) {
+            lowercased_name = FALSE;
             break;
         }
     }
 
-    (void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_CLIENT_PARMS_KEY,
-                         0, KEY_QUERY_VALUE, &NPKey);
-    LSPsize=sizeof(TraceOption);
-    RegQueryValueEx(NPKey, REG_CLIENT_TRACE_OPTION_PARM, NULL,
-                     &LSPtype, (LPBYTE)&TraceOption, &LSPsize);
-
-    RegCloseKey (NPKey);
-
     /*
      * Get Logon options
      */
@@ -657,6 +738,9 @@ DWORD APIENTRY NPLogonNotify(
     sleepInterval = opt.sleepInterval;
     *lpLogonScript = opt.logonScript;
 
+    if (retryInterval < sleepInterval)
+        sleepInterval = retryInterval;
+
     DebugEvent("Got logon script: %S",opt.logonScript);
 
     afsWillAutoStart = AFSWillAutoStart();
@@ -690,20 +774,20 @@ DWORD APIENTRY NPLogonNotify(
         /* 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)) {
+        if (ISREMOTE(opt.flags)) {
             DebugEvent("Is Remote");
             GetAdHomePath(homePath,MAX_PATH,lpLogonId,&opt);
         }       
     }
 
     /* loop until AFS is started. */
-    while (TRUE) {
-        DebugEvent("while(TRUE) LogonOption[%x], Service AutoStart[%d]",
+    while (IsServiceRunning() || IsServiceStartPending()) {
+        DebugEvent("while(autostart) LogonOption[%x], Service AutoStart[%d]",
                     opt.LogonOption,afsWillAutoStart);
 
-        if(ISADREALM(opt.flags)) {
+        if (ISADREALM(opt.flags)) {
             code = GetFileCellName(homePath,cell,256);
-            if(!code) {
+            if (!code) {
                 DebugEvent("profile path [%s] is in cell [%s]",homePath,cell);
             }
             /* Don't bail out if GetFileCellName failed.
@@ -718,42 +802,65 @@ DWORD APIENTRY NPLogonNotify(
             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);
-            }
-            else {
+                if (code == 0 && opt.theseCells) { 
+                    char * principal, *p;
+
+                    principal = (char *)malloc(strlen(uname) + strlen(cell) + 2);
+                    if ( principal ) {
+                        strcpy(principal, uname);
+                        p = principal + strlen(uname);
+                        *p++ = '@';
+                        strcpy(p, 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);
+                            p += strlen(p) + 1;
+                        }
+                        
+                        free(principal);
+                    }
+                }
+            } else {
                 code = ka_UserAuthenticateGeneral2(KA_USERAUTH_VERSION+KA_USERAUTH_AUTHENT_LOGON,
                                                     uname, "", cell, password, opt.smbName, 0, &pw_exp, 0,
                                                     &reason);
-                DebugEvent("AFS AfsLogon - (INTEGRATED only)ka_UserAuthenticateGeneral2","Code[%x]",
-                            code);
+                DebugEvent("AFS AfsLogon - (INTEGRATED only)ka_UserAuthenticateGeneral2","Code[%x] uname[%s] Cell[%s]",
+                            code,uname,cell);
             }       
-            if ( code && code != KTC_NOCM && code != KTC_NOCMRPC && uppercased_name ) {
+            if ( code && code != KTC_NOCM && code != KTC_NOCMRPC && !lowercased_name ) {
                 for ( ctemp = uname; *ctemp ; ctemp++) {
                     *ctemp = tolower(*ctemp);
                 }
-                uppercased_name = FALSE;
-                continue;
+                lowercased_name = TRUE;
+                goto sleeping;
             }
+
+            /* is service started yet?*/
+
+            /* 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. 
+            * If the error was something else, then give up. */
+            if (code != KTC_NOCM && code != KTC_NOCMRPC)
+                break;
         }
         else {  
             /*JUST check to see if its running*/
             if (IsServiceRunning())
                 break;
-            code = KTC_NOCM;
-            if (!afsWillAutoStart)
+            if (!IsServiceStartPending()) {
+                code = KTC_NOCMRPC;
+                reason = "AFS Service start failed";
                 break;
+            }
         }
 
-        /* is service started yet?*/
-        DebugEvent("AFS AfsLogon - ka_UserAuthenticateGeneral2","Code[%x] uname[%s] Cell[%s]",
-                    code,uname,cell);
-
-        /* 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. 
-         * If the error was something else, then give up. */
-        if (code != KTC_NOCM && code != KTC_NOCMRPC || !afsWillAutoStart)
-            break;
-
         /* If the retry interval has expired and we still aren't
          * logged in, then just give up if we are not in interactive
          * mode or the failSilently flag is set, otherwise let the
@@ -770,21 +877,24 @@ DWORD APIENTRY NPLogonNotify(
                 break;
 
             /* Wait just a little while and try again */
-            retryInterval = sleepInterval = DEFAULT_SLEEP_INTERVAL;
+            retryInterval = opt.retryInterval;
         }
 
-        if (retryInterval < sleepInterval)
-            sleepInterval = retryInterval;
-
+      sleeping:
         Sleep(sleepInterval * 1000);
-
         retryInterval -= sleepInterval;
     }
 
     DebugEvent("while loop exited");
-    /* remove any kerberos 5 tickets currently held by the SYSTEM account */
-    if ( KFW_is_available() )
-        KFW_AFS_destroy_tickets_for_cell(cell);
+    /* remove any kerberos 5 tickets currently held by the SYSTEM account
+     * for this user 
+     */
+    if ( KFW_is_available() ) {
+        sprintf(szLogonId,"%d.%d",lpLogonId->HighPart, lpLogonId->LowPart);
+        KFW_AFS_copy_cache_to_system_file(uname, szLogonId);
+
+        KFW_AFS_destroy_tickets_for_principal(uname);
+    }
 
     if (code) {
         char msg[128];
@@ -812,11 +922,11 @@ DWORD APIENTRY NPLogonNotify(
             *lpLogonScript = NULL;
             if (!afsWillAutoStart)     // its not running, so if not autostart or integrated logon then just skip
                 code = 0;
-
         }
     }
 
-    if(opt.smbName) free(opt.smbName);
+    if (opt.theseCells) free(opt.theseCells);
+    if (opt.smbName) free(opt.smbName);
 
     DebugEvent("AFS AfsLogon - Exit","Return Code[%x]",code);
     return code;
@@ -880,7 +990,7 @@ VOID AFS_Startup_Event( PWLX_NOTIFICATION_INFO pInfo )
     /* Make sure the AFS Libraries are initialized */
     AfsLogonInit();
 
-    (void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_CLIENT_PARMS_KEY,
+    (void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
                         0, KEY_QUERY_VALUE, &NPKey);
     LSPsize=sizeof(TraceOption);
     RegQueryValueEx(NPKey, REG_CLIENT_TRACE_OPTION_PARM, NULL,
@@ -897,12 +1007,88 @@ VOID AFS_Logoff_Event( PWLX_NOTIFICATION_INFO pInfo )
     DWORD  len = 1024;
     PTOKEN_USER  tokenUser = NULL;
     DWORD  retLen;
-    HANDLE hToken;
+    DWORD LSPtype, LSPsize;
+    HKEY NPKey;
+    DWORD LogoffPreserveTokens = 0;
 
     /* Make sure the AFS Libraries are initialized */
     AfsLogonInit();
 
-    DebugEvent0("AFS_Logoff_Event - Starting");
+    DebugEvent0("AFS_Logoff_Event - Start");
+
+    (void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
+                         0, KEY_QUERY_VALUE, &NPKey);
+    LSPsize=sizeof(LogoffPreserveTokens);
+    RegQueryValueEx(NPKey, REG_CLIENT_LOGOFF_TOKENS_PARM, NULL,
+                     &LSPtype, (LPBYTE)&LogoffPreserveTokens, &LSPsize);
+    RegCloseKey (NPKey);
+
+    if (LogoffPreserveTokens) {
+        if (!GetTokenInformation(pInfo->hToken, TokenUser, NULL, 0, &retLen))
+        {
+            if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) {
+                tokenUser = (PTOKEN_USER) LocalAlloc(LPTR, retLen);
+
+                if (!GetTokenInformation(pInfo->hToken, TokenUser, tokenUser, retLen, &retLen))
+                {
+                    DebugEvent("AFS_Logoff_Event - GetTokenInformation failed: GLE = %lX", GetLastError());
+                }
+            }
+        }
+
+        /* 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)) {
+            WCHAR Domain[64]=L"";
+            GetLocalShortDomain(Domain, sizeof(Domain));
+            if (QueryAdHomePathFromSid( profileDir, sizeof(profileDir), tokenUser->User.Sid, Domain)) {
+                if (NetUserGetProfilePath(pInfo->Domain, pInfo->UserName, profileDir, len))
+                    GetUserProfileDirectory(pInfo->hToken, profileDir, &len);
+            }
+        }
+
+        if (strlen(profileDir)) {
+            DebugEvent("AFS_Logoff_Event - Profile Directory: %s", profileDir);
+            if (!IsPathInAfs(profileDir)) {
+                if (code = ktc_ForgetAllTokens())
+                    DebugEvent("AFS_Logoff_Event - ForgetAllTokens failed [%lX]",code);
+                else
+                    DebugEvent0("AFS_Logoff_Event - ForgetAllTokens succeeded");
+            } else {
+                DebugEvent0("AFS_Logoff_Event - Tokens left in place; profile in AFS");
+            }
+        } else {
+            DebugEvent0("AFS_Logoff_Event - Unable to load profile");
+        }
+
+        if ( tokenUser )
+            LocalFree(tokenUser);
+    }
+
+    DebugEvent0("AFS_Logoff_Event - End");
+}   
+
+VOID AFS_Logon_Event( PWLX_NOTIFICATION_INFO pInfo )
+{
+    TCHAR profileDir[1024] = TEXT("");
+    DWORD  len = 1024;
+    PTOKEN_USER  tokenUser = NULL;
+    DWORD  retLen;
+    WCHAR szUserW[128] = L"";
+    char  szUserA[128] = "";
+    char  szClient[MAX_PATH];
+    char szPath[MAX_PATH] = "";
+    NETRESOURCE nr;
+    DWORD res;
+    DWORD dwSize;
+
+    /* Make sure the AFS Libraries are initialized */
+    AfsLogonInit();
+
+    DebugEvent0("AFS_Logon_Event - Start");
+
+    DebugEvent("AFS_Logon_Event Process ID: %d",GetCurrentProcessId());
 
     if (!GetTokenInformation(pInfo->hToken, TokenUser, NULL, 0, &retLen))
     {
@@ -911,7 +1097,7 @@ VOID AFS_Logoff_Event( PWLX_NOTIFICATION_INFO pInfo )
 
             if (!GetTokenInformation(pInfo->hToken, TokenUser, tokenUser, retLen, &retLen))
             {
-                DebugEvent("GetTokenInformation failed: GLE = %lX", GetLastError());
+                DebugEvent("AFS_Logon_Event - GetTokenInformation failed: GLE = %lX", GetLastError());
             }
         }
     }
@@ -929,20 +1115,154 @@ VOID AFS_Logoff_Event( PWLX_NOTIFICATION_INFO pInfo )
     }
     
     if (strlen(profileDir)) {
-        DebugEvent("Profile Directory: %s", profileDir);
-        if (!IsPathInAfs(profileDir)) {
-            if (code = ktc_ForgetAllTokens())
-                DebugEvent("AFS_Logoff_Event - ForgetAllTokens failed [%lX]",code);
-            else
-                DebugEvent0("AFS_Logoff_Event - ForgetAllTokens succeeded");
-        } else {
-            DebugEvent0("AFS_Logoff_Event - Tokens left in place; profile in AFS");
-        }
+        DebugEvent("AFS_Logon_Event - Profile Directory: %s", profileDir);
     } else {
-        DebugEvent0("AFS_Logoff_Event - Unable to load profile");
+        DebugEvent0("AFS_Logon_Event - Unable to load profile");
     }
 
+    dwSize = sizeof(szUserA);
+    if (!KFW_AFS_get_lsa_principal(szUserA, &dwSize)) {
+        StringCbPrintfW(szUserW, sizeof(szUserW), L"%s\\%s", pInfo->Domain, pInfo->UserName);
+        WideCharToMultiByte(CP_ACP, 0, szUserW, -1, szUserA, MAX_PATH, NULL, NULL);
+    }
+
+    if (szUserA[0])
+    {
+        lana_GetNetbiosName(szClient, LANA_NETBIOS_NAME_FULL);
+        StringCbPrintf(szPath, sizeof(szPath), "\\\\%s", szClient);
+
+        DebugEvent("AFS_Logon_Event - Logon Name: %s", szUserA);
+
+        memset (&nr, 0x00, sizeof(NETRESOURCE));
+        nr.dwType=RESOURCETYPE_DISK;
+        nr.lpLocalName=0;
+        nr.lpRemoteName=szPath;
+        res = WNetAddConnection2(&nr,NULL,szUserA,0);
+        if (res)
+            DebugEvent("AFS_Logon_Event - WNetAddConnection2(%s,%s) failed: 0x%X",
+                        szPath, szUserA,res);
+        else
+            DebugEvent0("AFS_Logon_Event - WNetAddConnection2() succeeded");
+    } else 
+        DebugEvent("AFS_Logon_Event - User name conversion failed: GLE = 0x%X",GetLastError());
+
     if ( tokenUser )
         LocalFree(tokenUser);
-}   
+
+    DebugEvent0("AFS_Logon_Event - End");
+}
+
+static BOOL
+GetSecurityLogonSessionData(HANDLE hToken, PSECURITY_LOGON_SESSION_DATA * ppSessionData)
+{
+    NTSTATUS Status = 0;
+    HANDLE  TokenHandle;
+    TOKEN_STATISTICS Stats;
+    DWORD   ReqLen;
+    BOOL    Success;
+
+    if (!ppSessionData)
+        return FALSE;
+    *ppSessionData = NULL;
+
+#if 0
+    Success = OpenProcessToken( HANDLE GetCurrentProcess(), TOKEN_QUERY, &TokenHandle );
+    if ( !Success )
+        return FALSE;
+#endif
+
+    Success = GetTokenInformation( hToken, TokenStatistics, &Stats, sizeof(TOKEN_STATISTICS), &ReqLen );
+#if 0
+    CloseHandle( TokenHandle );
+#endif
+    if ( !Success )
+        return FALSE;
+
+    Status = LsaGetLogonSessionData( &Stats.AuthenticationId, ppSessionData );
+    if ( FAILED(Status) || !ppSessionData )
+        return FALSE;
+
+    return TRUE;
+}
+
+VOID KFW_Logon_Event( PWLX_NOTIFICATION_INFO pInfo )
+{
+    DWORD code;
+
+    WCHAR szUserW[128] = L"";
+    char  szUserA[128] = "";
+    char  szClient[MAX_PATH];
+    char szPath[MAX_PATH] = "";
+    char szLogonId[128] = "";
+    NETRESOURCE nr;
+    DWORD res;
+    DWORD gle;
+    DWORD dwSize;
+    DWORD dwDisp;
+    DWORD dwType;
+    DWORD count;
+    VOID * ticketData;
+    char filename[256];
+    char commandline[512];
+    STARTUPINFO startupinfo;
+    PROCESS_INFORMATION procinfo;
+
+    LUID LogonId = {0, 0};
+    PSECURITY_LOGON_SESSION_DATA pLogonSessionData = NULL;
+
+    HKEY hKey1 = NULL, hKey2 = NULL;
+
+    /* Make sure the KFW Libraries are initialized */
+    AfsLogonInit();
+
+    DebugEvent0("KFW_Logon_Event - Start");
+
+    GetSecurityLogonSessionData( pInfo->hToken, &pLogonSessionData );
+
+    if ( pLogonSessionData ) {
+        LogonId = pLogonSessionData->LogonId;
+        DebugEvent("KFW_Logon_Event - LogonId(%d,%d)", LogonId.HighPart, LogonId.LowPart);
+
+        sprintf(szLogonId,"%d.%d",LogonId.HighPart, LogonId.LowPart);
+        LsaFreeReturnBuffer( pLogonSessionData );
+    } else {
+        DebugEvent0("KFW_Logon_Event - Unable to determine LogonId");
+        return;
+    }
+
+    count = GetEnvironmentVariable("TEMP", filename, sizeof(filename));
+    if ( count > sizeof(filename) || count == 0 ) {
+        GetWindowsDirectory(filename, sizeof(filename));
+    }
+
+    if ( strlen(filename) + strlen(szLogonId) + 2 <= sizeof(filename) ) {
+        strcat(filename, "\\");
+        strcat(filename, szLogonId);    
+
+        sprintf(commandline, "afscpcc.exe \"%s\"", filename);
+
+        GetStartupInfo(&startupinfo);
+        if (CreateProcessAsUser( pInfo->hToken,
+                             "afscpcc.exe",
+                             commandline,
+                             NULL,
+                             NULL,
+                             FALSE,
+                             CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS,
+                             NULL,
+                             NULL,
+                             &startupinfo,
+                             &procinfo)) 
+        {
+            WaitForSingleObject(procinfo.hProcess, 30000);
+
+            CloseHandle(procinfo.hThread);
+            CloseHandle(procinfo.hProcess);
+        }
+    }
+
+    DeleteFile(filename);
+
+    DebugEvent0("KFW_Logon_Event - End");
+}