Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

400 lines
11 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. init.c
  5. Abstract:
  6. Dll initialization for sspi digest package.
  7. Author:
  8. Adriaan Canter (adriaanc) 01-Aug-1998
  9. --*/
  10. #include "include.hxx"
  11. #include "digestui.hxx"
  12. #include "resource.h"
  13. //
  14. // Downlevel delay load support (we forward to shlwapi)
  15. //
  16. #include <delayimp.h>
  17. PfnDliHook __pfnDliFailureHook;
  18. // Serializes access to all globals in module
  19. CRITICAL_SECTION DllCritSect;
  20. // Per process credential cache.
  21. CCredCache *g_pCache = NULL;
  22. // Per process cache init flag
  23. BOOL g_fCredCacheInit = FALSE;
  24. // Global module handle.
  25. HMODULE g_hModule = NULL;
  26. // Global handle to shlwapi.
  27. HMODULE g_hShlwapi = NULL;
  28. // Status of cred persist services on machine.
  29. DWORD g_dwCredPersistAvail = CRED_PERSIST_UNKNOWN;
  30. DWORD_PTR g_pHeap = NULL;
  31. //--------------------------------------------------------------------
  32. // DigestServicesExist
  33. //--------------------------------------------------------------------
  34. BOOL DigestServicesExist()
  35. {
  36. INIT_SECURITY_INTERFACE addrProcISI = NULL;
  37. PSecurityFunctionTable pFuncTbl = NULL;
  38. PSecPkgInfoA pSecPkgInfo;
  39. SECURITY_STATUS ssResult;
  40. DWORD cPackages;
  41. OSVERSIONINFO VerInfo;
  42. CHAR szDLL[MAX_PATH];
  43. HINSTANCE hSecLib;
  44. BOOL fDigest = FALSE;
  45. // Get the OS version.
  46. VerInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
  47. GetVersionEx (&VerInfo);
  48. // Load the appropriate dll.
  49. if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
  50. lstrcpy (szDLL, SSP_SPM_NT_DLL);
  51. else if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
  52. lstrcpy (szDLL, SSP_SPM_WIN95_DLL);
  53. else
  54. goto exit;
  55. hSecLib = LoadLibrary (szDLL);
  56. if (!hSecLib)
  57. goto exit;
  58. // Get the dispatch table.
  59. addrProcISI = (INIT_SECURITY_INTERFACE) GetProcAddress( hSecLib,
  60. SECURITY_ENTRYPOINT_ANSI);
  61. pFuncTbl = (*addrProcISI)();
  62. if (!pFuncTbl)
  63. goto exit;
  64. // Enumerate security pkgs and determine if digest is installed.
  65. ssResult = (*(pFuncTbl->EnumerateSecurityPackagesA))(&cPackages, &pSecPkgInfo);
  66. if (ssResult == SEC_E_OK)
  67. {
  68. for (DWORD i = 0; i < cPackages; i++)
  69. {
  70. if (lstrcmpi(pSecPkgInfo[i].Name, "Digest") == 0)
  71. {
  72. fDigest = TRUE;
  73. break;
  74. }
  75. }
  76. }
  77. exit:
  78. return fDigest;
  79. }
  80. //--------------------------------------------------------------------
  81. // DLLInstall
  82. //--------------------------------------------------------------------
  83. STDAPI
  84. DllInstall
  85. (
  86. IN BOOL bInstall, // Install or Uninstall
  87. IN LPCWSTR pwStr
  88. )
  89. {
  90. HKEY hKey;
  91. DWORD dwError, dwRegDisp, cbSP = MAX_PATH;
  92. CHAR *ptr, *ptrNext, szSP[MAX_PATH];
  93. BOOL bHKLM = FALSE;
  94. // Determine if full install (provide client digest sspi svcs)
  95. // or just passport install (server pkg delegating to client)
  96. if (!pwStr || !*pwStr || (!wcscmp(pwStr, L"HKLM")))
  97. {
  98. bHKLM = TRUE;
  99. }
  100. // Add "digest.dll" to comma delimited Service Providers list in
  101. // HKLM\System\CurrentControlSet\Control\SecurityProviders only if
  102. // no digest security providers currently exist.
  103. if (bInstall && bHKLM && !DigestServicesExist())
  104. {
  105. // Open or create SecurityProviders key.
  106. dwError = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  107. SECURITY_PROVIDERS_REG_KEY, 0, NULL,
  108. 0, KEY_READ | KEY_WRITE, NULL, &hKey, &dwRegDisp);
  109. // Successfully opened/created key.
  110. if (dwError == ERROR_SUCCESS)
  111. {
  112. cbSP = MAX_PATH;
  113. dwError = RegQueryValueEx(hKey, SECURITY_PROVIDERS_SZ,
  114. NULL, NULL, (LPBYTE) szSP, &cbSP);
  115. // SecurityProviders value might not be
  116. // found which is ok since we will create it.
  117. if (dwError == ERROR_SUCCESS || dwError == ERROR_FILE_NOT_FOUND)
  118. {
  119. // Value not found same as value existed but no string.
  120. if (dwError == ERROR_FILE_NOT_FOUND)
  121. {
  122. ptr = NULL;
  123. cbSP = 0;
  124. }
  125. // Otherwise if value found -> check if "digest.dll" exists.
  126. else
  127. {
  128. // We can use the handy FindToken from the CParams object
  129. // to determine if a token occurs in a comma delmited list.
  130. if (!CParams::FindToken(szSP, cbSP, "digest.dll",
  131. sizeof("digest.dll") - 1, &ptr))
  132. {
  133. ptr = NULL;
  134. }
  135. }
  136. // Only add "digest.dll" if doesn't already exist.
  137. if (!ptr)
  138. {
  139. // If we found value/data append "digest.dll"
  140. if (cbSP > 1)
  141. strcat(szSP, ", digest.dll");
  142. // Otherwise "digest.dll" is only data
  143. else
  144. memcpy(szSP, "digest.dll", sizeof("digest.dll"));
  145. // Write the value back.
  146. dwError = RegSetValueEx(hKey, SECURITY_PROVIDERS_SZ, 0,
  147. REG_SZ, (LPBYTE) szSP, strlen(szSP));
  148. }
  149. }
  150. // Close SecurityProviders reg key.
  151. RegCloseKey(hKey);
  152. }
  153. }
  154. // Remove "digest.dll" from the comma delimited Service Providers list in
  155. // HKLM\System\CurrentControlSet\Control\SecurityProviders
  156. if (!bInstall && bHKLM)
  157. {
  158. // Open the Security Providers reg key.
  159. dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  160. SECURITY_PROVIDERS_REG_KEY, NULL, KEY_READ | KEY_WRITE, &hKey);
  161. if (dwError == ERROR_SUCCESS)
  162. {
  163. // Get the SecurityProviders value data string.
  164. dwError = RegQueryValueEx(hKey, SECURITY_PROVIDERS_SZ,
  165. NULL, NULL, (LPBYTE) szSP, &cbSP);
  166. if (dwError == ERROR_SUCCESS)
  167. {
  168. // Only remove "digest.dll" if exists.
  169. if (!CParams::FindToken(szSP, cbSP, "digest.dll",
  170. sizeof("digest.dll") - 1, &ptr))
  171. {
  172. ptr = NULL;
  173. }
  174. if (ptr)
  175. {
  176. // Point to next item in list, might be '\0'
  177. ptrNext = ptr + sizeof("digest.dll") - 1;
  178. // Digest.dll is only entry.
  179. if ((ptr == szSP) && cbSP == sizeof("digest.dll"))
  180. {
  181. *szSP = '\0';
  182. }
  183. // "digest.dll" is last entry.
  184. else if (*ptrNext == '\0')
  185. {
  186. *(ptr - (sizeof (", ") - 1)) = '\0';
  187. }
  188. else if (*ptrNext == ',' && *(ptrNext+1) == ' ')
  189. {
  190. ptrNext+=2;
  191. memcpy(ptr, ptrNext, (size_t)(cbSP - (ptrNext - szSP)));
  192. }
  193. dwError = RegSetValueEx(hKey, SECURITY_PROVIDERS_SZ, 0,
  194. REG_SZ, (LPBYTE) szSP, *szSP ? strlen(szSP) : 1);
  195. }
  196. }
  197. RegCloseKey(hKey);
  198. }
  199. }
  200. return S_OK;
  201. }
  202. //--------------------------------------------------------------------
  203. // MakeFullAccessSA
  204. //--------------------------------------------------------------------
  205. //Commenting this function as it doesn't seem to be used anywhere in the sources
  206. /*
  207. SECURITY_ATTRIBUTES *MakeFullAccessSA (void)
  208. {
  209. static SECURITY_ATTRIBUTES sa;
  210. static BYTE SDBuf[SECURITY_DESCRIPTOR_MIN_LENGTH];
  211. // Don't bother on Win95/Win98 which don't support security.
  212. OSVERSIONINFO versionInfo;
  213. versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
  214. if (!GetVersionEx(&versionInfo)
  215. || (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS))
  216. return NULL;
  217. // Create a security descriptor with ACE to allow full access to all.
  218. SECURITY_DESCRIPTOR* pSD = (SECURITY_DESCRIPTOR*) SDBuf;
  219. if (!InitializeSecurityDescriptor (pSD, SECURITY_DESCRIPTOR_REVISION))
  220. return NULL;
  221. if (!SetSecurityDescriptorDacl (pSD, TRUE, NULL, FALSE))
  222. return NULL;
  223. // Initialize the security attributes.
  224. sa.nLength = sizeof(sa);
  225. sa.lpSecurityDescriptor = pSD;
  226. sa.bInheritHandle = TRUE;
  227. return &sa;
  228. }*/
  229. //--------------------------------------------------------------------
  230. // NewString
  231. //--------------------------------------------------------------------
  232. LPSTR NewString(LPSTR szString)
  233. {
  234. if (!szString)
  235. return NULL;
  236. DWORD cbString = strlen(szString);
  237. LPSTR szNew = new CHAR[cbString+1];
  238. if (!szNew)
  239. {
  240. DIGEST_ASSERT(FALSE);
  241. return NULL;
  242. }
  243. memcpy(szNew, szString, cbString+1);
  244. return szNew;
  245. }
  246. //--------------------------------------------------------------------
  247. // InitGlobals
  248. //--------------------------------------------------------------------
  249. BOOL InitGlobals()
  250. {
  251. // Return success if we've already
  252. // initialized.
  253. if (g_fCredCacheInit)
  254. return TRUE;
  255. // Serialize per-process calls.
  256. LOCK_GLOBALS();
  257. // Recheck global flag in the case
  258. // the cache was initialized while
  259. // this thread was descheduled.
  260. if (g_fCredCacheInit)
  261. {
  262. goto exit;
  263. }
  264. // Global cred persist status.
  265. g_dwCredPersistAvail = CRED_PERSIST_UNKNOWN;
  266. // Create the credential cache.
  267. g_pCache = new CCredCache();
  268. if (!g_pCache || g_pCache->GetStatus() != ERROR_SUCCESS)
  269. {
  270. g_fCredCacheInit = FALSE;
  271. goto exit;
  272. }
  273. g_fCredCacheInit = TRUE;
  274. exit:
  275. UNLOCK_GLOBALS();
  276. return g_fCredCacheInit;
  277. }
  278. void SetupDelayloadErrorHandler()
  279. {
  280. __pfnDliFailureHook = (PfnDliHook)GetProcAddress(GetModuleHandleA("shlwapi.dll"), "DelayLoadFailureHook");
  281. }
  282. //--------------------------------------------------------------------
  283. // DllMain
  284. //--------------------------------------------------------------------
  285. #if defined(__cplusplus)
  286. extern "C"
  287. #endif
  288. BOOL
  289. WINAPI
  290. DllMain(
  291. IN PVOID DllHandle,
  292. IN ULONG Reason,
  293. IN PCONTEXT Context OPTIONAL
  294. )
  295. {
  296. UNREFERENCED_PARAMETER(Context);
  297. UNREFERENCED_PARAMETER(DllHandle );
  298. switch (Reason)
  299. {
  300. // Process attach.
  301. case DLL_PROCESS_ATTACH:
  302. {
  303. // BUGBUG - DislableThreadLibraryCalls and
  304. // don't do any work.
  305. g_hModule = (HMODULE) DllHandle;
  306. InitializeCriticalSection( &DllCritSect );
  307. SetupDelayloadErrorHandler();
  308. if ((hDigest = CreateMutex (NULL,
  309. FALSE,
  310. NULL)) == NULL)
  311. return FALSE;
  312. break;
  313. }
  314. // Process detatch.
  315. // Deinitialize the credential cache.
  316. // Delete the critical section.
  317. case DLL_PROCESS_DETACH:
  318. {
  319. if (g_pCache)
  320. delete g_pCache;
  321. DeleteCriticalSection( &DllCritSect );
  322. CloseHandle (hDigest);
  323. break;
  324. }
  325. }
  326. return TRUE;
  327. }
  328.