From eb272638c5c82544368118cb3eec7aee1dd85809 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Mon, 30 May 2005 04:58:34 +0000 Subject: [PATCH] STABLE14-windows-stuff-20050529 (1) Replace all calls to getenv() with GetEnvironment(). getenv() does not read from the real environment but instead from a copy created by the C RTL. (2) Add support for preserving Kerberos 5 tickets during the Integrated Logon process. Now when Integrated Logon is used, the tickets will be stored into the default ccache within the user session. (3) Stress testing at MIT uncovered two code paths that could leave threads in a permanent sleep state under heavy load. Calls to cm_SyncOpDone were added to plug this hole. ==================== This delta was composed from multiple commits as part of the CVS->Git migration. The checkin message with each commit was inconsistent. The following are the additional commit messages. ==================== Install afscpcc.exe and register the KFWLogon WinLogon Event Handler (cherry picked from commit 96472a6b3a71d5d5ef57e2481680920a7e006ffe) --- src/WINNT/afsd/NTMakefile | 10 +- src/WINNT/afsd/afscpcc.c | 21 +++ src/WINNT/afsd/afscpcc.rc | 15 ++ src/WINNT/afsd/afsd_init.c | 20 ++- src/WINNT/afsd/afskfw.c | 227 ++++++++++++++++++++++++++++- src/WINNT/afsd/afskfw.h | 5 + src/WINNT/afsd/afslogon.c | 167 ++++++++++++++++++--- src/WINNT/afsd/afslogon.def | 2 + src/WINNT/afsd/cm_buf.c | 11 +- src/WINNT/afsd/cm_config.c | 54 +++++-- src/WINNT/afsd/cm_dcache.c | 21 ++- src/WINNT/afsd/cm_ioctl.c | 9 +- src/WINNT/install/NSIS/OpenAFS.nsi | 8 + src/WINNT/install/wix/files.wxi | 6 + 14 files changed, 511 insertions(+), 65 deletions(-) create mode 100644 src/WINNT/afsd/afscpcc.c create mode 100644 src/WINNT/afsd/afscpcc.rc diff --git a/src/WINNT/afsd/NTMakefile b/src/WINNT/afsd/NTMakefile index 7194e87c7..8361c5188 100644 --- a/src/WINNT/afsd/NTMakefile +++ b/src/WINNT/afsd/NTMakefile @@ -282,7 +282,7 @@ install: install_headers install_objs $(CONF_DLLFILE) \ $(EXEDIR)\afsdacl.exe \ $(LOGON_DLLFILE) \ $(EXEDIR)\afsshare.exe \ - $(DESTDIR)\bin\kpasswd.exe $(EXEDIR)\cmdebug.exe + $(DESTDIR)\bin\kpasswd.exe $(EXEDIR)\cmdebug.exe $(EXEDIR)\afscpcc.exe install9X: install_headers $(CONF_DLLFILE) \ $(EXEDIR)\klog.exe \ @@ -354,6 +354,12 @@ $(EXEDIR)\unlog.exe: $(OUT)\cunlog.obj $(OUT)\unlog.res $(EXELIBS) $(EXECONLINK) dnsapi.lib mpr.lib iphlpapi.lib $(EXEPREP) +# afscpcc.exe +$(EXEDIR)\afscpcc.exe: $(OUT)\afscpcc.obj $(OUT)\afscpcc.res $(LOGON_DLLLIBS) + $(EXECONLINK) dnsapi.lib mpr.lib iphlpapi.lib + $(EXEPREP) + + # afsd.exe AFSD_EXEFILE = $(EXEDIR)\afsd.exe @@ -472,6 +478,8 @@ $(OUT)\tokens.res: tokens.rc AFS_component_version_number.h $(OUT)\unlog.res: unlog.rc AFS_component_version_number.h +$(OUT)\afscpcc.res: afscpcc.rc AFS_component_version_number.h + afsd_eventmessages.rc: afsd_eventmessages.h $(OUT)\afsd_service.res: afsd_service.rc afsd_eventmessages.rc AFS_component_version_number.h diff --git a/src/WINNT/afsd/afscpcc.c b/src/WINNT/afsd/afscpcc.c new file mode 100644 index 000000000..342ab6f5b --- /dev/null +++ b/src/WINNT/afsd/afscpcc.c @@ -0,0 +1,21 @@ +/* + * Copyright 2005, Secure Endpoints Inc. + * All Rights Reserved. + * + * This software has been released under the terms of the MIT License. + */ + +#include +#include + +int main(int argc, char *argv[]) +{ + if ( argc != 2 ) + return 1; + + KFW_initialize(); + + return KFW_AFS_copy_system_file_to_default_cache(argv[1]); +} + + diff --git a/src/WINNT/afsd/afscpcc.rc b/src/WINNT/afsd/afscpcc.rc new file mode 100644 index 000000000..0315e8307 --- /dev/null +++ b/src/WINNT/afsd/afscpcc.rc @@ -0,0 +1,15 @@ +/* + * Copyright 2005, Secure Endpoints Inc. + * All Rights Reserved. + * + * This software has been released under the terms of the MIT License. + */ + +/* Define VERSIONINFO resource */ + +#define AFS_VERINFO_FILE_DESCRIPTION "AFS Logon Copy Credentials Command" +#define AFS_VERINFO_NAME "afscpcc" +#define AFS_VERINFO_FILENAME "afscpcc.exe" + +#include "AFS_component_version_number.h" +#include "..\..\config\NTVersioninfo.rc" diff --git a/src/WINNT/afsd/afsd_init.c b/src/WINNT/afsd/afsd_init.c index bf5eebb9b..37189ec62 100644 --- a/src/WINNT/afsd/afsd_init.c +++ b/src/WINNT/afsd/afsd_init.c @@ -146,11 +146,8 @@ afsi_start() DWORD maxLogSize = 100 * 1024; afsi_file = INVALID_HANDLE_VALUE; - if (getenv("TEMP")) - { - StringCbCopyA(wd, sizeof(wd), getenv("TEMP")); - } - else + code = GetEnvironmentVariable("TEMP", wd, sizeof(wd)); + if ( code == 0 || code > sizeof(wd) ) { code = GetWindowsDirectory(wd, sizeof(wd)); if (code == 0) @@ -186,10 +183,13 @@ afsi_start() WriteFile(afsi_file, t, strlen(t), &zilch, NULL); WriteFile(afsi_file, u, strlen(u), &zilch, NULL); p = "PATH="; - path = getenv("PATH"); + code = GetEnvironmentVariable("PATH", NULL, 0); + path = malloc(code); + code = GetEnvironmentVariable("PATH", path, code); WriteFile(afsi_file, p, strlen(p), &zilch, NULL); WriteFile(afsi_file, path, strlen(path), &zilch, NULL); WriteFile(afsi_file, "\n", 1, &zilch, NULL); + free(path); /* Initialize C RTL Code Page conversion functions */ /* All of the path info obtained from the SMB client is in the OEM code page */ @@ -1399,12 +1399,10 @@ static HANDLE OpenDumpFile(void) { char wd[256]; + DWORD code; - if (getenv("TEMP")) - { - StringCbCopyA(wd, sizeof(wd), getenv("TEMP")); - } - else + code = GetEnvironmentVariable("TEMP", wd, sizeof(wd)); + if ( code == 0 || code > sizeof(wd) ) { if (!GetWindowsDirectory(wd, sizeof(wd))) return NULL; diff --git a/src/WINNT/afsd/afskfw.c b/src/WINNT/afsd/afskfw.c index adc858705..771a5118f 100644 --- a/src/WINNT/afsd/afskfw.c +++ b/src/WINNT/afsd/afskfw.c @@ -1080,7 +1080,7 @@ KFW_import_ccache_data(void) code = pkrb5_cc_close(ctx,cc); cc = 0; code = pkrb5_cc_close(ctx,oldcc); - cc = 0; + oldcc = 0; KRB5_error(code, "krb5_cc_copy_creds", 0, NULL, NULL); continue; } @@ -1370,7 +1370,7 @@ KFW_AFS_destroy_tickets_for_cell(char * cell) return 0; if ( IsDebuggerPresent() ) { - OutputDebugString("KFW_AFS_destroy_ticets_for_cell: "); + OutputDebugString("KFW_AFS_destroy_tickets_for_cell: "); OutputDebugString(cell); OutputDebugString("\n"); } @@ -1422,6 +1422,60 @@ KFW_AFS_destroy_tickets_for_cell(char * cell) return 0; } +int +KFW_AFS_destroy_tickets_for_principal(char * user) +{ + krb5_context ctx = 0; + krb5_error_code code; + int count; + char ** cells = NULL; + krb5_principal princ = 0; + krb5_ccache cc = 0; + + if (!pkrb5_init_context) + return 0; + + if ( IsDebuggerPresent() ) { + OutputDebugString("KFW_AFS_destroy_tickets_for_user: "); + OutputDebugString(user); + OutputDebugString("\n"); + } + + code = pkrb5_init_context(&ctx); + if (code) ctx = 0; + + code = pkrb5_parse_name(ctx, user, &princ); + if (code) goto loop_cleanup; + + code = KFW_get_ccache(ctx, princ, &cc); + if (code) goto loop_cleanup; + + code = pkrb5_cc_destroy(ctx, cc); + if (!code) cc = 0; + + loop_cleanup: + if ( cc ) { + pkrb5_cc_close(ctx, cc); + cc = 0; + } + if ( princ ) { + pkrb5_free_principal(ctx, princ); + princ = 0; + } + + count = KFW_AFS_find_cells_for_princ(ctx, user, &cells, TRUE); + if ( count >= 1 ) { + while ( count-- ) { + KFW_AFS_update_cell_princ_map(ctx, cells[count], user, FALSE); + free(cells[count]); + } + free(cells); + } + + pkrb5_free_context(ctx); + return 0; +} + int KFW_AFS_renew_expiring_tokens(void) { @@ -3454,4 +3508,171 @@ KFW_AFS_get_lsa_principal(char * szUser, DWORD *dwSize) if (ctx) pkrb5_free_context(ctx); return success; -} \ No newline at end of file +} + +#define AFS_LOGON_EVENT_NAME TEXT("AFS Logon") + +static void DebugEvent0(char *a) +{ + HANDLE h; char *ptbuf[1]; + h = RegisterEventSource(NULL, AFS_LOGON_EVENT_NAME); + ptbuf[0] = a; + ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL); + DeregisterEventSource(h); +} + +#define MAXBUF_ 512 +static void DebugEvent(char *b,...) +{ + HANDLE h; char *ptbuf[1],buf[MAXBUF_+1]; + va_list marker; + h = RegisterEventSource(NULL, AFS_LOGON_EVENT_NAME); + va_start(marker,b); + vsprintf(buf, b, marker); + buf[MAXBUF_] = '\0'; + ptbuf[0] = buf; + ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL); + DeregisterEventSource(h); + va_end(marker); +} + + +void +KFW_AFS_copy_cache_to_system_file(char * user, char * szLogonId) +{ + char filename[256]; + DWORD count; + char cachename[264] = "FILE:"; + krb5_context ctx = 0; + krb5_error_code code; + krb5_principal princ = 0; + krb5_ccache cc = 0; + krb5_ccache ncc = 0; + + if (!pkrb5_init_context) + 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) ) + return; + + strcat(filename, "\\"); + strcat(filename, szLogonId); + + strcat(cachename, filename); + + DebugEvent("Copy2File %s", filename); + + DeleteFile(filename); + + code = pkrb5_init_context(&ctx); + if (code) ctx = 0; + + code = pkrb5_parse_name(ctx, user, &princ); + if (code) goto cleanup; + + code = KFW_get_ccache(ctx, princ, &cc); + if (code) goto cleanup; + + code = pkrb5_cc_resolve(ctx, cachename, &ncc); + if (code) goto cleanup; + + code = pkrb5_cc_initialize(ctx, ncc, princ); + if (code) goto cleanup; + + DebugEvent0("Copy2File copying"); + + code = pkrb5_cc_copy_creds(ctx,cc,ncc); + + DebugEvent("Copy2File copy_creds=%d", code); + + cleanup: + if ( cc ) { + pkrb5_cc_close(ctx, cc); + cc = 0; + } + if ( ncc ) { + pkrb5_cc_close(ctx, ncc); + ncc = 0; + } + if ( princ ) { + pkrb5_free_principal(ctx, princ); + princ = 0; + } + + if (ctx) + pkrb5_free_context(ctx); +} + +int +KFW_AFS_copy_system_file_to_default_cache(char * filename) +{ + DWORD count; + char cachename[264] = "FILE:"; + HANDLE hFile; + krb5_context ctx = 0; + krb5_error_code code; + krb5_principal princ = 0; + krb5_ccache cc = 0; + krb5_ccache ncc = 0; + int retval = 1; + + if (!pkrb5_init_context) + return 1; + + if ( strlen(filename) + 6 > sizeof(cachename) ) + return 1; + + strcat(cachename, filename); + + DebugEvent("Copy2Cache %s", cachename); + + code = pkrb5_init_context(&ctx); + if (code) ctx = 0; + + code = pkrb5_cc_resolve(ctx, cachename, &cc); + if (code) goto cleanup; + + DebugEvent("Copy2Cache resolve=%d", code); + + code = pkrb5_cc_get_principal(ctx, cc, &princ); + + code = pkrb5_cc_default(ctx, &ncc); + DebugEvent("Copy2Cache default=%d", code); + + if (!code) { + code = pkrb5_cc_initialize(ctx, ncc, princ); + DebugEvent("Copy2Cache initialize=%d", code); + + code = pkrb5_cc_copy_creds(ctx,cc,ncc); + DebugEvent("Copy2Cache copy_creds=%d", code); + } + if ( ncc ) { + pkrb5_cc_close(ctx, ncc); + ncc = 0; + } + + retval=0; /* success */ + + cleanup: + if ( cc ) { + pkrb5_cc_close(ctx, cc); + cc = 0; + } + + DeleteFile(filename); + + if ( princ ) { + pkrb5_free_principal(ctx, princ); + princ = 0; + } + + if (ctx) + pkrb5_free_context(ctx); + + return 0; +} diff --git a/src/WINNT/afsd/afskfw.h b/src/WINNT/afsd/afskfw.h index 352e0595a..7c744e7bc 100644 --- a/src/WINNT/afsd/afskfw.h +++ b/src/WINNT/afsd/afskfw.h @@ -47,6 +47,7 @@ void KFW_initialize(void); void KFW_cleanup(void); int KFW_is_available(void); int KFW_AFS_destroy_tickets_for_cell(char *); +int KFW_AFS_destroy_tickets_for_principal(char *); int KFW_AFS_renew_expiring_tokens(void); int KFW_AFS_get_cred( char * username, char * cell, @@ -62,6 +63,10 @@ int KFW_AFS_get_cellconfig(char *, struct afsconf_cell *, char *); void KFW_import_windows_lsa(void); BOOL KFW_AFS_get_lsa_principal(char *, DWORD *); +/* These functions are only to be used in the afslogon.dll */ +void KFW_AFS_copy_cache_to_system_file(char *, char *); +int KFW_AFS_copy_system_file_to_default_cache(char *); + /* From afs/krb_prot.h */ /* values for kerb error codes */ #define KERB_ERR_OK 0 diff --git a/src/WINNT/afsd/afslogon.c b/src/WINNT/afsd/afslogon.c index 34833aa80..85ac65af7 100644 --- a/src/WINNT/afsd/afslogon.c +++ b/src/WINNT/afsd/afslogon.c @@ -41,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); @@ -651,6 +653,7 @@ DWORD APIENTRY NPLogonNotify( char logonDomain[MAX_DOMAIN_LENGTH]=""; char cell[256]=""; char homePath[MAX_PATH]=""; + char szLogonId[128] = ""; MSV1_0_INTERACTIVE_LOGON *IL; @@ -675,15 +678,33 @@ DWORD APIENTRY NPLogonNotify( 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? */ @@ -708,14 +729,6 @@ DWORD APIENTRY NPLogonNotify( } } - (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); - /* * Get Logon options */ @@ -873,9 +886,15 @@ DWORD APIENTRY NPLogonNotify( } 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]; @@ -1040,20 +1059,16 @@ VOID AFS_Logoff_Event( PWLX_NOTIFICATION_INFO pInfo ) VOID AFS_Logon_Event( PWLX_NOTIFICATION_INFO pInfo ) { - DWORD code; TCHAR profileDir[1024] = TEXT(""); DWORD len = 1024; PTOKEN_USER tokenUser = NULL; DWORD retLen; - HANDLE hToken; - WCHAR szUserW[128] = L""; char szUserA[128] = ""; char szClient[MAX_PATH]; char szPath[MAX_PATH] = ""; NETRESOURCE nr; DWORD res; - DWORD gle; DWORD dwSize; /* Make sure the AFS Libraries are initialized */ @@ -1061,6 +1076,8 @@ VOID AFS_Logon_Event( PWLX_NOTIFICATION_INFO pInfo ) DebugEvent0("AFS_Logon_Event - Start"); + DebugEvent("AFS_Logon_Event Process ID: %d",GetCurrentProcessId()); + if (!GetTokenInformation(pInfo->hToken, TokenUser, NULL, 0, &retLen)) { if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) { @@ -1123,3 +1140,117 @@ VOID AFS_Logon_Event( PWLX_NOTIFICATION_INFO pInfo ) 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"); +} + diff --git a/src/WINNT/afsd/afslogon.def b/src/WINNT/afsd/afslogon.def index fa8daccc1..77a9368eb 100644 --- a/src/WINNT/afsd/afslogon.def +++ b/src/WINNT/afsd/afslogon.def @@ -11,5 +11,7 @@ EXPORTS AFS_Startup_Event AFS_Logoff_Event AFS_Logon_Event + KFW_Logon_Event + diff --git a/src/WINNT/afsd/cm_buf.c b/src/WINNT/afsd/cm_buf.c index 151bccc43..641d45099 100644 --- a/src/WINNT/afsd/cm_buf.c +++ b/src/WINNT/afsd/cm_buf.c @@ -592,7 +592,7 @@ void buf_Recycle(cm_buf_t *bp) } /* we better find it */ - osi_assertx(tbp != NULL, "buf_GetNewLocked: hash table screwup"); + osi_assertx(tbp != NULL, "buf_Recycle: hash table screwup"); *lbpp = bp->hashp; /* hash out */ @@ -806,9 +806,7 @@ long buf_GetNew(struct cm_scache *scp, osi_hyper_t *offsetp, cm_buf_t **bufpp) pageOffset.HighPart = offsetp->HighPart; pageOffset.LowPart = offsetp->LowPart & ~(cm_data.buf_blockSize-1); while (1) { - lock_ObtainWrite(&buf_globalLock); - bp = buf_LockedFind(scp, &pageOffset); - lock_ReleaseWrite(&buf_globalLock); + bp = buf_Find(scp, &pageOffset); if (bp) { /* lock it and break out */ lock_ObtainMutex(&bp->mx); @@ -848,6 +846,7 @@ long buf_GetNew(struct cm_scache *scp, osi_hyper_t *offsetp, cm_buf_t **bufpp) } /* get a page, returning it held but unlocked. Make sure it is complete */ +/* The scp must be unlocked when passed to this function */ long buf_Get(struct cm_scache *scp, osi_hyper_t *offsetp, cm_buf_t **bufpp) { cm_buf_t *bp; @@ -869,9 +868,7 @@ long buf_Get(struct cm_scache *scp, osi_hyper_t *offsetp, cm_buf_t **bufpp) buf_ValidateBufQueues(); #endif /* TESTING */ - lock_ObtainWrite(&buf_globalLock); - bp = buf_LockedFind(scp, &pageOffset); - lock_ReleaseWrite(&buf_globalLock); + bp = buf_Find(scp, &pageOffset); if (bp) { /* lock it and break out */ lock_ObtainMutex(&bp->mx); diff --git a/src/WINNT/afsd/cm_config.c b/src/WINNT/afsd/cm_config.c index 25672c5a7..3d71d37fd 100644 --- a/src/WINNT/afsd/cm_config.c +++ b/src/WINNT/afsd/cm_config.c @@ -201,6 +201,7 @@ long cm_SearchCellFile(char *cellNamep, char *newCellNamep, int tracking = 1, partial = 0; #if defined(DJGPP) || defined(AFS_WIN95_ENV) char *afsconf_path; + DWORD dwSize; #endif cm_GetCellServDB(wdir); @@ -212,11 +213,15 @@ long cm_SearchCellFile(char *cellNamep, char *newCellNamep, /* If we are in Win95 here, we are linking with klog etc. and are using DJGPP client even though DJGPP is not defined. So we still need to check AFSCONF for location. */ - afsconf_path = getenv("AFSCONF"); + dwSize = GetEnvironmentVariable("AFSCONF", NULL, 0); + afsconf_path = malloc(dwSize); + dwSize = GetEnvironmentVariable("AFSCONF", afsconf_path, dwSize); if (!afsconf_path) strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH); - else + else { strcpy(wdir, afsconf_path); + free(afsconf_path); + } strcat(wdir, "/"); strcat(wdir, AFS_CELLSERVDB); /*fprintf(stderr, "opening cellservdb file %s\n", wdir);*/ @@ -485,17 +490,22 @@ long cm_GetRootCellName(char *cellNamep) FILE *thisCell; char thisCellPath[256]; char *newline; + DWORD dwSize; #ifdef DJGPP strcpy(thisCellPath, cm_confDir); #else /* Win 95 */ char *afsconf_path; - afsconf_path = getenv("AFSCONF"); + dwSize = GetEnvironmentVariable("AFSCONF", NULL, 0); + afsconf_path = malloc(dwSize); + dwSize = GetEnvironmentVariable("AFSCONF", afsconf_path, dwSize); if (!afsconf_path) strcpy(thisCellPath, AFSDIR_CLIENT_ETC_DIRPATH); - else + else { strcpy(thisCellPath, afsconf_path); + free(afsconf_path); + } #endif strcat(thisCellPath,"/"); @@ -532,11 +542,19 @@ cm_configFile_t *cm_CommonOpen(char *namep, char *rwp) #ifdef DJGPP strcpy(wdir,cm_confDir); #else - char *afsconf_path = getenv("AFSCONF"); + DWORD dwSize; + char *afsconf_path; + + dwSize = GetEnvironmentVariable("AFSCONF", NULL, 0); + afsconf_path = malloc(dwSize); + dwSize = GetEnvironmentVariable("AFSCONF", afsconf_path, dwSize); + if (!afsconf_path) - strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH); - else - strcpy(wdir, afsconf_path); + strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH); + else { + strcpy(wdir, afsconf_path); + free(afsconf_path); + } #endif /* !DJGPP */ strcat(wdir,"/"); #endif /* DJGPP || WIN95 */ @@ -682,13 +700,14 @@ long cm_AppendNewCellLine(cm_configFile_t *filep, char *linep) long cm_CloseCellFile(cm_configFile_t *filep) { - char wdir[256]; + char wdir[256]; char sdir[256]; long code; long closeCode; int tlen; #ifdef AFS_WIN95_ENV char *afsconf_path; + DWORD dwSize; #endif closeCode = fclose((FILE *)filep); @@ -702,11 +721,15 @@ long cm_CloseCellFile(cm_configFile_t *filep) #ifdef DJGPP strcpy(wdir,cm_confDir); #else - afsconf_path = getenv("AFSCONF"); + dwSize = GetEnvironmentVariable("AFSCONF", NULL, 0); + afsconf_path = malloc(dwSize); + dwSize = GetEnvironmentVariable("AFSCONF", afsconf_path, dwSize); if (!afsconf_path) strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH); - else + else { strcpy(wdir, afsconf_path); + free(afsconf_path); + } #endif /* !DJGPP */ strcat(wdir,"/"); #endif /* DJGPP || WIN95 */ @@ -739,6 +762,7 @@ void cm_GetConfigDir(char *dir) int tlen; #ifdef AFS_WIN95_ENV char *afsconf_path; + DWORD dwSize; #endif #if !defined(DJGPP) && !defined(AFS_WIN95_ENV) @@ -751,11 +775,15 @@ void cm_GetConfigDir(char *dir) #ifdef DJGPP strcpy(wdir,cm_confDir); #else - afsconf_path = getenv("AFSCONF"); + dwSize = GetEnvironmentVariable("AFSCONF", NULL, 0); + afsconf_path = malloc(dwSize); + dwSize = GetEnvironmentVariable("AFSCONF", afsconf_path, dwSize); if (!afsconf_path) strcpy(wdir, AFSDIR_CLIENT_ETC_DIRPATH); - else + else { strcpy(wdir, afsconf_path); + free(afsconf_path); + } #endif /* !DJGPP */ strcat(wdir,"\\"); #endif /* DJGPP || WIN95 */ diff --git a/src/WINNT/afsd/cm_dcache.c b/src/WINNT/afsd/cm_dcache.c index 8d347f696..d5d7c70a7 100644 --- a/src/WINNT/afsd/cm_dcache.c +++ b/src/WINNT/afsd/cm_dcache.c @@ -727,7 +727,9 @@ long cm_SetupStoreBIOD(cm_scache_t *scp, osi_hyper_t *inOffsetp, long inSize, break; /* try to lock it, and quit if we can't (simplifies locking) */ + lock_ReleaseMutex(&scp->mx); code = lock_TryMutex(&bufp->mx); + lock_ObtainMutex(&scp->mx); if (code == 0) { buf_Release(bufp); break; @@ -781,7 +783,9 @@ long cm_SetupStoreBIOD(cm_scache_t *scp, osi_hyper_t *inOffsetp, long inSize, break; /* try to lock it, and quit if we can't (simplifies locking) */ + lock_ReleaseMutex(&scp->mx); code = lock_TryMutex(&bufp->mx); + lock_ObtainMutex(&scp->mx); if (code == 0) { buf_Release(bufp); break; @@ -890,27 +894,27 @@ long cm_SetupFetchBIOD(cm_scache_t *scp, osi_hyper_t *offsetp, * sequence at a time. */ + // lock_ObtainMutex(&cm_bufGetMutex); /* first hold all buffers, since we can't hold any locks in buf_Get */ while (1) { /* stop at chunk boundary */ - if (collected >= cm_chunkSize) break; + if (collected >= cm_chunkSize) + break; /* see if the next page would be past EOF */ - if (LargeIntegerGreaterThanOrEqualTo(pageBase, fileSize)) break; - - lock_ObtainMutex(&cm_bufGetMutex); + if (LargeIntegerGreaterThanOrEqualTo(pageBase, fileSize)) + break; code = buf_Get(scp, &pageBase, &tbp); if (code) { lock_ReleaseMutex(&cm_bufGetMutex); lock_ObtainMutex(&scp->mx); + cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); return code; } buf_Release(tbp); - lock_ReleaseMutex(&cm_bufGetMutex); - toffset.HighPart = 0; toffset.LowPart = cm_data.buf_blockSize; pageBase = LargeIntegerAdd(toffset, pageBase); @@ -920,6 +924,8 @@ long cm_SetupFetchBIOD(cm_scache_t *scp, osi_hyper_t *offsetp, /* reserve a chunk's worth of buffers if possible */ reserving = buf_TryReserveBuffers(cm_chunkSize / cm_data.buf_blockSize); + // lock_ReleaseMutex(&cm_bufGetMutex); + pageBase = *offsetp; collected = pageBase.LowPart & (cm_chunkSize - 1); @@ -1376,6 +1382,9 @@ long cm_GetBuffer(cm_scache_t *scp, cm_buf_t *bufp, int *cpffp, cm_user_t *up, code = cm_MapRPCError(code, reqp); lock_ObtainMutex(&scp->mx); + + cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_FETCHSTATUS); + /* we know that no one else has changed the buffer, since we still have * the fetching flag on the buffers, and we have the scp locked again. * Copy in the version # into the buffer if we got code 0 back from the diff --git a/src/WINNT/afsd/cm_ioctl.c b/src/WINNT/afsd/cm_ioctl.c index 47a7094bb..d4e5ca5f9 100644 --- a/src/WINNT/afsd/cm_ioctl.c +++ b/src/WINNT/afsd/cm_ioctl.c @@ -2317,6 +2317,7 @@ long cm_IoctlMemoryDump(struct smb_ioctl *ioctlp, struct cm_user *userp) HANDLE hLogFile; char logfileName[MAX_PATH+1]; char *cookie; + DWORD dwSize; #ifdef _DEBUG static _CrtMemState memstate; @@ -2325,12 +2326,8 @@ long cm_IoctlMemoryDump(struct smb_ioctl *ioctlp, struct cm_user *userp) cm_SkipIoctlPath(ioctlp); memcpy(&inValue, ioctlp->inDatap, sizeof(long)); - if (getenv("TEMP")) - { - strncpy(logfileName, getenv("TEMP"), MAX_PATH); - logfileName[MAX_PATH] = '\0'; - } - else + dwSize = GetEnvironmentVariable("TEMP", logfileName, sizeof(logfileName)); + if ( dwSize == 0 || dwSize > sizeof(logfileName) ) { GetWindowsDirectory(logfileName, sizeof(logfileName)); } diff --git a/src/WINNT/install/NSIS/OpenAFS.nsi b/src/WINNT/install/NSIS/OpenAFS.nsi index f97924167..e7577b2d3 100644 --- a/src/WINNT/install/NSIS/OpenAFS.nsi +++ b/src/WINNT/install/NSIS/OpenAFS.nsi @@ -546,6 +546,7 @@ Section "AFS Client" secClient SetOutPath "$SYSDIR" !insertmacro ReplaceDLL "${AFS_CLIENT_BUILDDIR}\afslogon.dll" "$SYSDIR\afslogon.dll" "$INSTDIR" + File "${AFS_CLIENT_BUILDDIR}\afscpcc.exe" Call AFSLangFiles @@ -726,6 +727,11 @@ skipremove: WriteRegStr HKLM "Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\AfsLogon" "Logoff" "AFS_Logoff_Event" WriteRegStr HKLM "Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\AfsLogon" "Startup" "AFS_Startup_Event" + WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\KFWLogon" "Asynchronous" 0 + WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\KFWLogon" "Impersonate" 0 + WriteRegStr HKLM "Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\KFWLogon" "DLLName" "afslogon.dll" + WriteRegStr HKLM "Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\KFWLogon" "Logon" "KFW_Logon_Event" + SetRebootFlag true WriteUninstaller "$INSTDIR\Uninstall.exe" @@ -1800,10 +1806,12 @@ StartRemove: Delete /REBOOTOK "$SYSDIR\afsserver.cpl" Delete /REBOOTOK "$SYSDIR\afs_cpa.cpl" Delete /REBOOTOK "$SYSDIR\afslogon.dll" + Delete /REBOOTOK "$SYSDIR\afscpcc.exe" Delete /REBOOTOK "$SYSDIR\afsserver.pdb" Delete /REBOOTOK "$SYSDIR\afs_cpa.pdb" Delete /REBOOTOK "$SYSDIR\afslogon.pdb" + Delete /REBOOTOK "$SYSDIR\afscpcc.pdb" RMDir /r "$INSTDIR\Documentation\html\CmdRef" RMDir /r "$INSTDIR\Documentation\html\InstallGd" diff --git a/src/WINNT/install/wix/files.wxi b/src/WINNT/install/wix/files.wxi index cf18477f2..de2f81180 100644 --- a/src/WINNT/install/wix/files.wxi +++ b/src/WINNT/install/wix/files.wxi @@ -3,6 +3,7 @@ + @@ -11,10 +12,15 @@ + + + + + -- 2.39.5