2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
14 #include <sys/types.h>
21 #include <afs/param.h>
23 #include <afs/pioctl_nt.h>
24 #include <afs/kautils.h>
27 #include "cm_config.h"
30 #include "lanahelper.h"
32 /* Allocated in Windows Driver Kit */
33 #ifndef WNNC_NET_OPENAFS
34 #define WNNC_NET_OPENAFS 0x00390000
37 #include <WINNT\afsreg.h>
39 DWORD TraceOption = 0;
43 #define AFS_LOGON_EVENT_NAME TEXT("AFS Logon")
45 void DebugEvent0(char *a)
47 HANDLE h; char *ptbuf[1];
49 if (!ISLOGONTRACE(TraceOption))
52 h = RegisterEventSource(NULL, AFS_LOGON_EVENT_NAME);
53 if (h != INVALID_HANDLE_VALUE) {
55 ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 1008, NULL, 1, 0, (const char **)ptbuf, NULL);
56 DeregisterEventSource(h);
61 void DebugEvent(char *b,...)
63 HANDLE h; char *ptbuf[1],buf[MAXBUF_+1];
66 if (!ISLOGONTRACE(TraceOption))
69 h = RegisterEventSource(NULL, AFS_LOGON_EVENT_NAME);
70 if (h != INVALID_HANDLE_VALUE) {
72 StringCbVPrintf(buf, MAXBUF_+1,b,marker);
75 ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 1008, NULL, 1, 0, (const char **)ptbuf, NULL);
76 DeregisterEventSource(h);
81 static HANDLE hInitMutex = NULL;
82 static BOOL bInit = FALSE;
84 BOOLEAN APIENTRY DllEntryPoint(HANDLE dll, DWORD reason, PVOID reserved)
90 case DLL_PROCESS_ATTACH:
91 /* Initialization Mutex */
93 hInitMutex = CreateMutex(NULL, FALSE, NULL);
95 WSAStartup( MAKEWORD(2,2), &wsaData );
98 case DLL_PROCESS_DETACH:
100 CloseHandle(hInitMutex);
105 case DLL_THREAD_ATTACH:
106 case DLL_THREAD_DETACH:
108 /* Everything else succeeds but does nothing. */
115 void AfsLogonInit(void)
117 if ( bInit == FALSE ) {
118 if ( WaitForSingleObject( hInitMutex, INFINITE ) == WAIT_OBJECT_0 ) {
119 /* initAFSDirPath() initializes an array and sets a
120 * flag so that the initialization can only occur
121 * once. No cleanup will be done when the DLL is
122 * unloaded so the initialization will not be
123 * performed again on a subsequent reload
127 /* ka_Init initializes a number of error tables.
128 * and then calls ka_CellConfig() which grabs
129 * an afsconf_dir structure via afsconf_Open().
130 * Upon a second attempt to call ka_CellConfig()
131 * the structure will be released with afsconf_Close()
132 * and then re-opened. Could this corrupt memory?
134 * We only need this if we are not using KFW.
136 if (!KFW_is_available())
140 ReleaseMutex(hInitMutex);
144 CHAR *GenRandomName(CHAR *pbuf)
147 srand( (unsigned)time( NULL ) );
148 for (i=0;i<MAXRANDOMNAMELEN-1;i++)
149 pbuf[i]='a'+(rand() % 26);
150 pbuf[MAXRANDOMNAMELEN-1]=0;
154 BOOLEAN AFSWillAutoStart(void)
159 BOOLEAN result = FALSE;
160 LPQUERY_SERVICE_CONFIG pConfig = NULL;
164 /* Open services manager */
165 scm = OpenSCManager(NULL, NULL, GENERIC_READ);
166 if (!scm) return FALSE;
168 /* Open AFSD service */
169 svc = OpenService(scm, "TransarcAFSDaemon", SERVICE_QUERY_CONFIG);
173 /* Query AFSD service config, first just to get buffer size */
174 /* Expected to fail, so don't test return value */
175 (void) QueryServiceConfig(svc, NULL, 0, &BufSize);
176 status = GetLastError();
177 if (status != ERROR_INSUFFICIENT_BUFFER)
180 /* Allocate buffer */
181 pConfig = (LPQUERY_SERVICE_CONFIG)GlobalAlloc(GMEM_FIXED,BufSize);
185 /* Query AFSD service config, this time for real */
186 flag = QueryServiceConfig(svc, pConfig, BufSize, &BufSize);
190 /* Is it autostart? */
191 if (pConfig->dwStartType < SERVICE_DEMAND_START)
197 CloseServiceHandle(svc);
199 CloseServiceHandle(scm);
204 DWORD MapAuthError(DWORD code)
207 /* Unfortunately, returning WN_NO_NETWORK results in the MPR abandoning
208 * logon scripts for all credential managers, although they will still
209 * receive logon notifications. Since we don't want this, we return
210 * WN_SUCCESS. This is highly undesirable, but we also don't want to
211 * break other network providers.
215 return WN_NO_NETWORK; */
216 default: return WN_SUCCESS;
220 DWORD APIENTRY NPGetCaps(DWORD index)
224 /* Don't have our own type; use somebody else's. */
225 return WNNC_NET_OPENAFS;
228 /* Say we are already started, even though we might wait after we receive NPLogonNotify */
237 NetUserGetProfilePath( LPCWSTR Domain, LPCWSTR UserName, char * profilePath,
238 DWORD profilePathLen )
241 LPWSTR ServerName = NULL;
242 LPUSER_INFO_3 p3 = NULL;
244 NetGetAnyDCName(NULL, Domain, (LPBYTE *)&ServerName);
245 /* if NetGetAnyDCName fails, ServerName == NULL
246 * NetUserGetInfo will obtain local user information
248 code = NetUserGetInfo(ServerName, UserName, 3, (LPBYTE *)&p3);
249 if (code == NERR_Success)
251 code = NERR_UserNotFound;
253 if (p3->usri3_profile) {
254 DWORD len = lstrlenW(p3->usri3_profile);
256 /* Convert From Unicode to ANSI (UTF-8 for future) */
257 len = len < profilePathLen ? len : profilePathLen - 1;
258 WideCharToMultiByte(CP_UTF8, 0, p3->usri3_profile, len, profilePath, len, NULL, NULL);
259 profilePath[len] = '\0';
263 NetApiBufferFree(p3);
267 NetApiBufferFree(ServerName);
271 BOOL IsServiceRunning (void)
273 SERVICE_STATUS Status;
275 memset (&Status, 0x00, sizeof(Status));
276 Status.dwCurrentState = SERVICE_STOPPED;
278 if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
281 if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
283 QueryServiceStatus (hService, &Status);
284 CloseServiceHandle (hService);
287 CloseServiceHandle (hManager);
289 DebugEvent("AFS AfsLogon - Test Service Running Return Code[%x] ?Running[%d]",Status.dwCurrentState,(Status.dwCurrentState == SERVICE_RUNNING));
290 return (Status.dwCurrentState == SERVICE_RUNNING);
293 BOOL IsServiceStartPending (void)
295 SERVICE_STATUS Status;
297 memset (&Status, 0x00, sizeof(Status));
298 Status.dwCurrentState = SERVICE_STOPPED;
300 if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
303 if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
305 QueryServiceStatus (hService, &Status);
306 CloseServiceHandle (hService);
309 CloseServiceHandle (hManager);
311 DebugEvent("AFS AfsLogon - Test Service Start Pending Return Code[%x] ?Start Pending[%d]",Status.dwCurrentState,(Status.dwCurrentState == SERVICE_START_PENDING));
312 return (Status.dwCurrentState == SERVICE_START_PENDING);
315 /* LOOKUPKEYCHAIN: macro to look up the value in the list of keys in order until it's found
316 v:variable to receive value (reference type)
318 d:default, in case the value isn't on any of the keys
320 #define LOOKUPKEYCHAIN(v,t,d,n) \
322 rv = ~ERROR_SUCCESS; \
325 dwSize = sizeof(v); \
326 rv = RegQueryValueEx(hkDom, n, 0, &dwType, (LPBYTE) &(v), &dwSize); \
327 if(rv == ERROR_SUCCESS || rv == ERROR_MORE_DATA) \
328 DebugEvent(#v " found in hkDom with type [%d]", dwType); \
330 if(hkDoms && ((rv != ERROR_SUCCESS && rv != ERROR_MORE_DATA) || dwType != t)) { \
331 dwSize = sizeof(v); \
332 rv = RegQueryValueEx(hkDoms, n, 0, &dwType, (LPBYTE) &(v), &dwSize); \
333 if(rv == ERROR_SUCCESS || rv == ERROR_MORE_DATA) \
334 DebugEvent(#v " found in hkDoms with type [%d]", dwType); \
336 if(hkNp && ((rv != ERROR_SUCCESS && rv != ERROR_MORE_DATA) || dwType != t)) { \
337 dwSize = sizeof(v); \
338 rv = RegQueryValueEx(hkNp, n, 0, &dwType, (LPBYTE) &(v), &dwSize); \
339 if(rv == ERROR_SUCCESS || rv == ERROR_MORE_DATA) \
340 DebugEvent(#v " found in hkNp with type [%d]", dwType); \
342 if((rv != ERROR_SUCCESS && rv != ERROR_MORE_DATA) || dwType != t) { \
344 DebugEvent0(#v " being set to default"); \
348 /* Get domain specific configuration info. We are returning void because if anything goes wrong
349 we just return defaults.
352 GetDomainLogonOptions( PLUID lpLogonId, char * username, char * domain, LogonOptions_t *opt ) {
353 HKEY hkParm = NULL; /* Service parameter */
354 HKEY hkNp = NULL; /* network provider key */
355 HKEY hkDoms = NULL; /* domains key */
356 HKEY hkDom = NULL; /* DOMAINS/domain key */
362 char computerName[MAX_COMPUTERNAME_LENGTH + 1];
365 memset(opt, 0, sizeof(LogonOptions_t));
367 DebugEvent("In GetDomainLogonOptions for user [%s] in domain [%s]", username, domain);
368 /* If the domain is the same as the Netbios computer name, we use the LOCALHOST domain name*/
369 opt->flags = LOGON_FLAG_REMOTE;
371 dwSize = MAX_COMPUTERNAME_LENGTH;
372 if(GetComputerName(computerName, &dwSize)) {
373 if(!cm_stricmp_utf8(computerName, domain)) {
374 effDomain = "LOCALHOST";
375 opt->flags = LOGON_FLAG_LOCAL;
383 rv = RegOpenKeyEx( HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY, 0, KEY_READ, &hkParm );
384 if(rv != ERROR_SUCCESS) {
386 DebugEvent("GetDomainLogonOption: Can't open parms key [%d]", rv);
389 rv = RegOpenKeyEx( HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PROVIDER_SUBKEY, 0, KEY_READ, &hkNp );
390 if(rv != ERROR_SUCCESS) {
392 DebugEvent("GetDomainLogonOptions: Can't open NP key [%d]", rv);
396 rv = RegOpenKeyEx( hkNp, REG_CLIENT_DOMAINS_SUBKEY, 0, KEY_READ, &hkDoms );
397 if( rv != ERROR_SUCCESS ) {
399 DebugEvent("GetDomainLogonOptions: Can't open Domains key [%d]", rv);
403 if(hkDoms && effDomain) {
404 rv = RegOpenKeyEx( hkDoms, effDomain, 0, KEY_READ, &hkDom );
405 if( rv != ERROR_SUCCESS ) {
407 DebugEvent("GetDomainLogonOptions: Can't open domain key for [%s] [%d]", effDomain, rv);
408 /* If none of the domains match, we shouldn't use the domain key either */
413 DebugEvent0("Not opening domain key");
415 /* Each individual can either be specified on the domain key, the domains key or in the
416 net provider key. They fail over in that order. If none is found, we just use the
420 LOOKUPKEYCHAIN(opt->LogonOption, REG_DWORD, DEFAULT_LOGON_OPTION, REG_CLIENT_LOGON_OPTION_PARM);
422 /* FailLoginsSilently */
423 dwSize = sizeof(dwDummy);
424 rv = RegQueryValueEx(hkParm, REG_CLIENT_FAIL_SILENTLY_PARM, 0, &dwType, (LPBYTE) &dwDummy, &dwSize);
425 if (rv != ERROR_SUCCESS)
426 LOOKUPKEYCHAIN(dwDummy, REG_DWORD, DEFAULT_FAIL_SILENTLY, REG_CLIENT_FAIL_SILENTLY_PARM);
427 opt->failSilently = !!dwDummy;
430 LOOKUPKEYCHAIN(opt->retryInterval, REG_DWORD, DEFAULT_RETRY_INTERVAL, REG_CLIENT_RETRY_INTERVAL_PARM);
433 LOOKUPKEYCHAIN(opt->sleepInterval, REG_DWORD, DEFAULT_SLEEP_INTERVAL, REG_CLIENT_SLEEP_INTERVAL_PARM);
435 opt->logonScript = NULL;
438 if(!ISLOGONINTEGRATED(opt->LogonOption)) {
439 goto cleanup; /* no need to lookup the logon script */
442 /* come up with SMB username */
443 if(ISHIGHSECURITY(opt->LogonOption)) {
444 opt->smbName = malloc( MAXRANDOMNAMELEN );
445 GenRandomName(opt->smbName);
446 } else if (lpLogonId) {
447 /* username and domain for logon session is not necessarily the same as
448 username and domain passed into network provider. */
449 PSECURITY_LOGON_SESSION_DATA plsd;
450 char lsaUsername[MAX_USERNAME_LENGTH];
451 char lsaDomain[MAX_DOMAIN_LENGTH];
454 LsaGetLogonSessionData(lpLogonId, &plsd);
456 UnicodeStringToANSI(plsd->UserName, lsaUsername, MAX_USERNAME_LENGTH);
457 UnicodeStringToANSI(plsd->LogonDomain, lsaDomain, MAX_DOMAIN_LENGTH);
459 DebugEvent("PLSD username[%s] domain[%s]",lsaUsername,lsaDomain);
461 if(SUCCEEDED(StringCbLength(lsaUsername, MAX_USERNAME_LENGTH, &tlen)))
466 if(SUCCEEDED(StringCbLength(lsaDomain, MAX_DOMAIN_LENGTH, &tlen)))
473 opt->smbName = malloc(len);
475 StringCbCopy(opt->smbName, len, lsaDomain);
476 StringCbCat(opt->smbName, len, "\\");
477 StringCbCat(opt->smbName, len, lsaUsername);
479 strlwr(opt->smbName);
482 LsaFreeReturnBuffer(plsd);
486 DebugEvent("No LUID given. Constructing username using [%s] and [%s]",
489 len = strlen(username) + strlen(domain) + 2;
491 opt->smbName = malloc(len);
493 StringCbCopy(opt->smbName, len, username);
494 StringCbCat(opt->smbName, len, "\\");
495 StringCbCat(opt->smbName, len, domain);
497 strlwr(opt->smbName);
500 DebugEvent0("Looking up logon script");
502 /* First find out where the key is */
507 rv = RegQueryValueExW(hkDom, REG_CLIENT_LOGON_SCRIPT_PARMW, 0, &dwType, NULL, &dwSize);
508 if(rv == ERROR_SUCCESS && (dwType == REG_SZ || dwType == REG_EXPAND_SZ)) {
510 DebugEvent0("Located logon script in hkDom");
513 rv = RegQueryValueExW(hkDoms, REG_CLIENT_LOGON_SCRIPT_PARMW, 0, &dwType, NULL, &dwSize);
514 if(rv == ERROR_SUCCESS && !hkTemp && (dwType == REG_SZ || dwType == REG_EXPAND_SZ)) {
516 DebugEvent0("Located logon script in hkDoms");
518 /* Note that the LogonScript in the NP key is only used if we are doing high security. */
519 else if(hkNp && ISHIGHSECURITY(opt->LogonOption)) {
520 rv = RegQueryValueExW(hkNp, REG_CLIENT_LOGON_SCRIPT_PARMW, 0, &dwType, NULL, &dwSize);
521 if(rv == ERROR_SUCCESS && !hkTemp && (dwType == REG_SZ || dwType == REG_EXPAND_SZ)) {
523 DebugEvent0("Located logon script in hkNp");
529 WCHAR *regscript = NULL;
530 WCHAR *regexscript = NULL;
531 WCHAR *regexuscript = NULL;
532 WCHAR *wuname = NULL;
537 StringCbLength(opt->smbName, MAX_USERNAME_LENGTH, &len);
540 wuname = malloc(len * sizeof(WCHAR));
542 goto doneLogonScript;
543 MultiByteToWideChar(CP_ACP,0,opt->smbName,-1,wuname,(int)(len*sizeof(WCHAR)));
545 DebugEvent("Username is set for [%S]", wuname);
547 /* dwSize still has the size of the required buffer in bytes. */
548 regscript = malloc(dwSize);
550 goto doneLogonScript;
551 rv = RegQueryValueExW(hkTemp, REG_CLIENT_LOGON_SCRIPT_PARMW, 0, &dwType, (LPBYTE) regscript, &dwSize);
552 if(rv != ERROR_SUCCESS) {/* what the ..? */
553 DebugEvent("Can't look up logon script rv [%d] size [%d] gle %d",rv, dwSize, GetLastError());
554 goto doneLogonScript;
557 DebugEvent("Found logon script [%S]", regscript);
559 if(dwType == REG_EXPAND_SZ) {
562 dwSize += MAX_PATH * sizeof(WCHAR); /* make room for environment expansion. */
563 regexscript = malloc(dwSize);
565 goto doneLogonScript;
566 dwReq = ExpandEnvironmentStringsW(regscript, regexscript, dwSize / sizeof(WCHAR));
568 regscript = regexscript;
570 if(dwReq > (dwSize / sizeof(WCHAR))) {
571 DebugEvent0("Overflow while expanding environment strings.");
572 goto doneLogonScript;
576 DebugEvent("After expanding env strings [%S]", regscript);
578 if(wcsstr(regscript, L"%s")) {
579 dwSize += (DWORD)(len * sizeof(WCHAR)); /* make room for username expansion */
580 regexuscript = (WCHAR *) LocalAlloc(LMEM_FIXED, dwSize);
582 goto doneLogonScript;
583 hr = StringCbPrintfW(regexuscript, dwSize, regscript, wuname);
585 regexuscript = (WCHAR *) LocalAlloc(LMEM_FIXED, dwSize);
587 goto doneLogonScript;
588 hr = StringCbCopyW(regexuscript, dwSize, regscript);
591 DebugEvent("After expanding username [%S]", regexuscript);
594 opt->logonScript = regexuscript;
596 LocalFree(regexuscript);
599 if(wuname) free(wuname);
600 if(regscript) free(regscript);
601 if(regexscript) free(regexscript);
604 DebugEvent0("Looking up TheseCells");
606 /* First find out where the key is */
611 rv = RegQueryValueEx(hkDom, REG_CLIENT_THESE_CELLS_PARM, 0, &dwType, NULL, &dwSize);
612 if (rv == ERROR_SUCCESS && dwType == REG_MULTI_SZ) {
614 DebugEvent("Located TheseCells in hkDom size %d", dwSize);
616 rv = RegQueryValueEx(hkDoms, REG_CLIENT_THESE_CELLS_PARM, 0, &dwType, NULL, &dwSize);
617 if (rv == ERROR_SUCCESS && !hkTemp && dwType == REG_MULTI_SZ) {
619 DebugEvent("Located TheseCells in hkDoms size %d", dwSize);
621 rv = RegQueryValueEx(hkNp, REG_CLIENT_THESE_CELLS_PARM, 0, &dwType, NULL, &dwSize);
622 if (rv == ERROR_SUCCESS && !hkTemp && dwType == REG_MULTI_SZ) {
624 DebugEvent("Located TheseCells in hkNp size %d", dwSize);
630 CHAR * thesecells = NULL;
632 /* dwSize still has the size of the required buffer in bytes. */
633 thesecells = malloc(dwSize*2);
638 rv = RegQueryValueEx(hkTemp, REG_CLIENT_THESE_CELLS_PARM, 0, NULL, (LPBYTE) thesecells, &dwSize);
639 if(rv != ERROR_SUCCESS) {/* what the ..? */
640 DebugEvent("Can't look up TheseCells rv [%d] size [%d] gle [%d]",rv, dwSize, GetLastError());
644 DebugEvent("Found TheseCells [%s]", thesecells);
645 opt->theseCells = thesecells;
649 if (thesecells) free(thesecells);
652 DebugEvent0("Looking up Realm");
654 /* First find out where the key is */
659 rv = RegQueryValueEx(hkDom, REG_CLIENT_REALM_PARM, 0, &dwType, NULL, &dwSize);
660 if (rv == ERROR_SUCCESS && dwType == REG_SZ) {
662 DebugEvent("Located Realm in hkDom size %d", dwSize);
664 rv = RegQueryValueEx(hkDoms, REG_CLIENT_REALM_PARM, 0, &dwType, NULL, &dwSize);
665 if (rv == ERROR_SUCCESS && !hkTemp && dwType == REG_SZ) {
667 DebugEvent("Located Realm in hkDoms size %d", dwSize);
669 rv = RegQueryValueEx(hkNp, REG_CLIENT_REALM_PARM, 0, &dwType, NULL, &dwSize);
670 if (rv == ERROR_SUCCESS && !hkTemp && dwType == REG_SZ) {
672 DebugEvent("Located Realm in hkNp size %d", dwSize);
680 /* dwSize still has the size of the required buffer in bytes. */
681 realm = malloc(dwSize*2);
686 rv = RegQueryValueEx(hkTemp, REG_CLIENT_REALM_PARM, 0, NULL, (LPBYTE) realm, &dwSize);
687 if(rv != ERROR_SUCCESS) {/* what the ..? */
688 DebugEvent("Can't look up Realm rv [%d] size [%d] gle [%d]",rv, dwSize, GetLastError());
692 DebugEvent("Found Realm [%s]", realm);
697 if (realm) free(realm);
701 if(hkNp) RegCloseKey(hkNp);
702 if(hkDom) RegCloseKey(hkDom);
703 if(hkDoms) RegCloseKey(hkDoms);
704 if(hkParm) RegCloseKey(hkParm);
707 #undef LOOKUPKEYCHAIN
709 /* Try to find out which cell the given path is in. We must retain
710 the contents of *cell in case of failure. *cell is assumed to be
711 at least cellLen chars */
712 DWORD GetFileCellName(char * path, char * cell, size_t cellLen) {
713 struct ViceIoctl blob;
714 char tcell[MAX_PATH];
718 blob.out_size = MAX_PATH;
721 code = pioctl(path, VIOC_FILE_CELL_NAME, &blob, 1);
724 strncpy(cell, tcell, cellLen);
725 cell[cellLen - 1] = '\0';
733 UnicodeStringToANSI(UNICODE_STRING uInputString, LPSTR lpszOutputString, int nOutStringLen)
737 GetCPInfo(CP_ACP, &CodePageInfo);
739 if (CodePageInfo.MaxCharSize > 1)
740 // Only supporting non-Unicode strings
743 if (uInputString.Buffer && ((LPBYTE) uInputString.Buffer)[1] == '\0')
745 // Looks like unicode, better translate it
746 // UNICODE_STRING specifies the length of the buffer string in Bytes not WCHARS
747 WideCharToMultiByte(CP_ACP, 0, (LPCWSTR) uInputString.Buffer, uInputString.Length/2,
748 lpszOutputString, nOutStringLen-1, NULL, NULL);
749 lpszOutputString[min(uInputString.Length/2,nOutStringLen-1)] = '\0';
753 lpszOutputString[0] = '\0';
755 } // UnicodeStringToANSI
757 DWORD APIENTRY NPLogonNotify(
759 LPCWSTR lpAuthentInfoType,
760 LPVOID lpAuthentInfo,
761 LPCWSTR lpPreviousAuthentInfoType,
762 LPVOID lpPreviousAuthentInfo,
763 LPWSTR lpStationName,
764 LPVOID StationHandle,
765 LPWSTR *lpLogonScript)
767 char uname[MAX_USERNAME_LENGTH]="";
768 char password[MAX_PASSWORD_LENGTH]="";
769 char logonDomain[MAX_DOMAIN_LENGTH]="";
770 char cell[256]="<non-integrated logon>";
771 char homePath[MAX_PATH]="";
772 char szLogonId[128] = "";
774 MSV1_0_INTERACTIVE_LOGON *IL;
776 DWORD code = 0, code2;
784 DWORD LSPtype, LSPsize;
787 HWND hwndOwner = (HWND)StationHandle;
789 BOOLEAN afsWillAutoStart;
791 BOOLEAN lowercased_name = TRUE;
793 LogonOptions_t opt; /* domain specific logon options */
797 /* Are we interactive? */
798 interactive = (wcsicmp(lpStationName, L"WinSta0") == 0);
800 #ifdef DISABLE_NON_INTERACTIVE
801 /* Do not do anything if the logon session is not interactive. */
806 (void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
807 0, KEY_QUERY_VALUE, &NPKey);
808 LSPsize=sizeof(TraceOption);
809 RegQueryValueEx(NPKey, REG_CLIENT_TRACE_OPTION_PARM, NULL,
810 &LSPtype, (LPBYTE)&TraceOption, &LSPsize);
814 DebugEvent("NPLogonNotify - LoginId(%d,%d)", lpLogonId->HighPart, lpLogonId->LowPart);
816 /* Make sure the AFS Libraries are initialized */
819 /* Initialize Logon Script to none */
822 /* MSV1_0_INTERACTIVE_LOGON and KERB_INTERACTIVE_LOGON are equivalent for
825 if ( wcsicmp(lpAuthentInfoType,L"MSV1_0:Interactive") &&
826 wcsicmp(lpAuthentInfoType,L"Kerberos:Interactive") )
828 DebugEvent("Unsupported Authentication Info Type: %S",
833 IL = (MSV1_0_INTERACTIVE_LOGON *) lpAuthentInfo;
835 /* Convert from Unicode to ANSI */
837 /*TODO: Use SecureZeroMemory to erase passwords */
838 if (!UnicodeStringToANSI(IL->UserName, uname, MAX_USERNAME_LENGTH) ||
839 !UnicodeStringToANSI(IL->Password, password, MAX_PASSWORD_LENGTH) ||
840 !UnicodeStringToANSI(IL->LogonDomainName, logonDomain, MAX_DOMAIN_LENGTH))
843 /* Make sure AD-DOMANS sent from login that is sent to us is striped */
844 ctemp = strchr(uname, '@');
845 if (ctemp) *ctemp = 0;
847 /* is the name all lowercase? */
848 for ( ctemp = uname; *ctemp ; ctemp++) {
849 if ( !islower(*ctemp) ) {
850 lowercased_name = FALSE;
859 GetDomainLogonOptions( lpLogonId, uname, logonDomain, &opt );
860 retryInterval = opt.retryInterval;
861 sleepInterval = opt.sleepInterval;
862 *lpLogonScript = opt.logonScript;
864 if (retryInterval < sleepInterval)
865 sleepInterval = retryInterval;
867 DebugEvent("Got logon script: %S",opt.logonScript);
869 afsWillAutoStart = AFSWillAutoStart();
871 DebugEvent("LogonOption[%x], Service AutoStart[%d]",
872 opt.LogonOption,afsWillAutoStart);
874 /* Check for zero length password if integrated logon*/
875 if ( ISLOGONINTEGRATED(opt.LogonOption) ) {
876 if ( password[0] == 0 ) {
877 DebugEvent0("Password is the empty string");
879 reason = "zero length password is illegal";
883 /* Get cell name if doing integrated logon.
884 We might overwrite this if we are logging into an AD realm and we find out that
885 the user's home dir is in some other cell. */
886 DebugEvent("About to call cm_GetRootCellName(%s)",cell);
887 code = cm_GetRootCellName(cell);
889 DebugEvent0("Unable to obtain Root Cell");
891 reason = "unknown cell";
894 DebugEvent("Cell is %s",cell);
897 /* We get the user's home directory path, if applicable, though we can't lookup the
898 cell right away because the client service may not have started yet. This call
899 also sets the AD_REALM flag in opt.flags if applicable. */
900 if (ISREMOTE(opt.flags)) {
901 DebugEvent0("Is Remote");
902 GetAdHomePath(homePath,MAX_PATH,lpLogonId,&opt);
906 /* loop until AFS is started. */
907 if (afsWillAutoStart) {
908 while (IsServiceRunning() || IsServiceStartPending()) {
909 DebugEvent("while(autostart) LogonOption[%x], Service AutoStart[%d]",
910 opt.LogonOption,afsWillAutoStart);
912 if (ISADREALM(opt.flags)) {
913 code = GetFileCellName(homePath,cell,256);
915 DebugEvent("profile path [%s] is in cell [%s]",homePath,cell);
917 /* Don't bail out if GetFileCellName failed.
918 * The home dir may not be in AFS after all.
923 /* if Integrated Logon */
924 if (ISLOGONINTEGRATED(opt.LogonOption))
926 if ( KFW_is_available() ) {
927 SetEnvironmentVariable(DO_NOT_REGISTER_VARNAME, "");
929 char * principal, *p;
932 StringCchLength(opt.realm, MAX_DOMAIN_LENGTH, &tlen);
934 StringCchLength(uname, MAX_USERNAME_LENGTH, &tlen);
937 /* tlen is now the length of uname in characters */
938 principal = (char *)malloc(len * sizeof(char));
940 StringCchCopy(principal, len, uname);
941 p = principal + tlen;
943 StringCchCopy(p, len - tlen -1, opt.realm);
944 code = KFW_AFS_get_cred(principal, cell, password, 0, opt.smbName, &reason);
945 DebugEvent("KFW_AFS_get_cred uname=[%s] smbname=[%s] cell=[%s] code=[%d]",
946 principal,opt.smbName,cell,code);
950 code = KFW_AFS_get_cred(uname, cell, password, 0, opt.smbName, &reason);
951 DebugEvent("KFW_AFS_get_cred uname=[%s] smbname=[%s] cell=[%s] code=[%d]",
952 uname,opt.smbName,cell,code);
954 SetEnvironmentVariable(DO_NOT_REGISTER_VARNAME, NULL);
955 if (code == 0 && opt.theseCells) {
956 char * principal, *p;
959 StringCchLength(opt.realm ? opt.realm : cell, MAX_DOMAIN_LENGTH, &tlen);
961 StringCchLength(uname, MAX_USERNAME_LENGTH, &tlen);
964 /* tlen is now the length of uname in characters */
965 principal = (char *)malloc(len * sizeof(char));
967 StringCchCopy(principal, len, uname);
968 p = principal + tlen;
971 StringCchCopy(p, len - tlen -1, opt.realm);
973 StringCchCopy(p, len - tlen - 1, cell);
980 if ( cm_stricmp_utf8(p, cell) ) {
981 SetEnvironmentVariable(DO_NOT_REGISTER_VARNAME, "");
982 code2 = KFW_AFS_get_cred(principal, p, 0, 0, opt.smbName, &reason);
983 SetEnvironmentVariable(DO_NOT_REGISTER_VARNAME, NULL);
984 DebugEvent("KFW_AFS_get_cred uname=[%s] smbname=[%s] cell=[%s] code=[%d]",
985 principal,opt.smbName,p,code2);
993 code = ka_UserAuthenticateGeneral2(KA_USERAUTH_VERSION+KA_USERAUTH_AUTHENT_LOGON,
994 uname, "", cell, password, opt.smbName, 0, &pw_exp, 0,
996 DebugEvent("AFS AfsLogon - (INTEGRATED only)ka_UserAuthenticateGeneral2 Code[%x] uname[%s] smbname=[%s] Cell[%s] PwExp=[%d] Reason=[%s]",
997 code,uname,opt.smbName,cell,pw_exp,reason?reason:"");
999 if ( code && code != KTC_NOCM && code != KTC_NOCMRPC && !lowercased_name ) {
1000 for ( ctemp = uname; *ctemp ; ctemp++) {
1001 *ctemp = tolower(*ctemp);
1003 lowercased_name = TRUE;
1007 /* is service started yet?*/
1009 /* If we've failed because the client isn't running yet and the
1010 * client is set to autostart (and therefore it makes sense for
1011 * us to wait for it to start) then sleep a while and try again.
1012 * If the error was something else, then give up. */
1013 if (code != KTC_NOCM && code != KTC_NOCMRPC)
1017 /*JUST check to see if its running*/
1018 if (IsServiceRunning())
1020 if (!IsServiceStartPending()) {
1022 reason = "AFS Service start failed";
1027 /* If the retry interval has expired and we still aren't
1028 * logged in, then just give up if we are not in interactive
1029 * mode or the failSilently flag is set, otherwise let the
1030 * user know we failed and give them a chance to try again. */
1031 if (retryInterval <= 0) {
1032 reason = "AFS not running";
1033 if (!interactive || opt.failSilently)
1035 flag = MessageBox(hwndOwner,
1036 "AFS is still starting. Retry?",
1038 MB_ICONQUESTION | MB_RETRYCANCEL);
1039 if (flag == IDCANCEL)
1042 /* Wait just a little while and try again */
1043 retryInterval = opt.retryInterval;
1047 Sleep(sleepInterval * 1000);
1048 retryInterval -= sleepInterval;
1051 DebugEvent0("while loop exited");
1053 /* remove any kerberos 5 tickets currently held by the SYSTEM account
1057 if (ISLOGONINTEGRATED(opt.LogonOption) && KFW_is_available()) {
1059 sprintf(szLogonId,"%d.%d",lpLogonId->HighPart, lpLogonId->LowPart);
1060 KFW_AFS_copy_cache_to_system_file(uname, szLogonId);
1062 KFW_AFS_destroy_tickets_for_principal(uname);
1070 StringCbPrintf(msg, sizeof(msg), "Integrated login failed: %s", reason);
1072 if (ISLOGONINTEGRATED(opt.LogonOption) && interactive && !opt.failSilently)
1073 MessageBox(hwndOwner, msg, "AFS Logon", MB_OK);
1075 h = RegisterEventSource(NULL, AFS_LOGON_EVENT_NAME);
1077 ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1008, NULL,
1079 DeregisterEventSource(h);
1081 code = MapAuthError(code);
1084 if (ISLOGONINTEGRATED(opt.LogonOption) && (code!=0))
1087 LocalFree(*lpLogonScript);
1088 *lpLogonScript = NULL;
1089 if (!afsWillAutoStart) // its not running, so if not autostart or integrated logon then just skip
1094 if (opt.theseCells) free(opt.theseCells);
1095 if (opt.smbName) free(opt.smbName);
1096 if (opt.realm) free(opt.realm);
1098 DebugEvent("AFS AfsLogon - Exit","Return Code[%x]",code);
1102 DWORD APIENTRY NPPasswordChangeNotify(
1103 LPCWSTR lpAuthentInfoType,
1104 LPVOID lpAuthentInfo,
1105 LPCWSTR lpPreviousAuthentInfoType,
1106 LPVOID lpPreviousAuthentInfo,
1107 LPWSTR lpStationName,
1108 LPVOID StationHandle,
1111 BOOLEAN interactive;
1113 /* Are we interactive? */
1114 interactive = (wcsicmp(lpStationName, L"WinSta0") == 0);
1116 /* Do not do anything if the logon session is not interactive. */
1120 /* Make sure the AFS Libraries are initialized */
1123 DebugEvent0("AFS AfsLogon - NPPasswordChangeNotify");
1127 #include <userenv.h>
1129 #include <afs/vice.h>
1130 #include <afs/fs_utils.h>
1132 BOOL IsPathInAfs(const CHAR *strPath)
1135 struct ViceIoctl blob;
1139 blob.out_size = 2048;
1142 code = pioctl((LPTSTR)((LPCTSTR)strPath), VIOC_FILE_CELL_NAME, &blob, 1);
1149 typedef struct _WLX_NOTIFICATION_INFO {
1154 PWSTR WindowStation;
1157 PFNMSGECALLBACK pStatusCallback;
1158 } WLX_NOTIFICATION_INFO, *PWLX_NOTIFICATION_INFO;
1161 VOID AFS_Startup_Event( PWLX_NOTIFICATION_INFO pInfo )
1163 DWORD LSPtype, LSPsize;
1166 /* Make sure the AFS Libraries are initialized */
1169 (void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
1170 0, KEY_QUERY_VALUE, &NPKey);
1171 LSPsize=sizeof(TraceOption);
1172 RegQueryValueEx(NPKey, REG_CLIENT_TRACE_OPTION_PARM, NULL,
1173 &LSPtype, (LPBYTE)&TraceOption, &LSPsize);
1175 RegCloseKey (NPKey);
1176 DebugEvent0("AFS_Startup_Event");
1179 VOID AFS_Logoff_Event( PWLX_NOTIFICATION_INFO pInfo )
1182 TCHAR profileDir[1024] = TEXT("");
1184 PTOKEN_USER tokenUser = NULL;
1186 DWORD LSPtype, LSPsize;
1188 DWORD LogoffPreserveTokens = 0;
1191 /* Make sure the AFS Libraries are initialized */
1194 DebugEvent0("AFS_Logoff_Event - Start");
1196 (void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
1197 0, KEY_QUERY_VALUE, &NPKey);
1198 LSPsize=sizeof(LogoffPreserveTokens);
1199 RegQueryValueEx(NPKey, REG_CLIENT_LOGOFF_TOKENS_PARM, NULL,
1200 &LSPtype, (LPBYTE)&LogoffPreserveTokens, &LSPsize);
1201 RegCloseKey (NPKey);
1203 if (!LogoffPreserveTokens) {
1204 memset(&opt, 0, sizeof(LogonOptions_t));
1206 if (pInfo->UserName && pInfo->Domain) {
1207 char username[MAX_USERNAME_LENGTH] = "";
1208 char domain[MAX_DOMAIN_LENGTH] = "";
1211 StringCchLengthW(pInfo->UserName, MAX_USERNAME_LENGTH, &szlen);
1212 WideCharToMultiByte(CP_UTF8, 0, pInfo->UserName, szlen,
1213 username, sizeof(username), NULL, NULL);
1215 StringCchLengthW(pInfo->Domain, MAX_DOMAIN_LENGTH, &szlen);
1216 WideCharToMultiByte(CP_UTF8, 0, pInfo->Domain, szlen,
1217 domain, sizeof(domain), NULL, NULL);
1219 GetDomainLogonOptions(NULL, username, domain, &opt);
1222 if (ISREMOTE(opt.flags)) {
1223 if (!GetTokenInformation(pInfo->hToken, TokenUser, NULL, 0, &retLen))
1225 if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) {
1226 tokenUser = (PTOKEN_USER) LocalAlloc(LPTR, retLen);
1228 if (!GetTokenInformation(pInfo->hToken, TokenUser, tokenUser, retLen, &retLen))
1230 DebugEvent("AFS_Logoff_Event - GetTokenInformation failed: GLE = %lX", GetLastError());
1235 /* We can't use pInfo->Domain for the domain since in the cross realm case
1236 * this is source domain and not the destination domain.
1238 if (tokenUser && QueryAdHomePathFromSid( profileDir, sizeof(profileDir), tokenUser->User.Sid, pInfo->Domain)) {
1239 WCHAR Domain[64]=L"";
1240 GetLocalShortDomain(Domain, sizeof(Domain));
1241 if (QueryAdHomePathFromSid( profileDir, sizeof(profileDir), tokenUser->User.Sid, Domain)) {
1242 if (NetUserGetProfilePath(pInfo->Domain, pInfo->UserName, profileDir, len))
1243 GetUserProfileDirectory(pInfo->hToken, profileDir, &len);
1247 if (strlen(profileDir)) {
1248 DebugEvent("AFS_Logoff_Event - Profile Directory: %s", profileDir);
1249 if (!IsPathInAfs(profileDir)) {
1250 if (code = ktc_ForgetAllTokens())
1251 DebugEvent("AFS_Logoff_Event - ForgetAllTokens failed [%lX]",code);
1253 DebugEvent0("AFS_Logoff_Event - ForgetAllTokens succeeded");
1255 DebugEvent0("AFS_Logoff_Event - Tokens left in place; profile in AFS");
1258 DebugEvent0("AFS_Logoff_Event - Unable to load profile");
1262 LocalFree(tokenUser);
1264 DebugEvent0("AFS_Logoff_Event - Local Logon");
1265 if (code = ktc_ForgetAllTokens())
1266 DebugEvent("AFS_Logoff_Event - ForgetAllTokens failed [%lX]",code);
1268 DebugEvent0("AFS_Logoff_Event - ForgetAllTokens succeeded");
1271 DebugEvent0("AFS_Logoff_Event - Preserving Tokens");
1274 DebugEvent0("AFS_Logoff_Event - End");
1277 VOID AFS_Logon_Event( PWLX_NOTIFICATION_INFO pInfo )
1279 TCHAR profileDir[1024] = TEXT("");
1281 PTOKEN_USER tokenUser = NULL;
1283 WCHAR szUserW[128] = L"";
1284 char szUserA[128] = "";
1285 char szClient[MAX_PATH];
1286 char szPath[MAX_PATH] = "";
1292 /* Make sure the AFS Libraries are initialized */
1295 DebugEvent0("AFS_Logon_Event - Start");
1297 DebugEvent("AFS_Logon_Event Process ID: %d",GetCurrentProcessId());
1299 memset(&opt, 0, sizeof(LogonOptions_t));
1301 if (pInfo->UserName && pInfo->Domain) {
1302 char username[MAX_USERNAME_LENGTH] = "";
1303 char domain[MAX_DOMAIN_LENGTH] = "";
1306 DebugEvent0("AFS_Logon_Event - pInfo UserName and Domain");
1308 StringCchLengthW(pInfo->UserName, MAX_USERNAME_LENGTH, &szlen);
1309 WideCharToMultiByte(CP_UTF8, 0, pInfo->UserName, szlen,
1310 username, sizeof(username), NULL, NULL);
1312 StringCchLengthW(pInfo->Domain, MAX_DOMAIN_LENGTH, &szlen);
1313 WideCharToMultiByte(CP_UTF8, 0, pInfo->Domain, szlen,
1314 domain, sizeof(domain), NULL, NULL);
1316 DebugEvent0("AFS_Logon_Event - Calling GetDomainLogonOptions");
1317 GetDomainLogonOptions(NULL, username, domain, &opt);
1319 if (!pInfo->UserName)
1320 DebugEvent0("AFS_Logon_Event - No pInfo->UserName");
1322 DebugEvent0("AFS_Logon_Event - No pInfo->Domain");
1325 DebugEvent("AFS_Logon_Event - opt.LogonOption = %lX opt.flags = %lX",
1326 opt.LogonOption, opt.flags);
1328 if (!ISLOGONINTEGRATED(opt.LogonOption) || !ISREMOTE(opt.flags)) {
1329 DebugEvent0("AFS_Logon_Event - Logon is not integrated or not remote");
1330 goto done_logon_event;
1333 DebugEvent0("AFS_Logon_Event - Calling GetTokenInformation");
1335 if (!GetTokenInformation(pInfo->hToken, TokenUser, NULL, 0, &retLen))
1337 if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) {
1338 tokenUser = (PTOKEN_USER) LocalAlloc(LPTR, retLen);
1340 if (!GetTokenInformation(pInfo->hToken, TokenUser, tokenUser, retLen, &retLen))
1342 DebugEvent("AFS_Logon_Event - GetTokenInformation failed: GLE = %lX", GetLastError());
1347 /* We can't use pInfo->Domain for the domain since in the cross realm case
1348 * this is source domain and not the destination domain.
1350 if (tokenUser && QueryAdHomePathFromSid( profileDir, sizeof(profileDir), tokenUser->User.Sid, pInfo->Domain)) {
1351 WCHAR Domain[64]=L"";
1352 GetLocalShortDomain(Domain, sizeof(Domain));
1353 if (QueryAdHomePathFromSid( profileDir, sizeof(profileDir), tokenUser->User.Sid, Domain)) {
1354 if (NetUserGetProfilePath(pInfo->Domain, pInfo->UserName, profileDir, len))
1355 GetUserProfileDirectory(pInfo->hToken, profileDir, &len);
1359 if (strlen(profileDir)) {
1360 DebugEvent("AFS_Logon_Event - Profile Directory: %s", profileDir);
1362 DebugEvent0("AFS_Logon_Event - Unable to load profile");
1366 dwSize = sizeof(szUserA);
1367 if (!KFW_AFS_get_lsa_principal(szUserA, &dwSize)) {
1368 StringCbPrintfW(szUserW, sizeof(szUserW), L"%s\\%s", pInfo->Domain, pInfo->UserName);
1369 WideCharToMultiByte(CP_ACP, 0, szUserW, -1, szUserA, MAX_PATH, NULL, NULL);
1374 lana_GetNetbiosName(szClient, LANA_NETBIOS_NAME_FULL);
1375 StringCbPrintf(szPath, sizeof(szPath), "\\\\%s", szClient);
1377 DebugEvent("AFS_Logon_Event - Logon Name: %s", szUserA);
1379 memset (&nr, 0x00, sizeof(NETRESOURCE));
1380 nr.dwType=RESOURCETYPE_DISK;
1382 nr.lpRemoteName=szPath;
1383 res = WNetAddConnection2(&nr,NULL,szUserA,0);
1385 DebugEvent("AFS_Logon_Event - WNetAddConnection2(%s,%s) failed: 0x%X",
1386 szPath, szUserA,res);
1388 DebugEvent0("AFS_Logon_Event - WNetAddConnection2() succeeded");
1390 DebugEvent("AFS_Logon_Event - User name conversion failed: GLE = 0x%X",GetLastError());
1393 LocalFree(tokenUser);
1395 DebugEvent0("AFS_Logon_Event - End");
1399 GetSecurityLogonSessionData(HANDLE hToken, PSECURITY_LOGON_SESSION_DATA * ppSessionData)
1401 NTSTATUS Status = 0;
1402 TOKEN_STATISTICS Stats;
1408 *ppSessionData = NULL;
1410 Success = GetTokenInformation( hToken, TokenStatistics, &Stats, sizeof(TOKEN_STATISTICS), &ReqLen );
1414 Status = LsaGetLogonSessionData( &Stats.AuthenticationId, ppSessionData );
1415 if ( FAILED(Status) || !ppSessionData )
1421 VOID KFW_Logon_Event( PWLX_NOTIFICATION_INFO pInfo )
1424 WCHAR szUserW[128] = L"";
1425 char szUserA[128] = "";
1426 char szPath[MAX_PATH] = "";
1427 char szLogonId[128] = "";
1429 char filename[MAX_PATH] = "";
1430 char newfilename[MAX_PATH] = "";
1431 char commandline[MAX_PATH+256] = "";
1432 STARTUPINFO startupinfo;
1433 PROCESS_INFORMATION procinfo;
1434 HANDLE hf = INVALID_HANDLE_VALUE;
1436 LUID LogonId = {0, 0};
1437 PSECURITY_LOGON_SESSION_DATA pLogonSessionData = NULL;
1439 HKEY hKey1 = NULL, hKey2 = NULL;
1441 /* Make sure the KFW Libraries are initialized */
1444 DebugEvent0("KFW_Logon_Event - Start");
1446 GetSecurityLogonSessionData( pInfo->hToken, &pLogonSessionData );
1448 if ( pLogonSessionData ) {
1449 LogonId = pLogonSessionData->LogonId;
1450 DebugEvent("KFW_Logon_Event - LogonId(%d,%d)", LogonId.HighPart, LogonId.LowPart);
1452 sprintf(szLogonId,"%d.%d",LogonId.HighPart, LogonId.LowPart);
1453 LsaFreeReturnBuffer( pLogonSessionData );
1455 DebugEvent0("KFW_Logon_Event - Unable to determine LogonId");
1459 count = GetEnvironmentVariable("TEMP", filename, sizeof(filename));
1460 if ( count > sizeof(filename) || count == 0 ) {
1461 GetWindowsDirectory(filename, sizeof(filename));
1464 count = GetEnvironmentVariable("TEMP", filename, sizeof(filename));
1465 if ( count > sizeof(filename) || count == 0 ) {
1466 GetWindowsDirectory(filename, sizeof(filename));
1469 if ( strlen(filename) + strlen(szLogonId) + 2 > sizeof(filename) ) {
1470 DebugEvent0("KFW_Logon_Event - filename too long");
1474 strcat(filename, "\\");
1475 strcat(filename, szLogonId);
1477 hf = CreateFile(filename, FILE_ALL_ACCESS, 0, NULL, OPEN_EXISTING,
1478 FILE_ATTRIBUTE_NORMAL, NULL);
1479 if (hf == INVALID_HANDLE_VALUE) {
1480 DebugEvent0("KFW_Logon_Event - file cannot be opened");
1485 if (KFW_AFS_set_file_cache_dacl(filename, pInfo->hToken)) {
1486 DebugEvent0("KFW_Logon_Event - unable to set dacl");
1487 DeleteFile(filename);
1491 if (KFW_AFS_obtain_user_temp_directory(pInfo->hToken, newfilename, sizeof(newfilename))) {
1492 DebugEvent0("KFW_Logon_Event - unable to obtain temp directory");
1496 if ( strlen(newfilename) + strlen(szLogonId) + 2 > sizeof(newfilename) ) {
1497 DebugEvent0("KFW_Logon_Event - new filename too long");
1501 strcat(newfilename, "\\");
1502 strcat(newfilename, szLogonId);
1504 if (!MoveFileEx(filename, newfilename,
1505 MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) {
1506 DebugEvent("KFW_Logon_Event - MoveFileEx failed GLE = 0x%x", GetLastError());
1510 sprintf(commandline, "afscpcc.exe \"%s\"", newfilename);
1512 GetStartupInfo(&startupinfo);
1513 if (CreateProcessAsUser( pInfo->hToken,
1519 CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS,
1525 DebugEvent("KFW_Logon_Event - CommandLine %s", commandline);
1527 WaitForSingleObject(procinfo.hProcess, 30000);
1529 CloseHandle(procinfo.hThread);
1530 CloseHandle(procinfo.hProcess);
1532 DebugEvent0("KFW_Logon_Event - CreateProcessFailed");
1535 DeleteFile(filename);
1537 DebugEvent0("KFW_Logon_Event - End");