Source code of Windows XP (NT5)
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.

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