diff --git a/doc/txt/winnotes/afs-changes-since-1.2.txt b/doc/txt/winnotes/afs-changes-since-1.2.txt index 01af5652d4..9668eddf18 100644 --- a/doc/txt/winnotes/afs-changes-since-1.2.txt +++ b/doc/txt/winnotes/afs-changes-since-1.2.txt @@ -1,9 +1,54 @@ Since 1.3.82: + * A race condition in the rx library was fixed that resulted in + a deadlock in rx_NewCall when the RX_CONN_MAKECALL_WAITING flag + was cleared when threads were still waiting to use the + connection. Also, fixed a potential case in which the + connection could be destroyed while threads were waiting to use it. + + * The DNLC freelist has been seen to become corrupted with still + active entries being stored on the freelist. Changes were made + to perform a better job of cleaning entries before placing them + onto the freelist; marking them with the correct magic value when + purging the list; and allowing the list to be purged on startup + if the cache validation fails. + + * Windows Crash Reporting does not get triggered for afsd_service.exe + because it provides its own top level exception handler. This patch + places an explicit call to ReportCrash() on platforms which support + it. (XP and above.) + + If you configure Crash Reporting via AD Policy to capture crash + reports within the domain, then you will receive this output. + + * Generate MiniDumps independent of the Windows Crash Reporting. + + (a) If an exception occurs,a minidump will be generated at the path + %TEMP%\afsd.dmp. The type of minidump defaults to Normal but + can be set to any other type via use of the + registry. + + [HKLM\SOFTWARE\OpenAFS\Client] MiniDumpType (DWORD) + + (b) MiniDumps can be generated at any time using the "fs minidump" + command. This allows you to generate a minidump without + stopping the process or even requiring the use of a debugger + on the system. + + * an RX connection which reports bad ticket now treats it the same way + the expired ticket is treated. The ticket is removed from the + connection and a new anonymous connection is established. + + * fs memdump now requires that the caller be in the AFS Client Admins + group + + * additional debugging information is provided in cm_Analyze when the + error code is ignored. + * Fix a regression introduced into the pioctl() client code which will cause a crash in winlogon.exe, explorer.exe and fs.exe if - MIT KFW is not installed. + MIT KFW is not installed. (1.3.82a) - * Remove AFS Gateway option from OpenAFS Control Panel + * Remove AFS Gateway option from OpenAFS Control Panel (1.3.82a) Since 1.3.81: * Fix a race condition in cm_EndCallbackGrantingCall() that diff --git a/doc/txt/winnotes/afs-install-notes.txt b/doc/txt/winnotes/afs-install-notes.txt index aa9ca79a3b..ffb7b016af 100644 --- a/doc/txt/winnotes/afs-install-notes.txt +++ b/doc/txt/winnotes/afs-install-notes.txt @@ -1,4 +1,4 @@ -OpenAFS for Windows 1.3.8201 Installation Notes +OpenAFS for Windows 1.3.8300 Installation Notes --------------------------------------------- The OpenAFS for Windows product was very poorly maintained throughout the diff --git a/doc/txt/winnotes/msi-deployment-guide.txt b/doc/txt/winnotes/msi-deployment-guide.txt index 35656abaef..61a6cc75ac 100644 --- a/doc/txt/winnotes/msi-deployment-guide.txt +++ b/doc/txt/winnotes/msi-deployment-guide.txt @@ -85,7 +85,7 @@ OpenAFS for Windows (edit the openafs-modified.msi to include the necessary changes) - > msitran -g openafs-modified.msi openafs.msi openafs-transform.mst + > msitran -g openafs.msi openafs-modified.msi openafs-transform.mst (generates openafs-transform.mst, which is the transform) @@ -687,7 +687,7 @@ OpenAFS for Windows MSI package is 'openafs-en_US.msi'. Generates transform 'openafs-transform.mst') - > msitran.exe -g openafs-en_US.msi openafs-en_US_new.msi openafs-transform.mst glpruw + > msitran.exe -g openafs-en_US.msi openafs-en_US_new.msi openafs-transform.mst See the Platform SDK documentation for information on command line options for MSITRAN.EXE. diff --git a/doc/txt/winnotes/registry.txt b/doc/txt/winnotes/registry.txt index 0baa5ffbc7..72e7792bd2 100644 --- a/doc/txt/winnotes/registry.txt +++ b/doc/txt/winnotes/registry.txt @@ -405,6 +405,36 @@ Default : 0x0 pioctl() call is failing. +Value : MiniDumpType +Type : REG_DWORD +Default : 0x0 (MiniDumpNormal) + + This value is used to specify the type of minidump generated by + afsd_service.exe either when the process crashes or when a user + initiated is dump file is generated with the "fs.exe minidump" + command. + + Valid values are dependent on the version of DbgHelp.dll installed + on the machine. See the Microsoft Developer Library for further + information. + + MiniDumpNormal = 0x00000000, + MiniDumpWithDataSegs = 0x00000001, + MiniDumpWithFullMemory = 0x00000002, + MiniDumpWithHandleData = 0x00000004, + MiniDumpFilterMemory = 0x00000008, + MiniDumpScanMemory = 0x00000010, + MiniDumpWithUnloadedModules = 0x00000020, + MiniDumpWithIndirectlyReferencedMemory = 0x00000040, + MiniDumpFilterModulePaths = 0x00000080, + MiniDumpWithProcessThreadData = 0x00000100, + MiniDumpWithPrivateReadWriteMemory = 0x00000200, + MiniDumpWithoutOptionalData = 0x00000400, + MiniDumpWithFullMemoryInfo = 0x00000800, + MiniDumpWithThreadInfo = 0x00001000, + MiniDumpWithCodeSegs = 0x00002000 + + Value : StoreAnsiFilenames Type : REG_DWORD Default : 0x0 @@ -814,6 +844,17 @@ Function: Shortcut_FixStartup user value is checked first; if it does not exist the local machine value is checked. + The following subset of the command line options are appropriate for + use in this registry setting: + + -A = autoinit + -M = renew drive maps + -N = ip address change detection + -Q = quiet mode. do not display start service dialog + if afsd_service is not already running + -S = show tokens dialog on startup + -Z = unmap drives + Regkey: [HKCU\SOFTWARE\OpenAFS\Client] diff --git a/src/NTMakefile b/src/NTMakefile index 7949d04116..af94461fa8 100644 --- a/src/NTMakefile +++ b/src/NTMakefile @@ -469,7 +469,21 @@ license: talocale $(NTMAKE) $(CD) ..\..\.. -afsadmsvr: license +client_osi: license + echo ***** $@ + $(DOCD) $(SRC)\WINNT\$@ + $(CD) $(SRC)\WINNT\$@ + $(NTMAKE) + $(CD) ..\..\.. + +afsd: client_osi + echo ***** $@ + $(DOCD) $(SRC)\WINNT\$@ + $(CD) $(SRC)\WINNT\$@ + $(NTMAKE) + $(CD) ..\..\.. + +afsadmsvr: afsd echo ***** $@ $(DOCD) $(SRC)\WINNT\$@ $(CD) $(SRC)\WINNT\$@ @@ -511,21 +525,7 @@ client_talocale: afssvrcpa $(NTMAKE) $(CD) ..\..\.. -client_osi: client_talocale - echo ***** $@ - $(DOCD) $(SRC)\WINNT\$@ - $(CD) $(SRC)\WINNT\$@ - $(NTMAKE) - $(CD) ..\..\.. - -afsd: client_osi - echo ***** $@ - $(DOCD) $(SRC)\WINNT\$@ - $(CD) $(SRC)\WINNT\$@ - $(NTMAKE) - $(CD) ..\..\.. - -client_cpa: afsd +client_cpa: client_talocale echo ***** $@ $(DOCD) $(SRC)\WINNT\$@ $(CD) $(SRC)\WINNT\$@ diff --git a/src/WINNT/afsapplib/al_admsvr.cpp b/src/WINNT/afsapplib/al_admsvr.cpp index c2d672bf9b..ef8fb543f5 100644 --- a/src/WINNT/afsapplib/al_admsvr.cpp +++ b/src/WINNT/afsapplib/al_admsvr.cpp @@ -25,7 +25,7 @@ static struct { BOOL fUseAdminServer; DWORD idAdminServerClient; - } l; + } l = {0, 0}; /* diff --git a/src/WINNT/afsapplib/al_creds.cpp b/src/WINNT/afsapplib/al_creds.cpp index 237a606f61..f2f964dae7 100644 --- a/src/WINNT/afsapplib/al_creds.cpp +++ b/src/WINNT/afsapplib/al_creds.cpp @@ -68,7 +68,8 @@ BOOL AfsAppLib_CrackCredentials (PVOID hCreds, LPTSTR pszCell, LPTSTR pszUser, L { rc = asc_CredentialsCrack (idClient, hCreds, pszCell, pszUser, pst, &status); } - else if (OpenClientLibrary()) + else + if (OpenClientLibrary()) { char szUserA[ cchRESOURCE ], szUser2A[ cchRESOURCE ]; char szCellA[ cchRESOURCE ]; @@ -102,7 +103,8 @@ PVOID AfsAppLib_GetCredentials (LPCTSTR pszCell, ULONG *pStatus) { hCreds = asc_CredentialsGet (idClient, pszCell, &status); } - else if (OpenClientLibrary()) + else + if (OpenClientLibrary()) { LPSTR pszCellA = StringToAnsi (pszCell); @@ -128,7 +130,8 @@ PVOID AfsAppLib_SetCredentials (LPCTSTR pszCell, LPCTSTR pszUser, LPCTSTR pszPas { hCreds = asc_CredentialsSet (idClient, pszCell, pszUser, pszPassword, &status); } - else if (OpenClientLibrary()) + else + if (OpenClientLibrary()) { char szCellA[ cchRESOURCE ]; char szUserA[ cchRESOURCE ]; @@ -903,6 +906,9 @@ void OnExpiredCredentials (WPARAM wp, LPARAM lp) BOOL AfsAppLib_IsUserAdmin (PVOID hCreds, LPTSTR pszUser) { +#ifndef USE_KASERVER + return TRUE; +#else BOOL rc = FALSE; afs_status_t status; @@ -969,5 +975,6 @@ BOOL AfsAppLib_IsUserAdmin (PVOID hCreds, LPTSTR pszUser) } return rc; +#endif /* USE_KASERVER */ } diff --git a/src/WINNT/afsapplib/al_misc.cpp b/src/WINNT/afsapplib/al_misc.cpp index 3620bd2658..438c6f62fe 100644 --- a/src/WINNT/afsapplib/al_misc.cpp +++ b/src/WINNT/afsapplib/al_misc.cpp @@ -213,7 +213,8 @@ BOOL CALLBACK AfsAppLib_TranslateErrorFunc (LPTSTR pszText, ULONG code, LANGID i ULONG status; return asc_ErrorCodeTranslate (idClient, code, idLanguage, pszText, &status); } - else if (OpenUtilLibrary()) + else + if (OpenUtilLibrary()) { const char *pszTextA = NULL; afs_status_t status; @@ -463,7 +464,8 @@ BOOL AfsAppLib_GetLocalCell (LPTSTR pszCell, ULONG *pStatus) { rc = asc_LocalCellGet (idClient, szCell, &status); } - else if (OpenClientLibrary()) + else + if (OpenClientLibrary()) { char szCellNameA[ MAX_PATH ]; if ((rc = afsclient_LocalCellGet (szCellNameA, (afs_status_p)&status)) == TRUE) diff --git a/src/WINNT/afsd/afsd.h b/src/WINNT/afsd/afsd.h index 7f9291ced0..112b202281 100644 --- a/src/WINNT/afsd/afsd.h +++ b/src/WINNT/afsd/afsd.h @@ -147,4 +147,6 @@ typedef BOOL ( APIENTRY * AfsdDaemonHook )(void); typedef BOOL ( APIENTRY * AfsdStoppingHook )(void); #define AFSD_STOPPED_HOOK "AfsdStoppedHook" typedef BOOL ( APIENTRY * AfsdStoppedHook )(void); + +#define SERVICE_CONTROL_CUSTOM_DUMP 128 #endif /* AFSD_H_ENV */ diff --git a/src/WINNT/afsd/afsd_init.c b/src/WINNT/afsd/afsd_init.c index 94d68e85f9..bf5eebb9bf 100644 --- a/src/WINNT/afsd/afsd_init.c +++ b/src/WINNT/afsd/afsd_init.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "afsd.h" @@ -135,7 +136,7 @@ void afsd_initUpperCaseTable() void afsi_start() { - char wd[100]; + char wd[256]; char t[100], u[100], *p, *path; int zilch; int code; @@ -815,13 +816,9 @@ int afsd_InitCM(char **reasonP) dummyLen = sizeof(traceOnPanic); code = RegQueryValueEx(parmKey, "TrapOnPanic", NULL, NULL, (BYTE *) &traceOnPanic, &dummyLen); - if (code == ERROR_SUCCESS) - afsi_log("Set to %s on panic", - traceOnPanic ? "trap" : "not trap"); - else { - traceOnPanic = 0; - /* Don't log */ - } + if (code != ERROR_SUCCESS) + traceOnPanic = 1; /* log */ + afsi_log("Set to %s on panic", traceOnPanic ? "trap" : "not trap"); dummyLen = sizeof(reportSessionStartups); code = RegQueryValueEx(parmKey, "ReportSessionStartups", NULL, NULL, @@ -1390,12 +1387,104 @@ static DWORD *afsd_crtDbgBreakCurrent = NULL; static DWORD afsd_crtDbgBreaks[256]; #endif +static EFaultRepRetVal (WINAPI *pReportFault)(LPEXCEPTION_POINTERS pep, DWORD dwMode) = NULL; +static BOOL (WINAPI *pMiniDumpWriteDump)(HANDLE hProcess,DWORD ProcessId,HANDLE hFile, + MINIDUMP_TYPE DumpType, + PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, + PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, + PMINIDUMP_CALLBACK_INFORMATION CallbackParam) = NULL; + + +static HANDLE +OpenDumpFile(void) +{ + char wd[256]; + + if (getenv("TEMP")) + { + StringCbCopyA(wd, sizeof(wd), getenv("TEMP")); + } + else + { + if (!GetWindowsDirectory(wd, sizeof(wd))) + return NULL; + } + StringCbCatA(wd, sizeof(wd), "\\afsd.dmp"); + return CreateFile( wd, GENERIC_WRITE, FILE_SHARE_READ, NULL, + CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL); +} + +void +GenerateMiniDump(PEXCEPTION_POINTERS ep) +{ + if (ep == NULL) + { + // Generate exception to get proper context in dump + __try + { + RaiseException(DBG_CONTINUE, 0, 0, NULL); + } + __except(GenerateMiniDump(GetExceptionInformation()), EXCEPTION_CONTINUE_EXECUTION) + { + } + } + else + { + MINIDUMP_EXCEPTION_INFORMATION eInfo; + HANDLE hFile = NULL; + HMODULE hDbgHelp = NULL; + + hDbgHelp = LoadLibrary("Dbghelp.dll"); + if ( hDbgHelp == NULL ) + return; + + (FARPROC) pMiniDumpWriteDump = GetProcAddress(hDbgHelp, "MiniDumpWriteDump"); + if ( pMiniDumpWriteDump == NULL ) { + FreeLibrary(hDbgHelp); + return; + } + + hFile = OpenDumpFile(); + + if ( hFile ) { + HKEY parmKey; + DWORD dummyLen; + DWORD dwValue; + DWORD code; + DWORD dwMiniDumpType = MiniDumpNormal; + + code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_OPENAFS_SUBKEY, + 0, KEY_QUERY_VALUE, &parmKey); + if (code == ERROR_SUCCESS) { + dummyLen = sizeof(DWORD); + code = RegQueryValueEx(parmKey, "MiniDumpType", NULL, NULL, + (BYTE *) &dwValue, &dummyLen); + if (code == ERROR_SUCCESS) + dwMiniDumpType = dwValue ? 1 : 0; + RegCloseKey (parmKey); + } + + eInfo.ThreadId = GetCurrentThreadId(); + eInfo.ExceptionPointers = ep; + eInfo.ClientPointers = FALSE; + + pMiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(), + hFile, dwMiniDumpType, ep ? &eInfo : NULL, + NULL, NULL); + + CloseHandle(hFile); + } + FreeLibrary(hDbgHelp); + } +} + LONG __stdcall afsd_ExceptionFilter(EXCEPTION_POINTERS *ep) { CONTEXT context; #ifdef _DEBUG BOOL allocRequestBrk = FALSE; #endif + HMODULE hLib = NULL; afsi_log("UnhandledException : code : 0x%x, address: 0x%x\n", ep->ExceptionRecord->ExceptionCode, @@ -1414,7 +1503,17 @@ LONG __stdcall afsd_ExceptionFilter(EXCEPTION_POINTERS *ep) context = *ep->ContextRecord; afsd_printStack(GetCurrentThread(), &context); - + + GenerateMiniDump(ep); + + hLib = LoadLibrary("Faultrep.dll"); + if ( hLib ) { + (FARPROC) pReportFault = GetProcAddress(hLib, "ReportFault"); + if ( pReportFault ) + pReportFault(ep, 0); + FreeLibrary(hLib); + } + if (ep->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT) { afsi_log("\nEXCEPTION_BREAKPOINT - continue execution ...\n"); diff --git a/src/WINNT/afsd/afsd_init.h b/src/WINNT/afsd/afsd_init.h index 123bd385b6..6465341a51 100644 --- a/src/WINNT/afsd/afsd_init.h +++ b/src/WINNT/afsd/afsd_init.h @@ -12,6 +12,8 @@ void afsi_start(); #ifndef DJGPP int afsd_InitCM(char **reasonP); int afsd_InitSMB(char **reasonP, void *aMBfunc); + +void GenerateMiniDump(PEXCEPTION_POINTERS ep); #else /* DJGPP */ int afsd_InitCM(char **reasonP, struct cmd_syndesc *as, char *arock); int afsd_InitSMB(char **reasonP); @@ -22,3 +24,5 @@ void afsd_SetUnhandledExceptionFilter(); extern char cm_HostName[]; extern char cm_NetbiosName[]; + + diff --git a/src/WINNT/afsd/afsd_service.c b/src/WINNT/afsd/afsd_service.c index a539363b65..ad334c1e96 100644 --- a/src/WINNT/afsd/afsd_service.c +++ b/src/WINNT/afsd/afsd_service.c @@ -354,6 +354,14 @@ afsd_ServiceControlHandlerEx( } } } + break; + case SERVICE_CONTROL_CUSTOM_DUMP: + { + afsi_log("SERVICE_CONTROL_CUSTOM_DUMP"); + GenerateMiniDump(NULL); + dwRet = NO_ERROR; + } + break; } /* end switch(ctrlCode) */ return dwRet; } @@ -1050,7 +1058,7 @@ afsd_Main(DWORD argc, LPTSTR *argv) ServiceStatus.dwCheckPoint = 1; ServiceStatus.dwWaitHint = 30000; /* accept Power Events */ - ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_POWEREVENT; + ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_POWEREVENT | SERVICE_ACCEPT_PARAMCHANGE; SetServiceStatus(StatusHandle, &ServiceStatus); #endif @@ -1138,7 +1146,7 @@ afsd_Main(DWORD argc, LPTSTR *argv) ServiceStatus.dwCheckPoint = 2; ServiceStatus.dwWaitHint = 20000; /* accept Power Events */ - ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_POWEREVENT; + ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_POWEREVENT | SERVICE_ACCEPT_PARAMCHANGE; SetServiceStatus(StatusHandle, &ServiceStatus); } } @@ -1241,7 +1249,7 @@ afsd_Main(DWORD argc, LPTSTR *argv) ServiceStatus.dwWaitHint = 0; /* accept Power events */ - ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_POWEREVENT; + ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_POWEREVENT | SERVICE_ACCEPT_PARAMCHANGE; SetServiceStatus(StatusHandle, &ServiceStatus); #endif { diff --git a/src/WINNT/afsd/cm_conn.c b/src/WINNT/afsd/cm_conn.c index 2a4080df88..e4f4533ac0 100644 --- a/src/WINNT/afsd/cm_conn.c +++ b/src/WINNT/afsd/cm_conn.c @@ -378,7 +378,8 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp, if ( timeLeft > 2 ) retry = 1; } - else if (errorCode == RXKADEXPIRED) { + else if (errorCode == RXKADEXPIRED || + errorCode == RXKADBADTICKET) { if (!dead_session) { lock_ObtainMutex(&userp->mx); ucellp = cm_GetUCell(userp, serverp->cellp); @@ -393,8 +394,26 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp, retry = 1; } } else { - if (errorCode) - osi_Log1(afsd_logp, "cm_Analyze: ignoring error code 0x%x", errorCode); + if (errorCode) { + char * s = "unknown error"; + switch ( errorCode ) { + case RXKADINCONSISTENCY: s = "RXKADINCONSISTENCY"; break; + case RXKADPACKETSHORT : s = "RXKADPACKETSHORT "; break; + case RXKADLEVELFAIL : s = "RXKADLEVELFAIL "; break; + case RXKADTICKETLEN : s = "RXKADTICKETLEN "; break; + case RXKADOUTOFSEQUENCE: s = "RXKADOUTOFSEQUENCE"; break; + case RXKADNOAUTH : s = "RXKADNOAUTH "; break; + case RXKADBADKEY : s = "RXKADBADKEY "; break; + case RXKADBADTICKET : s = "RXKADBADTICKET "; break; + case RXKADUNKNOWNKEY : s = "RXKADUNKNOWNKEY "; break; + case RXKADEXPIRED : s = "RXKADEXPIRED "; break; + case RXKADSEALEDINCON : s = "RXKADSEALEDINCON "; break; + case RXKADDATALEN : s = "RXKADDATALEN "; break; + case RXKADILLEGALLEVEL : s = "RXKADILLEGALLEVEL "; break; + } + osi_Log2(afsd_logp, "cm_Analyze: ignoring error code 0x%x (%s)", + errorCode, s); + } } if (retry && dead_session) diff --git a/src/WINNT/afsd/cm_dnlc.c b/src/WINNT/afsd/cm_dnlc.c index eced524e51..47bbd75861 100644 --- a/src/WINNT/afsd/cm_dnlc.c +++ b/src/WINNT/afsd/cm_dnlc.c @@ -54,6 +54,7 @@ static int cm_debugDnlc = 0; /* debug dnlc */ #define dnlcNotify(x,debug) #endif /* !DJGPP */ +/* Must be called with cm_dnlcLock write locked */ static cm_nc_t * GetMeAnEntry() { @@ -332,8 +333,8 @@ RemoveEntry (tnc, key) tnc->next->prev = tnc->prev; } - tnc->prev = (cm_nc_t *) 0; /* everything not in hash table has 0 prev */ - tnc->key = 0; /* just for safety's sake */ + memset(tnc, 0, sizeof(cm_nc_t)); + tnc->magic = CM_DNLC_MAGIC; return 0; /* success */ } @@ -368,7 +369,6 @@ cm_dnlcRemove ( adp, aname) if ( (tnc->dirp == adp) && (tnc->key == key) && !strcmp(tnc->name,aname) ) { - tnc->dirp = (cm_scache_t *) 0; /* now it won't match anything */ tmp = tnc->next; error = RemoveEntry(tnc, skey); if ( error ) @@ -376,7 +376,7 @@ cm_dnlcRemove ( adp, aname) tnc->next = cm_data.ncfreelist; /* insert entry into freelist */ cm_data.ncfreelist = tnc; - found = 1; /* found atleast one entry */ + found = 1; /* found at least one entry */ tnc = tmp; /* continue down the linked list */ } @@ -426,13 +426,16 @@ cm_dnlcPurgedp (adp) { if (cm_data.nameCache[i].dirp == adp ) { - cm_data.nameCache[i].dirp = cm_data.nameCache[i].vp = (cm_scache_t *) 0; - if (cm_data.nameCache[i].prev && !err) - { - err = RemoveEntry(&cm_data.nameCache[i], cm_data.nameCache[i].key & (NHSIZE-1)); - cm_data.nameCache[i].next = cm_data.ncfreelist; - cm_data.ncfreelist = &cm_data.nameCache[i]; - } + if (cm_data.nameCache[i].prev) { + err = RemoveEntry(&cm_data.nameCache[i], cm_data.nameCache[i].key & (NHSIZE-1)); + if (!err) + { + cm_data.nameCache[i].next = cm_data.ncfreelist; + cm_data.ncfreelist = &cm_data.nameCache[i]; + } + } else { + cm_data.nameCache[i].dirp = cm_data.nameCache[i].vp = (cm_scache_t *) 0; + } } } lock_ReleaseWrite(&cm_dnlcLock); @@ -461,15 +464,16 @@ cm_dnlcPurgevp ( avc ) { if (cm_data.nameCache[i].vp == avc) { - cm_data.nameCache[i].dirp = cm_data.nameCache[i].vp = (cm_scache_t *) 0; - /* can't simply break; because of hard links -- might be two */ - /* different entries with same vnode */ - if (!err && cm_data.nameCache[i].prev) - { - err=RemoveEntry(&cm_data.nameCache[i], cm_data.nameCache[i].key & (NHSIZE-1)); - cm_data.nameCache[i].next = cm_data.ncfreelist; - cm_data.ncfreelist = &cm_data.nameCache[i]; - } + if (cm_data.nameCache[i].prev) { + err = RemoveEntry(&cm_data.nameCache[i], cm_data.nameCache[i].key & (NHSIZE-1)); + if (!err) + { + cm_data.nameCache[i].next = cm_data.ncfreelist; + cm_data.ncfreelist = &cm_data.nameCache[i]; + } + } else { + cm_data.nameCache[i].dirp = cm_data.nameCache[i].vp = (cm_scache_t *) 0; + } } } lock_ReleaseWrite(&cm_dnlcLock); @@ -494,10 +498,11 @@ void cm_dnlcPurge(void) cm_data.ncfreelist = (cm_nc_t *) 0; memset (cm_data.nameCache, 0, sizeof(cm_nc_t) * NCSIZE); memset (cm_data.nameHash, 0, sizeof(cm_nc_t *) * NHSIZE); - for (i=0; imagic != CM_DNLC_MAGIC) { afsi_log("cm_dnlcValidate failure: cm_data.nameCache[%d].next->magic != CM_DNLC_MAGIC", i); fprintf(stderr, "cm_dnlcValidate failure: cm_data.nameCache[%d].next->magic != CM_DNLC_MAGIC\n", i); - return -2; + goto purge; } if (cm_data.nameCache[i].prev && cm_data.nameCache[i].prev->magic != CM_DNLC_MAGIC) { afsi_log("cm_dnlcValidate failure: cm_data.nameCache[%d].prev->magic != CM_DNLC_MAGIC", i); fprintf(stderr, "cm_dnlcValidate failure: cm_data.nameCache[%d].prev->magic != CM_DNLC_MAGIC\n", i); - return -3; + goto purge; } if (cm_data.nameCache[i].dirp && cm_data.nameCache[i].dirp->magic != CM_SCACHE_MAGIC) { afsi_log("cm_dnlcValidate failure: cm_data.nameCache[%d].dirp->magic != CM_SCACHE_MAGIC", i); fprintf(stderr, "cm_dnlcValidate failure: cm_data.nameCache[%d].dirp->magic != CM_SCACHE_MAGIC\n", i); - return -4; + goto purge; } if (cm_data.nameCache[i].vp && cm_data.nameCache[i].vp->magic != CM_SCACHE_MAGIC) { afsi_log("cm_dnlcValidate failure: cm_data.nameCache[%d].vp->magic != CM_SCACHE_MAGIC", i); fprintf(stderr, "cm_dnlcValidate failure: cm_data.nameCache[%d].vp->magic != CM_SCACHE_MAGIC\n", i); - return -5; + goto purge; } } @@ -563,54 +569,82 @@ cm_dnlcValidate(void) if (ncp->magic != CM_DNLC_MAGIC) { afsi_log("cm_dnlcValidate failure: ncp->magic != CM_DNLC_MAGIC"); fprintf(stderr, "cm_dnlcValidate failure: ncp->magic != CM_DNLC_MAGIC\n"); - return -6; + goto purge; } if (ncp->prev && ncp->prev->magic != CM_DNLC_MAGIC) { afsi_log("cm_dnlcValidate failure: ncp->prev->magic != CM_DNLC_MAGIC"); fprintf(stderr, "cm_dnlcValidate failure: ncp->prev->magic != CM_DNLC_MAGIC\n"); - return -7; + goto purge; } if (ncp->dirp && ncp->dirp->magic != CM_SCACHE_MAGIC) { afsi_log("cm_dnlcValidate failure: ncp->dirp->magic != CM_DNLC_MAGIC"); fprintf(stderr, "cm_dnlcValidate failure: ncp->dirp->magic != CM_DNLC_MAGIC\n"); - return -8; + goto purge; } if (ncp->vp && ncp->vp->magic != CM_SCACHE_MAGIC) { afsi_log("cm_dnlcValidate failure: ncp->vp->magic != CM_DNLC_MAGIC"); fprintf(stderr, "cm_dnlcValidate failure: ncp->vp->magic != CM_DNLC_MAGIC\n"); - return -9; + goto purge; } } } // is the freelist stable? if ( cm_data.ncfreelist ) { - for (ncp = cm_data.ncfreelist; ncp; - ncp = ncp->next != cm_data.ncfreelist ? ncp->next : NULL) { + for (ncp = cm_data.ncfreelist, i = 0; ncp && i < NCSIZE; + ncp = ncp->next != cm_data.ncfreelist ? ncp->next : NULL, i++) { if (ncp->magic != CM_DNLC_MAGIC) { afsi_log("cm_dnlcValidate failure: ncp->magic != CM_DNLC_MAGIC"); fprintf(stderr, "cm_dnlcValidate failure: ncp->magic != CM_DNLC_MAGIC\n"); - return -10; + goto purge; } - if (ncp->prev && ncp->prev->magic != CM_DNLC_MAGIC) { - afsi_log("cm_dnlcValidate failure: ncp->prev->magic != CM_DNLC_MAGIC"); - fprintf(stderr, "cm_dnlcValidate failure: ncp->prev->magic != CM_DNLC_MAGIC\n"); - return -11; + if (ncp->prev) { + afsi_log("cm_dnlcValidate failure: ncp->prev != NULL"); + fprintf(stderr, "cm_dnlcValidate failure: ncp->prev != NULL\n"); + goto purge; } - if (ncp->dirp && ncp->dirp->magic != CM_SCACHE_MAGIC) { - afsi_log("cm_dnlcValidate failure: ncp->dirp->magic != CM_DNLC_MAGIC"); - fprintf(stderr, "cm_dnlcValidate failure: ncp->dirp->magic != CM_DNLC_MAGIC\n"); - return -12; + if (ncp->key) { + afsi_log("cm_dnlcValidate failure: ncp->key != 0"); + fprintf(stderr, "cm_dnlcValidate failure: ncp->key != 0\n"); + goto purge; } - if (ncp->vp && ncp->vp->magic != CM_SCACHE_MAGIC) { - afsi_log("cm_dnlcValidate failure: ncp->vp->magic != CM_DNLC_MAGIC"); - fprintf(stderr, "cm_dnlcValidate failure: ncp->vp->magic != CM_DNLC_MAGIC\n"); - return -13; + if (ncp->dirp) { + afsi_log("cm_dnlcValidate failure: ncp->dirp != NULL"); + fprintf(stderr, "cm_dnlcValidate failure: ncp->dirp != NULL\n"); + goto purge; + } + if (ncp->vp) { + afsi_log("cm_dnlcValidate failure: ncp->vp != NULL"); + fprintf(stderr, "cm_dnlcValidate failure: ncp->vp != NULL\n"); + goto purge; } } - } + if ( i == NCSIZE && ncp ) { + afsi_log("cm_dnlcValidate failure: dnlc freeList corrupted"); + fprintf(stderr, "cm_dnlcValidate failure: dnlc freeList corrupted\n"); + goto purge; + } + } return 0; + + purge: + if ( purged ) + return -1; + + afsi_log("cm_dnlcValidate information: purging"); + fprintf(stderr, "cm_dnlcValidate information: purging\n"); + cm_data.ncfreelist = (cm_nc_t *) 0; + memset (cm_data.nameCache, 0, sizeof(cm_nc_t) * NCSIZE); + memset (cm_data.nameHash, 0, sizeof(cm_nc_t *) * NHSIZE); + for (i=0; iparms[0].items && asp->parms[1].items)) { fprintf(stderr, "%s trace: must use at most one of '-begin' or '-end'\n", pn); return EINVAL; } - + /* determine if we're turning this tracing on or off */ - inValue = 0; if (asp->parms[0].items) inValue = 1; /* begin */ - else if (asp->parms[1].items) + else if (asp->parms[1].items) inValue = 0; /* end */ - + + blob.in_size = sizeof(long); blob.in = (char *) &inValue; blob.out_size = sizeof(long); @@ -3645,10 +3651,55 @@ MemDumpCmd(struct cmd_syndesc *asp, char *arock) return code; } - if (outValue) printf("AFS memdump begin.\n"); - else printf("AFS memdump end.\n"); + if (outValue) { + printf("AFS memdump created.\n"); + return 0; + } else { + printf("AFS memdump failed.\n"); + return -1; + } +} - return 0; +static int +MiniDumpCmd(struct cmd_syndesc *asp, char *arock) +{ + long code; + BOOL success = 0; + SERVICE_STATUS status; + SC_HANDLE hManager = NULL; + SC_HANDLE hService = NULL; + + if ( !IsAdmin() ) { + fprintf (stderr,"Permission denied: requires AFS Client Administrator access.\n"); + return EACCES; + } + + hManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); + if (!hManager) + goto failure; + + hService = OpenService(hManager, "TransarcAFSDaemon", SERVICE_USER_DEFINED_CONTROL); + if (!hService) + goto failure; + + success = ControlService(hService, SERVICE_CONTROL_CUSTOM_DUMP, &status); + + if (success) { + CloseServiceHandle(hService); + CloseServiceHandle(hManager); + + printf("AFS minidump generated.\n"); + return 0; + } + + failure: + if (hService) + CloseServiceHandle(hService); + if (hManager) + CloseServiceHandle(hManager); + + printf("AFS minidump failed.\n"); + return -1; } static int @@ -3658,6 +3709,11 @@ CSCPolicyCmd(struct cmd_syndesc *asp, char *arock) char *share = NULL; HKEY hkCSCPolicy; + if ( !IsAdmin() ) { + fprintf (stderr,"Permission denied: requires AFS Client Administrator access.\n"); + return EACCES; + } + for(ti=asp->parms[0].items; ti;ti=ti->next) { share = ti->data; if (share) @@ -4352,6 +4408,8 @@ main(int argc, char **argv) cmd_AddParm(ts, "-documents", CMD_FLAG, CMD_OPTIONAL, "automatic caching of documents"); cmd_AddParm(ts, "-disable", CMD_FLAG, CMD_OPTIONAL, "disable caching"); + ts = cmd_CreateSyntax("minidump", MiniDumpCmd, 0, "Generate MiniDump of current service state"); + code = cmd_Dispatch(argc, argv); #ifndef WIN32 diff --git a/src/WINNT/afsd/smb.c b/src/WINNT/afsd/smb.c index 3382b52a4e..27703fab55 100644 --- a/src/WINNT/afsd/smb.c +++ b/src/WINNT/afsd/smb.c @@ -1546,7 +1546,7 @@ int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName, /* Get the full name for this cell */ code = cm_SearchCellFile(p, temp, 0, 0); #ifdef AFS_AFSDB_ENV - if (code && cm_dnsEnabled) { + if (code && cm_dnsEnabled) { int ttl; code = cm_SearchCellByDNS(p, temp, &ttl, 0, 0); } @@ -1680,7 +1680,8 @@ void smb_ReleaseDirSearchNoLock(smb_dirSearch_t *dsp) lock_ReleaseMutex(&dsp->mx); } /* do this now to avoid spurious locking hierarchy creation */ - if (scp) cm_ReleaseSCache(scp); + if (scp) + cm_ReleaseSCache(scp); } void smb_ReleaseDirSearch(smb_dirSearch_t *dsp) @@ -4780,7 +4781,7 @@ smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp, i else code = CM_ERROR_EXISTS; cm_ReleaseSCache(tmpscp2); - tmpscp2 = NULL; + tmpscp2 = NULL; } else { code = CM_ERROR_NOSUCHFILE; } diff --git a/src/WINNT/afsd/smb3.c b/src/WINNT/afsd/smb3.c index cbdf54fe49..033012b772 100644 --- a/src/WINNT/afsd/smb3.c +++ b/src/WINNT/afsd/smb3.c @@ -5472,8 +5472,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) if (!smb_IsLegalFilename(lastNamep)) { if (scp) cm_ReleaseSCache(scp); - if (dscp) - cm_ReleaseSCache(dscp); + if (dscp) + cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); free(realPathp); return CM_ERROR_BADNTFILENAME; @@ -5492,7 +5492,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) userp, &req, &scp); } if (code && code != CM_ERROR_NOSUCHFILE) { - cm_ReleaseSCache(dscp); + if (dscp) + cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); free(realPathp); return code; @@ -5515,7 +5516,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) /* oops, file shouldn't be there */ if (dscp) cm_ReleaseSCache(dscp); - cm_ReleaseSCache(scp); + if (scp) + cm_ReleaseSCache(scp); cm_ReleaseUser(userp); free(realPathp); return CM_ERROR_EXISTS; @@ -5553,7 +5555,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) if (code) { if (dscp) cm_ReleaseSCache(dscp); - cm_ReleaseSCache(scp); + if (scp) + cm_ReleaseSCache(scp); cm_ReleaseUser(userp); free(realPathp); return code; @@ -5562,8 +5565,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) /* don't create if not found */ if (dscp) cm_ReleaseSCache(dscp); - if (scp) - cm_ReleaseSCache(scp); + if (scp) + cm_ReleaseSCache(scp); cm_ReleaseUser(userp); free(realPathp); return CM_ERROR_NOSUCHFILE; @@ -5736,7 +5739,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) /* (only applies to single component case) */ if (realDirFlag == 1 && scp->fileType == CM_SCACHETYPE_FILE) { cm_ReleaseSCache(scp); - cm_ReleaseSCache(dscp); + if (dscp) + cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); free(realPathp); return CM_ERROR_NOTDIR; @@ -6111,7 +6115,8 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp, &req); if (code) { - if (dscp) cm_ReleaseSCache(dscp); + if (dscp) + cm_ReleaseSCache(dscp); cm_ReleaseSCache(scp); cm_ReleaseUser(userp); free(realPathp); @@ -6120,7 +6125,8 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out if (createDisp == FILE_CREATE) { /* oops, file shouldn't be there */ - if (dscp) cm_ReleaseSCache(dscp); + if (dscp) + cm_ReleaseSCache(dscp); cm_ReleaseSCache(scp); cm_ReleaseUser(userp); free(realPathp); @@ -6156,7 +6162,8 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out } else if (createDisp == FILE_OPEN || createDisp == FILE_OVERWRITE) { /* don't create if not found */ - if (dscp) cm_ReleaseSCache(dscp); + if (dscp) + cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); free(realPathp); return CM_ERROR_NOSUCHFILE; @@ -6238,7 +6245,8 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out if (code) { /* something went wrong creating or truncating the file */ - if (scp) cm_ReleaseSCache(scp); + if (scp) + cm_ReleaseSCache(scp); cm_ReleaseUser(userp); free(realPathp); return code; @@ -6297,7 +6305,8 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out fidp->NTopen_wholepathp = realPathp; /* we don't need this any longer */ - if (dscp) cm_ReleaseSCache(dscp); + if (dscp) + cm_ReleaseSCache(dscp); cm_Open(scp, 0, userp); diff --git a/src/WINNT/afssvrmgr/creds.cpp b/src/WINNT/afssvrmgr/creds.cpp index 0ad004e5f3..b7cc625d70 100644 --- a/src/WINNT/afssvrmgr/creds.cpp +++ b/src/WINNT/afssvrmgr/creds.cpp @@ -18,6 +18,7 @@ extern "C" { #include "time.h" #include "subset.h" +#include /* * OPENCELL DIALOG ____________________________________________________________ @@ -91,28 +92,53 @@ void OpenCellDlg_Hook_OnOK (HWND hDlg, LPOPENCELLDLG_PARAMS lpp) TCHAR szPassword[ cchRESOURCE ]; GetDlgItemText (hDlg, IDC_OPENCELL_PASSWORD, szPassword, cchNAME); - ULONG status; - if ((lpp->hCreds = AfsAppLib_SetCredentials (lpp->szCell, szUser, szPassword, &status)) == NULL) - { - ErrorDialog (status, IDS_SVR_ERROR_BAD_CREDENTIALS); - } - else - { - // See if those credentials are sufficient - // - CHECKCREDS_PARAMS pp; - memset (&pp, 0x00, sizeof(pp)); - memcpy (&pp.bcdp, &lpp->bcdp, sizeof(BADCREDSDLG_PARAMS)); - pp.bcdp.hParent = hDlg; - pp.hCreds = lpp->hCreds; - pp.fShowWarning = TRUE; + ULONG status; - if ((rc = AfsAppLib_CheckCredentials (&pp)) == FALSE) - { - SetDlgItemText (hDlg, IDC_OPENCELL_ID, TEXT("admin")); - PostMessage (hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg,IDC_OPENCELL_PASSWORD), TRUE); - } - } + if ( KFW_is_available() ) { + // KFW_AFS_get_cred() parses the szNameA field as complete + // princial including potentially + // a different realm then the specified cell name. + char *Result = NULL; + + char szCellA[ 256 ]; + CopyStringToAnsi (szCellA, lpp->szCell); + + char szUserA[ 256 ]; + CopyStringToAnsi (szUserA, szUser); + + char szPasswordA[ 256 ]; + CopyStringToAnsi (szPasswordA, szPassword); + + rc = !KFW_AFS_get_cred(szUserA, szCellA, szPasswordA, 0, NULL, &Result); + if (rc) { + if ((lpp->hCreds = AfsAppLib_GetCredentials (lpp->szCell, &status)) == NULL) { + ErrorDialog (status, IDS_SVR_ERROR_BAD_CREDENTIALS); + } + } + } else { + if ((lpp->hCreds = AfsAppLib_SetCredentials (lpp->szCell, szUser, szPassword, &status)) == NULL) + { + ErrorDialog (status, IDS_SVR_ERROR_BAD_CREDENTIALS); + } + else + { + // See if those credentials are sufficient + // + CHECKCREDS_PARAMS pp; + memset (&pp, 0x00, sizeof(pp)); + memcpy (&pp.bcdp, &lpp->bcdp, sizeof(BADCREDSDLG_PARAMS)); + pp.bcdp.hParent = hDlg; + pp.hCreds = lpp->hCreds; + pp.fShowWarning = TRUE; + + if ((rc = AfsAppLib_CheckCredentials (&pp)) == FALSE) + { + SetDlgItemText (hDlg, IDC_OPENCELL_ID, TEXT("admin")); + PostMessage (hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg,IDC_OPENCELL_PASSWORD), TRUE); + } + } + + } if (rc) { diff --git a/src/config/NTMakefile.amd64_w2k b/src/config/NTMakefile.amd64_w2k index f89ed845e6..9fd4fc1a92 100644 --- a/src/config/NTMakefile.amd64_w2k +++ b/src/config/NTMakefile.amd64_w2k @@ -80,7 +80,7 @@ LIB = $(AFSDEV_LIB) #define used in WinNT/2000 installation and program version display AFSPRODUCT_VER_MAJOR=1 AFSPRODUCT_VER_MINOR=3 -AFSPRODUCT_VER_PATCH=8201 +AFSPRODUCT_VER_PATCH=8300 AFSPRODUCT_VER_BUILD=0 # For MSI installer, each major release should have a different GUID diff --git a/src/config/NTMakefile.i386_nt40 b/src/config/NTMakefile.i386_nt40 index 9f59def953..692072f8a8 100644 --- a/src/config/NTMakefile.i386_nt40 +++ b/src/config/NTMakefile.i386_nt40 @@ -80,7 +80,7 @@ LIB = $(AFSDEV_LIB) #define used in WinNT/2000 installation and program version display AFSPRODUCT_VER_MAJOR=1 AFSPRODUCT_VER_MINOR=3 -AFSPRODUCT_VER_PATCH=8201 +AFSPRODUCT_VER_PATCH=8300 AFSPRODUCT_VER_BUILD=0 # For MSI installer, each major release should have a different GUID diff --git a/src/config/NTMakefile.i386_w2k b/src/config/NTMakefile.i386_w2k index 9f59def953..692072f8a8 100644 --- a/src/config/NTMakefile.i386_w2k +++ b/src/config/NTMakefile.i386_w2k @@ -80,7 +80,7 @@ LIB = $(AFSDEV_LIB) #define used in WinNT/2000 installation and program version display AFSPRODUCT_VER_MAJOR=1 AFSPRODUCT_VER_MINOR=3 -AFSPRODUCT_VER_PATCH=8201 +AFSPRODUCT_VER_PATCH=8300 AFSPRODUCT_VER_BUILD=0 # For MSI installer, each major release should have a different GUID