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
10 #include <afsconfig.h>
11 #include <afs/param.h>
18 #include <sys/types.h>
26 #include <afs/pioctl_nt.h>
27 #include <afs/kautils.h>
30 #include "cm_config.h"
33 #include "lanahelper.h"
35 /* Allocated in Windows Driver Kit */
36 #ifndef WNNC_NET_OPENAFS
37 #define WNNC_NET_OPENAFS 0x00390000
40 #include <WINNT\afsreg.h>
42 DWORD TraceOption = 0;
46 #define AFS_LOGON_EVENT_NAME TEXT("AFS Logon")
48 void DebugEvent0(char *a)
50 HANDLE h; char *ptbuf[1];
52 if (!ISLOGONTRACE(TraceOption))
55 h = RegisterEventSource(NULL, AFS_LOGON_EVENT_NAME);
56 if (h != INVALID_HANDLE_VALUE) {
58 ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 1008, NULL, 1, 0, (const char **)ptbuf, NULL);
59 DeregisterEventSource(h);
64 void DebugEvent(char *b,...)
66 HANDLE h; char *ptbuf[1],buf[MAXBUF_+1];
69 if (!ISLOGONTRACE(TraceOption))
72 h = RegisterEventSource(NULL, AFS_LOGON_EVENT_NAME);
73 if (h != INVALID_HANDLE_VALUE) {
75 StringCbVPrintf(buf, MAXBUF_+1,b,marker);
78 ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 1008, NULL, 1, 0, (const char **)ptbuf, NULL);
79 DeregisterEventSource(h);
84 static HANDLE hInitMutex = NULL;
85 static BOOL bInit = FALSE;
87 BOOLEAN APIENTRY DllEntryPoint(HANDLE dll, DWORD reason, PVOID reserved)
93 case DLL_PROCESS_ATTACH:
94 /* Initialization Mutex */
96 hInitMutex = CreateMutex(NULL, FALSE, NULL);
98 WSAStartup( MAKEWORD(2,2), &wsaData );
101 case DLL_PROCESS_DETACH:
103 CloseHandle(hInitMutex);
108 case DLL_THREAD_ATTACH:
109 case DLL_THREAD_DETACH:
111 /* Everything else succeeds but does nothing. */
118 void AfsLogonInit(void)
120 if ( bInit == FALSE ) {
121 if ( WaitForSingleObject( hInitMutex, INFINITE ) == WAIT_OBJECT_0 ) {
122 /* initAFSDirPath() initializes an array and sets a
123 * flag so that the initialization can only occur
124 * once. No cleanup will be done when the DLL is
125 * unloaded so the initialization will not be
126 * performed again on a subsequent reload
130 /* ka_Init initializes a number of error tables.
131 * and then calls ka_CellConfig() which grabs
132 * an afsconf_dir structure via afsconf_Open().
133 * Upon a second attempt to call ka_CellConfig()
134 * the structure will be released with afsconf_Close()
135 * and then re-opened. Could this corrupt memory?
137 * We only need this if we are not using KFW.
139 if (!KFW_is_available())
143 ReleaseMutex(hInitMutex);
147 CHAR *GenRandomName(CHAR *pbuf)
150 srand( (unsigned)time( NULL ) );
151 for (i=0;i<MAXRANDOMNAMELEN-1;i++)
152 pbuf[i]='a'+(rand() % 26);
153 pbuf[MAXRANDOMNAMELEN-1]=0;
157 BOOLEAN AFSWillAutoStart(void)
162 BOOLEAN result = FALSE;
163 LPQUERY_SERVICE_CONFIG pConfig = NULL;
167 /* Open services manager */
168 scm = OpenSCManager(NULL, NULL, GENERIC_READ);
169 if (!scm) return FALSE;
171 /* Open AFSD service */
172 svc = OpenService(scm, "TransarcAFSDaemon", SERVICE_QUERY_CONFIG);
176 /* Query AFSD service config, first just to get buffer size */
177 /* Expected to fail, so don't test return value */
178 (void) QueryServiceConfig(svc, NULL, 0, &BufSize);
179 status = GetLastError();
180 if (status != ERROR_INSUFFICIENT_BUFFER)
183 /* Allocate buffer */
184 pConfig = (LPQUERY_SERVICE_CONFIG)GlobalAlloc(GMEM_FIXED,BufSize);
188 /* Query AFSD service config, this time for real */
189 flag = QueryServiceConfig(svc, pConfig, BufSize, &BufSize);
193 /* Is it autostart? */
194 if (pConfig->dwStartType < SERVICE_DEMAND_START)
200 CloseServiceHandle(svc);
202 CloseServiceHandle(scm);
207 DWORD MapAuthError(DWORD code)
210 /* Unfortunately, returning WN_NO_NETWORK results in the MPR abandoning
211 * logon scripts for all credential managers, although they will still
212 * receive logon notifications. Since we don't want this, we return
213 * WN_SUCCESS. This is highly undesirable, but we also don't want to
214 * break other network providers.
218 return WN_NO_NETWORK; */
219 default: return WN_SUCCESS;
223 DWORD APIENTRY NPGetCaps(DWORD index)
227 /* Don't have our own type; use somebody else's. */
228 return WNNC_NET_OPENAFS;
231 /* Say we are already started, even though we might wait after we receive NPLogonNotify */
240 NetUserGetProfilePath( LPCWSTR Domain, LPCWSTR UserName, char * profilePath,
241 DWORD profilePathLen )
244 LPWSTR ServerName = NULL;
245 LPUSER_INFO_3 p3 = NULL;
247 NetGetAnyDCName(NULL, Domain, (LPBYTE *)&ServerName);
248 /* if NetGetAnyDCName fails, ServerName == NULL
249 * NetUserGetInfo will obtain local user information
251 code = NetUserGetInfo(ServerName, UserName, 3, (LPBYTE *)&p3);
252 if (code == NERR_Success)
254 code = NERR_UserNotFound;
256 if (p3->usri3_profile) {
257 DWORD len = lstrlenW(p3->usri3_profile);
259 /* Convert From Unicode to ANSI (UTF-8 for future) */
260 len = len < profilePathLen ? len : profilePathLen - 1;
261 WideCharToMultiByte(CP_UTF8, 0, p3->usri3_profile, len, profilePath, len, NULL, NULL);
262 profilePath[len] = '\0';
266 NetApiBufferFree(p3);
270 NetApiBufferFree(ServerName);
274 BOOL IsServiceRunning (void)
276 SERVICE_STATUS Status;
278 memset (&Status, 0x00, sizeof(Status));
279 Status.dwCurrentState = SERVICE_STOPPED;
281 if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
284 if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
286 QueryServiceStatus (hService, &Status);
287 CloseServiceHandle (hService);
290 CloseServiceHandle (hManager);
292 DebugEvent("AFS AfsLogon - Test Service Running Return Code[%x] ?Running[%d]",Status.dwCurrentState,(Status.dwCurrentState == SERVICE_RUNNING));
293 return (Status.dwCurrentState == SERVICE_RUNNING);
296 BOOL IsServiceStartPending (void)
298 SERVICE_STATUS Status;
300 memset (&Status, 0x00, sizeof(Status));
301 Status.dwCurrentState = SERVICE_STOPPED;
303 if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
306 if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
308 QueryServiceStatus (hService, &Status);
309 CloseServiceHandle (hService);
312 CloseServiceHandle (hManager);
314 DebugEvent("AFS AfsLogon - Test Service Start Pending Return Code[%x] ?Start Pending[%d]",Status.dwCurrentState,(Status.dwCurrentState == SERVICE_START_PENDING));
315 return (Status.dwCurrentState == SERVICE_START_PENDING);
318 /* LOOKUPKEYCHAIN: macro to look up the value in the list of keys in order until it's found
319 v:variable to receive value (reference type)
321 d:default, in case the value isn't on any of the keys
323 #define LOOKUPKEYCHAIN(v,t,d,n) \
325 rv = ~ERROR_SUCCESS; \
328 dwSize = sizeof(v); \
329 rv = RegQueryValueEx(hkDom, n, 0, &dwType, (LPBYTE) &(v), &dwSize); \
330 if(rv == ERROR_SUCCESS || rv == ERROR_MORE_DATA) \
331 DebugEvent(#v " found in hkDom with type [%d]", dwType); \
333 if(hkDoms && ((rv != ERROR_SUCCESS && rv != ERROR_MORE_DATA) || dwType != t)) { \
334 dwSize = sizeof(v); \
335 rv = RegQueryValueEx(hkDoms, n, 0, &dwType, (LPBYTE) &(v), &dwSize); \
336 if(rv == ERROR_SUCCESS || rv == ERROR_MORE_DATA) \
337 DebugEvent(#v " found in hkDoms with type [%d]", dwType); \
339 if(hkNp && ((rv != ERROR_SUCCESS && rv != ERROR_MORE_DATA) || dwType != t)) { \
340 dwSize = sizeof(v); \
341 rv = RegQueryValueEx(hkNp, n, 0, &dwType, (LPBYTE) &(v), &dwSize); \
342 if(rv == ERROR_SUCCESS || rv == ERROR_MORE_DATA) \
343 DebugEvent(#v " found in hkNp with type [%d]", dwType); \
345 if((rv != ERROR_SUCCESS && rv != ERROR_MORE_DATA) || dwType != t) { \
347 DebugEvent0(#v " being set to default"); \
351 /* Get domain specific configuration info. We are returning void because if anything goes wrong
352 we just return defaults.
355 GetDomainLogonOptions( PLUID lpLogonId, char * username, char * domain, LogonOptions_t *opt ) {
356 HKEY hkParm = NULL; /* Service parameter */
357 HKEY hkNp = NULL; /* network provider key */
358 HKEY hkDoms = NULL; /* domains key */
359 HKEY hkDom = NULL; /* DOMAINS/domain key */
365 char computerName[MAX_COMPUTERNAME_LENGTH + 1]="";
366 char *effDomain = NULL;
368 memset(opt, 0, sizeof(LogonOptions_t));
370 DebugEvent("In GetDomainLogonOptions for user [%s] in domain [%s]", username, domain);
371 /* If the domain is the same as the Netbios computer name, we use the LOCALHOST domain name*/
372 opt->flags = LOGON_FLAG_REMOTE;
374 dwSize = MAX_COMPUTERNAME_LENGTH + 1;
375 if(GetComputerName(computerName, &dwSize)) {
376 if(!cm_stricmp_utf8(computerName, domain)) {
377 effDomain = "LOCALHOST";
378 opt->flags = LOGON_FLAG_LOCAL;
381 if (effDomain == NULL)
385 rv = RegOpenKeyEx( HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY, 0, KEY_READ, &hkParm );
386 if(rv != ERROR_SUCCESS) {
388 DebugEvent("GetDomainLogonOption: Can't open parms key [%d]", rv);
391 rv = RegOpenKeyEx( HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PROVIDER_SUBKEY, 0, KEY_READ, &hkNp );
392 if(rv != ERROR_SUCCESS) {
394 DebugEvent("GetDomainLogonOptions: Can't open NP key [%d]", rv);
398 rv = RegOpenKeyEx( hkNp, REG_CLIENT_DOMAINS_SUBKEY, 0, KEY_READ, &hkDoms );
399 if( rv != ERROR_SUCCESS ) {
401 DebugEvent("GetDomainLogonOptions: Can't open Domains key [%d]", rv);
405 if(hkDoms && effDomain) {
406 rv = RegOpenKeyEx( hkDoms, effDomain, 0, KEY_READ, &hkDom );
407 if( rv != ERROR_SUCCESS ) {
409 DebugEvent("GetDomainLogonOptions: Can't open domain key for [%s] [%d]", effDomain, rv);
410 /* If none of the domains match, we shouldn't use the domain key either */
415 DebugEvent0("Not opening domain key");
417 /* Each individual can either be specified on the domain key, the domains key or in the
418 net provider key. They fail over in that order. If none is found, we just use the
422 LOOKUPKEYCHAIN(opt->LogonOption, REG_DWORD, DEFAULT_LOGON_OPTION, REG_CLIENT_LOGON_OPTION_PARM);
424 /* FailLoginsSilently */
425 dwSize = sizeof(dwDummy);
426 rv = RegQueryValueEx(hkParm, REG_CLIENT_FAIL_SILENTLY_PARM, 0, &dwType, (LPBYTE) &dwDummy, &dwSize);
427 if (rv != ERROR_SUCCESS)
428 LOOKUPKEYCHAIN(dwDummy, REG_DWORD, DEFAULT_FAIL_SILENTLY, REG_CLIENT_FAIL_SILENTLY_PARM);
429 opt->failSilently = dwDummy ? 1 :0;
432 LOOKUPKEYCHAIN(opt->retryInterval, REG_DWORD, DEFAULT_RETRY_INTERVAL, REG_CLIENT_RETRY_INTERVAL_PARM);
435 LOOKUPKEYCHAIN(opt->sleepInterval, REG_DWORD, DEFAULT_SLEEP_INTERVAL, REG_CLIENT_SLEEP_INTERVAL_PARM);
437 if(!ISLOGONINTEGRATED(opt->LogonOption)) {
438 DebugEvent0("Integrated logon disabled");
439 goto cleanup; /* no need to lookup the logon script */
442 /* come up with SMB username */
443 if(ISHIGHSECURITY(opt->LogonOption)) {
444 DebugEvent0("High Security Mode active");
445 opt->smbName = malloc( MAXRANDOMNAMELEN );
446 if (opt->smbName == NULL)
448 GenRandomName(opt->smbName);
449 } else if (lpLogonId) {
450 /* username and domain for logon session is not necessarily the same as
451 username and domain passed into network provider. */
452 PSECURITY_LOGON_SESSION_DATA plsd=NULL;
453 char lsaUsername[MAX_USERNAME_LENGTH]="";
454 char lsaDomain[MAX_DOMAIN_LENGTH]="";
458 Status = LsaGetLogonSessionData(lpLogonId, &plsd);
459 if ( FAILED(Status) || plsd == NULL ) {
460 DebugEvent("LsaGetLogonSessionData failed [0x%x]", Status);
464 if (!UnicodeStringToANSI(plsd->UserName, lsaUsername, MAX_USERNAME_LENGTH))
467 if (!UnicodeStringToANSI(plsd->LogonDomain, lsaDomain, MAX_DOMAIN_LENGTH))
470 DebugEvent("PLSD username[%s] domain[%s]",lsaUsername,lsaDomain);
472 if(SUCCEEDED(StringCbLength(lsaUsername, MAX_USERNAME_LENGTH, &tlen)))
477 if(SUCCEEDED(StringCbLength(lsaDomain, MAX_DOMAIN_LENGTH, &tlen)))
484 opt->smbName = malloc(len);
485 if (opt->smbName == NULL)
488 StringCbCopy(opt->smbName, len, lsaDomain);
489 StringCbCat(opt->smbName, len, "\\");
490 StringCbCat(opt->smbName, len, lsaUsername);
492 strlwr(opt->smbName);
496 LsaFreeReturnBuffer(plsd);
498 if (opt->smbName == NULL) {
501 DebugEvent("Constructing username using [%s] and [%s]",
504 len = strlen(username) + strlen(domain) + 2;
506 opt->smbName = malloc(len);
507 if (opt->smbName == NULL)
510 StringCbCopy(opt->smbName, len, domain);
511 StringCbCat(opt->smbName, len, "\\");
512 StringCbCat(opt->smbName, len, username);
514 strlwr(opt->smbName);
517 DebugEvent0("Looking up logon script");
519 /* First find out where the key is */
524 rv = RegQueryValueExW(hkDom, REG_CLIENT_LOGON_SCRIPT_PARMW, 0, &dwType, NULL, &dwSize);
525 if(rv == ERROR_SUCCESS && (dwType == REG_SZ || dwType == REG_EXPAND_SZ)) {
527 DebugEvent0("Located logon script in hkDom");
530 rv = RegQueryValueExW(hkDoms, REG_CLIENT_LOGON_SCRIPT_PARMW, 0, &dwType, NULL, &dwSize);
531 if(rv == ERROR_SUCCESS && !hkTemp && (dwType == REG_SZ || dwType == REG_EXPAND_SZ)) {
533 DebugEvent0("Located logon script in hkDoms");
535 /* Note that the LogonScript in the NP key is only used if we are doing high security. */
536 else if(hkNp && ISHIGHSECURITY(opt->LogonOption)) {
537 rv = RegQueryValueExW(hkNp, REG_CLIENT_LOGON_SCRIPT_PARMW, 0, &dwType, NULL, &dwSize);
538 if(rv == ERROR_SUCCESS && !hkTemp && (dwType == REG_SZ || dwType == REG_EXPAND_SZ)) {
540 DebugEvent0("Located logon script in hkNp");
546 WCHAR *regscript = NULL;
547 WCHAR *regexscript = NULL;
548 WCHAR *regexuscript = NULL;
549 WCHAR *wuname = NULL;
554 StringCbLength(opt->smbName, MAX_USERNAME_LENGTH, &len);
557 wuname = malloc(len * sizeof(WCHAR));
559 goto doneLogonScript;
560 MultiByteToWideChar(CP_ACP,0,opt->smbName,-1,wuname,(int)(len*sizeof(WCHAR)));
562 DebugEvent("Username is set for [%S]", wuname);
564 /* dwSize still has the size of the required buffer in bytes. */
565 regscript = malloc(dwSize);
567 goto doneLogonScript;
568 rv = RegQueryValueExW(hkTemp, REG_CLIENT_LOGON_SCRIPT_PARMW, 0, &dwType, (LPBYTE) regscript, &dwSize);
569 if(rv != ERROR_SUCCESS) {/* what the ..? */
570 DebugEvent("Can't look up logon script rv [%d] size [%d] gle %d",rv, dwSize, GetLastError());
571 goto doneLogonScript;
574 DebugEvent("Found logon script [%S]", regscript);
576 if(dwType == REG_EXPAND_SZ) {
579 dwSize += MAX_PATH * sizeof(WCHAR); /* make room for environment expansion. */
580 regexscript = malloc(dwSize);
582 goto doneLogonScript;
583 dwReq = ExpandEnvironmentStringsW(regscript, regexscript, dwSize / sizeof(WCHAR));
585 regscript = regexscript;
587 if(dwReq > (dwSize / sizeof(WCHAR))) {
588 DebugEvent0("Overflow while expanding environment strings.");
589 goto doneLogonScript;
593 DebugEvent("After expanding env strings [%S]", regscript);
595 if(wcsstr(regscript, L"%s")) {
596 dwSize += (DWORD)(len * sizeof(WCHAR)); /* make room for username expansion */
597 regexuscript = (WCHAR *) LocalAlloc(LMEM_FIXED, dwSize);
599 goto doneLogonScript;
600 hr = StringCbPrintfW(regexuscript, dwSize, regscript, wuname);
602 regexuscript = (WCHAR *) LocalAlloc(LMEM_FIXED, dwSize);
604 goto doneLogonScript;
605 hr = StringCbCopyW(regexuscript, dwSize, regscript);
608 DebugEvent("After expanding username [%S]", regexuscript);
611 opt->logonScript = regexuscript;
613 LocalFree(regexuscript);
616 if(wuname) free(wuname);
617 if(regscript) free(regscript);
618 if(regexscript) free(regexscript);
621 DebugEvent0("Looking up TheseCells");
623 /* First find out where the key is */
628 rv = RegQueryValueEx(hkDom, REG_CLIENT_THESE_CELLS_PARM, 0, &dwType, NULL, &dwSize);
629 if (rv == ERROR_SUCCESS && dwType == REG_MULTI_SZ) {
631 DebugEvent("Located TheseCells in hkDom size %d", dwSize);
633 rv = RegQueryValueEx(hkDoms, REG_CLIENT_THESE_CELLS_PARM, 0, &dwType, NULL, &dwSize);
634 if (rv == ERROR_SUCCESS && !hkTemp && dwType == REG_MULTI_SZ) {
636 DebugEvent("Located TheseCells in hkDoms size %d", dwSize);
638 rv = RegQueryValueEx(hkNp, REG_CLIENT_THESE_CELLS_PARM, 0, &dwType, NULL, &dwSize);
639 if (rv == ERROR_SUCCESS && !hkTemp && dwType == REG_MULTI_SZ) {
641 DebugEvent("Located TheseCells in hkNp size %d", dwSize);
647 CHAR * thesecells = NULL, *p;
649 /* dwSize still has the size of the required buffer in bytes. */
650 thesecells = malloc(dwSize*2);
655 rv = RegQueryValueEx(hkTemp, REG_CLIENT_THESE_CELLS_PARM, 0, NULL, (LPBYTE) thesecells, &dwSize);
656 if(rv != ERROR_SUCCESS) {/* what the ..? */
657 DebugEvent("Can't look up TheseCells rv [%d] size [%d] gle [%d]",rv, dwSize, GetLastError());
661 /* TheseCells is a REG_MULTI_SZ */
662 if ( thesecells && thesecells[0]) {
663 for ( p=thesecells; *p; p += (strlen(p) + 1)) {
664 DebugEvent("Found TheseCells [%s]", p);
666 opt->theseCells = thesecells;
669 DebugEvent("TheseCells [REG_MULTI_SZ] not found");
673 if (thesecells) free(thesecells);
676 DebugEvent0("Looking up Realm");
678 /* First find out where the key is */
683 rv = RegQueryValueEx(hkDom, REG_CLIENT_REALM_PARM, 0, &dwType, NULL, &dwSize);
684 if (rv == ERROR_SUCCESS && dwType == REG_SZ) {
686 DebugEvent("Located Realm in hkDom size %d", dwSize);
688 rv = RegQueryValueEx(hkDoms, REG_CLIENT_REALM_PARM, 0, &dwType, NULL, &dwSize);
689 if (rv == ERROR_SUCCESS && !hkTemp && dwType == REG_SZ) {
691 DebugEvent("Located Realm in hkDoms size %d", dwSize);
693 rv = RegQueryValueEx(hkNp, REG_CLIENT_REALM_PARM, 0, &dwType, NULL, &dwSize);
694 if (rv == ERROR_SUCCESS && !hkTemp && dwType == REG_SZ) {
696 DebugEvent("Located Realm in hkNp size %d", dwSize);
704 /* dwSize still has the size of the required buffer in bytes. */
705 realm = malloc(dwSize*2);
710 rv = RegQueryValueEx(hkTemp, REG_CLIENT_REALM_PARM, 0, NULL, (LPBYTE) realm, &dwSize);
711 if(rv != ERROR_SUCCESS) {/* what the ..? */
712 DebugEvent("Can't look up Realm rv [%d] size [%d] gle [%d]",rv, dwSize, GetLastError());
716 DebugEvent("Found Realm [%s]", realm);
721 if (realm) free(realm);
725 if(hkNp) RegCloseKey(hkNp);
726 if(hkDom) RegCloseKey(hkDom);
727 if(hkDoms) RegCloseKey(hkDoms);
728 if(hkParm) RegCloseKey(hkParm);
731 #undef LOOKUPKEYCHAIN
733 /* Try to find out which cell the given path is in. We must retain
734 the contents of *cell in case of failure. *cell is assumed to be
735 at least cellLen chars */
736 DWORD GetFileCellName(char * path, char * cell, size_t cellLen) {
737 struct ViceIoctl blob;
738 char tcell[MAX_PATH];
742 blob.out_size = MAX_PATH;
745 code = pioctl(path, VIOC_FILE_CELL_NAME, &blob, 1);
748 strncpy(cell, tcell, cellLen);
749 cell[cellLen - 1] = '\0';
757 UnicodeStringToANSI(UNICODE_STRING uInputString, LPSTR lpszOutputString, int nOutStringLen)
761 GetCPInfo(CP_ACP, &CodePageInfo);
763 if (CodePageInfo.MaxCharSize > 1)
764 // Only supporting non-Unicode strings
767 if (uInputString.Buffer && ((LPBYTE) uInputString.Buffer)[1] == '\0')
769 // Looks like unicode, better translate it
770 // UNICODE_STRING specifies the length of the buffer string in Bytes not WCHARS
771 WideCharToMultiByte(CP_ACP, 0, (LPCWSTR) uInputString.Buffer, uInputString.Length/2,
772 lpszOutputString, nOutStringLen-1, NULL, NULL);
773 lpszOutputString[min(uInputString.Length/2,nOutStringLen-1)] = '\0';
777 lpszOutputString[0] = '\0';
779 } // UnicodeStringToANSI
781 DWORD APIENTRY NPLogonNotify(
783 LPCWSTR lpAuthentInfoType,
784 LPVOID lpAuthentInfo,
785 LPCWSTR lpPreviousAuthentInfoType,
786 LPVOID lpPreviousAuthentInfo,
787 LPWSTR lpStationName,
788 LPVOID StationHandle,
789 LPWSTR *lpLogonScript)
791 char uname[MAX_USERNAME_LENGTH]="";
792 char password[MAX_PASSWORD_LENGTH]="";
793 char logonDomain[MAX_DOMAIN_LENGTH]="";
794 char cell[256]="<non-integrated logon>";
795 char homePath[MAX_PATH]="";
796 char szLogonId[128] = "";
798 MSV1_0_INTERACTIVE_LOGON *IL;
800 DWORD code = 0, code2;
808 DWORD LSPtype, LSPsize;
811 HWND hwndOwner = (HWND)StationHandle;
813 BOOLEAN afsWillAutoStart;
815 BOOLEAN lowercased_name = TRUE;
817 LogonOptions_t opt; /* domain specific logon options */
821 /* Are we interactive? */
822 interactive = (wcsicmp(lpStationName, L"WinSta0") == 0);
824 #ifdef DISABLE_NON_INTERACTIVE
825 /* Do not do anything if the logon session is not interactive. */
830 (void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
831 0, KEY_QUERY_VALUE, &NPKey);
832 LSPsize=sizeof(TraceOption);
833 RegQueryValueEx(NPKey, REG_CLIENT_TRACE_OPTION_PARM, NULL,
834 &LSPtype, (LPBYTE)&TraceOption, &LSPsize);
838 DebugEvent("NPLogonNotify - LoginId(%d,%d)", lpLogonId->HighPart, lpLogonId->LowPart);
840 /* Make sure the AFS Libraries are initialized */
843 /* Initialize Logon Script to none */
846 /* MSV1_0_INTERACTIVE_LOGON and KERB_INTERACTIVE_LOGON are equivalent for
849 if ( wcsicmp(lpAuthentInfoType,L"MSV1_0:Interactive") &&
850 wcsicmp(lpAuthentInfoType,L"Kerberos:Interactive") )
852 DebugEvent("Unsupported Authentication Info Type: %S",
857 IL = (MSV1_0_INTERACTIVE_LOGON *) lpAuthentInfo;
859 /* Convert from Unicode to ANSI */
861 /*TODO: Use SecureZeroMemory to erase passwords */
862 if (!UnicodeStringToANSI(IL->UserName, uname, MAX_USERNAME_LENGTH) ||
863 !UnicodeStringToANSI(IL->Password, password, MAX_PASSWORD_LENGTH) ||
864 !UnicodeStringToANSI(IL->LogonDomainName, logonDomain, MAX_DOMAIN_LENGTH))
867 /* Make sure AD-DOMAINS sent from login that is sent to us is stripped */
868 ctemp = strchr(uname, '@');
872 if ( logonDomain[0] == '\0' )
873 StringCchCopy(logonDomain, MAX_DOMAIN_LENGTH, ctemp);
876 /* is the name all lowercase? */
877 for ( ctemp = uname; *ctemp ; ctemp++) {
878 if ( !islower(*ctemp) ) {
879 lowercased_name = FALSE;
888 GetDomainLogonOptions( lpLogonId, uname, logonDomain, &opt );
889 retryInterval = opt.retryInterval;
890 sleepInterval = opt.sleepInterval;
891 *lpLogonScript = opt.logonScript;
893 if (retryInterval < sleepInterval)
894 sleepInterval = retryInterval;
896 DebugEvent("Got logon script: [%S]", opt.logonScript);
898 afsWillAutoStart = AFSWillAutoStart();
900 DebugEvent("LogonOption[%x], Service AutoStart[%d]",
901 opt.LogonOption,afsWillAutoStart);
903 /* Check for zero length password if integrated logon*/
904 if ( ISLOGONINTEGRATED(opt.LogonOption) ) {
905 if ( password[0] == 0 ) {
906 DebugEvent0("Password is the empty string");
908 reason = "zero length password is illegal";
912 /* Get cell name if doing integrated logon.
913 We might overwrite this if we are logging into an AD realm and we find out that
914 the user's home dir is in some other cell. */
915 DebugEvent("About to call cm_GetRootCellName()");
916 code = cm_GetRootCellName(cell);
918 DebugEvent0("Unable to obtain Root Cell");
920 reason = "unknown cell";
923 DebugEvent("Default cell is %s", cell);
926 /* We get the user's home directory path, if applicable, though we can't lookup the
927 cell right away because the client service may not have started yet. This call
928 also sets the AD_REALM flag in opt.flags if applicable. */
929 if (ISREMOTE(opt.flags)) {
930 DebugEvent0("Is Remote");
931 GetAdHomePath(homePath,MAX_PATH,lpLogonId,&opt);
935 /* loop until AFS is started. */
936 if (afsWillAutoStart) {
937 while (IsServiceRunning() || IsServiceStartPending()) {
938 DebugEvent("while(autostart) LogonOption[%x], Service AutoStart[%d]",
939 opt.LogonOption,afsWillAutoStart);
941 if (ISADREALM(opt.flags)) {
942 code = GetFileCellName(homePath,cell,256);
944 DebugEvent("profile path [%s] is in cell [%s]",homePath,cell);
946 /* Don't bail out if GetFileCellName failed.
947 * The home dir may not be in AFS after all.
952 /* if Integrated Logon */
953 if (ISLOGONINTEGRATED(opt.LogonOption))
955 if ( KFW_is_available() ) {
956 SetEnvironmentVariable(DO_NOT_REGISTER_VARNAME, "");
958 char * principal, *p;
961 StringCchLength(opt.realm, MAX_DOMAIN_LENGTH, &tlen);
963 StringCchLength(uname, MAX_USERNAME_LENGTH, &tlen);
966 /* tlen is now the length of uname in characters */
967 principal = (char *)malloc(len * sizeof(char));
969 StringCchCopy(principal, len, uname);
970 p = principal + tlen;
972 StringCchCopy(p, len - tlen -1, opt.realm);
973 code = KFW_AFS_get_cred(principal, cell, password, 0, opt.smbName, &reason);
974 DebugEvent("KFW_AFS_get_cred uname=[%s] smbname=[%s] cell=[%s] code=[%d]",
975 principal,opt.smbName,cell,code);
979 code = KFW_AFS_get_cred(uname, cell, password, 0, opt.smbName, &reason);
980 DebugEvent("KFW_AFS_get_cred uname=[%s] smbname=[%s] cell=[%s] code=[%d]",
981 uname,opt.smbName,cell,code);
983 SetEnvironmentVariable(DO_NOT_REGISTER_VARNAME, NULL);
984 if (code == 0 && opt.theseCells) {
985 char * principal, *p;
988 StringCchLength(opt.realm ? opt.realm : cell, MAX_DOMAIN_LENGTH, &tlen);
990 StringCchLength(uname, MAX_USERNAME_LENGTH, &tlen);
993 /* tlen is now the length of uname in characters */
994 principal = (char *)malloc(len * sizeof(char));
996 StringCchCopy(principal, len, uname);
997 p = principal + tlen;
1000 StringCchCopy(p, len - tlen -1, opt.realm);
1002 StringCchCopy(p, len - tlen - 1, cell);
1009 if ( cm_stricmp_utf8(p, cell) ) {
1010 SetEnvironmentVariable(DO_NOT_REGISTER_VARNAME, "");
1011 code2 = KFW_AFS_get_cred(principal, p, 0, 0, opt.smbName, &reason);
1012 SetEnvironmentVariable(DO_NOT_REGISTER_VARNAME, NULL);
1013 DebugEvent("KFW_AFS_get_cred uname=[%s] smbname=[%s] cell=[%s] code=[%d]",
1014 principal,opt.smbName,p,code2);
1022 code = ka_UserAuthenticateGeneral2(KA_USERAUTH_VERSION+KA_USERAUTH_AUTHENT_LOGON,
1023 uname, "", cell, password, opt.smbName, 0, &pw_exp, 0,
1025 DebugEvent("AFS AfsLogon - (INTEGRATED only)ka_UserAuthenticateGeneral2 Code[%x] uname[%s] smbname=[%s] Cell[%s] PwExp=[%d] Reason=[%s]",
1026 code,uname,opt.smbName,cell,pw_exp,reason?reason:"");
1028 if ( code && code != KTC_NOCM && code != KTC_NOCMRPC && !lowercased_name ) {
1029 for ( ctemp = uname; *ctemp ; ctemp++) {
1030 *ctemp = tolower(*ctemp);
1032 lowercased_name = TRUE;
1036 /* is service started yet?*/
1038 /* If we've failed because the client isn't running yet and the
1039 * client is set to autostart (and therefore it makes sense for
1040 * us to wait for it to start) then sleep a while and try again.
1041 * If the error was something else, then give up. */
1042 if (code != KTC_NOCM && code != KTC_NOCMRPC)
1046 /*JUST check to see if its running*/
1047 if (IsServiceRunning())
1049 if (!IsServiceStartPending()) {
1051 reason = "AFS Service start failed";
1056 /* If the retry interval has expired and we still aren't
1057 * logged in, then just give up if we are not in interactive
1058 * mode or the failSilently flag is set, otherwise let the
1059 * user know we failed and give them a chance to try again. */
1060 if (retryInterval <= 0) {
1061 reason = "AFS not running";
1062 if (!interactive || opt.failSilently)
1064 flag = MessageBox(hwndOwner,
1065 "AFS is still starting. Retry?",
1067 MB_ICONQUESTION | MB_RETRYCANCEL);
1068 if (flag == IDCANCEL)
1071 /* Wait just a little while and try again */
1072 retryInterval = opt.retryInterval;
1076 Sleep(sleepInterval * 1000);
1077 retryInterval -= sleepInterval;
1080 DebugEvent0("while loop exited");
1082 /* remove any kerberos 5 tickets currently held by the SYSTEM account
1086 if (ISLOGONINTEGRATED(opt.LogonOption) && KFW_is_available()) {
1088 sprintf(szLogonId,"%d.%d",lpLogonId->HighPart, lpLogonId->LowPart);
1089 KFW_AFS_copy_cache_to_system_file(uname, szLogonId);
1091 KFW_AFS_destroy_tickets_for_principal(uname);
1099 StringCbPrintf(msg, sizeof(msg), "Integrated login failed: %s", reason);
1101 if (ISLOGONINTEGRATED(opt.LogonOption) && interactive && !opt.failSilently)
1102 MessageBox(hwndOwner, msg, "AFS Logon", MB_OK);
1104 h = RegisterEventSource(NULL, AFS_LOGON_EVENT_NAME);
1106 ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1008, NULL,
1108 DeregisterEventSource(h);
1110 code = MapAuthError(code);
1113 if (ISLOGONINTEGRATED(opt.LogonOption) && (code!=0))
1116 LocalFree(*lpLogonScript);
1117 *lpLogonScript = NULL;
1118 if (!afsWillAutoStart) // its not running, so if not autostart or integrated logon then just skip
1123 if (opt.theseCells) free(opt.theseCells);
1124 if (opt.smbName) free(opt.smbName);
1125 if (opt.realm) free(opt.realm);
1127 DebugEvent("AFS AfsLogon - Exit","Return Code[%x]",code);
1131 DWORD APIENTRY NPPasswordChangeNotify(
1132 LPCWSTR lpAuthentInfoType,
1133 LPVOID lpAuthentInfo,
1134 LPCWSTR lpPreviousAuthentInfoType,
1135 LPVOID lpPreviousAuthentInfo,
1136 LPWSTR lpStationName,
1137 LPVOID StationHandle,
1140 BOOLEAN interactive;
1142 /* Are we interactive? */
1143 interactive = (wcsicmp(lpStationName, L"WinSta0") == 0);
1145 /* Do not do anything if the logon session is not interactive. */
1149 /* Make sure the AFS Libraries are initialized */
1152 DebugEvent0("AFS AfsLogon - NPPasswordChangeNotify");
1156 #include <userenv.h>
1158 #include <afs/vice.h>
1159 #include <afs/fs_utils.h>
1161 BOOL IsPathInAfs(const CHAR *strPath)
1164 struct ViceIoctl blob;
1168 blob.out_size = 2048;
1171 code = pioctl((LPTSTR)((LPCTSTR)strPath), VIOC_FILE_CELL_NAME, &blob, 1);
1178 typedef struct _WLX_NOTIFICATION_INFO {
1183 PWSTR WindowStation;
1186 PFNMSGECALLBACK pStatusCallback;
1187 } WLX_NOTIFICATION_INFO, *PWLX_NOTIFICATION_INFO;
1190 VOID AFS_Startup_Event( PWLX_NOTIFICATION_INFO pInfo )
1192 DWORD LSPtype, LSPsize;
1195 /* Make sure the AFS Libraries are initialized */
1198 (void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
1199 0, KEY_QUERY_VALUE, &NPKey);
1200 LSPsize=sizeof(TraceOption);
1201 RegQueryValueEx(NPKey, REG_CLIENT_TRACE_OPTION_PARM, NULL,
1202 &LSPtype, (LPBYTE)&TraceOption, &LSPsize);
1204 RegCloseKey (NPKey);
1205 DebugEvent0("AFS_Startup_Event");
1208 VOID AFS_Logoff_Event( PWLX_NOTIFICATION_INFO pInfo )
1211 TCHAR profileDir[1024] = TEXT("");
1213 PTOKEN_USER tokenUser = NULL;
1215 DWORD LSPtype, LSPsize;
1217 DWORD LogoffPreserveTokens = 0;
1220 /* Make sure the AFS Libraries are initialized */
1223 DebugEvent0("AFS_Logoff_Event - Start");
1225 (void) RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
1226 0, KEY_QUERY_VALUE, &NPKey);
1227 LSPsize=sizeof(LogoffPreserveTokens);
1228 RegQueryValueEx(NPKey, REG_CLIENT_LOGOFF_TOKENS_PARM, NULL,
1229 &LSPtype, (LPBYTE)&LogoffPreserveTokens, &LSPsize);
1230 RegCloseKey (NPKey);
1232 if (!LogoffPreserveTokens) {
1233 memset(&opt, 0, sizeof(LogonOptions_t));
1235 if (pInfo->UserName && pInfo->Domain) {
1236 char username[MAX_USERNAME_LENGTH] = "";
1237 char domain[MAX_DOMAIN_LENGTH] = "";
1240 StringCchLengthW(pInfo->UserName, MAX_USERNAME_LENGTH, &szlen);
1241 WideCharToMultiByte(CP_UTF8, 0, pInfo->UserName, szlen,
1242 username, sizeof(username), NULL, NULL);
1244 StringCchLengthW(pInfo->Domain, MAX_DOMAIN_LENGTH, &szlen);
1245 WideCharToMultiByte(CP_UTF8, 0, pInfo->Domain, szlen,
1246 domain, sizeof(domain), NULL, NULL);
1248 GetDomainLogonOptions(NULL, username, domain, &opt);
1251 if (ISREMOTE(opt.flags)) {
1252 if (!GetTokenInformation(pInfo->hToken, TokenUser, NULL, 0, &retLen))
1254 if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) {
1255 tokenUser = (PTOKEN_USER) LocalAlloc(LPTR, retLen);
1257 if (!GetTokenInformation(pInfo->hToken, TokenUser, tokenUser, retLen, &retLen))
1259 DebugEvent("AFS_Logoff_Event - GetTokenInformation failed: GLE = %lX", GetLastError());
1264 /* We can't use pInfo->Domain for the domain since in the cross realm case
1265 * this is source domain and not the destination domain.
1267 if (tokenUser && QueryAdHomePathFromSid( profileDir, sizeof(profileDir), tokenUser->User.Sid, pInfo->Domain)) {
1268 WCHAR Domain[64]=L"";
1269 GetLocalShortDomain(Domain, sizeof(Domain));
1270 if (QueryAdHomePathFromSid( profileDir, sizeof(profileDir), tokenUser->User.Sid, Domain)) {
1271 if (NetUserGetProfilePath(pInfo->Domain, pInfo->UserName, profileDir, len))
1272 GetUserProfileDirectory(pInfo->hToken, profileDir, &len);
1276 if (strlen(profileDir)) {
1277 DebugEvent("AFS_Logoff_Event - Profile Directory: %s", profileDir);
1278 if (!IsPathInAfs(profileDir)) {
1279 if (code = ktc_ForgetAllTokens())
1280 DebugEvent("AFS_Logoff_Event - ForgetAllTokens failed [%lX]",code);
1282 DebugEvent0("AFS_Logoff_Event - ForgetAllTokens succeeded");
1284 DebugEvent0("AFS_Logoff_Event - Tokens left in place; profile in AFS");
1287 DebugEvent0("AFS_Logoff_Event - Unable to load profile");
1291 LocalFree(tokenUser);
1293 DebugEvent0("AFS_Logoff_Event - Local Logon");
1294 if (code = ktc_ForgetAllTokens())
1295 DebugEvent("AFS_Logoff_Event - ForgetAllTokens failed [%lX]",code);
1297 DebugEvent0("AFS_Logoff_Event - ForgetAllTokens succeeded");
1300 DebugEvent0("AFS_Logoff_Event - Preserving Tokens");
1303 DebugEvent0("AFS_Logoff_Event - End");
1306 VOID AFS_Logon_Event( PWLX_NOTIFICATION_INFO pInfo )
1308 TCHAR profileDir[1024] = TEXT("");
1310 PTOKEN_USER tokenUser = NULL;
1312 WCHAR szUserW[128] = L"";
1313 char szUserA[128] = "";
1314 char szClient[MAX_PATH];
1315 char szPath[MAX_PATH] = "";
1321 /* Make sure the AFS Libraries are initialized */
1324 DebugEvent0("AFS_Logon_Event - Start");
1326 DebugEvent("AFS_Logon_Event Process ID: %d",GetCurrentProcessId());
1328 memset(&opt, 0, sizeof(LogonOptions_t));
1330 if (pInfo->UserName && pInfo->Domain) {
1331 char username[MAX_USERNAME_LENGTH] = "";
1332 char domain[MAX_DOMAIN_LENGTH] = "";
1335 DebugEvent0("AFS_Logon_Event - pInfo UserName and Domain");
1337 StringCchLengthW(pInfo->UserName, MAX_USERNAME_LENGTH, &szlen);
1338 WideCharToMultiByte(CP_UTF8, 0, pInfo->UserName, szlen,
1339 username, sizeof(username), NULL, NULL);
1341 StringCchLengthW(pInfo->Domain, MAX_DOMAIN_LENGTH, &szlen);
1342 WideCharToMultiByte(CP_UTF8, 0, pInfo->Domain, szlen,
1343 domain, sizeof(domain), NULL, NULL);
1345 DebugEvent0("AFS_Logon_Event - Calling GetDomainLogonOptions");
1346 GetDomainLogonOptions(NULL, username, domain, &opt);
1348 if (!pInfo->UserName)
1349 DebugEvent0("AFS_Logon_Event - No pInfo->UserName");
1351 DebugEvent0("AFS_Logon_Event - No pInfo->Domain");
1354 DebugEvent("AFS_Logon_Event - opt.LogonOption = %lX opt.flags = %lX",
1355 opt.LogonOption, opt.flags);
1357 if (!ISLOGONINTEGRATED(opt.LogonOption) || !ISREMOTE(opt.flags)) {
1358 DebugEvent0("AFS_Logon_Event - Logon is not integrated or not remote");
1359 goto done_logon_event;
1362 DebugEvent0("AFS_Logon_Event - Calling GetTokenInformation");
1364 if (!GetTokenInformation(pInfo->hToken, TokenUser, NULL, 0, &retLen))
1366 if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) {
1367 tokenUser = (PTOKEN_USER) LocalAlloc(LPTR, retLen);
1369 if (!GetTokenInformation(pInfo->hToken, TokenUser, tokenUser, retLen, &retLen))
1371 DebugEvent("AFS_Logon_Event - GetTokenInformation failed: GLE = %lX", GetLastError());
1376 /* We can't use pInfo->Domain for the domain since in the cross realm case
1377 * this is source domain and not the destination domain.
1379 if (tokenUser && QueryAdHomePathFromSid( profileDir, sizeof(profileDir), tokenUser->User.Sid, pInfo->Domain)) {
1380 WCHAR Domain[64]=L"";
1381 GetLocalShortDomain(Domain, sizeof(Domain));
1382 if (QueryAdHomePathFromSid( profileDir, sizeof(profileDir), tokenUser->User.Sid, Domain)) {
1383 if (NetUserGetProfilePath(pInfo->Domain, pInfo->UserName, profileDir, len))
1384 GetUserProfileDirectory(pInfo->hToken, profileDir, &len);
1388 if (strlen(profileDir)) {
1389 DebugEvent("AFS_Logon_Event - Profile Directory: %s", profileDir);
1391 DebugEvent0("AFS_Logon_Event - Unable to load profile");
1395 dwSize = sizeof(szUserA);
1396 if (!KFW_AFS_get_lsa_principal(szUserA, &dwSize)) {
1397 StringCbPrintfW(szUserW, sizeof(szUserW), L"%s\\%s", pInfo->Domain, pInfo->UserName);
1398 WideCharToMultiByte(CP_ACP, 0, szUserW, -1, szUserA, MAX_PATH, NULL, NULL);
1403 lana_GetNetbiosName(szClient, LANA_NETBIOS_NAME_FULL);
1404 StringCbPrintf(szPath, sizeof(szPath), "\\\\%s", szClient);
1406 DebugEvent("AFS_Logon_Event - Logon Name: %s", szUserA);
1408 memset (&nr, 0x00, sizeof(NETRESOURCE));
1409 nr.dwType=RESOURCETYPE_DISK;
1411 nr.lpRemoteName=szPath;
1412 res = WNetAddConnection2(&nr,NULL,szUserA,0);
1414 DebugEvent("AFS_Logon_Event - WNetAddConnection2(%s,%s) failed: 0x%X",
1415 szPath, szUserA,res);
1417 DebugEvent0("AFS_Logon_Event - WNetAddConnection2() succeeded");
1419 DebugEvent("AFS_Logon_Event - User name conversion failed: GLE = 0x%X",GetLastError());
1422 LocalFree(tokenUser);
1424 DebugEvent0("AFS_Logon_Event - End");
1428 GetSecurityLogonSessionData(HANDLE hToken, PSECURITY_LOGON_SESSION_DATA * ppSessionData)
1430 NTSTATUS Status = 0;
1431 TOKEN_STATISTICS Stats;
1437 *ppSessionData = NULL;
1439 Success = GetTokenInformation( hToken, TokenStatistics, &Stats, sizeof(TOKEN_STATISTICS), &ReqLen );
1443 Status = LsaGetLogonSessionData( &Stats.AuthenticationId, ppSessionData );
1444 if ( FAILED(Status) || !ppSessionData )
1450 VOID KFW_Logon_Event( PWLX_NOTIFICATION_INFO pInfo )
1453 WCHAR szUserW[128] = L"";
1454 char szUserA[128] = "";
1455 char szPath[MAX_PATH] = "";
1456 char szLogonId[128] = "";
1458 char filename[MAX_PATH] = "";
1459 char newfilename[MAX_PATH] = "";
1460 char commandline[MAX_PATH+256] = "";
1461 STARTUPINFO startupinfo;
1462 PROCESS_INFORMATION procinfo;
1463 HANDLE hf = INVALID_HANDLE_VALUE;
1465 LUID LogonId = {0, 0};
1466 PSECURITY_LOGON_SESSION_DATA pLogonSessionData = NULL;
1468 HKEY hKey1 = NULL, hKey2 = NULL;
1470 /* Make sure the KFW Libraries are initialized */
1473 DebugEvent0("KFW_Logon_Event - Start");
1475 GetSecurityLogonSessionData( pInfo->hToken, &pLogonSessionData );
1477 if ( pLogonSessionData ) {
1478 LogonId = pLogonSessionData->LogonId;
1479 DebugEvent("KFW_Logon_Event - LogonId(%d,%d)", LogonId.HighPart, LogonId.LowPart);
1481 sprintf(szLogonId,"%d.%d",LogonId.HighPart, LogonId.LowPart);
1482 LsaFreeReturnBuffer( pLogonSessionData );
1484 DebugEvent0("KFW_Logon_Event - Unable to determine LogonId");
1488 count = GetEnvironmentVariable("TEMP", filename, sizeof(filename));
1489 if ( count > sizeof(filename) || count == 0 ) {
1490 GetWindowsDirectory(filename, sizeof(filename));
1493 count = GetEnvironmentVariable("TEMP", filename, sizeof(filename));
1494 if ( count > sizeof(filename) || count == 0 ) {
1495 GetWindowsDirectory(filename, sizeof(filename));
1498 if ( strlen(filename) + strlen(szLogonId) + 2 > sizeof(filename) ) {
1499 DebugEvent0("KFW_Logon_Event - filename too long");
1503 strcat(filename, "\\");
1504 strcat(filename, szLogonId);
1506 hf = CreateFile(filename, FILE_ALL_ACCESS, 0, NULL, OPEN_EXISTING,
1507 FILE_ATTRIBUTE_NORMAL, NULL);
1508 if (hf == INVALID_HANDLE_VALUE) {
1509 DebugEvent0("KFW_Logon_Event - file cannot be opened");
1514 if (KFW_AFS_set_file_cache_dacl(filename, pInfo->hToken)) {
1515 DebugEvent0("KFW_Logon_Event - unable to set dacl");
1516 DeleteFile(filename);
1520 if (KFW_AFS_obtain_user_temp_directory(pInfo->hToken, newfilename, sizeof(newfilename))) {
1521 DebugEvent0("KFW_Logon_Event - unable to obtain temp directory");
1525 if ( strlen(newfilename) + strlen(szLogonId) + 2 > sizeof(newfilename) ) {
1526 DebugEvent0("KFW_Logon_Event - new filename too long");
1530 strcat(newfilename, "\\");
1531 strcat(newfilename, szLogonId);
1533 if (!MoveFileEx(filename, newfilename,
1534 MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) {
1535 DebugEvent("KFW_Logon_Event - MoveFileEx failed GLE = 0x%x", GetLastError());
1539 sprintf(commandline, "afscpcc.exe \"%s\"", newfilename);
1541 GetStartupInfo(&startupinfo);
1542 if (CreateProcessAsUser( pInfo->hToken,
1548 CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS,
1554 DebugEvent("KFW_Logon_Event - CommandLine %s", commandline);
1556 WaitForSingleObject(procinfo.hProcess, 30000);
1558 CloseHandle(procinfo.hThread);
1559 CloseHandle(procinfo.hProcess);
1561 DebugEvent0("KFW_Logon_Event - CreateProcessFailed");
1564 DeleteFile(filename);
1566 DebugEvent0("KFW_Logon_Event - End");