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.

8434 lines
233 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: setuput.cpp
  8. //
  9. // Contents: Utility functions for OCM based setup.
  10. //
  11. // History: 04/20/97 JerryK Created
  12. //
  13. //-------------------------------------------------------------------------
  14. #include "pch.cpp"
  15. #pragma hdrstop
  16. // ** C Runtime Includes
  17. #include <sys/types.h>
  18. #include <sys/stat.h>
  19. // ** System Includes **
  20. #include <lmaccess.h>
  21. #include <lmapibuf.h>
  22. #include "csdisp.h"
  23. #include <shlobj.h>
  24. #include <userenv.h>
  25. #include <dsgetdc.h>
  26. #include <sddl.h>
  27. #include <winldap.h>
  28. #include <autoenr.h>
  29. #include <userenvp.h> // CreateLinkFile API
  30. // ** security includes **
  31. #include <aclapi.h>
  32. // ** Application Includes **
  33. #include "initcert.h"
  34. #include "cscsp.h"
  35. #include "cspenum.h"
  36. #include "csldap.h"
  37. #include "wizpage.h"
  38. #include "websetup.h"
  39. #include "certsrvd.h"
  40. #include "regd.h"
  41. #include "usecert.h"
  42. #include "certmsg.h"
  43. #include "dssetup.h"
  44. #include "progress.h"
  45. #include <certca.h>
  46. #include "cainfop.h"
  47. #include "csprop.h"
  48. #include "setupids.h"
  49. #include "multisz.h"
  50. #define __dwFILE__ __dwFILE_OCMSETUP_SETUPUT_CPP__
  51. EXTERN_C const IID IID_IGPEInformation;
  52. EXTERN_C const CLSID CLSID_GPESnapIn;
  53. #define CERT_HALF_SECOND 500 // # of milliseconds in half second
  54. #define CERT_MAX_ATTEMPT 2 * 60 * 2 // # of half seconds in 2 minutes
  55. #define wszREQUESTVERINDPROGID L"CertSrv.Request"
  56. #define wszREQUESTPROGID L"CertSrv.Request.1"
  57. #define wszADMINVERINDPROGID L"CertSrv.Admin"
  58. #define wszADMINPROGID L"CertSrv.Admin.1"
  59. #define wszREQUESTFRIENDLYNAME L"CertSrv Request"
  60. #define wszADMINFRIENDLYNAME L"CertSrv Admin"
  61. #define wszCERTSRV L"CertSrv"
  62. #define wszREGW3SCRIPTMAP L"System\\CurrentControlSet\\Services\\W3SVC\\Parameters\\Script Map"
  63. #define wszHTTPS L"https://"
  64. #define wszASPEXT L".asp"
  65. #define wszHTTP L"http://"
  66. #define wszDOTCERTEXT L".cer"
  67. #define wszNEWLINE L"\n"
  68. #define wszFILESC L"file://\\\\"
  69. #define SZ_REGSVR32 L"regsvr32.exe"
  70. #define SZ_REGSVR32_CERTCLI L"/i:i /n /s certcli.dll"
  71. #define SZ_VERB_OPEN L"open"
  72. // hardcoded shares
  73. #define wszCERTENROLLURLPATH L"/CertEnroll/"
  74. #define wszzREGSUBJECTTEMPLATEVALUE \
  75. wszPROPEMAIL L"\0" \
  76. wszPROPCOMMONNAME L"\0" \
  77. wszATTRORGUNIT4 L"\0" \
  78. wszPROPORGANIZATION L"\0" \
  79. wszPROPLOCALITY L"\0" \
  80. wszPROPSTATE L"\0" \
  81. wszPROPDOMAINCOMPONENT L"\0" \
  82. wszPROPCOUNTRY L"\0"
  83. // Whistler SMIME extension (or any other CSP):
  84. // SMIME Capabilities
  85. // [1]SMIME Capability
  86. // Object ID=1.2.840.113549.3.2 szOID_RSA_RC2CBC, 128 bit
  87. // Parameters=02 02 00 80
  88. // [2]SMIME Capability
  89. // Object ID=1.2.840.113549.3.4 szOID_RSA_RC4, 128 bit
  90. // Parameters=02 02 00 80
  91. // [3]SMIME Capability
  92. // Object ID=1.3.14.3.2.7 szOID_OIWSEC_desCBC
  93. // [4]SMIME Capability
  94. // Object ID=1.2.840.113549.3.7 szOID_RSA_DES_EDE3_CBC
  95. //
  96. #define wszzREGVALUEDEFAULTSMIME \
  97. TEXT(szOID_RSA_RC2CBC) L",128" L"\0" \
  98. TEXT(szOID_RSA_RC4) L",128" L"\0" \
  99. TEXT(szOID_OIWSEC_desCBC) L"\0" \
  100. TEXT(szOID_RSA_DES_EDE3_CBC) L"\0"
  101. #ifdef CERTSRV_ENABLE_ALL_REGISTRY_DEFAULTS
  102. # define wszREGSUBJECTALTNAMEVALUE L"EMail"
  103. # define wszREGSUBJECTALTNAME2VALUE L"EMail"
  104. #else
  105. # define wszREGSUBJECTALTNAMEVALUE \
  106. L"DISABLED: Set to EMail to set SubjectAltName extension to the email address"
  107. # define wszREGSUBJECTALTNAME2VALUE \
  108. L"DISABLED: Set to EMail to set SubjectAltName2 extension to the email address"
  109. #endif
  110. #define szNULL_SESSION_REG_LOCATION "System\\CurrentControlSet\\Services\\LanmanServer\\Parameters"
  111. #define szNULL_SESSION_VALUE "NullSessionPipes"
  112. #define wszDEFAULTSHAREDFOLDER L"\\CAConfig"
  113. // globals
  114. WCHAR *g_pwszArgvPath = NULL; // for installing from local directory
  115. WCHAR *g_pwszNoService = NULL; // skip CreateService
  116. WCHAR *g_pwszSanitizedChar = NULL; // take first char for sanitizing test
  117. #if DBG_CERTSRV
  118. WCHAR *g_pwszDumpStrings = NULL; // dump resource strings
  119. #endif
  120. BOOL g_fW3SvcRunning = FALSE;
  121. WCHAR g_wszServicePath[MAX_PATH];
  122. // Version-independent ProgID
  123. // ProgID
  124. WCHAR const g_wszCertAdmDotDll[] = L"certadm.dll";
  125. WCHAR const g_wszCertCliDotDll[] = L"certcli.dll";
  126. WCHAR const g_wszcertEncDotDll[] = L"certenc.dll";
  127. WCHAR const g_wszCertXDSDotDll[] = L"certxds.dll";
  128. WCHAR const g_wszCertIfDotDll[] = L"certif.dll";
  129. WCHAR const g_wszCertPDefDotDll[] = L"certpdef.dll";
  130. WCHAR const g_wszCertMMCDotDll[] = L"certmmc.dll";
  131. WCHAR const g_wszCertSrvDotMsc[] = L"certsrv.msc";
  132. WCHAR const g_wszSCrdEnrlDotDll[] = L"scrdenrl.dll";
  133. WCHAR const g_wszCertReqDotExe[] = L"certreq.exe";
  134. WCHAR const g_wszCertUtilDotExe[] = L"certutil.exe";
  135. WCHAR const g_wszCertDBDotDll[] = L"certdb.dll";
  136. WCHAR const g_wszCertViewDotDll[] = L"certview.dll";
  137. WCHAR const g_wszCSBullDotGif[] = L"csbull.gif";
  138. WCHAR const g_wszCSBackDotGif[] = L"csback.gif";
  139. WCHAR const g_wszCSLogoDotGif[] = L"cslogo.gif";
  140. CHAR const * const aszRegisterServer[] = {
  141. "DllRegisterServer",
  142. "DllUnregisterServer",
  143. };
  144. typedef struct _REGISTERDLL
  145. {
  146. WCHAR const *pwszDllName;
  147. DWORD Flags;
  148. } REGISTERDLL;
  149. #define RD_SERVER 0x00000001 // Register on server
  150. #define RD_CLIENT 0x00000002 // Register on client
  151. #define RD_UNREGISTER 0x00000004 // Unegister on client & server
  152. #define RD_WHISTLER 0x00000008 // Register must succeed on Whistler only
  153. #define RD_SKIPUNREGPOLICY 0x00000010 // not unreg custom policy during upgrade
  154. #define RD_SKIPUNREGEXIT 0x00000020 // not unreg custom exit during upgrade
  155. REGISTERDLL const g_aRegisterDll[] = {
  156. { g_wszCertAdmDotDll, RD_SERVER | RD_CLIENT },
  157. { g_wszCertCliDotDll, RD_SERVER | RD_CLIENT },
  158. { g_wszcertEncDotDll, RD_SERVER | RD_CLIENT | RD_UNREGISTER },
  159. { g_wszCertXDSDotDll, RD_SERVER },
  160. { g_wszCertIfDotDll, RD_UNREGISTER },
  161. { g_wszCertPDefDotDll, RD_SERVER },
  162. { g_wszCertMMCDotDll, RD_SERVER },
  163. { g_wszSCrdEnrlDotDll, RD_SERVER | RD_CLIENT | RD_UNREGISTER | RD_WHISTLER },
  164. { g_wszCertDBDotDll, RD_SERVER | RD_UNREGISTER },
  165. { g_wszCertViewDotDll, RD_UNREGISTER },
  166. { NULL, 0 }
  167. };
  168. typedef struct _PROGRAMENTRY
  169. {
  170. UINT uiLinkName;
  171. UINT uiGroupName;
  172. UINT uiDescription;
  173. DWORD csidl; // special folder index
  174. WCHAR const *pwszExeName;
  175. WCHAR const *pwszClientArgs;
  176. WCHAR const *pwszServerArgs;
  177. DWORD Flags;
  178. } PROGRAMENTRY;
  179. #define PE_SERVER 0x00000001 // Install on server
  180. #define PE_CLIENT 0x00000002 // Install on client
  181. #define PE_DELETEONLY 0x00000004 // Always delete
  182. PROGRAMENTRY const g_aProgramEntry[] = {
  183. {
  184. IDS_STARTMENU_NEWCRL_LINKNAME, // uiLinkName
  185. IDS_STARTMENU_CERTSERVER, // uiGroupName
  186. 0, // uiDescription
  187. CSIDL_COMMON_PROGRAMS, // "All Users\Start Menu\Programs"
  188. g_wszCertUtilDotExe, // pwszExeName
  189. NULL, // pwszClientArgs
  190. L"-crl -", // pwszServerArgs
  191. PE_DELETEONLY | PE_SERVER, // Flags
  192. },
  193. {
  194. IDS_STARTMENU_CERTHIER_LINKNAME, // uiLinkName
  195. IDS_STARTMENU_CERTSERVER, // uiGroupName
  196. 0, // uiDescription
  197. CSIDL_COMMON_PROGRAMS, // "All Users\Start Menu\Programs"
  198. L"certhier.exe", // pwszExeName
  199. NULL, // pwszClientArgs
  200. NULL, // pwszServerArgs
  201. PE_DELETEONLY | PE_SERVER, // Flags
  202. },
  203. {
  204. IDS_STARTMENU_CERTREQ_LINKNAME, // uiLinkName
  205. IDS_STARTMENU_CERTSERVER, // uiGroupName
  206. 0, // uiDescription
  207. CSIDL_COMMON_PROGRAMS, // "All Users\Start Menu\Programs"
  208. g_wszCertReqDotExe, // pwszExeName
  209. NULL, // pwszClientArgs
  210. NULL, // pwszServerArgs
  211. PE_DELETEONLY | PE_CLIENT | PE_SERVER, // Flags
  212. },
  213. };
  214. #define CPROGRAMENTRY ARRAYSIZE(g_aProgramEntry)
  215. static char rgcCERT_NULL_SESSION[] = {0x43, 0x45, 0x52, 0x54, 0x00, 0x00};
  216. // ** Prototypes **
  217. HRESULT
  218. UpgradeServerRegEntries(
  219. IN PER_COMPONENT_DATA *pComp);
  220. HRESULT
  221. CreateServerRegEntries(
  222. IN BOOL fUpgrade,
  223. IN PER_COMPONENT_DATA *pComp);
  224. HRESULT
  225. CreateWebClientRegEntries(
  226. BOOL fUpgrade,
  227. PER_COMPONENT_DATA *pComp);
  228. HRESULT
  229. UpgradeWebClientRegEntries(
  230. PER_COMPONENT_DATA *pComp);
  231. HRESULT
  232. GetServerNames(
  233. IN HWND hwnd,
  234. IN HINSTANCE hInstance,
  235. IN BOOL fUnattended,
  236. OUT WCHAR **ppwszServerName,
  237. OUT WCHAR **ppwszServerNameOld);
  238. HRESULT
  239. UpdateDomainAndUserName(
  240. IN HWND hwnd,
  241. IN OUT PER_COMPONENT_DATA *pComp);
  242. HRESULT
  243. RegisterAndUnRegisterDLLs(
  244. IN DWORD Flags,
  245. IN PER_COMPONENT_DATA *pComp,
  246. IN HWND hwnd);
  247. HRESULT RenameMiscTargets(HWND hwnd, PER_COMPONENT_DATA *pComp, BOOL fServer);
  248. HRESULT DeleteProgramGroups(IN BOOL fAll);
  249. HRESULT CreateCertificateService(PER_COMPONENT_DATA *pComp, HWND hwnd);
  250. //endproto
  251. #ifdef DBG_OCM_TRACE
  252. VOID
  253. CaptureStackBackTrace(
  254. EXCEPTION_POINTERS *pep,
  255. ULONG cSkip,
  256. ULONG cFrames,
  257. ULONG *aeip)
  258. {
  259. ZeroMemory(aeip, cFrames * sizeof(aeip[0]));
  260. #if i386 == 1
  261. ULONG ieip, *pebp;
  262. ULONG *pebpMax = (ULONG *) MAXLONG; // 2 * 1024 * 1024 * 1024; // 2 gig - 1
  263. ULONG *pebpMin = (ULONG *) (64 * 1024); // 64k
  264. if (pep == NULL)
  265. {
  266. ieip = 0;
  267. cSkip++; // always skip current frame
  268. pebp = ((ULONG *) &pep) - 2;
  269. }
  270. else
  271. {
  272. ieip = 1;
  273. CSASSERT(cSkip == 0);
  274. aeip[0] = pep->ContextRecord->Eip;
  275. pebp = (ULONG *) pep->ContextRecord->Ebp;
  276. }
  277. if (pebp >= pebpMin && pebp < pebpMax)
  278. {
  279. __try
  280. {
  281. for ( ; ieip < cSkip + cFrames; ieip++)
  282. {
  283. if (ieip >= cSkip)
  284. {
  285. aeip[ieip - cSkip] = *(pebp + 1); // save an eip
  286. }
  287. ULONG *pebpNext = (ULONG *) *pebp;
  288. if (pebpNext < pebp + 2 || pebpNext >= pebpMax - 1)
  289. {
  290. break;
  291. }
  292. pebp = pebpNext;
  293. }
  294. }
  295. __except(EXCEPTION_EXECUTE_HANDLER)
  296. {
  297. ;
  298. }
  299. }
  300. #endif // i386 == 1
  301. }
  302. #endif // DBG_OCM_TRACE
  303. VOID
  304. DumpBackTrace(
  305. char const *
  306. #ifdef DBG_OCM_TRACE
  307. pszName
  308. #endif // DBG_OCM_TRACE
  309. )
  310. {
  311. #ifdef DBG_OCM_TRACE
  312. ULONG aeip[10];
  313. DBGPRINT((MAXDWORD, "%hs: BackTrace:\n", pszName));
  314. CaptureStackBackTrace(NULL, 1, ARRAYSIZE(aeip), aeip);
  315. for (int i = 0; i < ARRAYSIZE(aeip); i++)
  316. {
  317. if (NULL == aeip[i])
  318. {
  319. break;
  320. }
  321. DBGPRINT((MAXDWORD, "ln %x;", aeip[i]));
  322. }
  323. DBGPRINT((MAXDWORD, "\n"));
  324. #endif // DBG_OCM_TRACE
  325. }
  326. __inline VOID
  327. AppendBackSlash(
  328. IN OUT WCHAR *pwszOut)
  329. {
  330. DWORD cwc = wcslen(pwszOut);
  331. if (0 == cwc || L'\\' != pwszOut[cwc - 1])
  332. {
  333. pwszOut[cwc++] = L'\\';
  334. pwszOut[cwc] = L'\0';
  335. }
  336. }
  337. __inline VOID
  338. StripBackSlash(
  339. IN OUT WCHAR *pwszOut)
  340. {
  341. DWORD cwc = wcslen(pwszOut);
  342. if (0 < cwc && L'\\' == pwszOut[cwc - 1])
  343. {
  344. pwszOut[cwc] = L'\0';
  345. }
  346. }
  347. VOID
  348. BuildPath(
  349. OUT WCHAR *pwszOut,
  350. IN DWORD DBGPARMREFERENCED(cwcOut),
  351. IN WCHAR const *pwszDir,
  352. IN WCHAR const *pwszFile)
  353. {
  354. wcscpy(pwszOut, pwszDir);
  355. AppendBackSlash(pwszOut);
  356. wcscat(pwszOut, pwszFile);
  357. StripBackSlash(pwszOut);
  358. CSASSERT(wcslen(pwszOut) < cwcOut);
  359. DBGPRINT((DBG_SS_CERTOCMI, "BuildPath(%ws, %ws) -> %ws\n", pwszDir, pwszFile, pwszOut));
  360. }
  361. VOID
  362. FreeCARequestInfo(CASERVERSETUPINFO *pServer)
  363. {
  364. if (NULL != pServer->pwszRequestFile)
  365. {
  366. LocalFree(pServer->pwszRequestFile);
  367. }
  368. if (NULL != pServer->pwszParentCAMachine)
  369. {
  370. LocalFree(pServer->pwszParentCAMachine);
  371. }
  372. if (NULL != pServer->pwszParentCAName)
  373. {
  374. LocalFree(pServer->pwszParentCAName);
  375. }
  376. }
  377. VOID
  378. FreeCAStoreInfo(CASERVERSETUPINFO *pServer)
  379. {
  380. if (NULL != pServer->pwszSharedFolder)
  381. {
  382. LocalFree(pServer->pwszSharedFolder);
  383. }
  384. if (NULL != pServer->pwszDBDirectory)
  385. {
  386. LocalFree(pServer->pwszDBDirectory);
  387. }
  388. if (NULL != pServer->pwszLogDirectory)
  389. {
  390. LocalFree(pServer->pwszLogDirectory);
  391. }
  392. }
  393. VOID
  394. FreeCAServerAdvanceInfo(CASERVERSETUPINFO *pServer)
  395. {
  396. if (NULL != pServer->pCSPInfoList)
  397. {
  398. FreeCSPInfoList(pServer->pCSPInfoList);
  399. }
  400. if (NULL != pServer->pKeyList)
  401. {
  402. csiFreeKeyList(pServer->pKeyList);
  403. }
  404. if (NULL != pServer->pDefaultCSPInfo)
  405. {
  406. freeCSPInfo(pServer->pDefaultCSPInfo);
  407. }
  408. if (NULL != pServer->pwszDesanitizedKeyContainerName)
  409. {
  410. LocalFree(pServer->pwszDesanitizedKeyContainerName);
  411. }
  412. if (NULL != pServer->pccExistingCert)
  413. {
  414. ClearExistingCertToUse(pServer);
  415. }
  416. if (NULL != pServer->pccUpgradeCert)
  417. {
  418. CertFreeCertificateContext(pServer->pccUpgradeCert);
  419. }
  420. if (NULL != pServer->pwszValidityPeriodCount)
  421. {
  422. LocalFree(pServer->pwszValidityPeriodCount);
  423. }
  424. if (NULL != pServer->pszAlgId)
  425. {
  426. LocalFree(pServer->pszAlgId);
  427. }
  428. if (NULL != pServer->hMyStore)
  429. {
  430. CertCloseStore(pServer->hMyStore, 0);
  431. }
  432. // don't free following because they are just pointers
  433. // pServer->pCSPInfo
  434. // pServer->pHashInfo
  435. }
  436. VOID
  437. FreeCAServerIdInfo(
  438. CASERVERSETUPINFO *pServer)
  439. {
  440. if (NULL != pServer->pwszCACommonName)
  441. {
  442. LocalFree(pServer->pwszCACommonName);
  443. pServer->pwszCACommonName = NULL;
  444. }
  445. }
  446. VOID
  447. FreeCAServerInfo(CASERVERSETUPINFO *pServer)
  448. {
  449. FreeCAServerIdInfo(pServer);
  450. FreeCAServerAdvanceInfo(pServer);
  451. FreeCAStoreInfo(pServer);
  452. FreeCARequestInfo(pServer);
  453. if (NULL != pServer->pwszSanitizedName)
  454. {
  455. LocalFree(pServer->pwszSanitizedName);
  456. }
  457. if (NULL != pServer->pwszDNSuffix)
  458. {
  459. LocalFree(pServer->pwszDNSuffix);
  460. }
  461. if (NULL != pServer->pwszFullCADN)
  462. {
  463. LocalFree(pServer->pwszFullCADN);
  464. }
  465. if (NULL != pServer->pwszKeyContainerName)
  466. {
  467. LocalFree(pServer->pwszKeyContainerName);
  468. }
  469. if (NULL != pServer->pwszCACertFile)
  470. {
  471. LocalFree(pServer->pwszCACertFile);
  472. }
  473. if (NULL != pServer->pwszUseExistingCert)
  474. {
  475. LocalFree(pServer->pwszUseExistingCert);
  476. }
  477. if (NULL != pServer->pwszPreserveDB)
  478. {
  479. LocalFree(pServer->pwszPreserveDB);
  480. }
  481. if (NULL != pServer->pwszCustomPolicy)
  482. {
  483. LocalFree(pServer->pwszCustomPolicy);
  484. }
  485. if (NULL != pServer->pwszzCustomExit)
  486. {
  487. LocalFree(pServer->pwszzCustomExit);
  488. }
  489. }
  490. VOID
  491. FreeCAClientInfo(CAWEBCLIENTSETUPINFO *pClient)
  492. {
  493. if (NULL != pClient)
  494. {
  495. if (NULL != pClient->pwszWebCAMachine)
  496. {
  497. LocalFree(pClient->pwszWebCAMachine);
  498. }
  499. if (NULL != pClient->pwszWebCAName)
  500. {
  501. LocalFree(pClient->pwszWebCAName);
  502. }
  503. if (NULL != pClient->pwszSanitizedWebCAName)
  504. {
  505. LocalFree(pClient->pwszSanitizedWebCAName);
  506. }
  507. if (NULL != pClient->pwszSharedFolder)
  508. {
  509. LocalFree(pClient->pwszSharedFolder);
  510. }
  511. }
  512. }
  513. VOID
  514. FreeCAInfo(CASETUPINFO *pCA)
  515. {
  516. if (NULL != pCA->pServer)
  517. {
  518. FreeCAServerInfo(pCA->pServer);
  519. LocalFree(pCA->pServer);
  520. pCA->pServer = NULL;
  521. }
  522. if (NULL != pCA->pClient)
  523. {
  524. FreeCAClientInfo(pCA->pClient);
  525. LocalFree(pCA->pClient);
  526. pCA->pClient = NULL;
  527. }
  528. }
  529. VOID
  530. FreeCAComponentInfo(PER_COMPONENT_DATA *pComp)
  531. {
  532. if (NULL != pComp->pwszCustomMessage)
  533. {
  534. LocalFree(pComp->pwszCustomMessage);
  535. }
  536. if (NULL != pComp->pwszComponent)
  537. {
  538. LocalFree(pComp->pwszComponent);
  539. }
  540. if (NULL != pComp->pwszUnattendedFile)
  541. {
  542. LocalFree(pComp->pwszUnattendedFile);
  543. }
  544. if (NULL != pComp->pwszServerName)
  545. {
  546. LocalFree(pComp->pwszServerName);
  547. }
  548. if (NULL != pComp->pwszServerNameOld)
  549. {
  550. LocalFree(pComp->pwszServerNameOld);
  551. }
  552. if (NULL != pComp->pwszSystem32)
  553. {
  554. LocalFree(pComp->pwszSystem32);
  555. }
  556. FreeCAInfo(&(pComp->CA));
  557. }
  558. VOID
  559. FreeCAGlobals(VOID)
  560. {
  561. if (NULL != g_pwszArgvPath)
  562. {
  563. LocalFree(g_pwszArgvPath);
  564. }
  565. if (NULL != g_pwszNoService)
  566. {
  567. LocalFree(g_pwszNoService);
  568. }
  569. if (NULL != g_pwszSanitizedChar)
  570. {
  571. LocalFree(g_pwszSanitizedChar);
  572. }
  573. #if DBG_CERTSRV
  574. if (NULL != g_pwszDumpStrings)
  575. {
  576. LocalFree(g_pwszDumpStrings);
  577. }
  578. #endif
  579. }
  580. VOID
  581. SaveCustomMessage(
  582. IN OUT PER_COMPONENT_DATA *pComp,
  583. OPTIONAL IN WCHAR const *pwszCustomMessage)
  584. {
  585. HRESULT hr;
  586. if (NULL != pwszCustomMessage)
  587. {
  588. if (NULL != pComp->pwszCustomMessage)
  589. {
  590. LocalFree(pComp->pwszCustomMessage);
  591. pComp->pwszCustomMessage = NULL;
  592. }
  593. hr = myDupString(pwszCustomMessage, &pComp->pwszCustomMessage);
  594. _JumpIfError(hr, error, "myDupString");
  595. }
  596. error:
  597. ;
  598. }
  599. HRESULT
  600. LoadDefaultCAIDAttributes(
  601. IN OUT PER_COMPONENT_DATA *pComp)
  602. {
  603. HRESULT hr;
  604. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  605. // free existing Id info before load default
  606. FreeCAServerIdInfo(pServer);
  607. // load default from resource
  608. if (NULL != g_pwszSanitizedChar)
  609. {
  610. if (NULL != pServer->pwszCACommonName)
  611. {
  612. LocalFree(pServer->pwszCACommonName);
  613. }
  614. // replace with the env var
  615. pServer->pwszCACommonName = (WCHAR*)LocalAlloc(LMEM_FIXED,
  616. (wcslen(g_pwszSanitizedChar) + 1) * sizeof(WCHAR));
  617. _JumpIfOutOfMemory(hr, error, pServer->pwszCACommonName);
  618. wcscpy(pServer->pwszCACommonName, g_pwszSanitizedChar);
  619. }
  620. // default validity
  621. pServer->enumValidityPeriod = dwVALIDITYPERIODENUMDEFAULT;
  622. pServer->dwValidityPeriodCount = dwVALIDITYPERIODCOUNTDEFAULT_ROOT;
  623. GetSystemTimeAsFileTime(&pServer->NotBefore);
  624. pServer->NotAfter = pServer->NotBefore;
  625. myMakeExprDateTime(
  626. &pServer->NotAfter,
  627. pServer->dwValidityPeriodCount,
  628. pServer->enumValidityPeriod);
  629. hr = S_OK;
  630. error:
  631. return(hr);
  632. }
  633. HRESULT
  634. GetDefaultDBDirectory(
  635. IN PER_COMPONENT_DATA *pComp,
  636. OUT WCHAR **ppwszDir)
  637. {
  638. HRESULT hr;
  639. DWORD cwc;
  640. *ppwszDir = NULL;
  641. cwc = wcslen(pComp->pwszSystem32) +
  642. wcslen(wszLOGPATH) +
  643. 1;
  644. *ppwszDir = (WCHAR *) LocalAlloc(LMEM_FIXED, cwc * sizeof(WCHAR));
  645. _JumpIfOutOfMemory(hr, error, *ppwszDir);
  646. // default
  647. wcscpy(*ppwszDir, pComp->pwszSystem32);
  648. wcscat(*ppwszDir, wszLOGPATH);
  649. CSASSERT(cwc == (DWORD) (wcslen(*ppwszDir) + 1));
  650. hr = S_OK;
  651. error:
  652. return(hr);
  653. }
  654. HRESULT
  655. LoadDefaultDBDirAttributes(
  656. IN OUT PER_COMPONENT_DATA *pComp)
  657. {
  658. HRESULT hr;
  659. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  660. if (NULL != pServer->pwszDBDirectory)
  661. {
  662. LocalFree(pServer->pwszDBDirectory);
  663. pServer->pwszDBDirectory = NULL;
  664. }
  665. hr = GetDefaultDBDirectory(pComp, &pServer->pwszDBDirectory);
  666. _JumpIfError(hr, error, "GetDefaultDBDirectory");
  667. // default log dir is the same as db
  668. if (NULL != pServer->pwszLogDirectory)
  669. {
  670. LocalFree(pServer->pwszLogDirectory);
  671. }
  672. pServer->pwszLogDirectory = (WCHAR *) LocalAlloc(
  673. LMEM_FIXED,
  674. (wcslen(pServer->pwszDBDirectory) + 1) * sizeof(WCHAR));
  675. _JumpIfOutOfMemory(hr, error, pServer->pwszLogDirectory);
  676. wcscpy(pServer->pwszLogDirectory, pServer->pwszDBDirectory);
  677. pServer->fPreserveDB = FALSE;
  678. hr = S_OK;
  679. error:
  680. return(hr);
  681. }
  682. HRESULT
  683. LoadDefaultAdvanceAttributes(
  684. IN OUT CASERVERSETUPINFO* pServer)
  685. {
  686. HRESULT hr;
  687. // load default csp, ms base csp
  688. pServer->fAdvance = FALSE;
  689. if (NULL == pServer->pDefaultCSPInfo)
  690. {
  691. pServer->pDefaultCSPInfo = newCSPInfo(PROV_RSA_FULL, wszBASECSP);
  692. if (NULL == pServer->pDefaultCSPInfo && !IsWhistler())
  693. {
  694. pServer->pDefaultCSPInfo = newCSPInfo(PROV_RSA_FULL, MS_DEF_PROV_W);
  695. }
  696. _JumpIfOutOfMemory(hr, error, pServer->pDefaultCSPInfo);
  697. }
  698. // determine default hash, sha1
  699. pServer->pDefaultHashInfo = pServer->pDefaultCSPInfo->pHashList;
  700. while (NULL != pServer->pDefaultHashInfo)
  701. {
  702. if (pServer->pDefaultHashInfo->idAlg == CALG_SHA1)
  703. {
  704. //got default
  705. break;
  706. }
  707. pServer->pDefaultHashInfo = pServer->pDefaultHashInfo->next;
  708. }
  709. // If we have not just created a default key, reset the key container name.
  710. if (pServer->pCSPInfo != pServer->pDefaultCSPInfo ||
  711. (pServer->dwKeyLength != CA_DEFAULT_KEY_LENGTH_ROOT &&
  712. pServer->dwKeyLength != CA_DEFAULT_KEY_LENGTH_SUB) ||
  713. !pServer->fDeletableNewKey) {
  714. ClearKeyContainerName(pServer);
  715. }
  716. // ok, point to defaults
  717. pServer->pCSPInfo = pServer->pDefaultCSPInfo;
  718. pServer->pHashInfo = pServer->pDefaultHashInfo;
  719. // some other related defaults
  720. pServer->dwKeyLength = IsRootCA(pServer->CAType)?
  721. CA_DEFAULT_KEY_LENGTH_ROOT:
  722. CA_DEFAULT_KEY_LENGTH_SUB;
  723. pServer->dwKeyLenMin = 0;
  724. pServer->dwKeyLenMax = 0;
  725. // update hash oid
  726. if (NULL != pServer->pszAlgId)
  727. {
  728. // free old
  729. LocalFree(pServer->pszAlgId);
  730. }
  731. hr = myGetSigningOID(
  732. NULL, // hProv
  733. pServer->pCSPInfo->pwszProvName,
  734. pServer->pCSPInfo->dwProvType,
  735. pServer->pHashInfo->idAlg,
  736. &(pServer->pszAlgId));
  737. _JumpIfError(hr, error, "myGetSigningOID");
  738. error:
  739. return(hr);
  740. }
  741. HRESULT
  742. LoadDefaultCAClientAttributes(
  743. IN OUT PER_COMPONENT_DATA *pComp)
  744. {
  745. HRESULT hr;
  746. CAWEBCLIENTSETUPINFO *pClient = pComp->CA.pClient;
  747. if (NULL != pClient)
  748. {
  749. // free existing client setup info
  750. FreeCAClientInfo(pClient);
  751. LocalFree(pClient);
  752. pComp->CA.pClient = NULL;
  753. }
  754. pComp->CA.pClient = (CAWEBCLIENTSETUPINFO *) LocalAlloc(
  755. LMEM_FIXED | LMEM_ZEROINIT,
  756. sizeof(CAWEBCLIENTSETUPINFO));
  757. _JumpIfOutOfMemory(hr, error, pComp->CA.pClient);
  758. pComp->CA.pClient->WebCAType = ENUM_UNKNOWN_CA;
  759. hr = S_OK;
  760. error:
  761. return(hr);
  762. }
  763. HRESULT
  764. GetDefaultSharedFolder(
  765. OUT WCHAR **ppwszSharedFolder)
  766. {
  767. HRESULT hr = S_OK;
  768. WCHAR *pwszSysDrive = NULL;
  769. *ppwszSharedFolder = NULL;
  770. hr = myGetEnvString(&pwszSysDrive, L"SystemDrive");
  771. if (S_OK == hr)
  772. {
  773. *ppwszSharedFolder = (WCHAR *) LocalAlloc(
  774. LMEM_FIXED,
  775. (wcslen(pwszSysDrive) + wcslen(wszDEFAULTSHAREDFOLDER) + 1) *
  776. sizeof(WCHAR));
  777. _JumpIfOutOfMemory(hr, error, *ppwszSharedFolder);
  778. wcscpy(*ppwszSharedFolder, pwszSysDrive);
  779. wcscat(*ppwszSharedFolder, wszDEFAULTSHAREDFOLDER);
  780. }
  781. error:
  782. if (NULL != pwszSysDrive)
  783. {
  784. LocalFree(pwszSysDrive);
  785. }
  786. return hr;
  787. }
  788. HRESULT
  789. LoadDefaultCAServerAttributes(
  790. IN OUT PER_COMPONENT_DATA *pComp)
  791. {
  792. HRESULT hr;
  793. BOOL fDSCA = FALSE;
  794. bool fIsDomainMember;
  795. bool fUserCanInstallCA;
  796. bool fIsOldDSVersion;
  797. if (NULL != pComp->CA.pServer)
  798. {
  799. // free existing server setup info
  800. FreeCAServerInfo(pComp->CA.pServer);
  801. LocalFree(pComp->CA.pServer);
  802. }
  803. // allocate server info buffer
  804. pComp->CA.pServer = (CASERVERSETUPINFO *) LocalAlloc(
  805. LMEM_FIXED | LMEM_ZEROINIT,
  806. sizeof(CASERVERSETUPINFO));
  807. _JumpIfOutOfMemory(hr, error, pComp->CA.pServer);
  808. hr = LoadDefaultCAIDAttributes(pComp);
  809. _JumpIfError(hr, error, "LoadDefaultCAIDAttributes");
  810. hr = LoadDefaultAdvanceAttributes(pComp->CA.pServer);
  811. _JumpIfError(hr, error, "LoadDefaultAdvanceAttributes");
  812. hr = LoadDefaultDBDirAttributes(pComp);
  813. _JumpIfError(hr, error, "LoadDefaultDBDirAttributes");
  814. // decide default using DS
  815. // xtan, the following call should be replaced with HasDSWritePermission()
  816. // remove DisableEnterpriseCAs()
  817. pComp->CA.pServer->fUseDS = FALSE;
  818. hr = myLocalMachineIsDomainMember(&fIsDomainMember);
  819. _JumpIfError(hr, error, "myLocalMachineIsDomainMember");
  820. if (fIsDomainMember)
  821. {
  822. if(IsDSAvailable(&fIsOldDSVersion))
  823. {
  824. if(fIsOldDSVersion)
  825. {
  826. pComp->CA.pServer->EnterpriseUnavailReason =
  827. ENUM_ENTERPRISE_UNAVAIL_REASON_OLD_DS_VERSION;
  828. }
  829. else
  830. {
  831. hr = CurrentUserCanInstallCA(fUserCanInstallCA);
  832. _JumpIfError(hr, error, "CurrentUserCanInstallCA");
  833. if(fUserCanInstallCA)
  834. {
  835. pComp->CA.pServer->fUseDS = TRUE;
  836. fDSCA = csiIsAnyDSCAAvailable();
  837. pComp->CA.pServer->EnterpriseUnavailReason =
  838. ENUM_ENTERPRISE_UNAVAIL_REASON_AVAILABLE;
  839. }
  840. else
  841. {
  842. pComp->CA.pServer->EnterpriseUnavailReason =
  843. ENUM_ENTERPRISE_UNAVAIL_REASON_NO_INSTALL_RIGHTS;
  844. }
  845. }
  846. }
  847. else
  848. {
  849. pComp->CA.pServer->EnterpriseUnavailReason =
  850. ENUM_ENTERPRISE_UNAVAIL_REASON_DS_UNAVAILABLE;
  851. }
  852. }
  853. else
  854. {
  855. pComp->CA.pServer->EnterpriseUnavailReason =
  856. ENUM_ENTERPRISE_UNAVAIL_REASON_DOMAIN_NOT_JOINED;
  857. }
  858. // alway free and null old shared folder
  859. if (NULL != pComp->CA.pServer->pwszSharedFolder)
  860. {
  861. LocalFree(pComp->CA.pServer->pwszSharedFolder);
  862. pComp->CA.pServer->pwszSharedFolder = NULL;
  863. }
  864. // decide default CA type and default shared folder
  865. pComp->CA.pServer->CAType = ENUM_STANDALONE_ROOTCA;
  866. if (pComp->CA.pServer->fUseDS)
  867. {
  868. if (fDSCA)
  869. {
  870. pComp->CA.pServer->CAType = ENUM_ENTERPRISE_SUBCA;
  871. }
  872. else
  873. {
  874. pComp->CA.pServer->CAType = ENUM_ENTERPRISE_ROOTCA;
  875. }
  876. }
  877. if (pComp->fUnattended || !pComp->CA.pServer->fUseDS)
  878. {
  879. BOOL fChangeToDefault = FALSE;
  880. // try reg load first
  881. hr = myGetCertRegStrValue(
  882. NULL,
  883. NULL,
  884. NULL,
  885. wszREGDIRECTORY,
  886. &pComp->CA.pServer->pwszSharedFolder);
  887. if (S_OK != hr && HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) != hr)
  888. {
  889. _JumpErrorStr(hr, error, "myGetCertRegStrValue", wszREGDIRECTORY);
  890. }
  891. if (S_OK == hr)
  892. {
  893. if (L'\0' == *pComp->CA.pServer->pwszSharedFolder)
  894. {
  895. // this mast be empty string
  896. fChangeToDefault = TRUE;
  897. }
  898. else
  899. {
  900. //got something, make sure unc path exist
  901. DWORD dwPathFlag;
  902. if (!myIsFullPath(pComp->CA.pServer->pwszSharedFolder,
  903. &dwPathFlag))
  904. {
  905. // somehow register an invalid path, don't use it
  906. fChangeToDefault = TRUE;
  907. }
  908. else
  909. {
  910. if (UNC_PATH == dwPathFlag &&
  911. DE_DIREXISTS != DirExists(pComp->CA.pServer->pwszSharedFolder))
  912. {
  913. // this unc path doesn't exist any more
  914. // not making any sense to use it
  915. fChangeToDefault = TRUE;
  916. pComp->CA.pServer->fUNCPathNotFound = TRUE;
  917. }
  918. }
  919. }
  920. }
  921. else
  922. {
  923. //must be not found
  924. fChangeToDefault = TRUE;
  925. }
  926. if (fChangeToDefault)
  927. {
  928. //free 1st
  929. if (NULL != pComp->CA.pServer->pwszSharedFolder)
  930. {
  931. LocalFree(pComp->CA.pServer->pwszSharedFolder);
  932. }
  933. // load default
  934. hr = GetDefaultSharedFolder(&pComp->CA.pServer->pwszSharedFolder);
  935. _JumpIfError(hr, error, "GetDefaultSharedFolder");
  936. }
  937. }
  938. pComp->CA.pServer->fSaveRequestAsFile = FALSE;
  939. pComp->CA.pServer->pwszRequestFile = NULL;
  940. pComp->CA.pServer->pwszParentCAMachine = NULL;
  941. pComp->CA.pServer->pwszParentCAName = NULL;
  942. hr = S_OK;
  943. error:
  944. return hr;
  945. }
  946. HRESULT
  947. InitCASetup(
  948. IN HWND hwnd,
  949. IN OUT PER_COMPONENT_DATA *pComp)
  950. {
  951. HRESULT hr;
  952. UINT ui;
  953. bool fIsAdmin = false;
  954. hr = GetServerNames(
  955. hwnd,
  956. pComp->hInstance,
  957. pComp->fUnattended,
  958. &pComp->pwszServerName,
  959. &pComp->pwszServerNameOld);
  960. _JumpIfError(hr, error, "GetServerNames");
  961. DBGPRINT((
  962. DBG_SS_CERTOCMI,
  963. "InitCASetup:GetServerNames:%ws,%ws\n",
  964. pComp->pwszServerName,
  965. pComp->pwszServerNameOld));
  966. DumpBackTrace("InitCASetup");
  967. hr = myIsCurrentUserBuiltinAdmin(&fIsAdmin);
  968. _JumpIfError(hr, error, "myIsCurrentUserBuiltinAdmin");
  969. if (!fIsAdmin)
  970. {
  971. hr = E_ACCESSDENIED;
  972. CertErrorMessageBox(
  973. pComp->hInstance,
  974. pComp->fUnattended,
  975. hwnd,
  976. IDS_ERR_NOT_ADM,
  977. hr,
  978. NULL);
  979. _JumpError(hr, error, "myIsCurrentUserBuiltinAdmin");
  980. }
  981. // load some of environment variables
  982. hr = myGetEnvString(&g_pwszArgvPath, L"CertSrv_BinDir");
  983. hr = myGetEnvString(&g_pwszNoService, L"CertSrv_NoService");
  984. hr = myGetEnvString(&g_pwszSanitizedChar, L"CertSrv_Sanitize");
  985. #if DBG_CERTSRV
  986. myGetEnvString(&g_pwszDumpStrings, L"CertSrv_DumpStrings");
  987. #endif
  988. // figure out where the system root directory is (build path to x:\\winnt\system32\)
  989. ui = GetSystemDirectory(NULL, 0); // returns chars neccessary to hold path (incl null)
  990. if (ui == 0)
  991. {
  992. hr = myHLastError();
  993. _JumpError(hr, error, "GetSystemDirectory");
  994. }
  995. pComp->pwszSystem32 = (LPWSTR)LocalAlloc(LMEM_FIXED, (ui+1)*sizeof(WCHAR));
  996. if (NULL == pComp->pwszSystem32)
  997. {
  998. hr = E_OUTOFMEMORY;
  999. _JumpError(hr, error, "LocalAlloc");
  1000. }
  1001. if (0 == GetSystemDirectory(pComp->pwszSystem32, ui))
  1002. {
  1003. hr = myHLastError();
  1004. _JumpError(hr, error, "GetSystemDirectory");
  1005. }
  1006. wcscat(pComp->pwszSystem32, L"\\");
  1007. // load default atrributes anyway
  1008. hr = LoadDefaultCAServerAttributes(pComp);
  1009. _JumpIfError(hr, error, "LoadDefaultCAServerAttributes");
  1010. hr = LoadDefaultCAClientAttributes(pComp);
  1011. _JumpIfError(hr, error, "LoadDefaultCAClientAttributes");
  1012. if (pComp->fUnattended)
  1013. {
  1014. // hook unattended data
  1015. hr = HookUnattendedServerAttributes(pComp,
  1016. LookupSubComponent(cscServer));
  1017. _JumpIfError(hr, error, "HookUnattendedServerAttributes");
  1018. hr = HookUnattendedClientAttributes(pComp,
  1019. LookupSubComponent(cscClient));
  1020. _JumpIfError(hr, error, "HookUnattendedClientAttributes");
  1021. }
  1022. hr = S_OK;
  1023. error:
  1024. return(hr);
  1025. }
  1026. HRESULT
  1027. CreateInitialCertificateRequest(
  1028. IN HCRYPTPROV hProv,
  1029. IN CASERVERSETUPINFO *pServer,
  1030. IN PER_COMPONENT_DATA *pComp,
  1031. IN HWND hwnd,
  1032. OUT BYTE **ppbEncode,
  1033. OUT DWORD *pcbEncode)
  1034. {
  1035. HRESULT hr;
  1036. BYTE *pbSubjectEncoded = NULL;
  1037. DWORD cbSubjectEncoded;
  1038. HINF hInf = INVALID_HANDLE_VALUE;
  1039. DWORD ErrorLine;
  1040. hr = AddCNAndEncode(
  1041. pServer->pwszCACommonName,
  1042. pServer->pwszDNSuffix,
  1043. &pbSubjectEncoded,
  1044. &cbSubjectEncoded);
  1045. _JumpIfError(hr, error, "AddCNAndEncodeCertStrToName");
  1046. hr = myInfOpenFile(NULL, &hInf, &ErrorLine);
  1047. _PrintIfError2(
  1048. hr,
  1049. "myInfOpenFile",
  1050. HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
  1051. hr = csiBuildRequest(
  1052. hInf,
  1053. NULL,
  1054. pbSubjectEncoded,
  1055. cbSubjectEncoded,
  1056. pServer->pszAlgId,
  1057. TRUE, // fNewKey
  1058. CANAMEIDTOICERT(pServer->dwCertNameId),
  1059. CANAMEIDTOIKEY(pServer->dwCertNameId),
  1060. hProv,
  1061. hwnd,
  1062. pComp->hInstance,
  1063. pComp->fUnattended,
  1064. ppbEncode,
  1065. pcbEncode);
  1066. _JumpIfError(hr, error, "csiBuildRequest");
  1067. error:
  1068. if (INVALID_HANDLE_VALUE != hInf)
  1069. {
  1070. myInfCloseFile(hInf);
  1071. }
  1072. if (NULL != pbSubjectEncoded)
  1073. {
  1074. myFree(pbSubjectEncoded, CERTLIB_USE_LOCALALLOC);
  1075. }
  1076. CSILOG(hr, IDS_LOG_CREATE_REQUEST, NULL, NULL, NULL);
  1077. return(hr);
  1078. }
  1079. HRESULT
  1080. BuildCAHierarchy(
  1081. HCRYPTPROV hProv,
  1082. PER_COMPONENT_DATA *pComp,
  1083. CRYPT_KEY_PROV_INFO const *pKeyProvInfo,
  1084. HWND hwnd)
  1085. {
  1086. HRESULT hr;
  1087. BYTE *pbRequest = NULL;
  1088. DWORD cbRequest;
  1089. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  1090. BSTR bStrChain = NULL;
  1091. if (!pServer->fSaveRequestAsFile)
  1092. {
  1093. // online case
  1094. if (NULL == pServer->pwszParentCAMachine ||
  1095. NULL == pServer->pwszParentCAName)
  1096. {
  1097. hr = E_POINTER;
  1098. _JumpError(hr, error, "Empty machine name or parent ca name");
  1099. }
  1100. }
  1101. // create request 1st
  1102. hr = CreateInitialCertificateRequest(
  1103. hProv,
  1104. pServer,
  1105. pComp,
  1106. hwnd,
  1107. &pbRequest,
  1108. &cbRequest);
  1109. if (S_OK != hr)
  1110. {
  1111. pComp->iErrMsg = IDS_ERR_BUILDCERTREQUEST;
  1112. _JumpError(hr, error, "CreateInitialCertificateRequest");
  1113. }
  1114. // save it to a file always
  1115. hr = EncodeToFileW(
  1116. pServer->pwszRequestFile,
  1117. pbRequest,
  1118. cbRequest,
  1119. DECF_FORCEOVERWRITE | CRYPT_STRING_BASE64REQUESTHEADER);
  1120. _JumpIfError(hr, error, "EncodeToFileW");
  1121. // register request file name always
  1122. hr = mySetCARegFileNameTemplate(
  1123. wszREGREQUESTFILENAME,
  1124. pComp->pwszServerName,
  1125. pServer->pwszSanitizedName,
  1126. pServer->pwszRequestFile);
  1127. _JumpIfErrorStr(hr, error, "mySetCARegFileNameTemplate", wszREGREQUESTFILENAME);
  1128. if (pServer->fSaveRequestAsFile)
  1129. {
  1130. // mark it as request file
  1131. hr = SetSetupStatus(
  1132. pServer->pwszSanitizedName,
  1133. SETUP_SUSPEND_FLAG | SETUP_REQUEST_FLAG,
  1134. TRUE);
  1135. _JumpIfError(hr, error, "SetSetupStatus");
  1136. // done if save as request file
  1137. goto done;
  1138. }
  1139. hr = csiSubmitCARequest(
  1140. pComp->hInstance,
  1141. pComp->fUnattended,
  1142. hwnd,
  1143. FALSE, // fRenew
  1144. 0, // ICert
  1145. FALSE, // fRetrievePending
  1146. pServer->pwszSanitizedName,
  1147. pServer->pwszParentCAMachine,
  1148. pServer->pwszParentCAName,
  1149. pbRequest,
  1150. cbRequest,
  1151. &bStrChain);
  1152. // in any case, you can finish setup from mmc
  1153. _JumpIfError(hr, done, "csiSubmitCARequest");
  1154. hr = csiFinishInstallationFromPKCS7(
  1155. pComp->hInstance,
  1156. pComp->fUnattended,
  1157. hwnd,
  1158. pServer->pwszSanitizedName,
  1159. pServer->pwszCACommonName,
  1160. pKeyProvInfo,
  1161. pServer->CAType,
  1162. CANAMEIDTOICERT(pServer->dwCertNameId),
  1163. CANAMEIDTOIKEY(pServer->dwCertNameId),
  1164. pServer->fUseDS,
  1165. FALSE, // fRenew
  1166. pComp->pwszServerName,
  1167. (BYTE *) bStrChain,
  1168. SysStringByteLen(bStrChain),
  1169. pServer->pwszCACertFile);
  1170. _JumpIfError(hr, error, "csiFinishInstallationFromPKCS7");
  1171. done:
  1172. hr = S_OK;
  1173. error:
  1174. if (NULL != pbRequest)
  1175. {
  1176. myFree(pbRequest, CERTLIB_USE_LOCALALLOC);
  1177. }
  1178. if (NULL != bStrChain)
  1179. {
  1180. SysFreeString(bStrChain);
  1181. }
  1182. return(hr);
  1183. }
  1184. // Find the newest CA cert that:
  1185. // - matches the passed Subject CN,
  1186. // - matches the passed cert index,
  1187. // - expires prior the next newer cert (compare to pNotAfter)
  1188. // - expires latest of all that match the above
  1189. // - has KeyProvInfo
  1190. // - key and cert can be used together to sign
  1191. HRESULT
  1192. SetCARegOldCertHashByIndex(
  1193. IN WCHAR const *pwszSanitizedName,
  1194. IN HCERTSTORE hStore,
  1195. IN WCHAR const *pwszCN,
  1196. IN DWORD iCert,
  1197. IN OUT FILETIME *pNotAfter)
  1198. {
  1199. HRESULT hr;
  1200. CERT_CONTEXT const *pCert = NULL;
  1201. CERT_CONTEXT const *pCertNewest = NULL;
  1202. WCHAR *pwszCNT = NULL;
  1203. DWORD dwProvType;
  1204. WCHAR *pwszProvName = NULL;
  1205. ALG_ID idAlg;
  1206. BOOL fMachineKeyset;
  1207. DWORD dwNameId;
  1208. DWORD cbKey;
  1209. CRYPT_KEY_PROV_INFO *pKey = NULL;
  1210. hr = myGetCertSrvCSP(
  1211. FALSE, // fEncryptionCSP
  1212. pwszSanitizedName,
  1213. &dwProvType,
  1214. &pwszProvName,
  1215. &idAlg,
  1216. &fMachineKeyset,
  1217. NULL); // pdwKeySize
  1218. _JumpIfError(hr, error, "myGetCertSrvCSP");
  1219. for (;;)
  1220. {
  1221. if (NULL != pKey)
  1222. {
  1223. LocalFree(pKey);
  1224. pKey = NULL;
  1225. }
  1226. if (NULL != pwszCNT)
  1227. {
  1228. LocalFree(pwszCNT);
  1229. pwszCNT = NULL;
  1230. }
  1231. pCert = CertEnumCertificatesInStore(hStore, pCert);
  1232. if (NULL == pCert)
  1233. {
  1234. break;
  1235. }
  1236. hr = myGetCommonName(
  1237. &pCert->pCertInfo->Subject,
  1238. FALSE, // fAllowDefault
  1239. &pwszCNT);
  1240. if (S_OK != hr)
  1241. {
  1242. _PrintError(hr, "myGetCommonName");
  1243. continue;
  1244. }
  1245. if (0 != lstrcmp(pwszCN, pwszCNT))
  1246. {
  1247. DBGPRINT((DBG_SS_CERTOCM, "Skipping cert: %ws\n", pwszCNT));
  1248. continue;
  1249. }
  1250. hr = myGetNameId(pCert, &dwNameId);
  1251. if (S_OK != hr ||
  1252. MAXDWORD == dwNameId ||
  1253. CANAMEIDTOICERT(dwNameId) != iCert)
  1254. {
  1255. DBGPRINT((DBG_SS_CERTOCM, "Skipping cert: NameId=%x\n", dwNameId));
  1256. continue;
  1257. }
  1258. DBGPRINT((DBG_SS_CERTOCM, "NameId=%x\n", dwNameId));
  1259. if (0 < CompareFileTime(&pCert->pCertInfo->NotAfter, pNotAfter))
  1260. {
  1261. DBGPRINT((DBG_SS_CERTOCM, "Skipping cert: too new\n"));
  1262. continue;
  1263. }
  1264. if (!myCertGetCertificateContextProperty(
  1265. pCert,
  1266. CERT_KEY_PROV_INFO_PROP_ID,
  1267. CERTLIB_USE_LOCALALLOC,
  1268. (VOID **) &pKey,
  1269. &cbKey))
  1270. {
  1271. hr = myHLastError();
  1272. _PrintError(hr, "CertGetCertificateContextProperty");
  1273. continue;
  1274. }
  1275. hr = myValidateSigningKey(
  1276. pKey->pwszContainerName,
  1277. pwszProvName,
  1278. dwProvType,
  1279. FALSE, // fCryptSilent
  1280. fMachineKeyset,
  1281. TRUE, // fForceSignatureTest
  1282. pCert,
  1283. NULL, // pPublicKeyInfo
  1284. idAlg,
  1285. NULL, // pfSigningTestAttempted
  1286. NULL); // phProv
  1287. if (S_OK != hr)
  1288. {
  1289. _PrintError(hr, "myValidateSigningKey");
  1290. continue;
  1291. }
  1292. if (NULL != pCertNewest)
  1293. {
  1294. if (0 > CompareFileTime(
  1295. &pCert->pCertInfo->NotAfter,
  1296. &pCertNewest->pCertInfo->NotAfter))
  1297. {
  1298. DBGPRINT((DBG_SS_CERTOCM, "Skipping cert: not newest\n"));
  1299. continue;
  1300. }
  1301. CertFreeCertificateContext(pCertNewest);
  1302. pCertNewest = NULL;
  1303. }
  1304. pCertNewest = CertDuplicateCertificateContext(pCert);
  1305. if (NULL == pCertNewest)
  1306. {
  1307. hr = myHLastError();
  1308. _JumpError(hr, error, "CertDuplicateCertificate");
  1309. }
  1310. }
  1311. if (NULL == pCertNewest)
  1312. {
  1313. hr = CRYPT_E_NOT_FOUND;
  1314. _JumpError(hr, error, "CertEnumCertificatesInStore");
  1315. }
  1316. // mark as unarchived:
  1317. CertSetCertificateContextProperty(
  1318. pCertNewest,
  1319. CERT_ARCHIVED_PROP_ID,
  1320. 0,
  1321. NULL);
  1322. hr = mySetCARegHash(pwszSanitizedName, CSRH_CASIGCERT, iCert, pCertNewest);
  1323. _JumpIfError(hr, error, "mySetCARegHash");
  1324. *pNotAfter = pCertNewest->pCertInfo->NotAfter;
  1325. error:
  1326. if (NULL != pKey)
  1327. {
  1328. LocalFree(pKey);
  1329. }
  1330. if (NULL != pwszCNT)
  1331. {
  1332. LocalFree(pwszCNT);
  1333. }
  1334. if (NULL != pwszProvName)
  1335. {
  1336. LocalFree(pwszProvName);
  1337. }
  1338. if (NULL != pCertNewest)
  1339. {
  1340. CertFreeCertificateContext(pCertNewest);
  1341. }
  1342. if (NULL != pCert)
  1343. {
  1344. CertFreeCertificateContext(pCert);
  1345. }
  1346. return(hr);
  1347. }
  1348. HRESULT
  1349. SetCARegOldCertHashes(
  1350. IN WCHAR const *pwszSanitizedName,
  1351. IN DWORD cCertOld,
  1352. IN CERT_CONTEXT const *pccCA)
  1353. {
  1354. HRESULT hr;
  1355. HCERTSTORE hMyStore = NULL;
  1356. DWORD i;
  1357. WCHAR *pwszCN = NULL;
  1358. FILETIME NotAfter;
  1359. if (0 != cCertOld)
  1360. {
  1361. hr = myGetCommonName(
  1362. &pccCA->pCertInfo->Subject,
  1363. FALSE, // fAllowDefault
  1364. &pwszCN);
  1365. _JumpIfError(hr, error, "myGetCommonName");
  1366. // open my store
  1367. hMyStore = CertOpenStore(
  1368. CERT_STORE_PROV_SYSTEM_W,
  1369. X509_ASN_ENCODING,
  1370. NULL, // hProv
  1371. CERT_SYSTEM_STORE_LOCAL_MACHINE |
  1372. CERT_STORE_ENUM_ARCHIVED_FLAG |
  1373. CERT_STORE_READONLY_FLAG,
  1374. wszMY_CERTSTORE);
  1375. if (NULL == hMyStore)
  1376. {
  1377. hr = myHLastError();
  1378. _JumpError(hr, error, "CertOpenStore");
  1379. }
  1380. NotAfter = pccCA->pCertInfo->NotAfter;
  1381. for (i = cCertOld; i > 0; i--)
  1382. {
  1383. hr = SetCARegOldCertHashByIndex(
  1384. pwszSanitizedName,
  1385. hMyStore,
  1386. pwszCN,
  1387. i - 1,
  1388. &NotAfter);
  1389. _PrintIfError(hr, "SetCARegOldCertHashByIndex");
  1390. }
  1391. }
  1392. hr = S_OK;
  1393. error:
  1394. if (NULL != pwszCN)
  1395. {
  1396. LocalFree(pwszCN);
  1397. }
  1398. if (NULL != hMyStore)
  1399. {
  1400. CertCloseStore(hMyStore, 0);
  1401. }
  1402. return(hr);
  1403. }
  1404. HRESULT
  1405. CreateCertificates(
  1406. IN OUT PER_COMPONENT_DATA *pComp,
  1407. IN HWND hwnd)
  1408. {
  1409. HRESULT hr;
  1410. HCRYPTPROV hCryptProv = NULL;
  1411. CRYPT_KEY_PROV_INFO keyProvInfo;
  1412. WCHAR wszEnrollPath[MAX_PATH];
  1413. CERT_CONTEXT const *pccCA = NULL;
  1414. BYTE *pbEncoded = NULL;
  1415. WCHAR *pwszEnrollPath = NULL;
  1416. WCHAR *pwszDir = NULL;
  1417. WCHAR *pwszFolderPath = NULL;
  1418. BOOL fEnableKeyCounting = FALSE;
  1419. wszEnrollPath[0] = L'\0';
  1420. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  1421. ZeroMemory(&keyProvInfo, sizeof(keyProvInfo));
  1422. if (NULL == pServer->pwszKeyContainerName && pComp->fUnattended)
  1423. {
  1424. hr = myInfGetEnableKeyCounting(
  1425. pComp->hinfCAPolicy,
  1426. &fEnableKeyCounting);
  1427. if (S_OK != hr)
  1428. {
  1429. fEnableKeyCounting = FALSE;
  1430. }
  1431. // create a new key if unattended
  1432. hr = csiGenerateCAKeys(
  1433. pServer->pwszSanitizedName,
  1434. pServer->pCSPInfo->pwszProvName,
  1435. pServer->pCSPInfo->dwProvType,
  1436. pServer->pCSPInfo->fMachineKeyset,
  1437. pServer->dwKeyLength,
  1438. pComp->hInstance,
  1439. pComp->fUnattended,
  1440. fEnableKeyCounting,
  1441. hwnd,
  1442. &pComp->CA.pServer->fKeyGenFailed);
  1443. if (S_OK != hr)
  1444. {
  1445. CertErrorMessageBox(
  1446. pComp->hInstance,
  1447. pComp->fUnattended,
  1448. hwnd,
  1449. IDS_ERR_FATAL_GENKEY,
  1450. hr,
  1451. pServer->pwszSanitizedName);
  1452. _JumpIfError(hr, error, "csiGenerateCAKeys");
  1453. }
  1454. // now set this as the existing key
  1455. hr = SetKeyContainerName(pServer, pServer->pwszSanitizedName);
  1456. _JumpIfError(hr, error, "SetKeyContainerName");
  1457. }
  1458. hr = csiFillKeyProvInfo(
  1459. pServer->pwszKeyContainerName,
  1460. pServer->pCSPInfo->pwszProvName,
  1461. pServer->pCSPInfo->dwProvType,
  1462. pServer->pCSPInfo->fMachineKeyset,
  1463. &keyProvInfo);
  1464. _JumpIfError(hr, error, "csiFillKeyProvInfo");
  1465. // get csp handle
  1466. if (!myCertSrvCryptAcquireContext(
  1467. &hCryptProv,
  1468. pServer->pwszKeyContainerName,
  1469. pServer->pCSPInfo->pwszProvName,
  1470. pServer->pCSPInfo->dwProvType,
  1471. pComp->fUnattended? CRYPT_SILENT : 0, // query
  1472. pServer->pCSPInfo->fMachineKeyset))
  1473. {
  1474. hr = myHLastError();
  1475. _JumpError(hr, error, "myCertSrvCryptAcquireContext");
  1476. }
  1477. if (hCryptProv == NULL)
  1478. {
  1479. hr = E_HANDLE;
  1480. _JumpError(hr, error, "myCertSrvCryptAcquireContext");
  1481. }
  1482. // open certificate store
  1483. if (NULL == pServer->hMyStore)
  1484. {
  1485. pServer->hMyStore = CertOpenStore(
  1486. CERT_STORE_PROV_SYSTEM_W,
  1487. X509_ASN_ENCODING,
  1488. NULL, // hProv
  1489. CERT_SYSTEM_STORE_LOCAL_MACHINE |
  1490. CERT_STORE_ENUM_ARCHIVED_FLAG,
  1491. wszMY_CERTSTORE);
  1492. if (NULL == pServer->hMyStore)
  1493. {
  1494. // no store exists, done
  1495. hr = myHLastError();
  1496. _JumpIfError(hr, error, "CertOpenStore");
  1497. }
  1498. }
  1499. if (NULL != pServer->pccExistingCert)
  1500. {
  1501. // reuse cert, mark unarchived
  1502. CertSetCertificateContextProperty(
  1503. pServer->pccExistingCert,
  1504. CERT_ARCHIVED_PROP_ID,
  1505. 0,
  1506. NULL);
  1507. }
  1508. if (IsSubordinateCA(pServer->CAType) && NULL == pServer->pccExistingCert)
  1509. {
  1510. hr = BuildCAHierarchy(hCryptProv, pComp, &keyProvInfo, hwnd);
  1511. _JumpIfError(hr, error, "BuildCAHierarchy");
  1512. }
  1513. else
  1514. {
  1515. WCHAR const *pwszCertName;
  1516. DWORD cwc;
  1517. BuildPath(
  1518. wszEnrollPath,
  1519. ARRAYSIZE(wszEnrollPath),
  1520. pComp->pwszSystem32,
  1521. wszCERTENROLLSHAREPATH);
  1522. hr = csiBuildFileName(
  1523. wszEnrollPath,
  1524. pServer->pwszSanitizedName,
  1525. L".crt",
  1526. CANAMEIDTOICERT(pServer->dwCertNameId),
  1527. &pwszEnrollPath,
  1528. pComp->hInstance,
  1529. pComp->fUnattended,
  1530. NULL);
  1531. _JumpIfError(hr, error, "csiBuildFileName");
  1532. CSASSERT(NULL != pServer->pwszCACertFile);
  1533. pwszCertName = wcsrchr(pServer->pwszCACertFile, L'\\');
  1534. CSASSERT(NULL != pwszCertName);
  1535. cwc = SAFE_SUBTRACT_POINTERS(pwszCertName, pServer->pwszCACertFile);
  1536. pwszDir = (WCHAR *) LocalAlloc(LMEM_FIXED, (cwc + 1) * sizeof(WCHAR));
  1537. if (NULL == pwszDir)
  1538. {
  1539. hr = E_OUTOFMEMORY;
  1540. _JumpError(hr, error, "LocalAlloc");
  1541. }
  1542. CopyMemory(pwszDir, pServer->pwszCACertFile, cwc * sizeof(WCHAR));
  1543. pwszDir[cwc] = L'\0';
  1544. hr = csiBuildFileName(
  1545. pwszDir,
  1546. pServer->pwszSanitizedName,
  1547. L".crt",
  1548. CANAMEIDTOICERT(pServer->dwCertNameId),
  1549. &pwszFolderPath,
  1550. pComp->hInstance,
  1551. pComp->fUnattended,
  1552. NULL);
  1553. _JumpIfError(hr, error, "csiBuildFileName");
  1554. // create and save a selfsigned root cert
  1555. hr = csiBuildAndWriteCert(
  1556. hCryptProv,
  1557. pServer,
  1558. pwszFolderPath,
  1559. pwszEnrollPath,
  1560. pServer->pccExistingCert, // if NULL, we will build a new cert
  1561. &pccCA,
  1562. wszCERTTYPE_CA,
  1563. pComp->hInstance,
  1564. pComp->fUnattended,
  1565. hwnd);
  1566. if (S_OK != hr)
  1567. {
  1568. CertErrorMessageBox(
  1569. pComp->hInstance,
  1570. pComp->fUnattended,
  1571. hwnd,
  1572. IDS_ERR_BUILDCERT,
  1573. hr,
  1574. NULL);
  1575. _JumpError(hr, error, "csiBuildAndWriteCert");
  1576. }
  1577. hr = SetCARegOldCertHashes(
  1578. pServer->pwszSanitizedName,
  1579. CANAMEIDTOICERT(pServer->dwCertNameId),
  1580. pccCA);
  1581. _JumpIfError(hr, error, "SetCARegOldCertHashes");
  1582. hr = mySetCARegHash(
  1583. pServer->pwszSanitizedName,
  1584. CSRH_CASIGCERT,
  1585. CANAMEIDTOICERT(pServer->dwCertNameId),
  1586. pccCA);
  1587. _JumpIfError(hr, error, "mySetCARegHash");
  1588. hr = csiSaveCertAndKeys(pccCA, NULL, &keyProvInfo, pServer->CAType);
  1589. _JumpIfError(hr, error, "csiSaveCertAndKeys");
  1590. if (pServer->fUseDS)
  1591. {
  1592. BOOL fLoadDefaultTemplates = TRUE;
  1593. DWORD ErrorLine;
  1594. HINF hInf = INVALID_HANDLE_VALUE;
  1595. hr = myInfOpenFile(NULL, &hInf, &ErrorLine);
  1596. _PrintIfError2(
  1597. hr,
  1598. "myInfOpenFile",
  1599. HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
  1600. if (INVALID_HANDLE_VALUE != hInf)
  1601. {
  1602. hr = myInfGetBooleanValue(
  1603. hInf,
  1604. wszINFSECTION_CERTSERVER,
  1605. wszINFKEY_LOADDEFAULTTEMPLATES,
  1606. TRUE,
  1607. &fLoadDefaultTemplates);
  1608. if (S_OK != hr)
  1609. {
  1610. _PrintErrorStr(
  1611. hr,
  1612. "myInfGetBooleanValue",
  1613. wszINFKEY_LOADDEFAULTTEMPLATES);
  1614. fLoadDefaultTemplates = TRUE;
  1615. }
  1616. myInfCloseFile(hInf);
  1617. }
  1618. hr = csiSetupCAInDS(
  1619. pComp->pwszServerName,
  1620. pServer->pwszSanitizedName,
  1621. pServer->pwszCACommonName,
  1622. fLoadDefaultTemplates,
  1623. pServer->CAType,
  1624. CANAMEIDTOICERT(pServer->dwCertNameId),
  1625. CANAMEIDTOIKEY(pServer->dwCertNameId),
  1626. FALSE, // fRenew
  1627. pccCA);
  1628. _PrintIfError(hr, "csiSetupCAInDS");
  1629. if (hr == S_OK)
  1630. pServer->fSavedCAInDS = TRUE;
  1631. }
  1632. }
  1633. hr = S_OK;
  1634. error:
  1635. csiFreeKeyProvInfo(&keyProvInfo);
  1636. if (NULL != pbEncoded)
  1637. {
  1638. LocalFree(pbEncoded);
  1639. }
  1640. if (NULL != pwszDir)
  1641. {
  1642. LocalFree(pwszDir);
  1643. }
  1644. if (NULL != pwszFolderPath)
  1645. {
  1646. LocalFree(pwszFolderPath);
  1647. }
  1648. if (NULL != pwszEnrollPath)
  1649. {
  1650. LocalFree(pwszEnrollPath);
  1651. }
  1652. if (NULL != pccCA)
  1653. {
  1654. CertFreeCertificateContext(pccCA);
  1655. }
  1656. if (NULL != hCryptProv)
  1657. {
  1658. CryptReleaseContext(hCryptProv, 0);
  1659. }
  1660. CSILOG(hr, IDS_LOG_CREATE_CERTIFICATE, NULL, NULL, NULL);
  1661. return(hr);
  1662. }
  1663. HRESULT
  1664. StartCertsrvService(BOOL fSilent)
  1665. {
  1666. HRESULT hr;
  1667. SC_HANDLE hSCManager = NULL;
  1668. SC_HANDLE hSCCertsvc = NULL;
  1669. SERVICE_STATUS status;
  1670. DWORD dwAttempt;
  1671. BOOL fSawPending;
  1672. WCHAR const *apwszSilentArg[1] = {L"-s"};
  1673. hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  1674. if (NULL == hSCManager)
  1675. {
  1676. hr = myHLastError();
  1677. _JumpError(hr, error, "OpenSCManager");
  1678. }
  1679. hSCCertsvc = OpenService(
  1680. hSCManager,
  1681. wszSERVICE_NAME,
  1682. SERVICE_ALL_ACCESS);
  1683. if (NULL == hSCCertsvc)
  1684. {
  1685. hr = myHLastError();
  1686. _JumpErrorStr(hr, error, "OpenService", wszSERVICE_NAME);
  1687. }
  1688. // START the service
  1689. if (!StartService(hSCCertsvc,
  1690. fSilent ? 1 : 0,
  1691. fSilent ? apwszSilentArg : NULL))
  1692. {
  1693. hr = myHLastError();
  1694. _JumpErrorStr(hr, error, "StartService", wszSERVICE_NAME);
  1695. }
  1696. // get out after it is really started
  1697. fSawPending = FALSE;
  1698. DBGCODE(status.dwCurrentState = MAXDWORD);
  1699. for (dwAttempt = 0; dwAttempt < CERT_MAX_ATTEMPT; dwAttempt++)
  1700. {
  1701. DBGCODE(status.dwCurrentState = MAXDWORD);
  1702. if (!QueryServiceStatus(hSCCertsvc, &status))
  1703. {
  1704. // query failed, ignore error
  1705. hr = S_OK;
  1706. _JumpErrorStr(
  1707. myHLastError(), // Display ignored error
  1708. error,
  1709. "QueryServiceStatus",
  1710. wszSERVICE_NAME);
  1711. }
  1712. if (SERVICE_START_PENDING != status.dwCurrentState &&
  1713. SERVICE_STOPPED != status.dwCurrentState)
  1714. {
  1715. // it was started already
  1716. break;
  1717. }
  1718. DBGPRINT((
  1719. DBG_SS_CERTOCM,
  1720. "Starting %ws service: current state=%d\n",
  1721. wszSERVICE_NAME,
  1722. status.dwCurrentState));
  1723. if (fSawPending && SERVICE_STOPPED == status.dwCurrentState)
  1724. {
  1725. hr = HRESULT_FROM_WIN32(ERROR_SERVICE_NEVER_STARTED);
  1726. _JumpErrorStr(
  1727. hr,
  1728. error,
  1729. "Service won't start",
  1730. wszSERVICE_NAME);
  1731. }
  1732. if (SERVICE_START_PENDING == status.dwCurrentState)
  1733. {
  1734. fSawPending = TRUE;
  1735. }
  1736. Sleep(CERT_HALF_SECOND);
  1737. }
  1738. if (dwAttempt >= CERT_MAX_ATTEMPT)
  1739. {
  1740. DBGPRINT((
  1741. DBG_SS_CERTOCM,
  1742. "Timeout starting %ws service: current state=%d\n",
  1743. wszSERVICE_NAME,
  1744. status.dwCurrentState));
  1745. }
  1746. else
  1747. {
  1748. DBGPRINT((
  1749. DBG_SS_CERTOCM,
  1750. "Started %ws service\n",
  1751. wszSERVICE_NAME));
  1752. }
  1753. hr = S_OK;
  1754. error:
  1755. if (NULL != hSCCertsvc)
  1756. {
  1757. CloseServiceHandle(hSCCertsvc);
  1758. }
  1759. if (NULL != hSCManager)
  1760. {
  1761. CloseServiceHandle(hSCManager);
  1762. }
  1763. CSILOG(hr, IDS_LOG_START_SERVICE, NULL, NULL, NULL);
  1764. return(hr);
  1765. }
  1766. HRESULT
  1767. EnforceCertFileExtensions(
  1768. PER_COMPONENT_DATA *pComp)
  1769. {
  1770. HRESULT hr;
  1771. WCHAR *pwszTmp = NULL;
  1772. WCHAR *pwszSuffix;
  1773. BOOL fAppendExtension = TRUE;
  1774. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  1775. if (NULL == pServer->pwszCACertFile)
  1776. {
  1777. // no ca cert file
  1778. goto done;
  1779. }
  1780. // make enough to hold extra extension crt
  1781. pwszTmp = (WCHAR *) LocalAlloc(
  1782. LMEM_FIXED,
  1783. (wcslen(pServer->pwszCACertFile) + 5) * sizeof(WCHAR));
  1784. _JumpIfOutOfMemory(hr, error, pwszTmp);
  1785. wcscpy(pwszTmp, pServer->pwszCACertFile);
  1786. // check to make sure our self-signed file has the right extension
  1787. // Is there an extension?
  1788. pwszSuffix = wcsrchr(pwszTmp, L'.');
  1789. if (NULL != pwszSuffix)
  1790. {
  1791. // Is the stuff after the '.' already a 'crt' extension?
  1792. if (0 == LSTRCMPIS(pwszSuffix, L".crt"))
  1793. {
  1794. fAppendExtension = FALSE;
  1795. }
  1796. else if (pwszSuffix[1] == L'\0') // Is '.' last character?
  1797. {
  1798. while (pwszSuffix >= pwszTmp && *pwszSuffix == L'.')
  1799. {
  1800. *pwszSuffix-- = L'\0';
  1801. }
  1802. }
  1803. }
  1804. if (fAppendExtension)
  1805. {
  1806. // Apply the extension
  1807. wcscat(pwszTmp, L".crt");
  1808. // free old one
  1809. LocalFree(pServer->pwszCACertFile);
  1810. pServer->pwszCACertFile = pwszTmp;
  1811. pwszTmp = NULL;
  1812. }
  1813. done:
  1814. hr = S_OK;
  1815. error:
  1816. if (NULL != pwszTmp)
  1817. {
  1818. LocalFree(pwszTmp);
  1819. }
  1820. return(hr);
  1821. }
  1822. HRESULT
  1823. PrepareEDBDirectory(
  1824. HWND hwnd,
  1825. PER_COMPONENT_DATA *pComp,
  1826. WCHAR const *pwszDir)
  1827. {
  1828. HRESULT hr;
  1829. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  1830. DWORD dwAttr = GetFileAttributes(pwszDir);
  1831. if (MAXDWORD == dwAttr)
  1832. {
  1833. // file not found or other error
  1834. hr = myHLastError();
  1835. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) != hr)
  1836. {
  1837. _JumpError(hr, error, "GetFileAttributes");
  1838. }
  1839. if (!CreateDirectory(pwszDir, NULL))
  1840. {
  1841. hr = myHLastError();
  1842. _JumpError(hr, error, "CreateDirectory");
  1843. }
  1844. }
  1845. else if (!(dwAttr & FILE_ATTRIBUTE_DIRECTORY))
  1846. {
  1847. // file already exists but it's not a directory
  1848. hr = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS);
  1849. _JumpError(hr, error, "GetFileAttributes");
  1850. }
  1851. if (!pServer->fPreserveDB)
  1852. {
  1853. hr = myDeleteDBFilesInDir(pwszDir);
  1854. _JumpIfError(hr, error, "myDeleteDBFilesInDir");
  1855. }
  1856. hr = S_OK;
  1857. error:
  1858. if (S_OK != hr)
  1859. {
  1860. CertErrorMessageBox(
  1861. pComp->hInstance,
  1862. pComp->fUnattended,
  1863. hwnd,
  1864. 0,
  1865. hr,
  1866. L""); // only message is the system error message
  1867. }
  1868. return(hr);
  1869. }
  1870. //--------------------------------------------------------------------
  1871. // Create the web configuration files
  1872. HRESULT
  1873. CreateCertWebIncPages(
  1874. IN PER_COMPONENT_DATA *pComp,
  1875. IN BOOL bIsServer)
  1876. {
  1877. HRESULT hr;
  1878. CSASSERT(NULL != pComp);
  1879. // create the web configuration file
  1880. hr = CreateCertWebDatIncPage(pComp, bIsServer);
  1881. _JumpIfError(hr, error, "CreateCertWebDatIncPage");
  1882. error:
  1883. CSILOG(hr, IDS_LOG_WEB_INCLUDE, NULL, NULL, NULL);
  1884. return hr;
  1885. }
  1886. //--------------------------------------------------------------------
  1887. HRESULT
  1888. EnableVRootsAndShares(
  1889. IN BOOL fFileSharesOnly,
  1890. IN BOOL fUpgrade,
  1891. IN BOOL fServer,
  1892. IN PER_COMPONENT_DATA *pComp,
  1893. IN HWND hwnd)
  1894. {
  1895. HRESULT hr;
  1896. DWORD Flags = VFF_CREATEFILESHARES |
  1897. VFF_SETREGFLAGFIRST |
  1898. VFF_SETRUNONCEIFERROR |
  1899. VFF_CLEARREGFLAGIFOK;
  1900. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  1901. int ret;
  1902. bool fASPEnabled = false;
  1903. DWORD dwShareDisposition = 0;
  1904. DWORD dwVRootDisposition = 0;
  1905. CSASSERT(!fServer || NULL != pServer);
  1906. CSASSERT(fServer || NULL != pComp->CA.pClient);
  1907. if (!fFileSharesOnly)
  1908. {
  1909. Flags |= VFF_CREATEVROOTS;
  1910. hr = IsASPEnabledInIIS_New(fASPEnabled);
  1911. _JumpIfError(hr, error, "IsASPEnabledInIIS_New");
  1912. if(!fASPEnabled)
  1913. {
  1914. ret = CertMessageBox(
  1915. pComp->hInstance,
  1916. pComp->fUnattended,
  1917. hwnd,
  1918. IDS_WRN_ASP_NOT_ENABLED,
  1919. 0,
  1920. MB_YESNO |
  1921. MB_ICONWARNING |
  1922. CMB_NOERRFROMSYS |
  1923. MB_DEFBUTTON2,
  1924. NULL);
  1925. if (IDYES == ret)
  1926. {
  1927. Flags |= VFF_ENABLEASP;
  1928. }
  1929. }
  1930. }
  1931. // if NT GUI mode (base setup) VRoot creation will fail during setup
  1932. // because IIS is not yet operational. Make a mark in the registry
  1933. // to try this on NEXT service startup or via runonce.
  1934. hr = myModifyVirtualRootsAndFileShares(
  1935. Flags,
  1936. fServer? pServer->CAType : pComp->CA.pClient->WebCAType,
  1937. FALSE, // synchronous -- blocking call
  1938. VFCSEC_TIMEOUT,
  1939. &dwVRootDisposition,
  1940. &dwShareDisposition);
  1941. _JumpIfError(hr, error, "myModifyVirtualRootsAndFileShares");
  1942. if(VFD_VERIFYERROR == dwShareDisposition)
  1943. {
  1944. CertWarningMessageBox(
  1945. pComp->hInstance,
  1946. pComp->fUnattended,
  1947. hwnd,
  1948. IDS_SHARE_VERIFY_ERROR,
  1949. 0,
  1950. NULL);
  1951. }
  1952. if (!fUpgrade)
  1953. {
  1954. pServer->fCreatedShare = TRUE;
  1955. if (!fFileSharesOnly)
  1956. {
  1957. pComp->fCreatedVRoot = TRUE;
  1958. }
  1959. }
  1960. error:
  1961. CSILOGDWORD(IDS_LOG_SHARE_DISP, dwShareDisposition);
  1962. CSILOGDWORD(IDS_LOG_VROOT_DISP, dwVRootDisposition);
  1963. CSILOG(hr, IDS_LOG_VROOT_DISP, NULL, NULL, NULL);
  1964. return(hr);
  1965. }
  1966. HRESULT
  1967. DisableVRootsAndShares(
  1968. IN BOOL fVRoot,
  1969. IN BOOL fFileShares)
  1970. {
  1971. HRESULT hr;
  1972. DWORD Flags = 0;
  1973. if (fVRoot)
  1974. {
  1975. Flags |= VFF_DELETEVROOTS;
  1976. }
  1977. if (fFileShares)
  1978. {
  1979. Flags |= VFF_DELETEFILESHARES;
  1980. }
  1981. if (0 == Flags)
  1982. {
  1983. goto done;
  1984. }
  1985. hr = myModifyVirtualRootsAndFileShares(
  1986. Flags,
  1987. ENUM_UNKNOWN_CA,
  1988. FALSE, // synchronous -- blocking call
  1989. VFCSEC_TIMEOUT,
  1990. NULL,
  1991. NULL);
  1992. _JumpIfError(hr, error, "myModifyVirtualRootsAndFileShares");
  1993. done:
  1994. hr = S_OK;
  1995. error:
  1996. return(hr);
  1997. }
  1998. HRESULT
  1999. InstallClient(
  2000. HWND hwnd,
  2001. PER_COMPONENT_DATA *pComp)
  2002. {
  2003. BOOL fCoInit = FALSE;
  2004. HRESULT hr;
  2005. hr = CoInitialize(NULL);
  2006. if (S_OK != hr && S_FALSE != hr)
  2007. {
  2008. _JumpError(hr, error, "CoInitialize");
  2009. }
  2010. fCoInit = TRUE;
  2011. certocmBumpGasGauge(pComp, 10 DBGPARM(L"InstallClient"));
  2012. hr = CreateWebClientRegEntries(FALSE, pComp);
  2013. _JumpIfError(hr, error, "CreateWebClientRegEntries");
  2014. certocmBumpGasGauge(pComp, 30 DBGPARM(L"InstallClient"));
  2015. hr = RegisterAndUnRegisterDLLs(RD_CLIENT, pComp, hwnd);
  2016. _JumpIfError(hr, error, "RegisterAndUnRegisterDLLs");
  2017. certocmBumpGasGauge(pComp, 50 DBGPARM(L"InstallClient"));
  2018. DeleteProgramGroups(FALSE);
  2019. hr = CreateProgramGroups(TRUE, pComp, hwnd);
  2020. _JumpIfError(hr, error, "CreateProgramGroups");
  2021. certocmBumpGasGauge(pComp, 70 DBGPARM(L"InstallClient"));
  2022. hr = CreateCertWebIncPages(pComp, FALSE /* IsServer */ );
  2023. _JumpIfError(hr, error, "CreateCertWebIncPages");
  2024. hr = RenameMiscTargets(hwnd, pComp, FALSE);
  2025. _JumpIfError(hr, error, "RenameMiscTargets");
  2026. certocmBumpGasGauge(pComp, 80 DBGPARM(L"InstallClient"));
  2027. hr = EnableVRootsAndShares(FALSE, FALSE, FALSE, pComp, hwnd);
  2028. if(REGDB_E_CLASSNOTREG == hr ||
  2029. HRESULT_FROM_WIN32(ERROR_SERVICE_DOES_NOT_EXIST) == hr ||
  2030. HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr)
  2031. {
  2032. CertWarningMessageBox(
  2033. pComp->hInstance,
  2034. pComp->fUnattended,
  2035. hwnd,
  2036. IDS_WRN_IIS_NOT_INSTALLED,
  2037. 0,
  2038. NULL);
  2039. hr = S_OK;
  2040. }
  2041. _JumpIfError(hr, error, "EnableVRootsAndShares");
  2042. certocmBumpGasGauge(pComp, 100 DBGPARM(L"InstallClient"));
  2043. hr = S_OK;
  2044. error:
  2045. if (fCoInit)
  2046. {
  2047. CoUninitialize();
  2048. }
  2049. CSILOG(hr, IDS_LOG_INSTALL_CLIENT, NULL, NULL, NULL);
  2050. return(hr);
  2051. }
  2052. HRESULT
  2053. RemoveWebClientRegEntries(VOID)
  2054. {
  2055. HRESULT hr;
  2056. hr = myDeleteCertRegValue(NULL, NULL, NULL, wszREGWEBCLIENTCAMACHINE);
  2057. _PrintIfError(hr, "myDeleteCertRegValue");
  2058. hr = myDeleteCertRegValue(NULL, NULL, NULL, wszREGWEBCLIENTCANAME);
  2059. _PrintIfError(hr, "myDeleteCertRegValue");
  2060. hr = myDeleteCertRegValue(NULL, NULL, NULL, wszREGWEBCLIENTCATYPE);
  2061. _PrintIfError(hr, "myDeleteCertRegValue");
  2062. hr = S_OK;
  2063. //error:
  2064. return hr;
  2065. }
  2066. HRESULT
  2067. InstallServer(
  2068. HWND hwnd,
  2069. PER_COMPONENT_DATA *pComp)
  2070. {
  2071. BOOL fCoInit = FALSE;
  2072. WCHAR *pwszDBFile = NULL;
  2073. DWORD dwSetupStatus;
  2074. HRESULT hr = pComp->hrContinue;
  2075. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  2076. WCHAR *pwszConfig = NULL;
  2077. BOOL fSetDSSecurity;
  2078. _JumpIfError(hr, error, "can't continue");
  2079. hr = UpdateDomainAndUserName(hwnd, pComp);
  2080. _JumpIfError(hr, error, "UpdateDomainAndUserName");
  2081. hr = CoInitialize(NULL);
  2082. if (S_OK != hr && S_FALSE != hr)
  2083. {
  2084. _JumpError(hr, error, "CoInitialize");
  2085. }
  2086. fCoInit = TRUE;
  2087. hr = EnforceCertFileExtensions(pComp);
  2088. _JumpIfError(hr, error, "EnforceCertFileExtensions");
  2089. hr = PrepareEDBDirectory(hwnd, pComp, pServer->pwszDBDirectory);
  2090. _JumpIfError(hr, error, "PrepareEDBDirectory");
  2091. hr = PrepareEDBDirectory(hwnd, pComp, pServer->pwszLogDirectory);
  2092. _JumpIfError(hr, error, "PrepareEDBDirectory");
  2093. certocmBumpGasGauge(pComp, 10 DBGPARM(L"InstallServer"));
  2094. // alway uninstall before install
  2095. PreUninstallCore(hwnd, pComp);
  2096. UninstallCore(hwnd, pComp, 10, 30, FALSE, FALSE, FALSE);
  2097. hr = CreateServerRegEntries(FALSE, pComp);
  2098. _JumpIfError(hr, error, "CreateServerRegEntries");
  2099. if ((IS_SERVER_INSTALL & pComp->dwInstallStatus) &&
  2100. (IS_CLIENT_UPGRADE & pComp->dwInstallStatus))
  2101. {
  2102. // case of install server only and keep web client
  2103. // remove parent ca config info of the old web client
  2104. hr = RemoveWebClientRegEntries();
  2105. _PrintIfError(hr, "RemoveWebClientRegEntries");
  2106. }
  2107. certocmBumpGasGauge(pComp, 35 DBGPARM(L"InstallServer"));
  2108. hr = RegisterAndUnRegisterDLLs(RD_SERVER, pComp, hwnd);
  2109. _JumpIfError(hr, error, "RegisterAndUnRegisterDLLs");
  2110. certocmBumpGasGauge(pComp, 40 DBGPARM(L"InstallServer"));
  2111. hr = CreateCertificateService(pComp, hwnd);
  2112. _JumpIfError(hr, error, "CreateCertificateService");
  2113. certocmBumpGasGauge(pComp, 45 DBGPARM(L"InstallServer"));
  2114. hr = CreateCertificates(pComp, hwnd);
  2115. _JumpIfError(hr, error, "CreateCertificates");
  2116. certocmBumpGasGauge(pComp, 50 DBGPARM(L"InstallServer"));
  2117. hr = CreateProgramGroups(FALSE, pComp, hwnd);
  2118. _JumpIfError(hr, error, "CreateProgramGroups");
  2119. certocmBumpGasGauge(pComp, 60 DBGPARM(L"InstallServer"));
  2120. hr = CreateCertWebIncPages(pComp, TRUE /* IsServer */ );
  2121. _JumpIfError(hr, error, "CreateCertWebIncPages");
  2122. hr = RenameMiscTargets(hwnd, pComp, TRUE);
  2123. _JumpIfError(hr, error, "RenameMiscTargets");
  2124. certocmBumpGasGauge(pComp, 70 DBGPARM(L"InstallServer"));
  2125. hr = RegisterDcomServer(
  2126. TRUE,
  2127. CLSID_CCertRequestD, // AppId
  2128. CLSID_CCertRequestD,
  2129. wszREQUESTFRIENDLYNAME,
  2130. wszREQUESTVERINDPROGID,
  2131. wszREQUESTPROGID);
  2132. _JumpIfError(hr, error, "RegisterDcomServer");
  2133. hr = RegisterDcomServer(
  2134. FALSE,
  2135. CLSID_CCertRequestD, // AppId
  2136. CLSID_CCertAdminD,
  2137. wszADMINFRIENDLYNAME,
  2138. wszADMINVERINDPROGID,
  2139. wszADMINPROGID);
  2140. _JumpIfError(hr, error, "RegisterDcomServer");
  2141. certocmBumpGasGauge(pComp, 80 DBGPARM(L"InstallServer"));
  2142. hr = RegisterDcomApp(CLSID_CCertRequestD);
  2143. _JumpIfError(hr, error, "RegisterDcomApp");
  2144. certocmBumpGasGauge(pComp, 90 DBGPARM(L"InstallServer"));
  2145. if (pServer->fUseDS)
  2146. {
  2147. hr = AddCAMachineToCertPublishers();
  2148. if(S_OK != hr)
  2149. {
  2150. // put out a warning dlg
  2151. CertWarningMessageBox(
  2152. pComp->hInstance,
  2153. pComp->fUnattended,
  2154. hwnd,
  2155. IDS_WRN_CANNOT_ADD_CA_TO_CERTPUBLISHERS,
  2156. hr,
  2157. NULL);
  2158. }
  2159. _PrintIfError(hr, "AddCAMachineToCertPublishers");
  2160. // For restricted officers feature to work the CA needs access to
  2161. // group membership info in DS. Give it rights by adding it to
  2162. // Pre-Win2k group. Feature is enabled on advanced server only.
  2163. if(FIsAdvancedServer())
  2164. {
  2165. hr = AddCAMachineToPreWin2kGroup();
  2166. if(S_OK != hr)
  2167. {
  2168. // put out a warning dlg
  2169. CertWarningMessageBox(
  2170. pComp->hInstance,
  2171. pComp->fUnattended,
  2172. hwnd,
  2173. IDS_WRN_CANNOT_ADD_CA_TO_PREWIN2K,
  2174. hr,
  2175. NULL);
  2176. }
  2177. _PrintIfError(hr, "AddCAMachineToPreWin2kGroup");
  2178. }
  2179. hr = InitializeCertificateTemplates();
  2180. _JumpIfError(hr, error, "InitializeCertificateTemplates");
  2181. }
  2182. certocmBumpGasGauge(pComp, 95 DBGPARM(L"InstallServer"));
  2183. // Set the security locally.
  2184. // A SubCA sets security when it receives its certificate from
  2185. // its parent. ALL OTHER CA installs (Root & reuse of existing certs)
  2186. // need to have security set now.
  2187. // On a SubCA the DS object security will have been set
  2188. // by a previous call in initlib if we already got our cert, or it will
  2189. // be set later when we install our cert.
  2190. // However, root certs install doesn't run completefrompkcs7(), so
  2191. // ds security on ent roots is never set. We must set it here.
  2192. // TODO: set security properly at DS object creation time!
  2193. fSetDSSecurity = (IsRootCA(pServer->CAType) || pServer->pccExistingCert);
  2194. hr = csiInitializeCertSrvSecurity(
  2195. pServer->pwszSanitizedName,
  2196. pServer->fUseDS,
  2197. fSetDSSecurity? pServer->fUseDS : FALSE); // clean SUBCA: happens during cert install, ROOT & reuse cert: apply now
  2198. if (S_OK != hr)
  2199. {
  2200. _PrintError(hr, "csiInitializeCertSrvSecurity");
  2201. if (IsWhistler())
  2202. {
  2203. goto error;
  2204. }
  2205. }
  2206. hr = GetSetupStatus(pServer->pwszSanitizedName, &dwSetupStatus);
  2207. if (S_OK == hr)
  2208. {
  2209. if (IsSubordinateCA(pServer->CAType) &&
  2210. (SETUP_SUSPEND_FLAG & dwSetupStatus) &&
  2211. (SETUP_REQUEST_FLAG & dwSetupStatus))
  2212. {
  2213. // put out an info dlg
  2214. CertInfoMessageBox(
  2215. pComp->hInstance,
  2216. pComp->fUnattended,
  2217. hwnd,
  2218. IDS_INCOMPLETE_REQUEST,
  2219. pServer->pwszRequestFile);
  2220. }
  2221. }
  2222. else
  2223. {
  2224. _PrintError(hr, "GetSetupStatus");
  2225. }
  2226. certocmBumpGasGauge(pComp, 100 DBGPARM(L"InstallServer"));
  2227. hr = S_OK;
  2228. error:
  2229. if (NULL != pwszConfig)
  2230. {
  2231. LocalFree(pwszConfig);
  2232. }
  2233. if (NULL != pwszDBFile)
  2234. {
  2235. LocalFree(pwszDBFile);
  2236. }
  2237. if (fCoInit)
  2238. {
  2239. CoUninitialize();
  2240. }
  2241. CSILOG(hr, IDS_LOG_INSTALL_SERVER, NULL, NULL, NULL);
  2242. return(hr);
  2243. }
  2244. HRESULT
  2245. CreateCertsrvDirectories(
  2246. IN PER_COMPONENT_DATA *pComp,
  2247. IN BOOL fUpgrade,
  2248. IN BOOL fServer)
  2249. {
  2250. HRESULT hr;
  2251. WCHAR wszCertEnroll[MAX_PATH];
  2252. wszCertEnroll[0] = L'\0';
  2253. BuildPath(
  2254. wszCertEnroll,
  2255. ARRAYSIZE(wszCertEnroll),
  2256. pComp->pwszSystem32,
  2257. wszCERTENROLLSHAREPATH);
  2258. if (0 == CreateDirectory(wszCertEnroll, NULL))
  2259. {
  2260. hr = myHLastError();
  2261. if (HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) != hr)
  2262. {
  2263. _JumpErrorStr(hr, error, "CreateDirectory", wszCertEnroll);
  2264. }
  2265. }
  2266. if (fServer && NULL != pComp->CA.pServer->pwszSharedFolder)
  2267. {
  2268. if (pComp->fUnattended && !fUpgrade)
  2269. {
  2270. // make sure shared folder is created
  2271. if (!CreateDirectory(pComp->CA.pServer->pwszSharedFolder, NULL))
  2272. {
  2273. hr = myHLastError();
  2274. if (HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) != hr)
  2275. {
  2276. _JumpErrorStr(hr, error, "CreateDirectory",
  2277. pComp->CA.pServer->pwszSharedFolder);
  2278. }
  2279. }
  2280. }
  2281. if (!fUpgrade)
  2282. {
  2283. // set security on shared folder to
  2284. // FULL: Admins, LocalSystem, DomainAdmins
  2285. // READ: Everyone
  2286. // NOTE: in upgrade path, the system doesn't enable file share yet
  2287. // so skip the call
  2288. hr = csiSetAdminOnlyFolderSecurity(
  2289. pComp->CA.pServer->pwszSharedFolder,
  2290. TRUE, // apply Everyone:READ
  2291. pComp->CA.pServer->fUseDS);
  2292. _JumpIfError(hr, error, "csiSetAdminOnlyFolderSecurity");
  2293. }
  2294. }
  2295. hr = S_OK;
  2296. error:
  2297. return hr;
  2298. }
  2299. // following remove unused file/directory/registry
  2300. #define wszOLDHELP L"..\\help\\"
  2301. #define wszOLDCERTADM L"\\certadm"
  2302. #define wszOLDCERTQUE L"\\certque"
  2303. VOID
  2304. DeleteOldFilesAndDirectories(
  2305. IN PER_COMPONENT_DATA *pComp)
  2306. {
  2307. HRESULT hr;
  2308. WCHAR wszPath[MAX_PATH];
  2309. WCHAR *pwszCertsrv;
  2310. wszPath[0] = L'\0';
  2311. // old help dir path
  2312. wcscpy(wszPath, pComp->pwszSystem32);
  2313. wcscat(wszPath, wszOLDHELP);
  2314. wcscat(wszPath, wszCERTSRV);
  2315. // remove old help files
  2316. hr = myRemoveFilesAndDirectory(wszPath, TRUE);
  2317. _PrintIfErrorStr(hr, "myRemoveFilesAndDirectory", wszPath);
  2318. // point to system32\certsrv
  2319. wcscpy(wszPath, pComp->pwszSystem32);
  2320. wcscat(wszPath, wszCERTSRV);
  2321. pwszCertsrv = &wszPath[wcslen(wszPath)];
  2322. // old vroot dir path
  2323. wcscpy(pwszCertsrv, wszOLDCERTADM);
  2324. hr = myRemoveFilesAndDirectory(wszPath, TRUE);
  2325. _PrintIfErrorStr(hr, "myRemoveFilesAndDirectory", wszPath);
  2326. wcscpy(pwszCertsrv, wszOLDCERTQUE);
  2327. hr = myRemoveFilesAndDirectory(wszPath, TRUE);
  2328. _PrintIfErrorStr(hr, "myRemoveFilesAndDirectory", wszPath);
  2329. // delete some obsolete registry keys and values
  2330. // old doc sub-component
  2331. hr = myDeleteCertRegValueEx(wszREGKEYOCMSUBCOMPONENTS,
  2332. NULL,
  2333. NULL,
  2334. wszOLDDOCCOMPONENT,
  2335. TRUE); //absolute path,
  2336. _PrintIfErrorStr2(hr, "myDeleteCertRegValueEx", wszOLDDOCCOMPONENT, hr);
  2337. // old CA cert serial number
  2338. if (NULL != pComp->CA.pServer &&
  2339. NULL != pComp->CA.pServer->pwszSanitizedName)
  2340. {
  2341. hr = myDeleteCertRegValue(
  2342. pComp->CA.pServer->pwszSanitizedName,
  2343. NULL,
  2344. NULL,
  2345. wszREGCASERIALNUMBER);
  2346. _PrintIfErrorStr2(hr, "myDeleteCertRegValue", wszREGCASERIALNUMBER, hr);
  2347. }
  2348. }
  2349. VOID
  2350. DeleteObsoleteResidue()
  2351. {
  2352. HRESULT hr;
  2353. hr = myDeleteCertRegValueEx(wszREGKEYKEYSNOTTORESTORE,
  2354. NULL,
  2355. NULL,
  2356. wszREGRESTORECERTIFICATEAUTHORITY,
  2357. TRUE); //absolute path,
  2358. _PrintIfErrorStr(hr, "myDeleteCertRegValueEx",
  2359. wszREGRESTORECERTIFICATEAUTHORITY);
  2360. hr = myDeleteCertRegValueEx(wszREGKEYFILESNOTTOBACKUP,
  2361. NULL,
  2362. NULL,
  2363. wszREGRESTORECERTIFICATEAUTHORITY,
  2364. TRUE); //absolute path,
  2365. _PrintIfErrorStr(hr, "myDeleteCertRegValueEx",
  2366. wszREGRESTORECERTIFICATEAUTHORITY);
  2367. }
  2368. HRESULT
  2369. TriggerAutoenrollment()
  2370. {
  2371. HRESULT hr = S_OK;
  2372. // must be cleaned up
  2373. CAutoHANDLE hEvent;
  2374. hEvent = OpenEvent(
  2375. EVENT_MODIFY_STATE,
  2376. FALSE,
  2377. L"Global\\" MACHINE_AUTOENROLLMENT_TRIGGER_EVENT);
  2378. if (!hEvent)
  2379. {
  2380. hr = myHLastError();
  2381. _JumpError(hr, error, "OpenEvent");
  2382. }
  2383. if (!SetEvent(hEvent))
  2384. {
  2385. hr = myHLastError();
  2386. _JumpError(hr, error, "OpenEvent");
  2387. }
  2388. error:
  2389. return(hr);
  2390. }
  2391. HRESULT
  2392. InstallCore(
  2393. IN HWND hwnd,
  2394. IN PER_COMPONENT_DATA *pComp,
  2395. IN BOOL fServer)
  2396. {
  2397. HRESULT hr = pComp->hrContinue;
  2398. _JumpIfError(hr, error, "can't continue");
  2399. hr = CreateCertsrvDirectories(pComp, FALSE, fServer);
  2400. _JumpIfError(hr, error, "CreateCertsrvDirectories");
  2401. // Trigger an autoenroll to download root certs (see bug# 341568)
  2402. // Might fail in a brand new domain...
  2403. if (IsEnterpriseCA(pComp->CA.pServer->CAType))
  2404. {
  2405. hr = TriggerAutoenrollment();
  2406. _PrintIfError(hr, "TriggerAutoenrollment");
  2407. }
  2408. if (fServer)
  2409. {
  2410. hr = InstallServer(hwnd, pComp);
  2411. _JumpIfError(hr, error, "InstallServer");
  2412. }
  2413. else
  2414. {
  2415. hr = InstallClient(hwnd, pComp);
  2416. _JumpIfError(hr, error, "InstallClient");
  2417. }
  2418. if (g_fW3SvcRunning)
  2419. {
  2420. hr = StartAndStopService(
  2421. pComp->hInstance,
  2422. pComp->fUnattended,
  2423. hwnd,
  2424. wszW3SVCNAME,
  2425. FALSE,
  2426. FALSE,
  2427. 0, // doesn't matter since no confirm
  2428. &g_fW3SvcRunning);
  2429. _PrintIfError(hr, "StartAndStopService");
  2430. }
  2431. DeleteOldFilesAndDirectories(pComp);
  2432. hr = S_OK;
  2433. error:
  2434. return(hr);
  2435. }
  2436. HRESULT
  2437. BuildMultiStringList(
  2438. IN WCHAR const * const *apwsz,
  2439. IN DWORD cpwsz,
  2440. OUT WCHAR **ppwszz)
  2441. {
  2442. HRESULT hr;
  2443. DWORD i;
  2444. DWORD cwc;
  2445. WCHAR *pwc;
  2446. WCHAR *apwszEmpty[] = { L"", };
  2447. if (0 == cpwsz)
  2448. {
  2449. cpwsz = ARRAYSIZE(apwszEmpty);
  2450. apwsz = apwszEmpty;
  2451. }
  2452. cwc = 1;
  2453. for (i = 0; i < cpwsz; i++)
  2454. {
  2455. cwc += wcslen(apwsz[i]) + 1;
  2456. }
  2457. *ppwszz = (WCHAR *) LocalAlloc(LMEM_FIXED, cwc * sizeof(WCHAR));
  2458. _JumpIfOutOfMemory(hr, error, *ppwszz);
  2459. pwc = *ppwszz;
  2460. for (i = 0; i < cpwsz; i++)
  2461. {
  2462. wcscpy(pwc, apwsz[i]);
  2463. pwc += wcslen(pwc) + 1;
  2464. }
  2465. *pwc = L'\0';
  2466. CSASSERT(SAFE_SUBTRACT_POINTERS(pwc, *ppwszz) + 1 == cwc);
  2467. hr = S_OK;
  2468. error:
  2469. return(hr);
  2470. }
  2471. VOID
  2472. helperDeleteTrashedDisableList(
  2473. IN WCHAR const *pwszSanitizedName)
  2474. {
  2475. HRESULT hr;
  2476. WCHAR *pwszzGet = NULL;
  2477. WCHAR const *pwsz;
  2478. hr = myGetCertRegMultiStrValue(
  2479. pwszSanitizedName,
  2480. wszREGKEYPOLICYMODULES,
  2481. wszCLASS_CERTPOLICY,
  2482. wszREGDISABLEEXTENSIONLIST,
  2483. &pwszzGet);
  2484. _JumpIfErrorStr(hr, error, "mySetCertRegMultiStrValueEx", wszREGDISABLEEXTENSIONLIST);
  2485. if (NULL != pwszzGet)
  2486. {
  2487. for (pwsz = pwszzGet; L'\0' != *pwsz; pwsz += wcslen(pwsz) + 1)
  2488. {
  2489. hr = myVerifyObjId(pwsz);
  2490. if (S_OK != hr)
  2491. {
  2492. hr = myDeleteCertRegValue(
  2493. pwszSanitizedName,
  2494. wszREGKEYPOLICYMODULES,
  2495. wszCLASS_CERTPOLICY,
  2496. wszREGDISABLEEXTENSIONLIST);
  2497. _JumpIfError(hr, error, "myDeleteCertRegValue");
  2498. break;
  2499. }
  2500. }
  2501. }
  2502. error:
  2503. if (NULL != pwszzGet)
  2504. {
  2505. LocalFree(pwszzGet);
  2506. }
  2507. }
  2508. HRESULT
  2509. helperGetDisableExtensionList(
  2510. OUT WCHAR **ppwszz)
  2511. {
  2512. HRESULT hr;
  2513. WCHAR *apwszExt[] = {
  2514. L"", // C compiler won't allow empty list
  2515. //TEXT(szOID_ENROLL_CERTTYPE_EXTENSION), // 1.3.6.1.4.1.311.20.2
  2516. };
  2517. hr = BuildMultiStringList(apwszExt, ARRAYSIZE(apwszExt), ppwszz);
  2518. _JumpIfError(hr, error, "BuildMultiStringList");
  2519. error:
  2520. return(hr);
  2521. }
  2522. HRESULT
  2523. helperGetRequestExtensionList(
  2524. OUT WCHAR **ppwszz)
  2525. {
  2526. HRESULT hr;
  2527. WCHAR *apwszExt[] = {
  2528. TEXT(szOID_RSA_SMIMECapabilities), // 1.2.840.113549.1.9.15
  2529. TEXT(szOID_CERTSRV_CA_VERSION), // 1.3.6.1.4.1.311.21.1
  2530. TEXT(szOID_CERTSRV_PREVIOUS_CERT_HASH), // 1.3.6.1.4.1.311.21.2
  2531. TEXT(szOID_KEY_USAGE), // 2.5.29.15
  2532. };
  2533. hr = BuildMultiStringList(apwszExt, ARRAYSIZE(apwszExt), ppwszz);
  2534. _JumpIfError(hr, error, "BuildMultiStringList");
  2535. error:
  2536. return(hr);
  2537. }
  2538. HRESULT
  2539. helperGetEnrolleeRequestExtensionList(
  2540. OUT WCHAR **ppwszz)
  2541. {
  2542. HRESULT hr;
  2543. WCHAR *apwszExt[] = {
  2544. TEXT(szOID_CROSS_CERT_DIST_POINTS), // 1.3.6.1.4.1.311.10.9.1
  2545. TEXT(szOID_ENROLL_CERTTYPE_EXTENSION), // 1.3.6.1.4.1.311.20.2
  2546. TEXT(szOID_CERTIFICATE_TEMPLATE), // 1.3.6.1.4.1.311.21.7
  2547. TEXT(szOID_APPLICATION_CERT_POLICIES), // 1.3.6.1.4.1.311.21.10
  2548. TEXT(szOID_APPLICATION_POLICY_MAPPINGS), // 1.3.6.1.4.1.311.21.11
  2549. TEXT(szOID_APPLICATION_POLICY_CONSTRAINTS), // 1.3.6.1.4.1.311.21.12
  2550. TEXT(szOID_SUBJECT_ALT_NAME2), // 2.5.29.17
  2551. TEXT(szOID_NAME_CONSTRAINTS), // 2.5.29.30
  2552. TEXT(szOID_CERT_POLICIES), // 2.5.29.32
  2553. TEXT(szOID_POLICY_MAPPINGS), // 2.5.29.33
  2554. TEXT(szOID_POLICY_CONSTRAINTS), // 2.5.29.36
  2555. TEXT(szOID_ENHANCED_KEY_USAGE), // 2.5.29.37
  2556. };
  2557. hr = BuildMultiStringList(apwszExt, ARRAYSIZE(apwszExt), ppwszz);
  2558. _JumpIfError(hr, error, "BuildMultiStringList");
  2559. error:
  2560. return(hr);
  2561. }
  2562. HRESULT
  2563. FindCACertByCommonNameAndSerialNumber(
  2564. IN HCERTSTORE hCAStore,
  2565. IN WCHAR const *pwszCommonName,
  2566. IN BYTE const *pbSerialNumber,
  2567. IN DWORD cbSerialNumber,
  2568. CERT_CONTEXT const **ppCACert)
  2569. {
  2570. HRESULT hr;
  2571. CERT_RDN_ATTR rdnAttr = { szOID_COMMON_NAME, CERT_RDN_ANY_TYPE,};
  2572. CERT_RDN rdn = { 1, &rdnAttr };
  2573. CRYPT_INTEGER_BLOB SerialNumber;
  2574. CERT_CONTEXT const *pCACert = NULL;
  2575. CSASSERT(NULL != hCAStore &&
  2576. NULL != pwszCommonName &&
  2577. NULL != pbSerialNumber &&
  2578. NULL != ppCACert);
  2579. *ppCACert = NULL;
  2580. rdnAttr.Value.pbData = (BYTE *) pwszCommonName;
  2581. rdnAttr.Value.cbData = 0;
  2582. pCACert = NULL;
  2583. SerialNumber.pbData = const_cast<BYTE *>(pbSerialNumber);
  2584. SerialNumber.cbData = cbSerialNumber;
  2585. for (;;)
  2586. {
  2587. pCACert = CertFindCertificateInStore(
  2588. hCAStore,
  2589. X509_ASN_ENCODING,
  2590. CERT_UNICODE_IS_RDN_ATTRS_FLAG |
  2591. CERT_CASE_INSENSITIVE_IS_RDN_ATTRS_FLAG,
  2592. CERT_FIND_SUBJECT_ATTR,
  2593. &rdn,
  2594. pCACert);
  2595. if (NULL == pCACert)
  2596. {
  2597. hr = myHLastError();
  2598. _JumpError(hr, error, "CertFindCertificateInStore");
  2599. }
  2600. if (myAreSerialNumberBlobsSame(
  2601. &SerialNumber,
  2602. &pCACert->pCertInfo->SerialNumber))
  2603. {
  2604. break; // found correct one
  2605. }
  2606. }
  2607. *ppCACert = pCACert;
  2608. pCACert = NULL;
  2609. hr = S_OK;
  2610. error:
  2611. if (NULL != pCACert)
  2612. {
  2613. CertFreeCertificateContext(pCACert);
  2614. }
  2615. return hr;
  2616. }
  2617. HRESULT
  2618. GetCARegSerialNumber(
  2619. IN WCHAR const *pwszSanitizedCAName,
  2620. OUT BYTE **ppbSerialNumber,
  2621. OUT DWORD *pcbSerialNumber)
  2622. {
  2623. HRESULT hr;
  2624. WCHAR *pwszSerialNumber = NULL;
  2625. BYTE *pbSN = NULL;
  2626. DWORD cbSN;
  2627. hr = myGetCertRegStrValue(
  2628. pwszSanitizedCAName,
  2629. NULL,
  2630. NULL,
  2631. wszREGCASERIALNUMBER,
  2632. &pwszSerialNumber);
  2633. _JumpIfErrorStr2(
  2634. hr,
  2635. error,
  2636. "myGetCertRegStrValue",
  2637. wszREGCASERIALNUMBER,
  2638. HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
  2639. hr = WszToMultiByteInteger(FALSE, pwszSerialNumber, &cbSN, &pbSN);
  2640. _JumpIfError(hr, error, "WszToMultiByteInteger");
  2641. *ppbSerialNumber = pbSN;
  2642. pbSN = NULL;
  2643. *pcbSerialNumber = cbSN;
  2644. error:
  2645. if (NULL != pwszSerialNumber)
  2646. {
  2647. LocalFree(pwszSerialNumber);
  2648. }
  2649. if (NULL != pbSN)
  2650. {
  2651. LocalFree(pbSN);
  2652. }
  2653. CSASSERT(S_OK == hr || FAILED(hr));
  2654. return(hr);
  2655. }
  2656. HRESULT
  2657. LoadCurrentCACert(
  2658. IN WCHAR const *pwszCommonName,
  2659. IN WCHAR const *pwszSanitizedName,
  2660. IN BOOL fSignTest,
  2661. OUT CERT_CONTEXT const **ppcc,
  2662. OUT DWORD *pdwNameId)
  2663. {
  2664. HRESULT hr;
  2665. DWORD Count;
  2666. HCERTSTORE hMyStore = NULL;
  2667. BYTE *pbSerialNumber = NULL;
  2668. DWORD cbSerialNumber;
  2669. CRYPT_KEY_PROV_INFO *pKey = NULL;
  2670. DWORD cbKey;
  2671. CERT_CONTEXT const *pcc = NULL;
  2672. WCHAR *pwszProvName = NULL;
  2673. DWORD dwProvType;
  2674. ALG_ID idAlg;
  2675. BOOL fMachineKeyset;
  2676. *ppcc = NULL;
  2677. // get prov name
  2678. hr = myGetCertSrvCSP(
  2679. FALSE, // fEncryptionCSP
  2680. pwszSanitizedName,
  2681. &dwProvType,
  2682. &pwszProvName,
  2683. &idAlg,
  2684. &fMachineKeyset,
  2685. NULL); // pdwKeySize
  2686. _JumpIfError(hr, error, "myGetCertSrvCSP");
  2687. // open my store
  2688. hMyStore = CertOpenStore(
  2689. CERT_STORE_PROV_SYSTEM_W,
  2690. X509_ASN_ENCODING,
  2691. NULL, // hProv
  2692. CERT_SYSTEM_STORE_LOCAL_MACHINE |
  2693. CERT_STORE_ENUM_ARCHIVED_FLAG,
  2694. wszMY_CERTSTORE);
  2695. if (NULL == hMyStore)
  2696. {
  2697. hr = myHLastError();
  2698. _JumpError(hr, error, "CertOpenStore");
  2699. }
  2700. hr = myGetCARegHashCount(pwszSanitizedName, CSRH_CASIGCERT, &Count);
  2701. _JumpIfError(hr, error, "myGetCARegHashCount");
  2702. if (0 == Count)
  2703. {
  2704. *pdwNameId = 0; // renewal wasn't implemented yet
  2705. // find current CA cert by serial number -- the old fashioned way
  2706. hr = GetCARegSerialNumber(
  2707. pwszSanitizedName,
  2708. &pbSerialNumber,
  2709. &cbSerialNumber);
  2710. _JumpIfError(hr, error, "GetCARegSerialNumber");
  2711. hr = FindCACertByCommonNameAndSerialNumber(
  2712. hMyStore,
  2713. pwszCommonName,
  2714. pbSerialNumber,
  2715. cbSerialNumber,
  2716. &pcc);
  2717. _JumpIfError(hr, error, "FindCACertByCommonNameAndSerialNumber");
  2718. }
  2719. else
  2720. {
  2721. hr = myFindCACertByHashIndex(
  2722. hMyStore,
  2723. pwszSanitizedName,
  2724. CSRH_CASIGCERT,
  2725. Count - 1,
  2726. pdwNameId,
  2727. &pcc);
  2728. _JumpIfError(hr, error, "myFindCACertByHashIndex");
  2729. }
  2730. // get the private key provider info
  2731. if (!myCertGetCertificateContextProperty(
  2732. pcc,
  2733. CERT_KEY_PROV_INFO_PROP_ID,
  2734. CERTLIB_USE_LOCALALLOC,
  2735. (VOID **) &pKey,
  2736. &cbKey))
  2737. {
  2738. hr = myHLastError();
  2739. _JumpError(hr, error, "CertGetCertificateContextProperty");
  2740. }
  2741. if (fSignTest)
  2742. {
  2743. // test signing key
  2744. hr = myValidateSigningKey(
  2745. pKey->pwszContainerName,
  2746. pwszProvName,
  2747. dwProvType,
  2748. FALSE, // fCryptSilent
  2749. fMachineKeyset,
  2750. TRUE, // fForceSignatureTest
  2751. pcc,
  2752. NULL, // pPublicKeyInfo
  2753. idAlg,
  2754. NULL, // pfSigningTestAttempted
  2755. NULL); // phProv
  2756. _JumpIfError(hr, error, "myValidateSigningKey");
  2757. }
  2758. *ppcc = pcc;
  2759. pcc = NULL;
  2760. hr = S_OK;
  2761. error:
  2762. if (NULL != hMyStore)
  2763. {
  2764. CertCloseStore(hMyStore, CERT_CLOSE_STORE_CHECK_FLAG);
  2765. }
  2766. if (NULL != pbSerialNumber)
  2767. {
  2768. LocalFree(pbSerialNumber);
  2769. }
  2770. if (NULL != pKey)
  2771. {
  2772. LocalFree(pKey);
  2773. }
  2774. if (NULL != pwszProvName)
  2775. {
  2776. LocalFree(pwszProvName);
  2777. }
  2778. if (NULL != pcc)
  2779. {
  2780. CertFreeCertificateContext(pcc);
  2781. }
  2782. CSASSERT(S_OK == hr || FAILED(hr));
  2783. return(hr);
  2784. }
  2785. HRESULT
  2786. ArchiveCACertificate(
  2787. IN WCHAR const *pwszSanitizedName)
  2788. {
  2789. HRESULT hr;
  2790. HCERTSTORE hMyStore = NULL;
  2791. DWORD Count;
  2792. DWORD i;
  2793. CERT_CONTEXT const *pCert = NULL;
  2794. DWORD dwNameId;
  2795. CRYPT_DATA_BLOB Archived;
  2796. // open my store
  2797. hMyStore = CertOpenStore(
  2798. CERT_STORE_PROV_SYSTEM_W,
  2799. X509_ASN_ENCODING,
  2800. NULL, // hProv
  2801. CERT_SYSTEM_STORE_LOCAL_MACHINE,
  2802. wszMY_CERTSTORE);
  2803. if (NULL == hMyStore)
  2804. {
  2805. hr = myHLastError();
  2806. _JumpError(hr, error, "CertOpenStore");
  2807. }
  2808. hr = myGetCARegHashCount(pwszSanitizedName, CSRH_CASIGCERT, &Count);
  2809. _JumpIfError(hr, error, "myGetCARegHashCount");
  2810. for (i = 0; i < Count; i++)
  2811. {
  2812. hr = myFindCACertByHashIndex(
  2813. hMyStore,
  2814. pwszSanitizedName,
  2815. CSRH_CASIGCERT,
  2816. i,
  2817. &dwNameId,
  2818. &pCert);
  2819. _PrintIfError2(hr, "myFindCACertByHashIndex", S_FALSE);
  2820. if (S_OK == hr)
  2821. {
  2822. Archived.cbData = 0;
  2823. Archived.pbData = NULL;
  2824. // We force an archive on the old cert and close it.
  2825. CertSetCertificateContextProperty(
  2826. pCert,
  2827. CERT_ARCHIVED_PROP_ID,
  2828. 0,
  2829. &Archived);
  2830. CertFreeCertificateContext(pCert);
  2831. pCert = NULL;
  2832. }
  2833. }
  2834. hr = S_OK;
  2835. error:
  2836. if (NULL != pCert)
  2837. {
  2838. CertFreeCertificateContext(pCert);
  2839. }
  2840. if (NULL != hMyStore)
  2841. {
  2842. CertCloseStore(hMyStore, CERT_CLOSE_STORE_CHECK_FLAG);
  2843. }
  2844. CSASSERT(S_OK == hr || FAILED(hr));
  2845. return(hr);
  2846. }
  2847. // determine CA info, from build to build upgrade
  2848. HRESULT
  2849. DetermineCAInfoAndType(
  2850. PER_COMPONENT_DATA *pComp)
  2851. {
  2852. HRESULT hr;
  2853. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  2854. ENUM_CATYPES CATypeDummy;
  2855. WCHAR *pwszCommonName = NULL;
  2856. CERT_CONTEXT const *pCACert = NULL;
  2857. // ca type
  2858. hr = myGetCertRegDWValue(
  2859. pServer->pwszSanitizedName,
  2860. NULL,
  2861. NULL,
  2862. wszREGCATYPE,
  2863. (DWORD *) &CATypeDummy);
  2864. if (S_OK == hr)
  2865. {
  2866. pServer->CAType = CATypeDummy;
  2867. }
  2868. else if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) != hr)
  2869. {
  2870. _JumpErrorStr(hr, error, "myGetCertRegDWValue", wszREGCATYPE);
  2871. }
  2872. // else keep default CAType flag
  2873. // get current ca common name
  2874. hr = myGetCertRegStrValue(
  2875. pServer->pwszSanitizedName,
  2876. NULL,
  2877. NULL,
  2878. wszREGCOMMONNAME,
  2879. &pwszCommonName);
  2880. _JumpIfErrorStr(hr, error, "myGetCertRegStrValue", wszREGCOMMONNAME);
  2881. hr = LoadCurrentCACert(
  2882. pwszCommonName,
  2883. pServer->pwszSanitizedName,
  2884. FALSE, // don't do signing test during upgrade
  2885. &pCACert,
  2886. &pServer->dwCertNameId);
  2887. _JumpIfError(hr, error, "LoadCurrentCACert");
  2888. // now ready to load DN info
  2889. hr = DetermineExistingCAIdInfo(pServer, pCACert);
  2890. _JumpIfError(hr, error, "DetermineExistingCAIdInfo");
  2891. if (NULL != pServer->pccUpgradeCert)
  2892. {
  2893. CertFreeCertificateContext(pServer->pccUpgradeCert);
  2894. }
  2895. pServer->pccUpgradeCert = pCACert;
  2896. pCACert = NULL;
  2897. error:
  2898. if (NULL != pwszCommonName)
  2899. {
  2900. LocalFree(pwszCommonName);
  2901. }
  2902. if (NULL != pCACert)
  2903. {
  2904. CertFreeCertificateContext(pCACert);
  2905. }
  2906. return(hr);
  2907. }
  2908. // the following will determine ca sanitized name and upgrade path
  2909. HRESULT
  2910. DetermineServerUpgradePath(
  2911. IN OUT PER_COMPONENT_DATA *pComp)
  2912. {
  2913. HRESULT hr;
  2914. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  2915. WCHAR *pwszDummy = NULL;
  2916. WCHAR *pwszSanitizedCAName = NULL;
  2917. LPWSTR pwszB2PolicyGuid = NULL;
  2918. DWORD dwVersion;
  2919. if (CS_UPGRADE_UNKNOWN != pComp->UpgradeFlag)
  2920. {
  2921. // already know upgrade type
  2922. CSASSERT(pServer->pwszSanitizedName); // this is a side-effect of this fxn, better have been set already
  2923. return S_OK;
  2924. }
  2925. // get active ca name
  2926. hr = myGetCertRegStrValue(
  2927. NULL,
  2928. NULL,
  2929. NULL,
  2930. wszREGACTIVE,
  2931. &pwszSanitizedCAName);
  2932. if (hr != S_OK)
  2933. {
  2934. BOOL fFinishCYS;
  2935. //for W2K after, it is possible to be in post mode
  2936. hr = CheckPostBaseInstallStatus(&fFinishCYS);
  2937. if (S_OK == hr && !fFinishCYS)
  2938. {
  2939. //this could be either w2k or whistler
  2940. //treat as whistler since upgrade path won't execute
  2941. pComp->UpgradeFlag = CS_UPGRADE_WHISTLER;
  2942. goto done;
  2943. }
  2944. // wszREGACTIVE used in Win2k product and after. If not found, this is way before our time
  2945. // make sure by grabbing wszREGSP4DEFAULTCONFIGURATION
  2946. LPWSTR pwszTmp = NULL;
  2947. hr = myGetCertRegStrValue(
  2948. NULL,
  2949. NULL,
  2950. NULL,
  2951. wszREGSP4DEFAULTCONFIGURATION,
  2952. &pwszTmp);
  2953. if (pwszTmp)
  2954. LocalFree(pwszTmp);
  2955. // error! bail, we have no idea what we're seeing
  2956. _JumpIfError(hr, error, "myGetCertRegStrValue wszREGSP4DEFAULTCONFIGURATION");
  2957. // hr == S_OK: yep, looks like valid NT4 installation
  2958. pComp->UpgradeFlag = CS_UPGRADE_UNSUPPORTED;
  2959. CSILOG(S_OK, IDS_LOG_UPGRADE_UNSUPPORTED, NULL, NULL, NULL);
  2960. _JumpError(hr, error, "myGetCertRegStrValue");
  2961. }
  2962. // check wszREGVERSION to get current version
  2963. hr = myGetCertRegDWValue(
  2964. NULL,
  2965. NULL,
  2966. NULL,
  2967. wszREGVERSION,
  2968. &dwVersion);
  2969. if (S_OK != hr && HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)!= hr)
  2970. {
  2971. _JumpErrorStr(hr, error, "myGetCertRegDWValue", wszREGVERSION);
  2972. }
  2973. // now either OK or FILE_NOT_FOUND
  2974. if (S_OK == hr)
  2975. {
  2976. // pComp->UpgradeFlag = SOME_FUNCTION(dwVersion); // CS_UPGRADE_WHISTLER already set as default; in future, key off of this
  2977. pComp->UpgradeFlag = CS_UPGRADE_WHISTLER;
  2978. pComp->dwVersion = dwVersion;
  2979. CSILOG(S_OK, IDS_LOG_UPGRADE_B2B, NULL, NULL, NULL);
  2980. }
  2981. else
  2982. {
  2983. // FILE_NOT_FOUND: now we know it's (NT5 Beta 2 <= X < Whistler)
  2984. pComp->dwVersion = CSVER_BUILD_VERSION(CSVER_MAJOR_WIN2K, CSVER_MINOR_WIN2K);
  2985. // is this Win2k, or NT5 Beta? Test for active policy module to have "ICertManageModule" entry
  2986. // check nt5 beta 2 and get active policy name
  2987. hr = myGetCertRegStrValue(
  2988. pwszSanitizedCAName,
  2989. wszREGKEYPOLICYMODULES,
  2990. NULL,
  2991. wszREGACTIVE,
  2992. &pwszB2PolicyGuid);
  2993. if (S_OK == hr)
  2994. {
  2995. hr = myGetCertRegStrValue(
  2996. wszREGKEYPOLICYMODULES,
  2997. pwszB2PolicyGuid,
  2998. NULL,
  2999. wszREGB2ICERTMANAGEMODULE,
  3000. &pwszDummy);
  3001. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
  3002. {
  3003. // this doesn't exist on Win2k
  3004. pComp->UpgradeFlag = CS_UPGRADE_WIN2000;
  3005. CSILOG(S_OK, IDS_LOG_UPGRADE_WIN2000, NULL, NULL, NULL);
  3006. }
  3007. else
  3008. {
  3009. // this is definitely beta 2
  3010. pComp->UpgradeFlag = CS_UPGRADE_UNSUPPORTED;
  3011. CSILOG(S_OK, IDS_LOG_UPGRADE_UNSUPPORTED, NULL, NULL, NULL);
  3012. }
  3013. }
  3014. else if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
  3015. {
  3016. // strange, maybe no active module. Assume OK, latest bits.
  3017. pComp->UpgradeFlag = CS_UPGRADE_WIN2000;
  3018. CSILOG(S_OK, IDS_LOG_UPGRADE_WIN2000, NULL, NULL, NULL);
  3019. }
  3020. else
  3021. {
  3022. // other failure, just bail
  3023. _JumpErrorStr(hr, error, "myGetCertRegStrValue",
  3024. wszREGKEYPOLICYMODULES);
  3025. }
  3026. } // wszREGVERSION: FILE_NOT_FOUND
  3027. // take sanitized name
  3028. if (NULL != pServer->pwszSanitizedName)
  3029. {
  3030. // this will free the default name
  3031. LocalFree(pServer->pwszSanitizedName);
  3032. }
  3033. pServer->pwszSanitizedName = pwszSanitizedCAName;
  3034. pwszSanitizedCAName = NULL;
  3035. done:
  3036. hr = S_OK;
  3037. error:
  3038. if (NULL != pwszDummy)
  3039. {
  3040. LocalFree(pwszDummy);
  3041. }
  3042. if (NULL != pwszSanitizedCAName)
  3043. {
  3044. LocalFree(pwszSanitizedCAName);
  3045. }
  3046. CSILOG(hr, IDS_LOG_UPGRADE_TYPE, NULL, NULL, (DWORD const *) &pComp->UpgradeFlag);
  3047. return hr;
  3048. }
  3049. // Description: load and determine necessary information for upgrade
  3050. // upgrade won't continue if any error
  3051. HRESULT
  3052. LoadAndDetermineServerUpgradeInfo(
  3053. IN OUT PER_COMPONENT_DATA *pComp)
  3054. {
  3055. HRESULT hr;
  3056. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  3057. WCHAR *pwszRevocationType = NULL;
  3058. BOOL fDummy;
  3059. ALG_ID idAlgDummy;
  3060. CSP_INFO CSPInfoDummy;
  3061. WCHAR *pwszCommonName = NULL;
  3062. // initialize
  3063. ZeroMemory(&CSPInfoDummy, sizeof(CSPInfoDummy));
  3064. // load information for all upgrade scenarios
  3065. // csp
  3066. hr = myGetCertRegStrValue(
  3067. pServer->pwszSanitizedName,
  3068. wszREGKEYCSP,
  3069. NULL,
  3070. wszREGPROVIDER,
  3071. &CSPInfoDummy.pwszProvName);
  3072. if (S_OK == hr && NULL != CSPInfoDummy.pwszProvName)
  3073. {
  3074. if (NULL != pServer->pCSPInfo->pwszProvName)
  3075. {
  3076. // free default csp
  3077. LocalFree(pServer->pCSPInfo->pwszProvName);
  3078. }
  3079. // use reg one as default for upgrade
  3080. pServer->pCSPInfo->pwszProvName = CSPInfoDummy.pwszProvName;
  3081. }
  3082. else if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) != hr)
  3083. {
  3084. _JumpErrorStr(hr, error, "myGetCertRegStrValue", wszREGPROVIDER);
  3085. }
  3086. hr = myGetCertRegDWValue(
  3087. pServer->pwszSanitizedName,
  3088. wszREGKEYCSP,
  3089. NULL,
  3090. wszREGPROVIDERTYPE,
  3091. &CSPInfoDummy.dwProvType);
  3092. if (S_OK == hr)
  3093. {
  3094. pServer->pCSPInfo->dwProvType = CSPInfoDummy.dwProvType;
  3095. }
  3096. else if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) != hr)
  3097. {
  3098. _JumpErrorStr(hr, error, "myGetCertRegDWValue", wszREGPROVIDERTYPE);
  3099. }
  3100. hr = myGetCertRegDWValue(
  3101. pServer->pwszSanitizedName,
  3102. wszREGKEYCSP,
  3103. NULL,
  3104. wszMACHINEKEYSET,
  3105. (DWORD*)&CSPInfoDummy.fMachineKeyset);
  3106. if (S_OK == hr)
  3107. {
  3108. pServer->pCSPInfo->fMachineKeyset = CSPInfoDummy.fMachineKeyset;
  3109. }
  3110. else if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) != hr)
  3111. {
  3112. _JumpErrorStr(hr, error, "myGetCertRegDWValue", wszMACHINEKEYSET);
  3113. }
  3114. hr = myGetCertRegDWValue(
  3115. pServer->pwszSanitizedName,
  3116. wszREGKEYCSP,
  3117. NULL,
  3118. wszHASHALGORITHM,
  3119. (DWORD*)&idAlgDummy);
  3120. if (S_OK == hr)
  3121. {
  3122. pServer->pHashInfo->idAlg = idAlgDummy;
  3123. }
  3124. else if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) != hr)
  3125. {
  3126. _JumpIfErrorStr(hr, error, "myGetCertRegDWValue", wszHASHALGORITHM);
  3127. }
  3128. if (NULL != pServer->pCSPInfoList)
  3129. {
  3130. // BUG, this will never happen because csp info list is not loaded yet
  3131. // one more checking, make sure csp is installed
  3132. if (NULL == findCSPInfoFromList(
  3133. pServer->pCSPInfoList,
  3134. pServer->pCSPInfo->pwszProvName,
  3135. pServer->pCSPInfo->dwProvType))
  3136. {
  3137. // if not, this is a broken ca
  3138. hr = E_INVALIDARG;
  3139. _JumpErrorStr(hr, error, "findCSPInfoFromList",
  3140. pServer->pCSPInfo->pwszProvName);
  3141. }
  3142. }
  3143. // UseDS flag
  3144. hr = myGetCertRegDWValue(
  3145. pServer->pwszSanitizedName,
  3146. NULL,
  3147. NULL,
  3148. wszREGCAUSEDS,
  3149. (DWORD*)&fDummy);
  3150. if (S_OK == hr)
  3151. {
  3152. // use from reg
  3153. pServer->fUseDS = fDummy;
  3154. }
  3155. else if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) != hr)
  3156. {
  3157. _JumpErrorStr(hr, error, "myGetCertRegDWValue", wszREGCAUSEDS);
  3158. }
  3159. // CACommonName
  3160. // this will be used for looking cert in store to determine ca DN info
  3161. hr = myGetCertRegStrValue(
  3162. pServer->pwszSanitizedName,
  3163. NULL,
  3164. NULL,
  3165. wszREGCOMMONNAME,
  3166. &pwszCommonName);
  3167. if (S_OK != hr && HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) != hr)
  3168. {
  3169. _JumpError(hr, error, "myGetCertRegStrValue");
  3170. }
  3171. else if ((HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) ||
  3172. (S_OK == hr && L'\0' == pwszCommonName[0]))
  3173. {
  3174. if (S_OK == hr && L'\0' == pwszCommonName[0])
  3175. {
  3176. // empty string, use snaitized name instead
  3177. LocalFree(pwszCommonName);
  3178. }
  3179. // in case empty or not found, use sanitized
  3180. pwszCommonName = (WCHAR*)LocalAlloc(LMEM_FIXED,
  3181. (wcslen(pServer->pwszSanitizedName) + 1) * sizeof(WCHAR));
  3182. _JumpIfOutOfMemory(hr, error, pwszCommonName);
  3183. wcscpy(pwszCommonName, pServer->pwszSanitizedName);
  3184. }
  3185. if (NULL != pServer->pwszCACommonName)
  3186. {
  3187. LocalFree(pServer->pwszCACommonName);
  3188. }
  3189. pServer->pwszCACommonName = pwszCommonName;
  3190. pwszCommonName = NULL;
  3191. // Collect CAType, DN info, dwCertNameId and upgrade ca cert
  3192. hr = DetermineCAInfoAndType(pComp);
  3193. _JumpIfError(hr, error, "DetermineCAInfoAndType");
  3194. // load following values for later
  3195. // check revocation type
  3196. hr = myGetCertRegDWValue(
  3197. pServer->pwszSanitizedName,
  3198. wszREGKEYPOLICYMODULES,
  3199. wszCLASS_CERTPOLICY,
  3200. wszREGREVOCATIONTYPE,
  3201. &pServer->dwRevocationFlags);
  3202. if(hr != S_OK)
  3203. {
  3204. pServer->dwRevocationFlags = pServer->fUseDS?
  3205. REVEXT_DEFAULT_DS : REVEXT_DEFAULT_NODS;
  3206. }
  3207. // following for web page creation
  3208. // load shared folder for ca cert file name creation
  3209. if (NULL != pServer->pwszSharedFolder)
  3210. {
  3211. // shouldn't happen but in case
  3212. LocalFree(pServer->pwszSharedFolder);
  3213. pServer->pwszSharedFolder = NULL;
  3214. }
  3215. hr = myGetCertRegStrValue(
  3216. NULL,
  3217. NULL,
  3218. NULL,
  3219. wszREGDIRECTORY,
  3220. &pServer->pwszSharedFolder);
  3221. if (S_OK == hr && L'\0' == pServer->pwszSharedFolder[0])
  3222. {
  3223. // in case of empty, set to null
  3224. LocalFree(pServer->pwszSharedFolder);
  3225. pServer->pwszSharedFolder = NULL;
  3226. }
  3227. else if (S_OK != hr && HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) != hr)
  3228. {
  3229. _JumpError(hr, error, "myGetCertRegStrValue");
  3230. }
  3231. // build ca cert file name for web install and ca cert saving
  3232. if (NULL != pServer->pwszCACertFile)
  3233. {
  3234. // free old one
  3235. LocalFree(pServer->pwszCACertFile);
  3236. }
  3237. hr = csiBuildCACertFileName(
  3238. pComp->hInstance,
  3239. NULL, //hwnd, ok for upgrade
  3240. pComp->fUnattended,
  3241. pServer->pwszSharedFolder,
  3242. pServer->pwszSanitizedName,
  3243. L".crt",
  3244. 0, // iCert
  3245. &pServer->pwszCACertFile);
  3246. _JumpIfError(hr, error, "BuildCACertFileName");
  3247. hr = S_OK;
  3248. error:
  3249. if (NULL != pwszRevocationType)
  3250. {
  3251. LocalFree(pwszRevocationType);
  3252. }
  3253. if (NULL != pwszCommonName)
  3254. {
  3255. LocalFree(pwszCommonName);
  3256. }
  3257. return hr;
  3258. }
  3259. HRESULT
  3260. GetConfigInSharedFolderWithCert(
  3261. WCHAR const *pwszSharedFolder,
  3262. OUT WCHAR **ppwszConfig)
  3263. {
  3264. HRESULT hr;
  3265. ICertConfig * pICertConfig = NULL;
  3266. BSTR bstrConfig = NULL;
  3267. BOOL fCoInit = FALSE;
  3268. WCHAR *pwszCAMachine;
  3269. WCHAR *pwszCAName;
  3270. WCHAR wszCertFileInSharedFolder[MAX_PATH];
  3271. LONG i;
  3272. LONG lCount;
  3273. LONG Index;
  3274. BSTR strConfigConfig = NULL;
  3275. CSASSERT(NULL != ppwszConfig);
  3276. *ppwszConfig = NULL;
  3277. hr = CoInitialize(NULL);
  3278. if (S_OK != hr && S_FALSE != hr)
  3279. {
  3280. _JumpError(hr, error, "CoInitialize");
  3281. }
  3282. fCoInit = TRUE;
  3283. hr = CoCreateInstance(
  3284. CLSID_CCertConfig,
  3285. NULL,
  3286. CLSCTX_INPROC_SERVER,
  3287. IID_ICertConfig,
  3288. (VOID**) &pICertConfig);
  3289. _JumpIfError(hr, error, "CoCreateInstance");
  3290. // get local
  3291. hr = pICertConfig->Reset(0, &lCount);
  3292. _JumpIfError(hr, error, "ICertConfig->Reset");
  3293. strConfigConfig = SysAllocString(wszCONFIG_CONFIG);
  3294. if (NULL == strConfigConfig)
  3295. {
  3296. hr = E_OUTOFMEMORY;
  3297. _JumpError(hr, error, "SysAllocString");
  3298. }
  3299. for (i = 0; i < lCount; ++i)
  3300. {
  3301. hr = pICertConfig->Next(&Index);
  3302. if (S_OK != hr && S_FALSE != hr)
  3303. {
  3304. _JumpError(hr, error, "ICertConfig->Next");
  3305. }
  3306. if (-1 == Index)
  3307. {
  3308. hr = HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS);
  3309. _JumpError(hr, error, "No CA cert file");
  3310. }
  3311. hr = pICertConfig->GetField(strConfigConfig, &bstrConfig);
  3312. _JumpIfError(hr, error, "ICertConfig->GetField(Config)");
  3313. pwszCAMachine = (WCHAR*)bstrConfig;
  3314. pwszCAName = wcschr(pwszCAMachine, L'\\');
  3315. if (NULL == pwszCAName)
  3316. {
  3317. hr = E_INVALIDARG;
  3318. _JumpError(hr, error, "Invalid config string");
  3319. }
  3320. pwszCAName[0] = '\0'; // make pwszCAMachine
  3321. ++pwszCAName;
  3322. if (wcslen(pwszSharedFolder) +
  3323. 1 +
  3324. wcslen(pwszCAMachine) +
  3325. 1 +
  3326. wcslen(pwszCAName) +
  3327. WSZARRAYSIZE(wszCRTFILENAMEEXT) >= ARRAYSIZE(wszCertFileInSharedFolder))
  3328. {
  3329. hr = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
  3330. _JumpErrorStr(hr, error, "wszCertFileInSharedFolder", pwszSharedFolder);
  3331. }
  3332. // form NT4 ca cert file path in shared folder
  3333. wcscpy(wszCertFileInSharedFolder, pwszSharedFolder);
  3334. wcscat(wszCertFileInSharedFolder, L"\\");
  3335. wcscat(wszCertFileInSharedFolder, pwszCAMachine);
  3336. wcscat(wszCertFileInSharedFolder, L"_");
  3337. wcscat(wszCertFileInSharedFolder, pwszCAName);
  3338. wcscat(wszCertFileInSharedFolder, wszCRTFILENAMEEXT);
  3339. DBGPRINT((
  3340. DBG_SS_CERTOCM,
  3341. "wszCertFileInSharedFolder: %ws\n",
  3342. wszCertFileInSharedFolder));
  3343. if (myDoesFileExist(wszCertFileInSharedFolder))
  3344. {
  3345. //done
  3346. break;
  3347. }
  3348. SysFreeString(bstrConfig);
  3349. bstrConfig = NULL;
  3350. }
  3351. if (i >= lCount)
  3352. {
  3353. hr = HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS);
  3354. _JumpError(hr, error, "No CA cert file");
  3355. }
  3356. *ppwszConfig = (WCHAR*)LocalAlloc(LMEM_FIXED,
  3357. SysStringByteLen(bstrConfig) + sizeof(WCHAR));
  3358. _JumpIfOutOfMemory(hr, error, *ppwszConfig);
  3359. wcscpy(*ppwszConfig, bstrConfig);
  3360. hr = S_OK;
  3361. error:
  3362. if (NULL != pICertConfig)
  3363. {
  3364. pICertConfig->Release();
  3365. }
  3366. if (NULL != strConfigConfig)
  3367. {
  3368. SysFreeString(strConfigConfig);
  3369. }
  3370. if (NULL != bstrConfig)
  3371. {
  3372. SysFreeString(bstrConfig);
  3373. }
  3374. if (fCoInit)
  3375. {
  3376. CoUninitialize();
  3377. }
  3378. return hr;
  3379. }
  3380. HRESULT
  3381. DetermineClientUpgradePath(
  3382. IN OUT PER_COMPONENT_DATA *pComp)
  3383. {
  3384. HRESULT hr;
  3385. CAWEBCLIENTSETUPINFO *pClient = pComp->CA.pClient;
  3386. DWORD dwVersion;
  3387. if (CS_UPGRADE_UNKNOWN != pComp->UpgradeFlag)
  3388. {
  3389. // already know upgrade type
  3390. CSASSERT(pClient->pwszWebCAMachine); // this is a side-effect of this fxn, better have been set already
  3391. CSASSERT(pClient->pwszWebCAName); // this is a side-effect of this fxn, better have been set already
  3392. return S_OK;
  3393. }
  3394. //get ca info from registry here
  3395. if (NULL != pClient->pwszWebCAMachine)
  3396. {
  3397. // shouldn't happen, just in case
  3398. LocalFree(pClient->pwszWebCAMachine);
  3399. pClient->pwszWebCAMachine = NULL;
  3400. }
  3401. if (NULL != pClient->pwszWebCAName)
  3402. {
  3403. // shouldn't happen, just in case
  3404. LocalFree(pClient->pwszWebCAName);
  3405. pClient->pwszWebCAName = NULL;
  3406. }
  3407. // get ca machine
  3408. hr = myGetCertRegStrValue(
  3409. NULL,
  3410. NULL,
  3411. NULL,
  3412. wszREGWEBCLIENTCAMACHINE,
  3413. &pClient->pwszWebCAMachine);
  3414. if (S_OK != hr || L'\0' == pClient->pwszWebCAMachine[0])
  3415. {
  3416. BOOL fFinishCYS;
  3417. //for W2K after, it is possible to be in post mode
  3418. hr = CheckPostBaseInstallStatus(&fFinishCYS);
  3419. if (S_OK == hr && !fFinishCYS)
  3420. {
  3421. //this could be either w2k or whistler
  3422. //treat as whistler since upgrade path won't execute
  3423. pComp->UpgradeFlag = CS_UPGRADE_WHISTLER;
  3424. goto done;
  3425. }
  3426. // incorrect reg state,
  3427. // either not found entry or empty string: NT4
  3428. pComp->UpgradeFlag = CS_UPGRADE_UNSUPPORTED;
  3429. hr = S_OK;
  3430. CSILOG(S_OK, IDS_LOG_UPGRADE_UNSUPPORTED, NULL, NULL, NULL);
  3431. _JumpErrorStr(hr, error, "myGetCertRegStrValue", wszREGWEBCLIENTCAMACHINE);
  3432. }
  3433. // get ca
  3434. hr = myGetCertRegStrValue(
  3435. NULL,
  3436. NULL,
  3437. NULL,
  3438. wszREGWEBCLIENTCANAME,
  3439. &pClient->pwszWebCAName);
  3440. if (S_OK != hr || L'\0' == pClient->pwszWebCAName[0])
  3441. {
  3442. // incorrect reg state,
  3443. // either not found entry or empty string: NT4
  3444. if (pClient->pwszWebCAMachine)
  3445. LocalFree(pClient->pwszWebCAMachine);
  3446. pComp->UpgradeFlag = CS_UPGRADE_UNSUPPORTED;
  3447. hr = S_OK;
  3448. CSILOG(S_OK, IDS_LOG_UPGRADE_UNSUPPORTED, NULL, NULL, NULL);
  3449. _JumpErrorStr(hr, error, "myGetCertRegStrValue", wszREGWEBCLIENTCANAME);
  3450. }
  3451. // Now either W2k or Whistler
  3452. // check wszREGVERSION to get current version on Whistler++
  3453. hr = myGetCertRegDWValue(
  3454. NULL,
  3455. NULL,
  3456. NULL,
  3457. wszREGVERSION,
  3458. &dwVersion);
  3459. if (S_OK != hr && HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)!= hr)
  3460. {
  3461. _JumpErrorStr(hr, error, "myGetCertRegDWValue", wszREGVERSION);
  3462. }
  3463. // now either OK or FILE_NOT_FOUND
  3464. if (S_OK == hr)
  3465. {
  3466. // pComp->UpgradeFlag = SOME_FUNCTION(dwVersion); // CS_UPGRADE_WHISTLER already set as default; in future, key off of this
  3467. pComp->UpgradeFlag = CS_UPGRADE_WHISTLER;
  3468. pComp->dwVersion = dwVersion;
  3469. CSILOG(S_OK, IDS_LOG_UPGRADE_B2B, NULL, NULL, NULL);
  3470. }
  3471. else
  3472. {
  3473. pComp->UpgradeFlag = CS_UPGRADE_WIN2000;
  3474. pComp->dwVersion = CSVER_BUILD_VERSION(CSVER_MAJOR_WIN2K, CSVER_MINOR_WIN2K);
  3475. CSILOG(S_OK, IDS_LOG_UPGRADE_WIN2000, NULL, NULL, NULL);
  3476. }
  3477. done:
  3478. hr = S_OK;
  3479. error:
  3480. CSILOG(hr, IDS_LOG_UPGRADE_TYPE, NULL, NULL, (DWORD const *) &pComp->UpgradeFlag);
  3481. return hr;
  3482. }
  3483. HRESULT
  3484. LoadAndDetermineClientUpgradeInfo(
  3485. IN OUT PER_COMPONENT_DATA *pComp)
  3486. {
  3487. HRESULT hr;
  3488. CAWEBCLIENTSETUPINFO *pClient = pComp->CA.pClient;
  3489. //get ca info from registry here
  3490. if (NULL != pClient->pwszSanitizedWebCAName)
  3491. {
  3492. // shouldn't happen, just in case
  3493. LocalFree(pClient->pwszSanitizedWebCAName);
  3494. pClient->pwszSanitizedWebCAName = NULL;
  3495. }
  3496. hr = DetermineClientUpgradePath(pComp);
  3497. _JumpIfError(hr, error, "DetermineClientUpgradePath");
  3498. // get ca
  3499. hr = myGetCertRegDWValue(
  3500. NULL,
  3501. NULL,
  3502. NULL,
  3503. wszREGWEBCLIENTCATYPE,
  3504. (DWORD *) &pClient->WebCAType);
  3505. _PrintIfErrorStr(hr, "myGetCertRegDWValue", wszREGWEBCLIENTCATYPE);
  3506. hr = mySanitizeName(pClient->pwszWebCAName,
  3507. &pClient->pwszSanitizedWebCAName);
  3508. _JumpIfError(hr, error, "mySanitizeName");
  3509. hr = S_OK;
  3510. error:
  3511. CSILOG(hr, IDS_LOG_UPGRADE_TYPE, NULL, NULL, (DWORD const *) &pComp->UpgradeFlag);
  3512. return hr;
  3513. }
  3514. // apply ACL to key container for all upgrade scenarios
  3515. HRESULT
  3516. UpgradeKeyContainerSecurity(
  3517. PER_COMPONENT_DATA *pComp)
  3518. {
  3519. HRESULT hr;
  3520. HCRYPTPROV hProv = NULL;
  3521. WCHAR *pwszProvName = NULL;
  3522. DWORD dwProvType;
  3523. ALG_ID idAlg;
  3524. BOOL fMachineKeyset;
  3525. // get prov name
  3526. hr = myGetCertSrvCSP(
  3527. FALSE, // fEncryptionCSP
  3528. pComp->CA.pServer->pwszSanitizedName,
  3529. &dwProvType,
  3530. &pwszProvName,
  3531. &idAlg,
  3532. &fMachineKeyset,
  3533. NULL); // pdwKeySize
  3534. _JumpIfError(hr, error, "myGetCertSrvCSP");
  3535. if (!myCertSrvCryptAcquireContext(&hProv,
  3536. pComp->CA.pServer->pwszSanitizedName,
  3537. pwszProvName,
  3538. dwProvType,
  3539. CRYPT_SILENT, // get key, upgrade, no UI
  3540. fMachineKeyset))
  3541. {
  3542. hr = myHLastError();
  3543. _JumpError(hr, error, "myCertSrvCryptAcquireContext");
  3544. }
  3545. // set acl on it
  3546. hr = csiSetKeyContainerSecurity(hProv);
  3547. _JumpIfError(hr, error, "csiSetKeyContainerSecurity");
  3548. error:
  3549. if (NULL != hProv)
  3550. {
  3551. CryptReleaseContext(hProv, 0);
  3552. }
  3553. if (NULL != pwszProvName)
  3554. {
  3555. LocalFree(pwszProvName);
  3556. }
  3557. CSILOG(hr, IDS_LOG_UPGRADE_KEY_SECURITY, NULL, NULL, NULL);
  3558. return hr;
  3559. }
  3560. HRESULT
  3561. InstallNewTemplates(HWND hwnd)
  3562. {
  3563. HRESULT hr = S_OK;
  3564. SHELLEXECUTEINFO shi;
  3565. ZeroMemory(&shi, sizeof(shi));
  3566. shi.cbSize = sizeof(shi);
  3567. shi.hwnd = hwnd;
  3568. shi.lpVerb = SZ_VERB_OPEN;
  3569. shi.lpFile = SZ_REGSVR32;
  3570. shi.lpParameters = SZ_REGSVR32_CERTCLI;
  3571. shi.fMask = SEE_MASK_FLAG_NO_UI |
  3572. SEE_MASK_NOCLOSEPROCESS;
  3573. if(!ShellExecuteEx(&shi))
  3574. {
  3575. hr = myHLastError();
  3576. _JumpError(hr, error, "ShellExecuteEx");
  3577. }
  3578. if(WAIT_FAILED == WaitForSingleObject(shi.hProcess, INFINITE))
  3579. {
  3580. hr = myHLastError();
  3581. _JumpError(hr, error, "WaitForSingleObject");
  3582. }
  3583. error:
  3584. if(shi.hProcess)
  3585. {
  3586. CloseHandle(shi.hProcess);
  3587. }
  3588. return hr;
  3589. }
  3590. HRESULT
  3591. UpgradeServer(
  3592. IN HWND hwnd,
  3593. IN PER_COMPONENT_DATA *pComp)
  3594. {
  3595. HRESULT hr;
  3596. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  3597. hr = RegisterAndUnRegisterDLLs(RD_SERVER, pComp, hwnd);
  3598. _JumpIfError(hr, error, "RegisterAndUnRegisterDLLs");
  3599. hr = LoadAndDetermineServerUpgradeInfo(pComp);
  3600. _JumpIfError(hr, error, "LoadAndDetermineServerUpgradeInfo");
  3601. // create enroll dir
  3602. hr = CreateCertsrvDirectories(pComp, TRUE, TRUE);
  3603. _JumpIfError(hr, error, "CreateCertsrvDirectories");
  3604. hr = EnableVRootsAndShares(FALSE, TRUE, TRUE, pComp, hwnd);
  3605. _PrintIfError(hr, "EnableVRootsAndShares(share only)");
  3606. hr = UpgradeServerRegEntries(pComp);
  3607. _JumpIfError(hr, error, "UpgradeServerRegEntries");
  3608. hr = CreateCertWebIncPages(pComp, TRUE /* IsServer */ );
  3609. _JumpIfError(hr, error, "CreateCertWebIncPages");
  3610. hr = RenameMiscTargets(hwnd, pComp, TRUE);
  3611. _JumpIfError(hr, error, "RenameMiscTargets");
  3612. hr = UpgradeKeyContainerSecurity(pComp);
  3613. // ignore new acl failure
  3614. _PrintIfError(hr, "UpgradeKeyContainerSecurity");
  3615. // always register dcom
  3616. hr = RegisterDcomServer(
  3617. TRUE,
  3618. CLSID_CCertRequestD, // AppId
  3619. CLSID_CCertRequestD,
  3620. wszREQUESTFRIENDLYNAME,
  3621. wszREQUESTVERINDPROGID,
  3622. wszREQUESTPROGID);
  3623. _JumpIfError(hr, error, "RegisterDcomServer");
  3624. hr = RegisterDcomServer(
  3625. FALSE,
  3626. CLSID_CCertRequestD, // AppId
  3627. CLSID_CCertAdminD,
  3628. wszADMINFRIENDLYNAME,
  3629. wszADMINVERINDPROGID,
  3630. wszADMINPROGID);
  3631. _JumpIfError(hr, error, "RegisterDcomServer");
  3632. hr = RegisterDcomApp(CLSID_CCertRequestD);
  3633. _JumpIfError(hr, error, "RegisterDcomApp");
  3634. // bug 446444: remove CLSID_CCertAdminD AppId
  3635. {
  3636. WCHAR wszCLSIDAppId[CLSID_STRING_SIZE];
  3637. WCHAR wszKey[CLSID_STRING_SIZE+7] = L"AppID\\";
  3638. CLSIDtochar(CLSID_CCertAdminD, wszCLSIDAppId, ARRAYSIZE(wszCLSIDAppId));
  3639. wcscat(wszKey, wszCLSIDAppId);
  3640. hr = RegDeleteKey(
  3641. HKEY_CLASSES_ROOT,
  3642. wszKey);
  3643. _PrintIfErrorStr(hr, "Cannot delete ICertAdminD AppID", wszKey);
  3644. }
  3645. // fix for 155772 Certsrv: After upgrading a 2195 Enterprise Root CA
  3646. // to 2254.01VBL03 the CA will no longer issue Certs
  3647. hr = InstallNewTemplates(hwnd);
  3648. _JumpIfError(hr, error, "InstallNewTemplates");
  3649. // always fix certsvc in upgrade
  3650. hr = FixCertsvcService(pComp);
  3651. _PrintIfError(hr, "FixCertsvcService");
  3652. // delete any old program groups
  3653. DeleteProgramGroups(TRUE);
  3654. hr = CreateProgramGroups(FALSE, pComp, hwnd);
  3655. _PrintIfError(hr, "CreateProgramGroups");
  3656. // delete old stuff
  3657. DeleteOldFilesAndDirectories(pComp);
  3658. DBGPRINT((DBG_SS_CERTOCM, "UpgradeServer: setting SETUP_SERVER_UPGRADED_FLAG\n"));
  3659. hr = SetSetupStatus(NULL, SETUP_SERVER_UPGRADED_FLAG, TRUE);
  3660. _JumpIfError(hr, error, "SetSetupStatus");
  3661. // Force new CRL generation on startup when upgrading from Win2k
  3662. if(CS_UPGRADE_WIN2000 == pComp->UpgradeFlag)
  3663. {
  3664. DBGPRINT((DBG_SS_CERTOCM, "UpgradeServer: setting SETUP_FORCECRL_FLAG\n"));
  3665. hr = SetSetupStatus(pServer->pwszSanitizedName, SETUP_FORCECRL_FLAG, TRUE);
  3666. _PrintIfError(hr, "SetSetupStatus");
  3667. }
  3668. hr = csiUpgradeCertSrvSecurity(
  3669. pServer->pwszSanitizedName,
  3670. IsEnterpriseCA(pServer->CAType)?true:false,
  3671. pServer->fUseDS?true:false,
  3672. pComp->UpgradeFlag);
  3673. if (hr == HRESULT_FROM_WIN32(ERROR_CAN_NOT_COMPLETE))
  3674. {
  3675. _PrintError(hr, "csiUpgradeCertSrvSecurity marked for later fixup; error ignored");
  3676. hr = S_OK;
  3677. }
  3678. _JumpIfError(hr, error, "csiUpgradeCertSrvSecurity");
  3679. hr = S_OK;
  3680. error:
  3681. CSILOG(hr, IDS_LOG_UPGRADE_SERVER, NULL, NULL, NULL);
  3682. return hr;
  3683. }
  3684. HRESULT
  3685. UpgradeClient(
  3686. IN HWND hwnd,
  3687. IN PER_COMPONENT_DATA *pComp)
  3688. {
  3689. HRESULT hr;
  3690. if ((IS_CLIENT_UPGRADE & pComp->dwInstallStatus) &&
  3691. (IS_SERVER_UPGRADE & pComp->dwInstallStatus))
  3692. {
  3693. // upgrade server will also hit here so skip it
  3694. goto done;
  3695. }
  3696. // unset client
  3697. hr = SetSetupStatus(NULL, SETUP_CLIENT_FLAG, FALSE);
  3698. _JumpIfError(hr, error, "SetSetupStatus");
  3699. hr = RegisterAndUnRegisterDLLs(RD_CLIENT, pComp, hwnd);
  3700. _JumpIfError(hr, error, "RegisterAndUnRegisterDLLs");
  3701. hr = LoadAndDetermineClientUpgradeInfo(pComp);
  3702. _JumpIfError(hr, error, "LoadAndDetermineClientUpgradeInfo");
  3703. hr = UpgradeWebClientRegEntries(pComp);
  3704. _JumpIfError(hr, error, "UpgradeWebClientRegEntries");
  3705. hr = CreateCertWebIncPages(pComp, FALSE /* IsServer */ );
  3706. _JumpIfError(hr, error, "CreateCertWebIncPages");
  3707. hr = RenameMiscTargets(hwnd, pComp, FALSE);
  3708. _JumpIfError(hr, error, "RenameMiscTargets");
  3709. // delete any old program groups
  3710. DeleteProgramGroups(FALSE);
  3711. hr = CreateProgramGroups(TRUE, pComp, hwnd);
  3712. _PrintIfError(hr, "CreateProgramGroups");
  3713. hr = SetSetupStatus(NULL, SETUP_CLIENT_FLAG, TRUE);
  3714. _JumpIfError(hr, error, "SetSetupStatus");
  3715. DeleteOldFilesAndDirectories(pComp);
  3716. done:
  3717. hr = S_OK;
  3718. error:
  3719. CSILOG(hr, IDS_LOG_UPGRADE_CLIENT, NULL, NULL, NULL);
  3720. return hr;
  3721. }
  3722. HRESULT
  3723. GetServerNames(
  3724. IN HWND hwnd,
  3725. IN HINSTANCE hInstance,
  3726. IN BOOL fUnattended,
  3727. OUT WCHAR **ppwszServerName,
  3728. OUT WCHAR **ppwszServerNameOld)
  3729. {
  3730. HRESULT hr;
  3731. // Retrieve computer name strings.
  3732. hr = myGetComputerNames(ppwszServerName, ppwszServerNameOld);
  3733. if (S_OK != hr)
  3734. {
  3735. CertErrorMessageBox(
  3736. hInstance,
  3737. fUnattended,
  3738. hwnd,
  3739. IDS_ERR_GETCOMPUTERNAME,
  3740. hr,
  3741. NULL);
  3742. _JumpError(hr, error, "myGetComputerNames");
  3743. }
  3744. error:
  3745. return(hr);
  3746. }
  3747. HRESULT
  3748. UpdateDomainAndUserName(
  3749. IN HWND hwnd,
  3750. IN OUT PER_COMPONENT_DATA *pComp)
  3751. {
  3752. HRESULT hr;
  3753. // free old server and installer info because we might get them in nt base
  3754. if (NULL != pComp->pwszServerName)
  3755. {
  3756. LocalFree(pComp->pwszServerName);
  3757. pComp->pwszServerName = NULL;
  3758. }
  3759. if (NULL != pComp->pwszServerNameOld)
  3760. {
  3761. LocalFree(pComp->pwszServerNameOld);
  3762. pComp->pwszServerNameOld = NULL;
  3763. }
  3764. hr = GetServerNames(
  3765. hwnd,
  3766. pComp->hInstance,
  3767. pComp->fUnattended,
  3768. &pComp->pwszServerName,
  3769. &pComp->pwszServerNameOld);
  3770. _JumpIfError(hr, error, "GetServerNames");
  3771. DBGPRINT((DBG_SS_CERTOCM, "UpdateDomainAndUserName:%ws,%ws\n", pComp->pwszServerName, pComp->pwszServerNameOld));
  3772. DumpBackTrace("UpdateDomainAndUserName");
  3773. error:
  3774. return(hr);
  3775. }
  3776. HRESULT
  3777. StopCertService(
  3778. IN SC_HANDLE hSC,
  3779. IN WCHAR const *pwszServiceName)
  3780. {
  3781. HRESULT hr;
  3782. SERVICE_STATUS status;
  3783. DWORD dwAttempt;
  3784. if (!ControlService(hSC, SERVICE_CONTROL_STOP, &status))
  3785. {
  3786. hr = myHLastError();
  3787. if (HRESULT_FROM_WIN32(ERROR_SERVICE_NOT_ACTIVE) != hr)
  3788. {
  3789. _JumpErrorStr(hr, error, "ControlService(Stop)", pwszServiceName);
  3790. }
  3791. }
  3792. // get out after it is really stopped
  3793. for (dwAttempt = 0; dwAttempt < CERT_MAX_ATTEMPT; dwAttempt++)
  3794. {
  3795. DBGCODE(status.dwCurrentState = MAXDWORD);
  3796. if (!QueryServiceStatus(hSC, &status))
  3797. {
  3798. // query failed, ignore error
  3799. hr = S_OK;
  3800. _JumpErrorStr(
  3801. myHLastError(), // Display ignored error
  3802. error,
  3803. "QueryServiceStatus",
  3804. pwszServiceName);
  3805. }
  3806. if (status.dwCurrentState != SERVICE_STOP_PENDING &&
  3807. status.dwCurrentState != SERVICE_RUNNING)
  3808. {
  3809. // it was stopped already
  3810. break;
  3811. }
  3812. DBGPRINT((
  3813. DBG_SS_CERTOCM,
  3814. "Stopping %ws service: current state=%d\n",
  3815. pwszServiceName,
  3816. status.dwCurrentState));
  3817. Sleep(CERT_HALF_SECOND);
  3818. }
  3819. if (dwAttempt >= CERT_MAX_ATTEMPT)
  3820. {
  3821. DBGPRINT((
  3822. DBG_SS_CERTOCM,
  3823. "Timeout stopping %ws service: current state=%d\n",
  3824. pwszServiceName,
  3825. status.dwCurrentState));
  3826. }
  3827. else
  3828. {
  3829. DBGPRINT((
  3830. DBG_SS_CERTOCM,
  3831. "Stopped %ws service\n",
  3832. pwszServiceName));
  3833. }
  3834. hr = S_OK;
  3835. error:
  3836. CSILOG(hr, IDS_LOG_SERVICE_STOPPED, pwszServiceName, NULL, NULL);
  3837. return(hr);
  3838. }
  3839. HRESULT
  3840. GetServiceControl(
  3841. WCHAR const *pwszServiceName,
  3842. OUT SC_HANDLE *phService)
  3843. {
  3844. HRESULT hr;
  3845. SC_HANDLE hSCManager = NULL;
  3846. *phService = NULL;
  3847. hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  3848. if (NULL == hSCManager)
  3849. {
  3850. hr = myHLastError();
  3851. _JumpError(hr, error, "OpenSCManager");
  3852. }
  3853. *phService = OpenService(hSCManager, pwszServiceName, SERVICE_ALL_ACCESS);
  3854. if (NULL == *phService)
  3855. {
  3856. hr = myHLastError();
  3857. _JumpErrorStr2(
  3858. hr,
  3859. error,
  3860. "OpenService",
  3861. pwszServiceName,
  3862. HRESULT_FROM_WIN32(ERROR_SERVICE_DOES_NOT_EXIST));
  3863. }
  3864. hr = S_OK;
  3865. error:
  3866. if (NULL != hSCManager)
  3867. {
  3868. CloseServiceHandle(hSCManager);
  3869. }
  3870. return hr;
  3871. }
  3872. HRESULT
  3873. IsServiceRunning(
  3874. IN SC_HANDLE const hSCService,
  3875. OUT BOOL *pfRun)
  3876. {
  3877. HRESULT hr;
  3878. SERVICE_STATUS status;
  3879. *pfRun = FALSE;
  3880. if (!QueryServiceStatus(hSCService, &status))
  3881. {
  3882. hr = myHLastError();
  3883. _JumpError(hr, error, "QueryServiceStatus");
  3884. }
  3885. if (SERVICE_STOPPED != status.dwCurrentState &&
  3886. SERVICE_STOP_PENDING != status.dwCurrentState)
  3887. {
  3888. *pfRun = TRUE;
  3889. }
  3890. hr = S_OK;
  3891. error:
  3892. return hr;
  3893. }
  3894. HRESULT
  3895. StartAndStopService(
  3896. IN HINSTANCE hInstance,
  3897. IN BOOL fUnattended,
  3898. IN HWND const hwnd,
  3899. IN WCHAR const *pwszServiceName,
  3900. IN BOOL const fStopService,
  3901. IN BOOL const fConfirm,
  3902. IN int iMsg,
  3903. OUT BOOL *pfServiceWasRunning)
  3904. {
  3905. HRESULT hr;
  3906. SC_HANDLE hService = NULL;
  3907. *pfServiceWasRunning = FALSE;
  3908. hr = GetServiceControl(pwszServiceName, &hService);
  3909. if (S_OK != hr)
  3910. {
  3911. _PrintError2(
  3912. hr,
  3913. "GetServiceControl",
  3914. HRESULT_FROM_WIN32(ERROR_SERVICE_DOES_NOT_EXIST));
  3915. if (HRESULT_FROM_WIN32(ERROR_SERVICE_DOES_NOT_EXIST) == hr)
  3916. {
  3917. hr = S_OK;
  3918. }
  3919. goto error;
  3920. }
  3921. // to get status if the service is running
  3922. hr = IsServiceRunning(hService, pfServiceWasRunning);
  3923. _JumpIfError(hr, error, "IsServiceRunning");
  3924. if (fStopService)
  3925. {
  3926. if (*pfServiceWasRunning)
  3927. {
  3928. // stop the service
  3929. if (fConfirm)
  3930. {
  3931. // confirmation dialog
  3932. int ret = CertMessageBox(
  3933. hInstance,
  3934. fUnattended,
  3935. hwnd,
  3936. iMsg,
  3937. 0,
  3938. MB_YESNO |
  3939. MB_ICONWARNING |
  3940. CMB_NOERRFROMSYS,
  3941. NULL);
  3942. if (IDYES != ret)
  3943. {
  3944. hr = E_ABORT;
  3945. _JumpError(hr, error, "Cancel it");
  3946. }
  3947. }
  3948. hr = StopCertService(hService, pwszServiceName);
  3949. _JumpIfErrorStr(hr, error, "StopCertService", pwszServiceName);
  3950. }
  3951. }
  3952. else
  3953. {
  3954. // START the service
  3955. if (!*pfServiceWasRunning)
  3956. {
  3957. if (!StartService(hService, 0, NULL))
  3958. {
  3959. hr = myHLastError();
  3960. _JumpErrorStr(hr, error, "StartService", pwszServiceName);
  3961. }
  3962. }
  3963. }
  3964. hr = S_OK;
  3965. error:
  3966. if (NULL != hService)
  3967. {
  3968. CloseServiceHandle(hService);
  3969. }
  3970. CSILOG(
  3971. hr,
  3972. fStopService? IDS_LOG_SERVICE_STOPPED : IDS_LOG_SERVICE_STARTED,
  3973. pwszServiceName,
  3974. NULL,
  3975. NULL);
  3976. return hr;
  3977. }
  3978. // fix existing certsvc service to add/use new service description
  3979. HRESULT
  3980. FixCertsvcService(PER_COMPONENT_DATA *pComp)
  3981. {
  3982. HRESULT hr;
  3983. SC_HANDLE hService = NULL;
  3984. QUERY_SERVICE_CONFIG *pServiceConfig = NULL;
  3985. WCHAR *pwszServiceDesc = NULL;
  3986. WCHAR const *pwszDisplayName;
  3987. SERVICE_DESCRIPTION sd;
  3988. DWORD dwSize;
  3989. hr = GetServiceControl(wszSERVICE_NAME, &hService);
  3990. _JumpIfError(hr, error, "GetServiceControl");
  3991. // get size
  3992. if (!QueryServiceConfig(hService,
  3993. NULL,
  3994. 0,
  3995. &dwSize))
  3996. {
  3997. hr = myHLastError();
  3998. if (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) != hr)
  3999. {
  4000. _JumpError(hr, fix_desc, "QueryServiceConfig");
  4001. }
  4002. }
  4003. else
  4004. {
  4005. // impossible???
  4006. hr = E_INVALIDARG;
  4007. _JumpError(hr, fix_desc, "QueryServiceConfig");
  4008. }
  4009. CSASSERT(0 < dwSize);
  4010. // allocate config buffer
  4011. pServiceConfig = (QUERY_SERVICE_CONFIG*)LocalAlloc(
  4012. LMEM_FIXED | LMEM_ZEROINIT,
  4013. dwSize);
  4014. _JumpIfOutOfMemory(hr, error, pServiceConfig);
  4015. // get config
  4016. if (!QueryServiceConfig(hService,
  4017. pServiceConfig,
  4018. dwSize,
  4019. &dwSize))
  4020. {
  4021. hr = myHLastError();
  4022. _JumpError(hr, fix_desc, "QueryServiceConfig");
  4023. }
  4024. // use new display name
  4025. pwszDisplayName = myLoadResourceString(IDS_CA_SERVICEDISPLAYNAME);
  4026. if (NULL == pwszDisplayName)
  4027. {
  4028. hr = myHLastError();
  4029. _JumpError(hr, error, "myLoadResourceString");
  4030. }
  4031. if (!ChangeServiceConfig(hService,
  4032. pServiceConfig->dwServiceType, //dwServiceType
  4033. SERVICE_NO_CHANGE, //dwStartType
  4034. SERVICE_NO_CHANGE, //dwErrorControl
  4035. NULL, //lpBinaryPathName
  4036. NULL, //lpLoadOrderGroup
  4037. NULL, //lpdwTagId
  4038. NULL, //lpDependences
  4039. NULL, //lpServiceStartName
  4040. NULL, //lpPassword
  4041. pwszDisplayName))
  4042. {
  4043. hr = myHLastError();
  4044. _JumpIfError(hr, fix_desc, "ChangeServiceConfig");
  4045. }
  4046. fix_desc:
  4047. // add description
  4048. hr = myLoadRCString(pComp->hInstance, IDS_CA_SERVICEDESCRIPTION, &pwszServiceDesc);
  4049. _JumpIfError(hr, error, "myLoadRCString");
  4050. sd.lpDescription = pwszServiceDesc;
  4051. if (!ChangeServiceConfig2(hService,
  4052. SERVICE_CONFIG_DESCRIPTION,
  4053. (VOID*)&sd))
  4054. {
  4055. hr = myHLastError();
  4056. _JumpError(hr, error, "ChangeServiceConfig2");
  4057. }
  4058. hr = S_OK;
  4059. error:
  4060. if (NULL != hService)
  4061. {
  4062. CloseServiceHandle(hService);
  4063. }
  4064. if (NULL != pwszServiceDesc)
  4065. {
  4066. LocalFree(pwszServiceDesc);
  4067. }
  4068. if (NULL != pServiceConfig)
  4069. {
  4070. LocalFree(pServiceConfig);
  4071. }
  4072. return hr;
  4073. }
  4074. HRESULT
  4075. PreUninstallCore(
  4076. IN HWND hwnd,
  4077. IN PER_COMPONENT_DATA *pComp)
  4078. {
  4079. BOOL fDummy;
  4080. HRESULT hr;
  4081. DWORD dwFlags = RD_UNREGISTER;
  4082. hr = StartAndStopService(pComp->hInstance,
  4083. pComp->fUnattended,
  4084. hwnd,
  4085. wszSERVICE_NAME,
  4086. TRUE, // stop the service
  4087. FALSE, // no confirm
  4088. 0, //doesn't matter since no confirm
  4089. &fDummy);
  4090. _PrintIfError(hr, "StartAndStopService");
  4091. hr = RegisterAndUnRegisterDLLs(dwFlags, pComp, hwnd);
  4092. _PrintIfError(hr, "RegisterAndUnRegisterDLLs");
  4093. hr = S_OK;
  4094. return(hr);
  4095. }
  4096. VOID
  4097. DeleteServiceAndGroups(
  4098. IN HINSTANCE hInstance,
  4099. IN BOOL fUnattended,
  4100. IN HWND hwnd)
  4101. {
  4102. SC_HANDLE hSCManager = NULL;
  4103. SC_HANDLE hSC = NULL;
  4104. HRESULT hr;
  4105. hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  4106. if (NULL == hSCManager)
  4107. {
  4108. hr = myHLastError();
  4109. _JumpError(hr, error, "OpenSCManager");
  4110. }
  4111. hSC = OpenService(hSCManager, wszSERVICE_NAME, SERVICE_ALL_ACCESS);
  4112. if (NULL != hSC)
  4113. {
  4114. if (!DeleteService(hSC))
  4115. {
  4116. hr = myHLastError();
  4117. CertErrorMessageBox(
  4118. hInstance,
  4119. fUnattended,
  4120. hwnd,
  4121. IDS_ERR_DELETESERVICE,
  4122. hr,
  4123. wszSERVICE_NAME);
  4124. _PrintError(hr, "DeleteService");
  4125. }
  4126. CloseServiceHandle(hSC);
  4127. }
  4128. error:
  4129. if (NULL != hSCManager)
  4130. {
  4131. CloseServiceHandle(hSCManager);
  4132. }
  4133. }
  4134. HRESULT
  4135. SetCertSrvInstallVersion()
  4136. {
  4137. HRESULT hr;
  4138. hr = mySetCertRegDWValueEx(
  4139. FALSE,
  4140. NULL,
  4141. NULL,
  4142. NULL,
  4143. wszREGVERSION,
  4144. CSVER_BUILD_VERSION(CSVER_MAJOR, CSVER_MINOR));
  4145. _PrintIfErrorStr(hr, "mySetCertRegDWValueEx", wszREGVERSION);
  4146. return hr;
  4147. }
  4148. HRESULT
  4149. CreateWebClientRegEntries(
  4150. BOOL fUpgrade,
  4151. PER_COMPONENT_DATA *pComp)
  4152. {
  4153. HRESULT hr;
  4154. CAWEBCLIENTSETUPINFO *pClient = pComp->CA.pClient;
  4155. hr = mySetCertRegStrValueEx(fUpgrade, NULL, NULL, NULL,
  4156. wszREGWEBCLIENTCAMACHINE, pClient->pwszWebCAMachine);
  4157. _JumpIfError(hr, error, "mySetCertRegStrValueEx");
  4158. hr = mySetCertRegStrValueEx(fUpgrade, NULL, NULL, NULL,
  4159. wszREGWEBCLIENTCANAME, pClient->pwszWebCAName);
  4160. _JumpIfError(hr, error, "mySetCertRegStrValueEx");
  4161. hr = mySetCertRegDWValueEx(fUpgrade, NULL, NULL, NULL,
  4162. wszREGWEBCLIENTCATYPE, pClient->WebCAType);
  4163. _JumpIfError(hr, error, "mySetCertRegDWValueEx");
  4164. hr = mySetCertRegDWValueEx(
  4165. fUpgrade,
  4166. NULL,
  4167. NULL,
  4168. NULL,
  4169. wszREGLDAPFLAGS,
  4170. 0);
  4171. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGLDAPFLAGS);
  4172. hr = SetCertSrvInstallVersion();
  4173. _JumpIfError(hr, error, "SetCertSrvInstallVersion");
  4174. if (NULL != pClient->pwszSharedFolder)
  4175. {
  4176. hr = mySetCertRegStrValueEx(fUpgrade, NULL, NULL, NULL,
  4177. wszREGDIRECTORY, pClient->pwszSharedFolder);
  4178. _JumpIfError(hr, error, "mySetCertRegStrValue");
  4179. }
  4180. hr = S_OK;
  4181. error:
  4182. CSILOG(hr, IDS_LOG_CREATE_CLIENT_REG, NULL, NULL, NULL);
  4183. return hr;
  4184. }
  4185. HRESULT
  4186. UpgradeWebClientRegEntries(
  4187. PER_COMPONENT_DATA *pComp)
  4188. {
  4189. HRESULT hr;
  4190. hr = CreateWebClientRegEntries(TRUE, pComp);
  4191. _JumpIfError(hr, error, "CreateWebClientRegEntries");
  4192. // hr = S_OK;
  4193. error:
  4194. return hr;
  4195. }
  4196. HRESULT
  4197. DeleteCertificates(
  4198. IN WCHAR const *pwszSanitizedCAName,
  4199. IN BOOL fRoot)
  4200. {
  4201. HRESULT hr;
  4202. DWORD cCACerts;
  4203. DWORD cCACert;
  4204. DWORD dwNameId;
  4205. HCERTSTORE hStore = NULL;
  4206. CERT_CONTEXT const *pCACert = NULL;
  4207. hr = myGetCARegHashCount(pwszSanitizedCAName, CSRH_CASIGCERT, &cCACerts);
  4208. _JumpIfError(hr, error, "myGetCARegHashCount CSRH_CASIGCERT");
  4209. hStore = CertOpenStore(
  4210. CERT_STORE_PROV_SYSTEM_REGISTRY,
  4211. X509_ASN_ENCODING,
  4212. NULL, // hProv
  4213. CERT_SYSTEM_STORE_LOCAL_MACHINE,
  4214. fRoot?wszROOT_CERTSTORE:wszCA_CERTSTORE);
  4215. for (cCACert = 0; cCACert < cCACerts; cCACert++)
  4216. {
  4217. HRESULT hr2;
  4218. hr2 = myFindCACertByHashIndex(
  4219. hStore,
  4220. pwszSanitizedCAName,
  4221. CSRH_CASIGCERT,
  4222. cCACert,
  4223. &dwNameId,
  4224. &pCACert);
  4225. if (S_OK != hr2)
  4226. {
  4227. _PrintIfError2(hr2, "myFindCACertByHashIndex", S_FALSE);
  4228. if (S_FALSE != hr2 &&
  4229. CRYPT_E_NOT_FOUND != hr2)
  4230. {
  4231. hr = hr2;
  4232. }
  4233. continue;
  4234. }
  4235. if (!CertDeleteCertificateFromStore(pCACert))
  4236. {
  4237. hr = myHLastError();
  4238. _PrintError(hr, "CertDeleteCertificateFromStore");
  4239. }
  4240. pCACert = NULL;
  4241. }
  4242. error:
  4243. CSASSERT(NULL == pCACert);
  4244. if (NULL != hStore)
  4245. {
  4246. CertCloseStore(hStore, CERT_CLOSE_STORE_FORCE_FLAG);
  4247. }
  4248. return hr;
  4249. }
  4250. HRESULT
  4251. UninstallCore(
  4252. IN HWND hwnd,
  4253. IN PER_COMPONENT_DATA *pComp,
  4254. IN DWORD PerCentCompleteBase,
  4255. IN DWORD PerCentCompleteMax,
  4256. IN BOOL fPreserveClient,
  4257. IN BOOL fRemoveVD,
  4258. IN BOOL fPreserveToDoList)
  4259. {
  4260. BOOL fCoInit = FALSE;
  4261. HRESULT hr;
  4262. WCHAR *pwszSharedFolder = NULL;
  4263. WCHAR *pwszSanitizedCAName = NULL;
  4264. ENUM_CATYPES caType = ENUM_UNKNOWN_CA;
  4265. BOOL fUseDS = FALSE;
  4266. WCHAR *pwszDBDirectory = NULL;
  4267. WCHAR *pwszLogDirectory = NULL;
  4268. WCHAR *pwszSysDirectory = NULL;
  4269. WCHAR *pwszTmpDirectory = NULL;
  4270. DWORD DBSessionCount = 0;
  4271. DWORD PerCentCompleteDelta;
  4272. PerCentCompleteDelta = (PerCentCompleteMax - PerCentCompleteBase) / 10;
  4273. #define _UNINSTALLPERCENT(tenths) \
  4274. (PerCentCompleteBase + (tenths) * PerCentCompleteDelta)
  4275. // get current active CA info
  4276. hr = myGetCertRegStrValue(NULL, NULL, NULL, wszREGACTIVE, &pwszSanitizedCAName);
  4277. _PrintIfError(hr, "UninstallCore(no active CA)");
  4278. if (S_OK == hr)
  4279. {
  4280. hr = ArchiveCACertificate(pwszSanitizedCAName);
  4281. _PrintIfError2(hr, "ArchiveCACertificate", HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
  4282. hr = myGetCertRegDWValue(pwszSanitizedCAName, NULL, NULL, wszREGCATYPE, (DWORD*)&caType);
  4283. _PrintIfError(hr, "no reg ca type");
  4284. hr = myGetCertRegDWValue(pwszSanitizedCAName, NULL, NULL, wszREGCAUSEDS, (DWORD*)&fUseDS);
  4285. _PrintIfError(hr, "no reg use ds");
  4286. hr = DeleteCertificates(pwszSanitizedCAName, IsRootCA(caType));
  4287. if(S_OK != hr)
  4288. {
  4289. CertWarningMessageBox(
  4290. pComp->hInstance,
  4291. pComp->fUnattended,
  4292. hwnd,
  4293. IDS_IDINFO_DELETECERTIFICATES,
  4294. hr,
  4295. NULL);
  4296. }
  4297. }
  4298. hr = myGetCertRegStrValue(NULL, NULL, NULL, wszREGDIRECTORY, &pwszSharedFolder);
  4299. _PrintIfError(hr, "no shared folder");
  4300. hr = myGetCertRegStrValue(NULL, NULL, NULL, wszREGDBDIRECTORY, &pwszDBDirectory);
  4301. _PrintIfError(hr, "no db directory");
  4302. hr = myGetCertRegStrValue(NULL, NULL, NULL, wszREGDBLOGDIRECTORY, &pwszLogDirectory);
  4303. _PrintIfError(hr, "no log directory");
  4304. hr = myGetCertRegStrValue(NULL, NULL, NULL, wszREGDBSYSDIRECTORY, &pwszSysDirectory);
  4305. _PrintIfError(hr, "no sys directory");
  4306. hr = myGetCertRegStrValue(NULL, NULL, NULL, wszREGDBTEMPDIRECTORY, &pwszTmpDirectory);
  4307. _PrintIfError(hr, "no tmp directory");
  4308. hr = myGetCertRegDWValue(NULL, NULL, NULL, wszREGDBSESSIONCOUNT, &DBSessionCount);
  4309. _PrintIfError(hr, "no session count");
  4310. hr = CoInitialize(NULL);
  4311. if (S_OK != hr && S_FALSE != hr)
  4312. {
  4313. _JumpError(hr, error, "CoInitialize");
  4314. }
  4315. fCoInit = TRUE;
  4316. DeleteServiceAndGroups(pComp->hInstance, pComp->fUnattended, hwnd);
  4317. certocmBumpGasGauge(pComp, _UNINSTALLPERCENT(1) DBGPARM(L"UninstallCore"));
  4318. if (!fPreserveToDoList)
  4319. {
  4320. // if we're uninstalling, always clear post-base ToDo list
  4321. RegDeleteKey(HKEY_LOCAL_MACHINE, wszREGKEYCERTSRVTODOLIST);
  4322. }
  4323. if (fPreserveClient)
  4324. {
  4325. hr = RegisterAndUnRegisterDLLs(RD_CLIENT, pComp, hwnd);
  4326. _JumpIfError(hr, error, "RegisterAndUnRegisterDLLs");
  4327. hr = CreateCertWebIncPages(pComp, FALSE /* IsServer */ );
  4328. _JumpIfError(hr, error, "CreateCertWebIncPages");
  4329. }
  4330. certocmBumpGasGauge(pComp, _UNINSTALLPERCENT(2) DBGPARM(L"UninstallCore"));
  4331. DeleteProgramGroups(TRUE);
  4332. if (fPreserveClient)
  4333. {
  4334. hr = CreateProgramGroups(TRUE, pComp, hwnd);
  4335. _JumpIfError(hr, error, "CreateProgramGroups");
  4336. }
  4337. certocmBumpGasGauge(pComp, _UNINSTALLPERCENT(3) DBGPARM(L"UninstallCore"));
  4338. UnregisterDcomServer(
  4339. CLSID_CCertRequestD,
  4340. wszREQUESTVERINDPROGID,
  4341. wszREQUESTPROGID);
  4342. certocmBumpGasGauge(pComp, _UNINSTALLPERCENT(4) DBGPARM(L"UninstallCore"));
  4343. UnregisterDcomServer(
  4344. CLSID_CCertAdminD,
  4345. wszADMINVERINDPROGID,
  4346. wszADMINPROGID);
  4347. certocmBumpGasGauge(pComp, _UNINSTALLPERCENT(5) DBGPARM(L"UninstallCore"));
  4348. UnregisterDcomApp();
  4349. certocmBumpGasGauge(pComp, _UNINSTALLPERCENT(6) DBGPARM(L"UninstallCore"));
  4350. if (fRemoveVD && !fPreserveClient)
  4351. {
  4352. DisableVRootsAndShares(TRUE, TRUE);
  4353. myDeleteFilePattern(pComp->pwszSystem32, wszCERTSRV, TRUE);
  4354. }
  4355. certocmBumpGasGauge(pComp, _UNINSTALLPERCENT(7) DBGPARM(L"UninstallCore"));
  4356. if (NULL != pwszSharedFolder)
  4357. {
  4358. // this must be restore before CreateConfigFiles()
  4359. hr = mySetCertRegStrValue(NULL, NULL, NULL,
  4360. wszREGDIRECTORY, pwszSharedFolder);
  4361. _PrintIfError(hr, "mySetCertRegStrValue");
  4362. //remove entry
  4363. hr = CreateConfigFiles(pwszSharedFolder, pComp, TRUE);
  4364. _PrintIfError2(hr, "CreateConfigFiles(Remove old entry)", hr);
  4365. }
  4366. certocmBumpGasGauge(pComp, _UNINSTALLPERCENT(8) DBGPARM(L"UninstallCore"));
  4367. // restore db path
  4368. if (NULL != pwszDBDirectory)
  4369. {
  4370. hr = mySetCertRegStrValue(NULL, NULL, NULL,
  4371. wszREGDBDIRECTORY, pwszDBDirectory);
  4372. _PrintIfError(hr, "mySetCertRegStrValue");
  4373. }
  4374. if (NULL != pwszLogDirectory)
  4375. {
  4376. hr = mySetCertRegStrValue(NULL, NULL, NULL,
  4377. wszREGDBLOGDIRECTORY, pwszLogDirectory);
  4378. _PrintIfError(hr, "mySetCertRegStrValue");
  4379. }
  4380. if (NULL != pwszSysDirectory)
  4381. {
  4382. hr = mySetCertRegStrValue(NULL, NULL, NULL,
  4383. wszREGDBSYSDIRECTORY, pwszSysDirectory);
  4384. _PrintIfError(hr, "mySetCertRegStrValue");
  4385. }
  4386. if (NULL != pwszTmpDirectory)
  4387. {
  4388. hr = mySetCertRegStrValue(NULL, NULL, NULL,
  4389. wszREGDBTEMPDIRECTORY, pwszTmpDirectory);
  4390. _PrintIfError(hr, "mySetCertRegStrValue");
  4391. }
  4392. if (0 != DBSessionCount)
  4393. {
  4394. hr = mySetCertRegDWValue(NULL, NULL, NULL,
  4395. wszREGDBSESSIONCOUNT, DBSessionCount);
  4396. _PrintIfError(hr, "mySetCertRegDWValueEx");
  4397. }
  4398. if (fPreserveClient)
  4399. {
  4400. // this means uninstall server component and keep web client
  4401. hr = CreateWebClientRegEntries(FALSE, pComp);
  4402. _JumpIfError(hr, error, "CreateWebClientRegEntries");
  4403. }
  4404. DeleteObsoleteResidue();
  4405. DeleteOldFilesAndDirectories(pComp);
  4406. certocmBumpGasGauge(pComp, _UNINSTALLPERCENT(9) DBGPARM(L"UninstallCore"));
  4407. if (fUseDS)
  4408. {
  4409. hr = RemoveCAInDS(pwszSanitizedCAName);
  4410. _PrintIfError2(hr, "RemoveCAInDS", hr);
  4411. }
  4412. certocmBumpGasGauge(pComp, PerCentCompleteMax DBGPARM(L"UninstallCore"));
  4413. hr = S_OK;
  4414. error:
  4415. if (NULL != pwszSanitizedCAName)
  4416. {
  4417. LocalFree(pwszSanitizedCAName);
  4418. }
  4419. if (NULL != pwszSharedFolder)
  4420. {
  4421. LocalFree(pwszSharedFolder);
  4422. }
  4423. if (NULL != pwszDBDirectory)
  4424. {
  4425. LocalFree(pwszDBDirectory);
  4426. }
  4427. if (NULL != pwszLogDirectory)
  4428. {
  4429. LocalFree(pwszLogDirectory);
  4430. }
  4431. if (NULL != pwszSysDirectory)
  4432. {
  4433. LocalFree(pwszSysDirectory);
  4434. }
  4435. if (NULL != pwszTmpDirectory)
  4436. {
  4437. LocalFree(pwszTmpDirectory);
  4438. }
  4439. if (fCoInit)
  4440. {
  4441. CoUninitialize();
  4442. }
  4443. return(hr);
  4444. }
  4445. HRESULT
  4446. AddCAToRPCNullSessions()
  4447. {
  4448. HRESULT hr;
  4449. HKEY hRegKey = NULL;
  4450. char *pszOriginal = NULL;
  4451. char *psz;
  4452. DWORD cb;
  4453. DWORD cbTmp;
  4454. DWORD cbSum;
  4455. DWORD dwType;
  4456. hr = RegOpenKeyExA(
  4457. HKEY_LOCAL_MACHINE,
  4458. szNULL_SESSION_REG_LOCATION,
  4459. 0, // dwOptions
  4460. KEY_READ | KEY_WRITE,
  4461. &hRegKey);
  4462. _JumpIfError(hr, error, "RegOpenKeyExA");
  4463. // Need to get the size of the value first
  4464. hr = RegQueryValueExA(hRegKey, szNULL_SESSION_VALUE, 0, &dwType, NULL, &cb);
  4465. _JumpIfError(hr, error, "RegQueryValueExA");
  4466. if (REG_MULTI_SZ != dwType)
  4467. {
  4468. hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
  4469. _JumpError(hr, error, "RegQueryValueExA: Type");
  4470. }
  4471. cb += sizeof(rgcCERT_NULL_SESSION) - 1;
  4472. pszOriginal = (char *) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, cb);
  4473. if (NULL == pszOriginal)
  4474. {
  4475. hr = E_OUTOFMEMORY;
  4476. _JumpError(hr, error, "LocalAlloc");
  4477. }
  4478. // get the multi string of RPC null session pipes
  4479. hr = RegQueryValueExA(
  4480. hRegKey,
  4481. szNULL_SESSION_VALUE,
  4482. 0,
  4483. &dwType,
  4484. (BYTE *) pszOriginal,
  4485. &cb);
  4486. _JumpIfError(hr, error, "RegQueryValueExA");
  4487. psz = pszOriginal;
  4488. // look for CERT in the list
  4489. cbSum = 0;
  4490. for (;;)
  4491. {
  4492. if (0 == strcmp(rgcCERT_NULL_SESSION, psz))
  4493. {
  4494. break;
  4495. }
  4496. cbTmp = strlen(psz) + 1;
  4497. psz += cbTmp;
  4498. cbSum += cbTmp;
  4499. if (cb < cbSum + 1)
  4500. {
  4501. break;
  4502. }
  4503. if ('\0' == psz[0])
  4504. {
  4505. // add the CA pipe to the multi string
  4506. CopyMemory(psz, rgcCERT_NULL_SESSION, sizeof(rgcCERT_NULL_SESSION));
  4507. // set the new multi string in the reg value
  4508. hr = RegSetValueExA(
  4509. hRegKey,
  4510. szNULL_SESSION_VALUE,
  4511. 0,
  4512. REG_MULTI_SZ,
  4513. (BYTE *) pszOriginal,
  4514. cbSum + sizeof(rgcCERT_NULL_SESSION));
  4515. _JumpIfError(hr, error, "RegSetValueExA");
  4516. break;
  4517. }
  4518. }
  4519. hr = S_OK;
  4520. error:
  4521. if (NULL != pszOriginal)
  4522. {
  4523. LocalFree(pszOriginal);
  4524. }
  4525. if (NULL != hRegKey)
  4526. {
  4527. RegCloseKey(hRegKey);
  4528. }
  4529. return(hr);
  4530. }
  4531. HRESULT
  4532. AddCARegKeyToRegConnectExemptions()
  4533. {
  4534. // add ourselves to list of people that take ACLs seriously
  4535. // and should be allowed to reveal our key to outsiders.
  4536. HRESULT hr;
  4537. LPWSTR pszExempt = NULL;
  4538. HKEY hkeyWinReg = NULL, hkeyAllowedPaths = NULL;
  4539. LPWSTR pszTmp;
  4540. DWORD dwDisposition, dwType;
  4541. DWORD cb=0, cbRegKeyCertSrvPath = (wcslen(wszREGKEYCERTSVCPATH)+1) *sizeof(WCHAR);
  4542. // carefully query this -- if it doesn't exist, we don't have to apply workaround
  4543. hr = RegOpenKeyEx(
  4544. HKEY_LOCAL_MACHINE,
  4545. L"SYSTEM\\CurrentControlSet\\Control\\SecurePipeServers\\Winreg",
  4546. 0,
  4547. KEY_ALL_ACCESS,
  4548. &hkeyWinReg);
  4549. _JumpIfError(hr, Ret, "RegOpenKeyEx");
  4550. // creation of this optional key is always ok if above key exists
  4551. hr = RegCreateKeyEx(
  4552. hkeyWinReg,
  4553. L"AllowedPaths",
  4554. NULL,
  4555. NULL,
  4556. 0,
  4557. KEY_ALL_ACCESS,
  4558. NULL,
  4559. &hkeyAllowedPaths,
  4560. &dwDisposition);
  4561. _JumpIfError(hr, Ret, "RegCreateKeyEx exempt regkey");
  4562. hr = RegQueryValueEx(
  4563. hkeyAllowedPaths,
  4564. L"Machine",
  4565. NULL, // reserved
  4566. &dwType, // type
  4567. NULL, // pb
  4568. &cb);
  4569. _PrintIfError(hr, "RegQueryValueEx exempt regkey 1");
  4570. if ((hr == S_OK) && (dwType != REG_MULTI_SZ))
  4571. {
  4572. hr = HRESULT_FROM_WIN32(ERROR_DATATYPE_MISMATCH);
  4573. _JumpError(hr, Ret, "RegQueryValueEx invalid type");
  4574. }
  4575. // always include at least a terminator
  4576. if (cb < sizeof(WCHAR))
  4577. cb = sizeof(WCHAR);
  4578. pszExempt = (LPWSTR)LocalAlloc(LMEM_FIXED, cb + cbRegKeyCertSrvPath );
  4579. _JumpIfOutOfMemory(hr, Ret, pszExempt);
  4580. // start with double null for safety
  4581. pszExempt[0] = L'\0';
  4582. pszExempt[1] = L'\0';
  4583. hr = RegQueryValueEx(
  4584. hkeyAllowedPaths,
  4585. L"Machine",
  4586. NULL, // reserved
  4587. NULL, // type
  4588. (PBYTE)pszExempt, // pb
  4589. &cb);
  4590. _PrintIfError(hr, "RegQueryValueEx exempt regkey 2");
  4591. pszTmp = pszExempt;
  4592. while(pszTmp[0] != L'\0') // skip all existing strings
  4593. {
  4594. // if entry already exists, bail
  4595. if (0 == LSTRCMPIS(pszTmp, wszREGKEYCERTSVCPATH))
  4596. {
  4597. hr = S_OK;
  4598. goto Ret;
  4599. }
  4600. pszTmp += wcslen(pszTmp)+1;
  4601. }
  4602. wcscpy(&pszTmp[0], wszREGKEYCERTSVCPATH);
  4603. pszTmp[wcslen(wszREGKEYCERTSVCPATH)+1] = L'\0'; // double NULL
  4604. hr = RegSetValueEx(
  4605. hkeyAllowedPaths,
  4606. L"Machine",
  4607. NULL,
  4608. REG_MULTI_SZ,
  4609. (PBYTE)pszExempt,
  4610. cb + cbRegKeyCertSrvPath);
  4611. _JumpIfError(hr, Ret, "RegSetValueEx exempt regkey");
  4612. Ret:
  4613. if (hkeyAllowedPaths)
  4614. RegCloseKey(hkeyAllowedPaths);
  4615. if (hkeyWinReg)
  4616. RegCloseKey(hkeyWinReg);
  4617. if (pszExempt)
  4618. LocalFree(pszExempt);
  4619. return hr;
  4620. }
  4621. HRESULT
  4622. helperGetFilesNotToRestore(
  4623. PER_COMPONENT_DATA *pComp,
  4624. OUT WCHAR **ppwszz)
  4625. {
  4626. HRESULT hr;
  4627. WCHAR *pwsz;
  4628. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  4629. DWORD cwc;
  4630. WCHAR const wszDBDIRPATTERN[] = L"\\*.edb";
  4631. WCHAR const wszDBLOGDIRPATTERN[] = L"\\*";
  4632. *ppwszz = NULL;
  4633. cwc = wcslen(pServer->pwszDBDirectory) +
  4634. WSZARRAYSIZE(wszDBDIRPATTERN) +
  4635. 1 +
  4636. wcslen(pServer->pwszLogDirectory) +
  4637. WSZARRAYSIZE(wszDBLOGDIRPATTERN) +
  4638. 1 +
  4639. 1;
  4640. pwsz = (WCHAR *) LocalAlloc(LMEM_FIXED, cwc * sizeof(WCHAR));
  4641. _JumpIfOutOfMemory(hr, error, pwsz);
  4642. *ppwszz = pwsz;
  4643. wcscpy(pwsz, pServer->pwszDBDirectory);
  4644. wcscat(pwsz, wszDBDIRPATTERN);
  4645. pwsz += wcslen(pwsz) + 1;
  4646. wcscpy(pwsz, pServer->pwszLogDirectory);
  4647. wcscat(pwsz, wszDBLOGDIRPATTERN);
  4648. pwsz += wcslen(pwsz) + 1;
  4649. *pwsz = L'\0';
  4650. CSASSERT(cwc == (DWORD) (pwsz - *ppwszz + 1));
  4651. hr = S_OK;
  4652. error:
  4653. return(hr);
  4654. }
  4655. #define wszURLPREFIXFORMAT L"%u:"
  4656. HRESULT
  4657. RemoveDuplicatesIgnoreAndClearFlags(
  4658. IN LPCWSTR pcwszSanitizedName,
  4659. IN BOOL fCDP,
  4660. IN LPCWSTR pcwszURLRegLocation,
  4661. IN OUT LPWSTR pwszzNewURLs)
  4662. {
  4663. HRESULT hr;
  4664. CMultiSz szzOrig, szzNew, szzNewUpdated;
  4665. WCHAR *pOrig = NULL;
  4666. DWORD dwLen;
  4667. void *pNewUpdated = NULL;
  4668. CString *pStrNew;
  4669. // read old URL list from registry
  4670. hr = myGetCertRegMultiStrValue(
  4671. pcwszSanitizedName,
  4672. NULL,
  4673. NULL,
  4674. pcwszURLRegLocation,
  4675. &pOrig);
  4676. if (S_OK != hr)
  4677. {
  4678. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) != hr)
  4679. {
  4680. _JumpErrorStr(
  4681. hr,
  4682. error,
  4683. "myGetCertRegMultiStrValue",
  4684. pcwszURLRegLocation);
  4685. }
  4686. }
  4687. else if (NULL != pOrig)
  4688. {
  4689. hr = szzOrig.Unmarshal(pOrig);
  4690. _JumpIfError(hr, error, "CMultiSz::Unmarshal");
  4691. }
  4692. hr = szzNew.Unmarshal(pwszzNewURLs);
  4693. _JumpIfError(hr, error, "CMultiSz::Unmarshal");
  4694. {
  4695. CMultiSzEnum szzNewEnum(szzNew);
  4696. // Compare the lists ignoring flags
  4697. // (ie jump over "64:" in "64:http://foo.crl")
  4698. // If match found, ignore the new URL
  4699. for(pStrNew = szzNewEnum.Next();
  4700. pStrNew;
  4701. pStrNew = szzNewEnum.Next())
  4702. {
  4703. WCHAR *pchNewSkipFlags = wcschr(*pStrNew, L':');
  4704. bool fDuplicate = false;
  4705. if(!pchNewSkipFlags)
  4706. pchNewSkipFlags = pStrNew->GetBuffer();
  4707. if (!szzOrig.IsEmpty())
  4708. {
  4709. CMultiSzEnum szzOrigEnum(szzOrig);
  4710. CString *pStrOrig;
  4711. for(pStrOrig = szzOrigEnum.Next();
  4712. pStrOrig;
  4713. pStrOrig = szzOrigEnum.Next())
  4714. {
  4715. WCHAR *pchOrigSkipFlags = wcschr(*pStrOrig, L':');
  4716. if(!pchOrigSkipFlags)
  4717. pchOrigSkipFlags = pStrOrig->GetBuffer();
  4718. if(!mylstrcmpiL(pchOrigSkipFlags, pchNewSkipFlags))
  4719. {
  4720. fDuplicate = true;
  4721. break;
  4722. }
  4723. }
  4724. }
  4725. if(!fDuplicate)
  4726. {
  4727. WCHAR awcPrefix[cwcDWORDSPRINTF + 1];
  4728. DWORD dwPrefixFlags = 0;
  4729. if (fCDP)
  4730. {
  4731. dwPrefixFlags = _wtoi(*pStrNew) & CSURL_ADDTOCRLCDP;
  4732. }
  4733. wsprintf(awcPrefix, wszURLPREFIXFORMAT, dwPrefixFlags);
  4734. CString *pstrAdd = new CString(awcPrefix);
  4735. _JumpIfAllocFailed(pstrAdd, error);
  4736. *pstrAdd += &pchNewSkipFlags[1];
  4737. DBGPRINT((DBG_SS_CERTOCM, "OLD URL: %ws\n", *pStrNew));
  4738. DBGPRINT((DBG_SS_CERTOCM, "NEW URL: %ws\n", *pstrAdd));
  4739. if(!szzNewUpdated.AddTail(pstrAdd))
  4740. {
  4741. hr = E_OUTOFMEMORY;
  4742. _JumpError(hr, error, "AddTail");
  4743. }
  4744. }
  4745. }
  4746. }
  4747. hr = szzNewUpdated.Marshal(pNewUpdated, dwLen);
  4748. _JumpIfError(hr, error, "CMultiSz::Marshal");
  4749. memcpy(pwszzNewURLs, pNewUpdated, dwLen);
  4750. hr = S_OK;
  4751. error:
  4752. LOCAL_FREE(pOrig);
  4753. LOCAL_FREE(pNewUpdated);
  4754. return hr;
  4755. }
  4756. HRESULT
  4757. CreateServerRegEntries(
  4758. BOOL fUpgrade,
  4759. PER_COMPONENT_DATA *pComp)
  4760. {
  4761. HRESULT hr;
  4762. HKEY hKeyBase = NULL;
  4763. WCHAR *pwszCLSIDCertGetConfig = NULL;
  4764. WCHAR *pwszCLSIDCertRequest = NULL;
  4765. WCHAR *pwszCRLPeriodString = NULL;
  4766. WCHAR *pwszCRLDeltaPeriodString = NULL;
  4767. WCHAR *pwszzCRLPublicationValue = NULL;
  4768. WCHAR *pwszzCACertPublicationValue = NULL;
  4769. WCHAR *pwszzRequestExtensionList = NULL;
  4770. WCHAR *pwszzEnrolleeRequestExtensionList = NULL;
  4771. WCHAR *pwszzDisableExtensionList = NULL;
  4772. WCHAR *pwszzFilesNotToRestore = NULL;
  4773. WCHAR *pwszProvNameReg = NULL;
  4774. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  4775. DWORD dwUpgradeFlags = fUpgrade ? CSREG_UPGRADE : 0x0;
  4776. DWORD dwCRLPeriodCount, dwCRLDeltaPeriodCount;
  4777. LDAP *pld = NULL;
  4778. BSTR strDomainDN = NULL;
  4779. BSTR strConfigDN = NULL;
  4780. // no error checking?
  4781. hr = AddCAToRPCNullSessions();
  4782. _PrintIfError(hr, "AddCAToRPCNullSessions");
  4783. hr = AddCARegKeyToRegConnectExemptions();
  4784. _PrintIfError(hr, "AddCARegKeyToRegConnectExemptions");
  4785. // create the CA key, so we can set security on it.
  4786. hr = myCreateCertRegKey(pServer->pwszSanitizedName, NULL, NULL);
  4787. _JumpIfError(hr, error, "myCreateCertRegKey");
  4788. // configuration level
  4789. // active ca
  4790. hr = mySetCertRegStrValueEx(
  4791. fUpgrade,
  4792. NULL,
  4793. NULL,
  4794. NULL,
  4795. wszREGACTIVE,
  4796. pServer->pwszSanitizedName);
  4797. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGACTIVE);
  4798. if (NULL != pServer->pwszSharedFolder)
  4799. {
  4800. // shared folder
  4801. hr = mySetCertRegStrValueEx(
  4802. fUpgrade,
  4803. NULL,
  4804. NULL,
  4805. NULL,
  4806. wszREGDIRECTORY,
  4807. pServer->pwszSharedFolder);
  4808. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGDIRECTORY);
  4809. }
  4810. // db dir
  4811. hr = mySetCertRegStrValueEx(
  4812. fUpgrade,
  4813. NULL,
  4814. NULL,
  4815. NULL,
  4816. wszREGDBDIRECTORY,
  4817. pServer->pwszDBDirectory);
  4818. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGDBDIRECTORY);
  4819. // log dir
  4820. hr = mySetCertRegStrValueEx(
  4821. fUpgrade,
  4822. NULL,
  4823. NULL,
  4824. NULL,
  4825. wszREGDBLOGDIRECTORY,
  4826. pServer->pwszLogDirectory);
  4827. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGDBLOGDIRECTORY);
  4828. // db tmp dir
  4829. hr = mySetCertRegStrValueEx(
  4830. fUpgrade,
  4831. NULL,
  4832. NULL,
  4833. NULL,
  4834. wszREGDBTEMPDIRECTORY,
  4835. pServer->pwszLogDirectory);
  4836. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGDBTEMPDIRECTORY);
  4837. // db sys dir
  4838. hr = mySetCertRegStrValueEx(
  4839. fUpgrade,
  4840. NULL,
  4841. NULL,
  4842. NULL,
  4843. wszREGDBSYSDIRECTORY,
  4844. pServer->pwszLogDirectory);
  4845. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGDBSYSDIRECTORY);
  4846. hr = mySetCertRegDWValueEx(
  4847. fUpgrade,
  4848. NULL,
  4849. NULL,
  4850. NULL,
  4851. wszREGDBSESSIONCOUNT,
  4852. DBSESSIONCOUNTDEFAULT);
  4853. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGDBSESSIONCOUNT);
  4854. hr = mySetCertRegDWValueEx(
  4855. fUpgrade,
  4856. NULL,
  4857. NULL,
  4858. NULL,
  4859. wszREGLDAPFLAGS,
  4860. 0);
  4861. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGLDAPFLAGS);
  4862. hr = mySetCertRegDWValueEx(
  4863. fUpgrade,
  4864. NULL,
  4865. NULL,
  4866. NULL,
  4867. wszREGDBFLAGS,
  4868. DBFLAGS_DEFAULT);
  4869. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGDBFLAGS);
  4870. hr = SetCertSrvInstallVersion();
  4871. _JumpIfError(hr, error, "SetCertSrvInstallVersion");
  4872. if (!fUpgrade)
  4873. {
  4874. // preserve db
  4875. hr = SetSetupStatus(NULL, SETUP_CREATEDB_FLAG, !pServer->fPreserveDB);
  4876. _JumpIfError(hr, error, "SetSetupStatus");
  4877. }
  4878. // ca level
  4879. if (!fUpgrade && pServer->fUseDS)
  4880. {
  4881. hr = myLdapOpen(
  4882. NULL,
  4883. RLBF_REQUIRE_SECURE_LDAP,
  4884. &pld,
  4885. &strDomainDN,
  4886. &strConfigDN);
  4887. _JumpIfError(hr, error, "myLdapOpen");
  4888. // Config DN
  4889. hr = mySetCertRegStrValueEx(
  4890. FALSE,
  4891. pServer->pwszSanitizedName,
  4892. NULL,
  4893. NULL,
  4894. wszREGDSCONFIGDN,
  4895. strConfigDN);
  4896. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGDSCONFIGDN);
  4897. // Domain DN
  4898. hr = mySetCertRegStrValueEx(
  4899. FALSE,
  4900. pServer->pwszSanitizedName,
  4901. NULL,
  4902. NULL,
  4903. wszREGDSDOMAINDN,
  4904. strDomainDN);
  4905. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGDSDOMAINDN);
  4906. }
  4907. // (hard code) view age, idle minutes
  4908. hr = mySetCertRegDWValueEx(
  4909. fUpgrade,
  4910. pServer->pwszSanitizedName,
  4911. NULL,
  4912. NULL,
  4913. wszREGVIEWAGEMINUTES,
  4914. CVIEWAGEMINUTESDEFAULT);
  4915. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGVIEWAGEMINUTES);
  4916. hr = mySetCertRegDWValueEx(
  4917. fUpgrade,
  4918. pServer->pwszSanitizedName,
  4919. NULL,
  4920. NULL,
  4921. wszREGVIEWIDLEMINUTES,
  4922. CVIEWIDLEMINUTESDEFAULT);
  4923. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGVIEWIDLEMINUTES);
  4924. // ca type
  4925. CSASSERT(IsEnterpriseCA(pServer->CAType) || IsStandaloneCA(pServer->CAType));
  4926. hr = mySetCertRegDWValueEx(
  4927. fUpgrade,
  4928. pServer->pwszSanitizedName,
  4929. NULL,
  4930. NULL,
  4931. wszREGCATYPE,
  4932. pServer->CAType);
  4933. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGCATYPE);
  4934. // use DS flag
  4935. hr = mySetCertRegDWValueEx(
  4936. fUpgrade,
  4937. pServer->pwszSanitizedName,
  4938. NULL,
  4939. NULL,
  4940. wszREGCAUSEDS,
  4941. pServer->fUseDS);
  4942. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGCAUSEDS);
  4943. // teletex flag
  4944. hr = mySetCertRegDWValueEx(
  4945. fUpgrade,
  4946. pServer->pwszSanitizedName,
  4947. NULL,
  4948. NULL,
  4949. wszREGFORCETELETEX,
  4950. ENUM_TELETEX_AUTO | ENUM_TELETEX_UTF8);
  4951. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGFORCETELETEX);
  4952. hr = mySetCertRegMultiStrValueEx(
  4953. dwUpgradeFlags,
  4954. pServer->pwszSanitizedName,
  4955. NULL,
  4956. NULL,
  4957. wszSECUREDATTRIBUTES,
  4958. wszzDEFAULTSIGNEDATTRIBUTES);
  4959. _JumpIfErrorStr(hr, error, "mySetCertRegMultiStrValueEx", wszSECUREDATTRIBUTES);
  4960. // common name
  4961. hr = mySetCertRegStrValueEx(
  4962. fUpgrade,
  4963. pServer->pwszSanitizedName,
  4964. NULL,
  4965. NULL,
  4966. wszREGCOMMONNAME,
  4967. pServer->pwszCACommonName);
  4968. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGCOMMONNAME);
  4969. // enable reg
  4970. hr = mySetCertRegDWValueEx(
  4971. fUpgrade,
  4972. pServer->pwszSanitizedName,
  4973. NULL,
  4974. NULL,
  4975. wszREGENABLED,
  4976. TRUE);
  4977. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGENABLED);
  4978. // policy flag
  4979. hr = mySetCertRegDWValueEx(
  4980. fUpgrade,
  4981. pServer->pwszSanitizedName,
  4982. NULL,
  4983. NULL,
  4984. wszREGPOLICYFLAGS,
  4985. 0);
  4986. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGPOLICYFLAGS);
  4987. // enroll compatible flag, always turn it off
  4988. // BUG, consider use mySetCertRegDWValueEx with fUpgrade
  4989. // after W2K to support CertEnrollCompatible upgrade
  4990. hr = mySetCertRegDWValue(
  4991. pServer->pwszSanitizedName,
  4992. NULL,
  4993. NULL,
  4994. wszREGCERTENROLLCOMPATIBLE,
  4995. FALSE);
  4996. _JumpIfErrorStr(hr, error, "mySetCertRegDWValue", wszREGCERTENROLLCOMPATIBLE);
  4997. // Cert Server CRL Edit Flags
  4998. hr = mySetCertRegDWValueEx(
  4999. fUpgrade,
  5000. pServer->pwszSanitizedName,
  5001. NULL,
  5002. NULL,
  5003. wszREGCRLEDITFLAGS,
  5004. EDITF_ENABLEAKIKEYID);
  5005. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGCRLEDITFLAGS);
  5006. // Cert Server CRL Flags
  5007. hr = mySetCertRegDWValueEx(
  5008. fUpgrade,
  5009. pServer->pwszSanitizedName,
  5010. NULL,
  5011. NULL,
  5012. wszREGCRLFLAGS,
  5013. CRLF_DELETE_EXPIRED_CRLS);
  5014. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGCRLFLAGS);
  5015. // Cert Server Interface Flags
  5016. hr = mySetCertRegDWValueEx(
  5017. fUpgrade,
  5018. pServer->pwszSanitizedName,
  5019. NULL,
  5020. NULL,
  5021. wszREGINTERFACEFLAGS,
  5022. IF_DEFAULT);
  5023. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGINTERFACEFLAGS);
  5024. hr = mySetCertRegDWValueEx(
  5025. fUpgrade,
  5026. pServer->pwszSanitizedName,
  5027. NULL,
  5028. NULL,
  5029. wszREGENFORCEX500NAMELENGTHS,
  5030. TRUE);
  5031. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGENFORCEX500NAMELENGTHS);
  5032. // set subject template; if upgrading, fix the template only if it's win2k upgrade
  5033. if (!fUpgrade ||
  5034. (fUpgrade && (pComp->UpgradeFlag == CS_UPGRADE_WIN2000)))
  5035. {
  5036. hr = mySetCertRegMultiStrValueEx(
  5037. 0, // dwUpgradeFlags: always overwrite!
  5038. pServer->pwszSanitizedName,
  5039. NULL,
  5040. NULL,
  5041. wszREGSUBJECTTEMPLATE,
  5042. wszzREGSUBJECTTEMPLATEVALUE);
  5043. _JumpIfErrorStr(hr, error, "mySetCertRegMultiStrValueEx", wszREGSUBJECTTEMPLATE);
  5044. }
  5045. // (hard code) clock skew minutes
  5046. hr = mySetCertRegDWValueEx(
  5047. fUpgrade,
  5048. pServer->pwszSanitizedName,
  5049. NULL,
  5050. NULL,
  5051. wszREGCLOCKSKEWMINUTES,
  5052. CCLOCKSKEWMINUTESDEFAULT);
  5053. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGCLOCKSKEWMINUTES);
  5054. // (hard code) log level
  5055. hr = mySetCertRegDWValueEx(
  5056. fUpgrade,
  5057. pServer->pwszSanitizedName,
  5058. NULL,
  5059. NULL,
  5060. wszREGLOGLEVEL,
  5061. CERTLOG_WARNING);
  5062. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGLOGLEVEL);
  5063. hr = mySetCertRegDWValueEx(
  5064. fUpgrade,
  5065. pServer->pwszSanitizedName,
  5066. NULL,
  5067. NULL,
  5068. wszREGHIGHSERIAL,
  5069. 0);
  5070. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGLOGLEVEL);
  5071. // register server name
  5072. hr = mySetCertRegStrValueEx(
  5073. fUpgrade,
  5074. pServer->pwszSanitizedName,
  5075. NULL,
  5076. NULL,
  5077. wszREGCASERVERNAME,
  5078. pComp->pwszServerName);
  5079. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGCASERVERNAME);
  5080. // default validity period string and count for issued certs
  5081. // use years for string
  5082. hr = mySetCertRegStrValueEx(
  5083. fUpgrade,
  5084. pServer->pwszSanitizedName,
  5085. NULL,
  5086. NULL,
  5087. wszREGVALIDITYPERIODSTRING,
  5088. wszVALIDITYPERIODSTRINGDEFAULT);
  5089. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGVALIDITYPERIODSTRING);
  5090. // validity period count
  5091. // use 1 year for standalone and 2 years for enterprise
  5092. hr = mySetCertRegDWValueEx(
  5093. fUpgrade,
  5094. pServer->pwszSanitizedName,
  5095. NULL,
  5096. NULL,
  5097. wszREGVALIDITYPERIODCOUNT,
  5098. IsEnterpriseCA(pServer->CAType)?
  5099. dwVALIDITYPERIODCOUNTDEFAULT_ENTERPRISE :
  5100. dwVALIDITYPERIODCOUNTDEFAULT_STANDALONE);
  5101. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGVALIDITYPERIODCOUNT);
  5102. hr = mySetCertRegMultiStrValueEx(
  5103. dwUpgradeFlags,
  5104. pServer->pwszSanitizedName,
  5105. NULL,
  5106. NULL,
  5107. wszREGCAXCHGCERTHASH,
  5108. NULL);
  5109. _JumpIfErrorStr(hr, error, "mySetCertRegMultiStrValueEx", wszREGCAXCHGCERTHASH);
  5110. hr = mySetCertRegMultiStrValueEx(
  5111. dwUpgradeFlags,
  5112. pServer->pwszSanitizedName,
  5113. NULL,
  5114. NULL,
  5115. wszREGKRACERTHASH,
  5116. NULL);
  5117. _JumpIfErrorStr(hr, error, "mySetCertRegMultiStrValueEx", wszREGKRACERTHASH);
  5118. hr = mySetCertRegDWValueEx(
  5119. dwUpgradeFlags,
  5120. pServer->pwszSanitizedName,
  5121. NULL,
  5122. NULL,
  5123. wszREGKRACERTCOUNT,
  5124. 0);
  5125. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGKRACERTCOUNT);
  5126. hr = mySetCertRegDWValueEx(
  5127. dwUpgradeFlags,
  5128. pServer->pwszSanitizedName,
  5129. NULL,
  5130. NULL,
  5131. wszREGKRAFLAGS,
  5132. 0);
  5133. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGKRAFLAGS);
  5134. // CRL Publication URLs:
  5135. hr = csiGetCRLPublicationURLTemplates(
  5136. pServer->fUseDS,
  5137. pComp->pwszSystem32,
  5138. &pwszzCRLPublicationValue);
  5139. _JumpIfError(hr, error, "csiGetCRLPublicationURLTemplates");
  5140. // bug 489467 - NTDEV CAs after upgrade have duplicated http: & file: URLs
  5141. if (fUpgrade)
  5142. {
  5143. hr = RemoveDuplicatesIgnoreAndClearFlags(
  5144. pServer->pwszSanitizedName,
  5145. TRUE,
  5146. wszREGCRLPUBLICATIONURLS,
  5147. pwszzCRLPublicationValue);
  5148. _JumpIfErrorStr(
  5149. hr,
  5150. error,
  5151. "RemoveDuplicatesIgnoreAndClearFlags",
  5152. wszREGCRLPUBLICATIONURLS);
  5153. }
  5154. hr = mySetCertRegMultiStrValueEx(
  5155. dwUpgradeFlags | (fUpgrade? CSREG_MERGE : 0),
  5156. pServer->pwszSanitizedName,
  5157. NULL,
  5158. NULL,
  5159. wszREGCRLPUBLICATIONURLS,
  5160. pwszzCRLPublicationValue);
  5161. _JumpIfErrorStr(
  5162. hr,
  5163. error,
  5164. "mySetCertRegMultiStrValueEx",
  5165. wszREGCRLPUBLICATIONURLS);
  5166. // if this API returns non-null strings, it's got good data
  5167. hr = csiGetCRLPublicationParams(
  5168. TRUE,
  5169. &pwszCRLPeriodString,
  5170. &dwCRLPeriodCount);
  5171. _PrintIfError(hr, "csiGetCRLPublicationParams");
  5172. // crl period string
  5173. hr = mySetCertRegStrValueEx(
  5174. fUpgrade,
  5175. pServer->pwszSanitizedName,
  5176. NULL,
  5177. NULL,
  5178. wszREGCRLPERIODSTRING,
  5179. (pwszCRLPeriodString == NULL) ? wszCRLPERIODSTRINGDEFAULT : pwszCRLPeriodString);
  5180. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGCRLPERIODSTRING);
  5181. // crl period count
  5182. hr = mySetCertRegDWValueEx(
  5183. fUpgrade,
  5184. pServer->pwszSanitizedName,
  5185. NULL,
  5186. NULL,
  5187. wszREGCRLPERIODCOUNT,
  5188. (pwszCRLPeriodString == NULL) ? dwCRLPERIODCOUNTDEFAULT : dwCRLPeriodCount);
  5189. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGCRLPERIODCOUNT);
  5190. // crl overlap period string
  5191. hr = mySetCertRegStrValueEx(
  5192. fUpgrade,
  5193. pServer->pwszSanitizedName,
  5194. NULL,
  5195. NULL,
  5196. wszREGCRLOVERLAPPERIODSTRING,
  5197. wszCRLOVERLAPPERIODSTRINGDEFAULT);
  5198. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGCRLOVERLAPPERIODSTRING);
  5199. // crl overlap period count
  5200. hr = mySetCertRegDWValueEx(
  5201. fUpgrade,
  5202. pServer->pwszSanitizedName,
  5203. NULL,
  5204. NULL,
  5205. wszREGCRLOVERLAPPERIODCOUNT,
  5206. dwCRLOVERLAPPERIODCOUNTDEFAULT);
  5207. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGCRLOVERLAPPERIODCOUNT);
  5208. // if this API returns non-null strings, it's got good data
  5209. hr = csiGetCRLPublicationParams(
  5210. FALSE, // delta
  5211. &pwszCRLDeltaPeriodString,
  5212. &dwCRLDeltaPeriodCount);
  5213. _PrintIfError(hr, "csiGetCRLPublicationParams");
  5214. // delta crl period string
  5215. hr = mySetCertRegStrValueEx(
  5216. fUpgrade,
  5217. pServer->pwszSanitizedName,
  5218. NULL,
  5219. NULL,
  5220. wszREGCRLDELTAPERIODSTRING,
  5221. (pwszCRLDeltaPeriodString == NULL) ? wszCRLDELTAPERIODSTRINGDEFAULT : pwszCRLDeltaPeriodString);
  5222. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGCRLDELTAPERIODSTRING);
  5223. {
  5224. DWORD dwCRLDeltaPeriodCountEffective =
  5225. (pwszCRLDeltaPeriodString == NULL) ?
  5226. dwCRLPERIODCOUNTDEFAULT :
  5227. dwCRLDeltaPeriodCount;
  5228. // 435575: disable delta CRL on standalone root CAs
  5229. // 498370: unless delta CRL validity is defined in capolicy.inf
  5230. // 751244: upgrade logic same as clean install (if no registry value)
  5231. if (!IsEnterpriseCA(pServer->CAType) &&
  5232. IsRootCA(pServer->CAType) &&
  5233. !pwszCRLDeltaPeriodString)
  5234. {
  5235. dwCRLDeltaPeriodCountEffective = 0;
  5236. }
  5237. // delta crl period count
  5238. hr = mySetCertRegDWValueEx(
  5239. fUpgrade,
  5240. pServer->pwszSanitizedName,
  5241. NULL,
  5242. NULL,
  5243. wszREGCRLDELTAPERIODCOUNT,
  5244. dwCRLDeltaPeriodCountEffective);
  5245. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGCRLDELTAPERIODCOUNT);
  5246. }
  5247. // delta crl overlap period string
  5248. hr = mySetCertRegStrValueEx(
  5249. fUpgrade,
  5250. pServer->pwszSanitizedName,
  5251. NULL,
  5252. NULL,
  5253. wszREGCRLDELTAOVERLAPPERIODSTRING,
  5254. wszCRLDELTAOVERLAPPERIODSTRINGDEFAULT);
  5255. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGCRLDELTAOVERLAPPERIODSTRING);
  5256. // delta crl overlap period count
  5257. hr = mySetCertRegDWValueEx(
  5258. fUpgrade,
  5259. pServer->pwszSanitizedName,
  5260. NULL,
  5261. NULL,
  5262. wszREGCRLDELTAOVERLAPPERIODCOUNT,
  5263. dwCRLDELTAOVERLAPPERIODCOUNTDEFAULT);
  5264. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGCRLDELTAOVERLAPPERIODCOUNT);
  5265. // CA xchg cert validity period string
  5266. hr = mySetCertRegStrValueEx(
  5267. fUpgrade,
  5268. pServer->pwszSanitizedName,
  5269. NULL,
  5270. NULL,
  5271. wszREGCAXCHGVALIDITYPERIODSTRING,
  5272. wszCAXCHGVALIDITYPERIODSTRINGDEFAULT);
  5273. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGCRLDELTAOVERLAPPERIODSTRING);
  5274. // CA xchg cert validity period count
  5275. hr = mySetCertRegDWValueEx(
  5276. fUpgrade,
  5277. pServer->pwszSanitizedName,
  5278. NULL,
  5279. NULL,
  5280. wszREGCAXCHGVALIDITYPERIODCOUNT,
  5281. dwCAXCHGVALIDITYPERIODCOUNTDEFAULT);
  5282. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGCRLDELTAOVERLAPPERIODCOUNT);
  5283. // CA xchg cert overlap period string
  5284. hr = mySetCertRegStrValueEx(
  5285. fUpgrade,
  5286. pServer->pwszSanitizedName,
  5287. NULL,
  5288. NULL,
  5289. wszREGCAXCHGOVERLAPPERIODSTRING,
  5290. wszCAXCHGOVERLAPPERIODSTRINGDEFAULT);
  5291. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGCRLDELTAOVERLAPPERIODSTRING);
  5292. // CA xchg cert overlap period count
  5293. hr = mySetCertRegDWValueEx(
  5294. fUpgrade,
  5295. pServer->pwszSanitizedName,
  5296. NULL,
  5297. NULL,
  5298. wszREGCAXCHGOVERLAPPERIODCOUNT,
  5299. dwCAXCHGOVERLAPPERIODCOUNTDEFAULT);
  5300. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGCRLDELTAOVERLAPPERIODCOUNT);
  5301. hr = mySetCertRegDWValueEx(
  5302. fUpgrade,
  5303. pServer->pwszSanitizedName,
  5304. NULL,
  5305. NULL,
  5306. wszREGMAXINCOMINGMESSAGESIZE,
  5307. MAXINCOMINGMESSAGESIZEDEFAULT);
  5308. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGMAXINCOMINGMESSAGESIZE);
  5309. hr = mySetCertRegDWValueEx(
  5310. fUpgrade,
  5311. pServer->pwszSanitizedName,
  5312. NULL,
  5313. NULL,
  5314. wszREGMAXINCOMINGALLOCSIZE,
  5315. MAXINCOMINGALLOCSIZEDEFAULT);
  5316. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx", wszREGMAXINCOMINGALLOCSIZE);
  5317. if (NULL != pServer->pwszSharedFolder)
  5318. {
  5319. // register CA file name for certhier and renewal
  5320. hr = mySetCARegFileNameTemplate(
  5321. wszREGCACERTFILENAME,
  5322. pComp->pwszServerName,
  5323. pServer->pwszSanitizedName,
  5324. pServer->pwszCACertFile);
  5325. _JumpIfError(hr, error, "SetRegCertFileName");
  5326. }
  5327. // policy
  5328. // create default policy entry explicitly to get correct acl if upgrade
  5329. hr = myCreateCertRegKeyEx(
  5330. fUpgrade,
  5331. pServer->pwszSanitizedName,
  5332. wszREGKEYPOLICYMODULES,
  5333. wszCLASS_CERTPOLICY);
  5334. _JumpIfErrorStr(hr, error, "myCreateCertRegKeyEx", wszCLASS_CERTPOLICY);
  5335. // if customized policy, create a new entry with correct acl
  5336. if (fUpgrade &&
  5337. NULL != pServer->pwszCustomPolicy &&
  5338. 0 != wcscmp(wszCLASS_CERTPOLICY, pServer->pwszCustomPolicy) )
  5339. {
  5340. hr = myCreateCertRegKeyEx(
  5341. TRUE, // upgrade
  5342. pServer->pwszSanitizedName,
  5343. wszREGKEYPOLICYMODULES,
  5344. pServer->pwszCustomPolicy);
  5345. _JumpIfError(hr, error, "myCreateCertRegKey");
  5346. }
  5347. // set default policy
  5348. hr = mySetCertRegStrValueEx(
  5349. fUpgrade,
  5350. pServer->pwszSanitizedName,
  5351. wszREGKEYPOLICYMODULES,
  5352. NULL,
  5353. wszREGACTIVE,
  5354. (fUpgrade && (NULL != pServer->pwszCustomPolicy)) ?
  5355. pServer->pwszCustomPolicy :
  5356. wszCLASS_CERTPOLICY);
  5357. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGACTIVE);
  5358. hr = mySetCertRegDWValueEx(
  5359. fUpgrade,
  5360. pServer->pwszSanitizedName,
  5361. wszREGKEYPOLICYMODULES,
  5362. wszCLASS_CERTPOLICY,
  5363. wszREGREVOCATIONTYPE,
  5364. pServer->dwRevocationFlags);
  5365. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGREVOCATIONTYPE);
  5366. hr = mySetCertRegDWValueEx(
  5367. fUpgrade,
  5368. pServer->pwszSanitizedName,
  5369. wszREGKEYPOLICYMODULES,
  5370. wszCLASS_CERTPOLICY,
  5371. wszREGCAPATHLENGTH,
  5372. CAPATHLENGTH_INFINITE);
  5373. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGCAPATHLENGTH);
  5374. // revocation url
  5375. hr = mySetCertRegStrValueEx(
  5376. fUpgrade,
  5377. pServer->pwszSanitizedName,
  5378. wszREGKEYPOLICYMODULES,
  5379. wszCLASS_CERTPOLICY,
  5380. wszREGREVOCATIONURL,
  5381. g_wszASPRevocationURLTemplate);
  5382. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGREVOCATIONURL);
  5383. // Exit module publish flags
  5384. hr = mySetCertRegDWValueEx(
  5385. fUpgrade,
  5386. pServer->pwszSanitizedName,
  5387. wszREGKEYEXITMODULES,
  5388. wszCLASS_CERTEXIT,
  5389. wszREGCERTPUBLISHFLAGS,
  5390. pServer->fUseDS ?
  5391. EXITPUB_DEFAULT_ENTERPRISE :
  5392. EXITPUB_DEFAULT_STANDALONE);
  5393. _JumpIfErrorStr(
  5394. hr,
  5395. error,
  5396. "mySetCertRegStrValueEx",
  5397. wszREGCERTPUBLISHFLAGS);
  5398. // Enable Request Extensions:
  5399. hr = helperGetRequestExtensionList(&pwszzRequestExtensionList);
  5400. _JumpIfError(hr, error, "helperGetRequestExtensionList");
  5401. hr = mySetCertRegMultiStrValueEx(
  5402. dwUpgradeFlags | CSREG_MERGE,
  5403. pServer->pwszSanitizedName,
  5404. wszREGKEYPOLICYMODULES,
  5405. wszCLASS_CERTPOLICY,
  5406. wszREGENABLEREQUESTEXTENSIONLIST,
  5407. pwszzRequestExtensionList);
  5408. _JumpIfErrorStr(hr, error, "mySetCertRegMultiStrValueEx", wszREGENABLEREQUESTEXTENSIONLIST);
  5409. hr = helperGetEnrolleeRequestExtensionList(
  5410. &pwszzEnrolleeRequestExtensionList);
  5411. _JumpIfError(hr, error, "helperGetRequestExtensionList");
  5412. hr = mySetCertRegMultiStrValueEx(
  5413. dwUpgradeFlags | CSREG_MERGE,
  5414. pServer->pwszSanitizedName,
  5415. wszREGKEYPOLICYMODULES,
  5416. wszCLASS_CERTPOLICY,
  5417. wszREGENABLEENROLLEEREQUESTEXTENSIONLIST,
  5418. pwszzEnrolleeRequestExtensionList);
  5419. _JumpIfErrorStr(hr, error, "mySetCertRegMultiStrValueEx", wszREGENABLEENROLLEEREQUESTEXTENSIONLIST);
  5420. hr = helperGetDisableExtensionList(&pwszzDisableExtensionList);
  5421. _JumpIfError(hr, error, "helperGetDisableExtensionList");
  5422. if (fUpgrade)
  5423. {
  5424. helperDeleteTrashedDisableList(pServer->pwszSanitizedName);
  5425. }
  5426. // Disables Template Extensions:
  5427. hr = mySetCertRegMultiStrValueEx(
  5428. dwUpgradeFlags | CSREG_MERGE,
  5429. pServer->pwszSanitizedName,
  5430. wszREGKEYPOLICYMODULES,
  5431. wszCLASS_CERTPOLICY,
  5432. wszREGDISABLEEXTENSIONLIST,
  5433. pwszzDisableExtensionList);
  5434. _JumpIfErrorStr(hr, error, "mySetCertRegMultiStrValueEx", wszREGDISABLEEXTENSIONLIST);
  5435. // Subject Alt Name Extension
  5436. hr = mySetCertRegStrValueEx(
  5437. fUpgrade,
  5438. pServer->pwszSanitizedName,
  5439. wszREGKEYPOLICYMODULES,
  5440. wszCLASS_CERTPOLICY,
  5441. wszREGSUBJECTALTNAME,
  5442. wszREGSUBJECTALTNAMEVALUE);
  5443. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGSUBJECTALTNAME);
  5444. // Subject Alt Name 2 Extension
  5445. hr = mySetCertRegStrValueEx(
  5446. fUpgrade,
  5447. pServer->pwszSanitizedName,
  5448. wszREGKEYPOLICYMODULES,
  5449. wszCLASS_CERTPOLICY,
  5450. wszREGSUBJECTALTNAME2,
  5451. wszREGSUBJECTALTNAME2VALUE);
  5452. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGSUBJECTALTNAME2);
  5453. // Request Disposition
  5454. hr = mySetCertRegDWValueEx(
  5455. fUpgrade,
  5456. pServer->pwszSanitizedName,
  5457. wszREGKEYPOLICYMODULES,
  5458. wszCLASS_CERTPOLICY,
  5459. wszREGREQUESTDISPOSITION,
  5460. IsEnterpriseCA(pServer->CAType)?
  5461. REQDISP_DEFAULT_ENTERPRISE :
  5462. REQDISP_DEFAULT_STANDALONE);
  5463. _JumpIfErrorStr(hr, error, "mySetCertRegDWValueEx",
  5464. wszREGREQUESTDISPOSITION);
  5465. // Edit Flags
  5466. hr = mySetCertRegDWValueEx(
  5467. fUpgrade,
  5468. pServer->pwszSanitizedName,
  5469. wszREGKEYPOLICYMODULES,
  5470. wszCLASS_CERTPOLICY,
  5471. wszREGEDITFLAGS,
  5472. IsEnterpriseCA(pServer->CAType)?
  5473. (EDITF_DEFAULT_ENTERPRISE | pServer->dwUpgradeEditFlags) :
  5474. (EDITF_DEFAULT_STANDALONE | pServer->dwUpgradeEditFlags));
  5475. _JumpIfErrorStr(hr, error, "mySetCertRegStrValueEx", wszREGEDITFLAGS);
  5476. // add new flags if this is EntCA W2k or Whistler beta2 upgrade
  5477. if (fUpgrade &&
  5478. ((pComp->UpgradeFlag == CS_UPGRADE_WIN2000) ||
  5479. ((pComp->UpgradeFlag == CS_UPGRADE_WHISTLER) &&
  5480. CSVER_MINOR_WHISTLER_BETA2 == CSVER_EXTRACT_MINOR(pComp->dwVersion))) &&
  5481. IsEnterpriseCA(pServer->CAType))
  5482. {
  5483. DWORD dwEditFlags=0;
  5484. hr = myGetCertRegDWValue(
  5485. pServer->pwszSanitizedName,
  5486. wszREGKEYPOLICYMODULES,
  5487. wszCLASS_CERTPOLICY,
  5488. wszREGEDITFLAGS,
  5489. (DWORD *) &dwEditFlags);
  5490. _JumpIfError(hr, error, "myGetCertRegDWValue");
  5491. dwEditFlags |= EDITF_ENABLEDEFAULTSMIME;
  5492. // bug 446444: remove these flags on upgrade:
  5493. dwEditFlags &= ~(EDITF_ENABLEAKIISSUERNAME |
  5494. EDITF_ENABLEAKIISSUERSERIAL);
  5495. hr = mySetCertRegDWValue(
  5496. pServer->pwszSanitizedName,
  5497. wszREGKEYPOLICYMODULES,
  5498. wszCLASS_CERTPOLICY,
  5499. wszREGEDITFLAGS,
  5500. dwEditFlags);
  5501. _JumpIfError(hr, error, "mySetCertRegDWValue");
  5502. }
  5503. // bug 446444: don't set IssuerCertURLFlags on fresh install
  5504. //
  5505. // ...code removed
  5506. hr = mySetCertRegMultiStrValueEx(
  5507. dwUpgradeFlags,
  5508. pServer->pwszSanitizedName,
  5509. wszREGKEYPOLICYMODULES,
  5510. wszCLASS_CERTPOLICY,
  5511. wszREGDEFAULTSMIME,
  5512. wszzREGVALUEDEFAULTSMIME);
  5513. _JumpIfErrorStr(hr, error, "mySetCertRegMultiStrValueEx", wszREGDEFAULTSMIME);
  5514. hr = csiGetCACertPublicationURLTemplates(
  5515. pServer->fUseDS,
  5516. pComp->pwszSystem32,
  5517. &pwszzCACertPublicationValue);
  5518. _JumpIfError(hr, error, "csiGetCACertPublicationURLTemplates");
  5519. // bug 489467 - NTDEV CAs after upgrade have duplicated http: & file: URLs
  5520. if (fUpgrade)
  5521. {
  5522. hr = RemoveDuplicatesIgnoreAndClearFlags(
  5523. pServer->pwszSanitizedName,
  5524. FALSE,
  5525. wszREGCACERTPUBLICATIONURLS,
  5526. pwszzCACertPublicationValue);
  5527. _JumpIfErrorStr(
  5528. hr,
  5529. error,
  5530. "RemoveDuplicatesIgnoreAndClearFlags",
  5531. wszREGCACERTPUBLICATIONURLS);
  5532. }
  5533. hr = mySetCertRegMultiStrValueEx(
  5534. dwUpgradeFlags | (fUpgrade? CSREG_MERGE : 0),
  5535. pServer->pwszSanitizedName,
  5536. NULL,
  5537. NULL,
  5538. wszREGCACERTPUBLICATIONURLS,
  5539. pwszzCACertPublicationValue);
  5540. _JumpIfErrorStr(
  5541. hr,
  5542. error,
  5543. "mySetCertRegMultiStrValueEx",
  5544. wszREGCACERTPUBLICATIONURLS);
  5545. // exit
  5546. // create default exit entry to get correct acl if upgrade
  5547. hr = myCreateCertRegKeyEx(
  5548. fUpgrade,
  5549. pServer->pwszSanitizedName,
  5550. wszREGKEYEXITMODULES,
  5551. wszCLASS_CERTEXIT);
  5552. _JumpIfErrorStr(hr, error, "myCreateCertRegKeyEx", wszCLASS_CERTPOLICY);
  5553. // if customized exit, create a new entry with correct acl
  5554. if (fUpgrade &&
  5555. NULL != pServer->pwszzCustomExit &&
  5556. 0 != wcscmp(wszCLASS_CERTEXIT, pServer->pwszzCustomExit) )
  5557. {
  5558. // create a new entry for custom exit
  5559. hr = myCreateCertRegKeyEx(
  5560. TRUE, // upgrade
  5561. pServer->pwszSanitizedName,
  5562. wszREGKEYEXITMODULES,
  5563. pServer->pwszzCustomExit);
  5564. _JumpIfError(hr, error, "myCreateCertRegKey");
  5565. }
  5566. // set default exit
  5567. hr = mySetCertRegMultiStrValueEx(
  5568. dwUpgradeFlags,
  5569. pServer->pwszSanitizedName,
  5570. wszREGKEYEXITMODULES,
  5571. NULL,
  5572. wszREGACTIVE,
  5573. (fUpgrade && (NULL != pServer->pwszzCustomExit)) ?
  5574. pServer->pwszzCustomExit :
  5575. wszCLASS_CERTEXIT L"\0");
  5576. _JumpIfErrorStr(hr, error, "mySetCertRegMultiStrValueEx", wszREGACTIVE);
  5577. // set some absolute keys and values
  5578. hr = mySetAbsRegMultiStrValue(
  5579. wszREGKEYKEYSNOTTORESTORE,
  5580. wszREGRESTORECERTIFICATEAUTHORITY,
  5581. wszzREGVALUERESTORECERTIFICATEAUTHORITY);
  5582. _JumpIfError(hr, error, "mySetAbsRegMultiStrValue");
  5583. hr = helperGetFilesNotToRestore(pComp, &pwszzFilesNotToRestore);
  5584. _JumpIfError(hr, error, "helperGetFilesNotToRestore");
  5585. hr = mySetAbsRegMultiStrValue(
  5586. wszREGKEYFILESNOTTOBACKUP,
  5587. wszREGRESTORECERTIFICATEAUTHORITY,
  5588. pwszzFilesNotToRestore);
  5589. _JumpIfError(hr, error, "mySetAbsRegMultiStrValue");
  5590. // ICertGetConfig
  5591. hr = StringFromCLSID(CLSID_CCertGetConfig, &pwszCLSIDCertGetConfig);
  5592. _JumpIfError(hr, error, "StringFromCLSID(CCertGetConfig)");
  5593. hr = mySetAbsRegStrValue(
  5594. wszREGKEYKEYRING,
  5595. wszREGCERTGETCONFIG,
  5596. pwszCLSIDCertGetConfig);
  5597. _JumpIfError(hr, error, "mySetAbsRegStrValue");
  5598. // ICertCertRequest
  5599. hr = StringFromCLSID(CLSID_CCertRequest, &pwszCLSIDCertRequest);
  5600. _JumpIfError(hr, error, "StringFromCLSID(CCertRequest)");
  5601. hr = mySetAbsRegStrValue(
  5602. wszREGKEYKEYRING,
  5603. wszREGCERTREQUEST,
  5604. pwszCLSIDCertRequest);
  5605. _JumpIfError(hr, error, "mySetAbsRegStrValue");
  5606. if (NULL != pServer->pCSPInfo &&
  5607. NULL != pServer->pHashInfo)
  5608. {
  5609. WCHAR const *pwszProvName = pServer->pCSPInfo->pwszProvName;
  5610. DWORD dwProvType;
  5611. ALG_ID idAlg;
  5612. BOOL fMachineKeyset;
  5613. DWORD dwKeySize;
  5614. if (0 == LSTRCMPIS(pwszProvName, MS_DEF_PROV_W) && IsWhistler())
  5615. {
  5616. pwszProvName = MS_STRONG_PROV_W;
  5617. }
  5618. hr = SetCertSrvCSP(
  5619. FALSE, // fEncryptionCSP
  5620. pServer->pwszSanitizedName,
  5621. pServer->pCSPInfo->dwProvType,
  5622. pwszProvName,
  5623. pServer->pHashInfo->idAlg,
  5624. pServer->pCSPInfo->fMachineKeyset,
  5625. 0); // dwKeySize
  5626. _JumpIfError(hr, error, "SetCertSrvCSP");
  5627. hr = myGetCertSrvCSP(
  5628. TRUE, // fEncryptionCSP
  5629. pServer->pwszSanitizedName,
  5630. &dwProvType,
  5631. &pwszProvNameReg,
  5632. &idAlg,
  5633. &fMachineKeyset,
  5634. &dwKeySize); // pdwKeySize
  5635. if (S_OK != hr)
  5636. {
  5637. _PrintError(hr, "myGetCertSrvCSP");
  5638. dwProvType = pServer->pCSPInfo->dwProvType;
  5639. idAlg = CALG_3DES;
  5640. fMachineKeyset = pServer->pCSPInfo->fMachineKeyset;
  5641. dwKeySize = 1024;
  5642. }
  5643. else if (NULL != pwszProvNameReg && L'\0' != *pwszProvNameReg)
  5644. {
  5645. pwszProvName = pwszProvNameReg;
  5646. if (0 == LSTRCMPIS(pwszProvName, MS_DEF_PROV_W) && IsWhistler())
  5647. {
  5648. pwszProvName = MS_STRONG_PROV_W;
  5649. }
  5650. }
  5651. hr = SetCertSrvCSP(
  5652. TRUE, // fEncryptionCSP
  5653. pServer->pwszSanitizedName,
  5654. dwProvType,
  5655. pwszProvName,
  5656. idAlg,
  5657. fMachineKeyset,
  5658. dwKeySize); // dwKeySize
  5659. _JumpIfError(hr, error, "SetCertSrvCSP");
  5660. }
  5661. hr = S_OK;
  5662. error:
  5663. if (NULL != pwszProvNameReg)
  5664. {
  5665. LocalFree(pwszProvNameReg);
  5666. }
  5667. myLdapClose(pld, strDomainDN, strConfigDN);
  5668. if (NULL != pwszCLSIDCertGetConfig)
  5669. {
  5670. CoTaskMemFree(pwszCLSIDCertGetConfig);
  5671. }
  5672. if (NULL != pwszCRLPeriodString)
  5673. {
  5674. LocalFree(pwszCRLPeriodString);
  5675. }
  5676. if (NULL != pwszCRLDeltaPeriodString)
  5677. {
  5678. LocalFree(pwszCRLDeltaPeriodString);
  5679. }
  5680. if (NULL != pwszCLSIDCertRequest)
  5681. {
  5682. CoTaskMemFree(pwszCLSIDCertRequest);
  5683. }
  5684. if (NULL != pwszzCRLPublicationValue)
  5685. {
  5686. LocalFree(pwszzCRLPublicationValue);
  5687. }
  5688. if (NULL != pwszzCACertPublicationValue)
  5689. {
  5690. LocalFree(pwszzCACertPublicationValue);
  5691. }
  5692. if (NULL != pwszzRequestExtensionList)
  5693. {
  5694. LocalFree(pwszzRequestExtensionList);
  5695. }
  5696. if (NULL != pwszzEnrolleeRequestExtensionList)
  5697. {
  5698. LocalFree(pwszzEnrolleeRequestExtensionList);
  5699. }
  5700. if (NULL != pwszzDisableExtensionList)
  5701. {
  5702. LocalFree(pwszzDisableExtensionList);
  5703. }
  5704. if (NULL != pwszzFilesNotToRestore)
  5705. {
  5706. LocalFree(pwszzFilesNotToRestore);
  5707. }
  5708. if (NULL != hKeyBase)
  5709. {
  5710. RegCloseKey(hKeyBase);
  5711. }
  5712. CSILOG(hr, IDS_LOG_CREATE_SERVER_REG, NULL, NULL, NULL);
  5713. return(hr);
  5714. }
  5715. HRESULT
  5716. UpgradeRevocationURLReplaceParam(
  5717. IN BOOL fPolicy,
  5718. IN BOOL fMultiString,
  5719. IN WCHAR const *pwszSanitizedName,
  5720. IN WCHAR const *pwszValueName)
  5721. {
  5722. HRESULT hr;
  5723. WCHAR *pwszzValue = NULL;
  5724. WCHAR *pwsz;
  5725. BOOL fModified = FALSE;
  5726. CSASSERT(
  5727. WSZARRAYSIZE(wszFCSAPARM_CERTFILENAMESUFFIX) ==
  5728. WSZARRAYSIZE(wszFCSAPARM_CRLFILENAMESUFFIX));
  5729. // getMultiStr will read REG_SZs as well and double-terminate
  5730. hr = myGetCertRegMultiStrValue(
  5731. pwszSanitizedName,
  5732. fPolicy ? wszREGKEYPOLICYMODULES : wszREGKEYEXITMODULES,
  5733. fPolicy ? wszCLASS_CERTPOLICY : wszCLASS_CERTEXIT,
  5734. pwszValueName,
  5735. &pwszzValue);
  5736. _JumpIfErrorStr2(hr, error, "myGetCertRegMultiStrValue", pwszValueName, hr);
  5737. for (pwsz = pwszzValue; L'\0' != *pwsz; pwsz += wcslen(pwsz) + 1)
  5738. {
  5739. WCHAR *pwszT = pwsz;
  5740. // Replace wszFCSAPARM_CERTFILENAMESUFFIX with
  5741. // wszFCSAPARM_CRLFILENAMESUFFIX. Beta 3's registry values incorrectly
  5742. // used a Cert Suffix instead of CRL Suffix.
  5743. for (;;)
  5744. {
  5745. DWORD i;
  5746. pwszT = wcschr(pwszT, wszFCSAPARM_CERTFILENAMESUFFIX[0]);
  5747. if (NULL == pwszT)
  5748. {
  5749. break;
  5750. }
  5751. for (i = 1; ; i++)
  5752. {
  5753. if (i == WSZARRAYSIZE(wszFCSAPARM_CERTFILENAMESUFFIX))
  5754. {
  5755. CopyMemory(
  5756. pwszT,
  5757. wszFCSAPARM_CRLFILENAMESUFFIX,
  5758. i * sizeof(WCHAR));
  5759. pwszT += i;
  5760. fModified = TRUE;
  5761. break;
  5762. }
  5763. if (pwszT[i] != wszFCSAPARM_CERTFILENAMESUFFIX[i])
  5764. {
  5765. pwszT++;
  5766. break;
  5767. }
  5768. }
  5769. }
  5770. }
  5771. if (fModified)
  5772. {
  5773. if (fMultiString)
  5774. {
  5775. // set as REG_MULTI_SZ
  5776. hr = mySetCertRegMultiStrValue(
  5777. pwszSanitizedName,
  5778. fPolicy ? wszREGKEYPOLICYMODULES : wszREGKEYEXITMODULES,
  5779. fPolicy ? wszCLASS_CERTPOLICY : wszCLASS_CERTEXIT,
  5780. pwszValueName,
  5781. pwszzValue);
  5782. _JumpIfErrorStr(hr, error, "mySetCertRegMultiStrValue", pwszValueName);
  5783. }
  5784. else
  5785. {
  5786. // set as REG_SZ
  5787. hr = mySetCertRegStrValue(
  5788. pwszSanitizedName,
  5789. fPolicy ? wszREGKEYPOLICYMODULES : wszREGKEYEXITMODULES,
  5790. fPolicy ? wszCLASS_CERTPOLICY : wszCLASS_CERTEXIT,
  5791. pwszValueName,
  5792. pwszzValue);
  5793. _JumpIfErrorStr(hr, error, "mySetCertRegStrValue", pwszValueName);
  5794. }
  5795. }
  5796. error:
  5797. if (NULL != pwszzValue)
  5798. {
  5799. LocalFree(pwszzValue);
  5800. }
  5801. CSASSERT(S_OK == hr || FAILED(hr));
  5802. return(hr);
  5803. }
  5804. HRESULT
  5805. UpgradeRevocationURLRemoveParam(
  5806. IN WCHAR const *pwszSanitizedName,
  5807. IN WCHAR const *pwszValueName)
  5808. {
  5809. HRESULT hr;
  5810. WCHAR *pwszValue = NULL;
  5811. BOOL fModified = FALSE;
  5812. WCHAR *pwszT;
  5813. hr = myGetCertRegStrValue(
  5814. pwszSanitizedName,
  5815. wszREGKEYPOLICYMODULES,
  5816. wszCLASS_CERTPOLICY,
  5817. pwszValueName,
  5818. &pwszValue);
  5819. _JumpIfErrorStr2(hr, error, "myGetCertRegStrValue", pwszValueName, hr);
  5820. pwszT = pwszValue;
  5821. // Remove wszFCSAPARM_CERTFILENAMESUFFIX from the Netscape Revocaton URL
  5822. // It should never have been written out in Beta 3's registry value.
  5823. for (;;)
  5824. {
  5825. DWORD i;
  5826. pwszT = wcschr(pwszT, wszFCSAPARM_CERTFILENAMESUFFIX[0]);
  5827. if (NULL == pwszT)
  5828. {
  5829. break;
  5830. }
  5831. for (i = 1; ; i++)
  5832. {
  5833. if (i == WSZARRAYSIZE(wszFCSAPARM_CERTFILENAMESUFFIX))
  5834. {
  5835. MoveMemory(
  5836. pwszT,
  5837. &pwszT[i],
  5838. (wcslen(&pwszT[i]) + 1) * sizeof(WCHAR));
  5839. pwszT += i;
  5840. fModified = TRUE;
  5841. break;
  5842. }
  5843. if (pwszT[i] != wszFCSAPARM_CERTFILENAMESUFFIX[i])
  5844. {
  5845. pwszT++;
  5846. break;
  5847. }
  5848. }
  5849. }
  5850. if (fModified)
  5851. {
  5852. hr = mySetCertRegStrValue(
  5853. pwszSanitizedName,
  5854. wszREGKEYPOLICYMODULES,
  5855. wszCLASS_CERTPOLICY,
  5856. pwszValueName,
  5857. pwszValue);
  5858. _JumpIfErrorStr(hr, error, "mySetCertRegStrValue", pwszValueName);
  5859. }
  5860. error:
  5861. if (NULL != pwszValue)
  5862. {
  5863. LocalFree(pwszValue);
  5864. }
  5865. CSASSERT(S_OK == hr || FAILED(hr));
  5866. return(hr);
  5867. }
  5868. WCHAR const *apwszB3ExitEntriesToFix[] =
  5869. {
  5870. wszREGLDAPREVOCATIONDNTEMPLATE_OLD,
  5871. NULL
  5872. };
  5873. HRESULT
  5874. UpgradeCRLPath(
  5875. WCHAR const *pwszSanitizedName)
  5876. {
  5877. HRESULT hr;
  5878. WCHAR *pwszzCRLPath = NULL;
  5879. WCHAR *pwszzFixedCRLPath = NULL;
  5880. WCHAR *pwsz;
  5881. BOOL fRenewReady = TRUE;
  5882. DWORD dwSize = 0;
  5883. // get current crl path
  5884. hr = myGetCertRegMultiStrValue(
  5885. pwszSanitizedName,
  5886. NULL,
  5887. NULL,
  5888. wszREGCRLPATH_OLD,
  5889. &pwszzCRLPath);
  5890. _JumpIfErrorStr(hr, error, "myGetCertRegStrValue", wszREGCRLPATH_OLD);
  5891. // to see if it is in renew ready format
  5892. for (pwsz = pwszzCRLPath; L'\0' != *pwsz; pwsz += wcslen(pwsz) + 1)
  5893. {
  5894. dwSize += wcslen(pwsz) + 1;
  5895. if (NULL == wcsstr(pwsz, wszFCSAPARM_CRLFILENAMESUFFIX))
  5896. {
  5897. // found one without suffix
  5898. fRenewReady = FALSE;
  5899. // add suffix len
  5900. dwSize += WSZARRAYSIZE(wszFCSAPARM_CRLFILENAMESUFFIX);
  5901. }
  5902. if (NULL == wcsstr(pwsz, wszFCSAPARM_CRLDELTAFILENAMESUFFIX))
  5903. {
  5904. // found one without suffix
  5905. fRenewReady = FALSE;
  5906. // add suffix len
  5907. dwSize += WSZARRAYSIZE(wszFCSAPARM_CRLDELTAFILENAMESUFFIX);
  5908. }
  5909. }
  5910. if (!fRenewReady)
  5911. {
  5912. ++dwSize; // multi string
  5913. // at least one of crl path missed suffix
  5914. pwszzFixedCRLPath = (WCHAR*)LocalAlloc(LMEM_FIXED,
  5915. dwSize * sizeof(WCHAR));
  5916. _JumpIfOutOfMemory(hr, error, pwszzFixedCRLPath);
  5917. WCHAR *pwszPt = pwszzFixedCRLPath;
  5918. for (pwsz = pwszzCRLPath; L'\0' != *pwsz; pwsz += wcslen(pwsz) + 1)
  5919. {
  5920. BOOL fCRLFileName;
  5921. BOOL fCRLDeltaSuffix;
  5922. // copy over whole path 1st
  5923. wcscpy(pwszPt, pwsz);
  5924. fCRLFileName = NULL != wcsstr(pwszPt, wszFCSAPARM_CRLFILENAMESUFFIX);
  5925. fCRLDeltaSuffix = NULL != wcsstr(pwszPt, wszFCSAPARM_CRLDELTAFILENAMESUFFIX);
  5926. if (!fCRLFileName || !fCRLDeltaSuffix)
  5927. {
  5928. // miss suffix, find file portion
  5929. WCHAR *pwszFile = wcsrchr(pwszPt, L'\\');
  5930. if (NULL == pwszFile)
  5931. {
  5932. // may be relative path, point to begin
  5933. pwszFile = pwszPt;
  5934. }
  5935. // find crl extension portion
  5936. WCHAR *pwszCRLExt = wcsrchr(pwszFile, L'.');
  5937. if (NULL != pwszCRLExt)
  5938. {
  5939. *pwszCRLExt = L'\0';
  5940. if (!fCRLFileName)
  5941. {
  5942. wcscat(pwszCRLExt, wszFCSAPARM_CRLFILENAMESUFFIX);
  5943. }
  5944. if (!fCRLDeltaSuffix)
  5945. {
  5946. wcscat(pwszPt, wszFCSAPARM_CRLDELTAFILENAMESUFFIX);
  5947. }
  5948. // add extension portion from original buffer
  5949. wcscat(pwszCRLExt,
  5950. pwsz + SAFE_SUBTRACT_POINTERS(pwszCRLExt, pwszPt));
  5951. }
  5952. else
  5953. {
  5954. // no crl file extension, append suffix at end
  5955. if (!fCRLFileName)
  5956. {
  5957. wcscat(pwszPt, wszFCSAPARM_CRLFILENAMESUFFIX);
  5958. }
  5959. if (!fCRLDeltaSuffix)
  5960. {
  5961. wcscat(pwszPt, wszFCSAPARM_CRLDELTAFILENAMESUFFIX);
  5962. }
  5963. }
  5964. }
  5965. // update pointer
  5966. pwszPt += wcslen(pwszPt) + 1;
  5967. }
  5968. // mutil string
  5969. *pwszPt = L'\0';
  5970. CSASSERT(dwSize == SAFE_SUBTRACT_POINTERS(pwszPt, pwszzFixedCRLPath) + 1);
  5971. // reset crl path with the fixed crl path
  5972. hr = mySetCertRegMultiStrValue(
  5973. pwszSanitizedName,
  5974. NULL,
  5975. NULL,
  5976. wszREGCRLPATH_OLD,
  5977. pwszzFixedCRLPath);
  5978. _JumpIfErrorStr(hr, error, "mySetCertRegMultiStrValue", wszREGCRLPATH_OLD);
  5979. }
  5980. hr = S_OK;
  5981. error:
  5982. if (NULL != pwszzCRLPath)
  5983. {
  5984. LocalFree(pwszzCRLPath);
  5985. }
  5986. if (NULL != pwszzFixedCRLPath)
  5987. {
  5988. LocalFree(pwszzFixedCRLPath);
  5989. }
  5990. return hr;
  5991. }
  5992. HRESULT
  5993. MergeCRLPath(
  5994. IN WCHAR const *pwszSanitizedName)
  5995. {
  5996. HRESULT hr;
  5997. WCHAR *pwszzCRLPath = NULL;
  5998. WCHAR *pwszzFixedCRLPath = NULL;
  5999. WCHAR *pwsz;
  6000. DWORD cwc;
  6001. WCHAR awcPrefix[cwcDWORDSPRINTF + 1];
  6002. DWORD cwcPrefix;
  6003. // get current crl path
  6004. hr = myGetCertRegMultiStrValue(
  6005. pwszSanitizedName,
  6006. NULL,
  6007. NULL,
  6008. wszREGCRLPATH_OLD,
  6009. &pwszzCRLPath);
  6010. _JumpIfErrorStr(hr, error, "myGetCertRegStrValue", wszREGCRLPATH_OLD);
  6011. wsprintf(
  6012. awcPrefix,
  6013. wszURLPREFIXFORMAT,
  6014. CSURL_SERVERPUBLISH | CSURL_SERVERPUBLISHDELTA);
  6015. cwcPrefix = wcslen(awcPrefix);
  6016. cwc = 1;
  6017. for (pwsz = pwszzCRLPath; L'\0' != *pwsz; pwsz += wcslen(pwsz) + 1)
  6018. {
  6019. cwc += cwcPrefix + wcslen(pwsz) + 1;
  6020. }
  6021. if (1 < cwc)
  6022. {
  6023. WCHAR *pwszT;
  6024. pwszzFixedCRLPath = (WCHAR *) LocalAlloc(
  6025. LMEM_FIXED,
  6026. cwc * sizeof(WCHAR));
  6027. _JumpIfOutOfMemory(hr, error, pwszzFixedCRLPath);
  6028. pwszT = pwszzFixedCRLPath;
  6029. for (pwsz = pwszzCRLPath; L'\0' != *pwsz; pwsz += wcslen(pwsz) + 1)
  6030. {
  6031. wcscpy(pwszT, awcPrefix);
  6032. wcscat(pwszT, pwsz);
  6033. pwszT += wcslen(pwszT) + 1;
  6034. }
  6035. *pwszT = L'\0';
  6036. CSASSERT(cwc == SAFE_SUBTRACT_POINTERS(pwszT, pwszzFixedCRLPath) + 1);
  6037. hr = mySetCertRegMultiStrValueEx(
  6038. CSREG_UPGRADE | CSREG_MERGE,
  6039. pwszSanitizedName,
  6040. NULL,
  6041. NULL,
  6042. wszREGCRLPUBLICATIONURLS,
  6043. pwszzFixedCRLPath);
  6044. _JumpIfErrorStr(
  6045. hr,
  6046. error,
  6047. "mySetCertRegMultiStrValue",
  6048. wszREGCRLPUBLICATIONURLS);
  6049. hr = myDeleteCertRegValue(
  6050. pwszSanitizedName,
  6051. NULL,
  6052. NULL,
  6053. wszREGCRLPATH_OLD);
  6054. _PrintIfErrorStr(hr, "myGetCertRegMultiStrValue", wszREGCRLPATH_OLD);
  6055. }
  6056. hr = S_OK;
  6057. error:
  6058. if (NULL != pwszzCRLPath)
  6059. {
  6060. LocalFree(pwszzCRLPath);
  6061. }
  6062. if (NULL != pwszzFixedCRLPath)
  6063. {
  6064. LocalFree(pwszzFixedCRLPath);
  6065. }
  6066. return(hr);
  6067. }
  6068. typedef struct _URLPREFIXSTRUCT
  6069. {
  6070. WCHAR const *pwszURLPrefix;
  6071. DWORD dwURLFlags;
  6072. } URLPREFIXSTRUCT;
  6073. //array of cdp url type and its default usage which is prefix of url
  6074. URLPREFIXSTRUCT aCDPURLPrefixList[] =
  6075. {
  6076. {L"file:", CSURL_ADDTOCERTCDP | CSURL_ADDTOFRESHESTCRL },
  6077. {L"http:", CSURL_ADDTOCERTCDP | CSURL_ADDTOFRESHESTCRL },
  6078. {L"ldap:", CSURL_SERVERPUBLISH | CSURL_SERVERPUBLISHDELTA | CSURL_ADDTOCERTCDP | CSURL_ADDTOFRESHESTCRL | CSURL_ADDTOCRLCDP},
  6079. {NULL, 0}
  6080. };
  6081. //array of aia url type and its default usage which is prefix of url
  6082. URLPREFIXSTRUCT aAIAURLPrefixList[] =
  6083. {
  6084. {L"file:", CSURL_ADDTOCERTCDP},
  6085. {L"http:", CSURL_ADDTOCERTCDP},
  6086. {L"ldap:", CSURL_ADDTOCERTCDP | CSURL_SERVERPUBLISH},
  6087. {NULL, 0}
  6088. };
  6089. //pass an old url, determine what is prefix in a format of "XX:"
  6090. HRESULT
  6091. DetermineURLPrefixFlags(
  6092. IN BOOL fDisabled,
  6093. IN BOOL fCDP,
  6094. IN WCHAR const *pwszURL,
  6095. IN WCHAR *pwszPrefixFlags)
  6096. {
  6097. HRESULT hr;
  6098. URLPREFIXSTRUCT *pURLPrefix;
  6099. DWORD dwPathFlags;
  6100. WCHAR *pwszT;
  6101. WCHAR *pwszLower = NULL;
  6102. DWORD dwPrefixFlags = 0; // default to disable
  6103. if (myIsFullPath(pwszURL, &dwPathFlags))
  6104. {
  6105. //local path, easy
  6106. dwPrefixFlags = fCDP?
  6107. (CSURL_SERVERPUBLISH | CSURL_SERVERPUBLISHDELTA) :
  6108. CSURL_SERVERPUBLISH;
  6109. goto done;
  6110. }
  6111. //make lower case url string
  6112. pwszLower = (WCHAR*)LocalAlloc(LMEM_FIXED,
  6113. (wcslen(pwszURL) + 1) * sizeof(WCHAR));
  6114. if (NULL == pwszLower)
  6115. {
  6116. hr = E_OUTOFMEMORY;
  6117. _JumpError(hr, error, "LocalAlloc");
  6118. }
  6119. wcscpy(pwszLower, pwszURL);
  6120. CharLower(pwszLower);
  6121. //loop through to find out url type
  6122. for (pURLPrefix = fCDP ? aCDPURLPrefixList : aAIAURLPrefixList;
  6123. NULL != pURLPrefix->pwszURLPrefix; ++pURLPrefix)
  6124. {
  6125. pwszT = wcsstr(pwszLower, pURLPrefix->pwszURLPrefix);
  6126. if (0 == _wcsnicmp(pwszLower, pURLPrefix->pwszURLPrefix,
  6127. wcslen(pURLPrefix->pwszURLPrefix)))
  6128. {
  6129. dwPrefixFlags = pURLPrefix->dwURLFlags;
  6130. goto done;
  6131. }
  6132. }
  6133. // if nothing matches, keep 0 flag
  6134. done:
  6135. if (fDisabled)
  6136. {
  6137. if (fCDP)
  6138. {
  6139. dwPrefixFlags &= CSURL_ADDTOCRLCDP;
  6140. }
  6141. else
  6142. {
  6143. dwPrefixFlags = 0;
  6144. }
  6145. }
  6146. wsprintf(pwszPrefixFlags, wszURLPREFIXFORMAT, dwPrefixFlags);
  6147. hr = S_OK;
  6148. error:
  6149. if (NULL != pwszLower)
  6150. {
  6151. LocalFree(pwszLower);
  6152. }
  6153. return hr;
  6154. }
  6155. //move old cdp or aia url from policy to a new location under ca
  6156. HRESULT
  6157. UpgradeMoveURLsLocation(
  6158. IN BOOL fCDP,
  6159. IN WCHAR const *pwszSanitizedName,
  6160. IN WCHAR const *pwszValueName,
  6161. IN DWORD dwEnableFlagsBits)
  6162. {
  6163. HRESULT hr;
  6164. WCHAR *pwszzValue = NULL;
  6165. WCHAR *pwszzURLs = NULL;
  6166. BOOL fDisabled;
  6167. DWORD cURLs = 0; //count of url from multi_sz
  6168. DWORD dwLen = 0;
  6169. DWORD dwSize = 0; //total size of chars in multi_sz url exluding '-'
  6170. WCHAR *pwsz;
  6171. WCHAR *pwszT;
  6172. WCHAR *pwszNoMinus;
  6173. WCHAR wszPrefixFlags[cwcDWORDSPRINTF + 1];
  6174. DWORD dwRegFlags;
  6175. // get urls in the old location
  6176. hr = myGetCertRegMultiStrValue(
  6177. pwszSanitizedName,
  6178. wszREGKEYPOLICYMODULES,
  6179. wszCLASS_CERTPOLICY,
  6180. pwszValueName,
  6181. &pwszzValue);
  6182. _JumpIfErrorStr2(hr, error, "myGetCertRegMultiStrValue", pwszValueName, hr);
  6183. hr = myGetCertRegDWValue(
  6184. pwszSanitizedName,
  6185. wszREGKEYPOLICYMODULES,
  6186. wszCLASS_CERTPOLICY,
  6187. fCDP? wszREGREVOCATIONTYPE : wszREGISSUERCERTURLFLAGS,
  6188. &dwRegFlags);
  6189. if (S_OK != hr)
  6190. {
  6191. dwRegFlags = MAXDWORD; // Enable all URL types
  6192. }
  6193. // fix "-" prefix for disable and count size
  6194. for (pwsz = pwszzValue; L'\0' != *pwsz; pwsz += dwLen)
  6195. {
  6196. //current url length
  6197. dwLen = wcslen(pwsz) + 1;
  6198. //update size
  6199. dwSize += dwLen;
  6200. ++cURLs;
  6201. pwszNoMinus = pwsz;
  6202. while (L'-' == *pwszNoMinus)
  6203. {
  6204. //exclude prefix '-'s
  6205. --dwSize;
  6206. ++pwszNoMinus;
  6207. }
  6208. }
  6209. //allocate buffer in "XX:URL" format
  6210. pwszzURLs = (WCHAR*)LocalAlloc(LMEM_FIXED,
  6211. (dwSize + cURLs * ARRAYSIZE(wszPrefixFlags) + 1) * sizeof(WCHAR));
  6212. if (NULL == pwszzURLs)
  6213. {
  6214. hr = E_OUTOFMEMORY;
  6215. _JumpError(hr, error, "LocalAlloc");
  6216. }
  6217. pwszT = pwszzURLs;
  6218. //form string in new url format
  6219. for (pwsz = pwszzValue; L'\0' != *pwsz; pwsz += wcslen(pwsz) + 1)
  6220. {
  6221. fDisabled = FALSE;
  6222. pwszNoMinus = pwsz;
  6223. while (L'-' == *pwszNoMinus)
  6224. {
  6225. //exclude prefix '-'s
  6226. ++pwszNoMinus;
  6227. fDisabled = !fDisabled;
  6228. }
  6229. if ((dwEnableFlagsBits & dwRegFlags) != dwEnableFlagsBits)
  6230. {
  6231. fDisabled = TRUE;
  6232. }
  6233. hr = DetermineURLPrefixFlags(fDisabled, fCDP, pwszNoMinus, wszPrefixFlags);
  6234. _JumpIfErrorStr(hr, error, "DetermineURLPrefixFlags", pwszNoMinus);
  6235. //format "xx:url"
  6236. wcscpy(pwszT, wszPrefixFlags);
  6237. wcscat(pwszT, pwszNoMinus);
  6238. //ready for next url
  6239. pwszT += wcslen(pwszT) + 1;
  6240. }
  6241. //zz
  6242. *pwszT = L'\0';
  6243. pwszT = fCDP ? wszREGCRLPUBLICATIONURLS : wszREGCACERTPUBLICATIONURLS,
  6244. //move or merge to ca
  6245. hr = mySetCertRegMultiStrValueEx(
  6246. CSREG_UPGRADE | CSREG_MERGE,
  6247. pwszSanitizedName,
  6248. NULL,
  6249. NULL,
  6250. pwszT,
  6251. pwszzURLs);
  6252. _JumpIfErrorStr(hr, error, "mySetCertRegMultiStrValue", pwszT);
  6253. //remove url under policy
  6254. hr = myDeleteCertRegValue(
  6255. pwszSanitizedName,
  6256. wszREGKEYPOLICYMODULES,
  6257. wszCLASS_CERTPOLICY,
  6258. pwszValueName);
  6259. _PrintIfErrorStr(hr, "myGetCertRegMultiStrValue", pwszValueName);
  6260. hr = S_OK;
  6261. error:
  6262. if (NULL != pwszzValue)
  6263. {
  6264. LocalFree(pwszzValue);
  6265. }
  6266. if (NULL != pwszzURLs)
  6267. {
  6268. LocalFree(pwszzURLs);
  6269. }
  6270. return(hr);
  6271. }
  6272. // Order MUST be the same as adwPolicyCDPEntriesToFix
  6273. WCHAR const *apwszPolicyCDPEntriesToFix[] =
  6274. {
  6275. wszREGLDAPREVOCATIONCRLURL_OLD, //"LDAPRevocationCRLURL"
  6276. wszREGREVOCATIONCRLURL_OLD, //"RevocationCRLURL"
  6277. wszREGFTPREVOCATIONCRLURL_OLD, //"FTPRevocationCRLURL"
  6278. wszREGFILEREVOCATIONCRLURL_OLD, //"FileRevocationCRLURL"
  6279. NULL
  6280. };
  6281. // Order MUST be the same as apwszPolicyCDPEntriesToFix
  6282. DWORD adwPolicyCDPEntriesToFix[] =
  6283. {
  6284. REVEXT_CDPLDAPURL_OLD,
  6285. REVEXT_CDPHTTPURL_OLD,
  6286. REVEXT_CDPFTPURL_OLD,
  6287. REVEXT_CDPFILEURL_OLD,
  6288. 0
  6289. };
  6290. HRESULT
  6291. myPrintIfError(
  6292. IN HRESULT hrNew,
  6293. IN HRESULT hrOld,
  6294. IN CHAR const *DBGCODE(psz),
  6295. IN OPTIONAL WCHAR const *pwsz)
  6296. {
  6297. if (S_OK != hrNew)
  6298. {
  6299. if (NULL != pwsz)
  6300. {
  6301. _PrintErrorStr(hrNew, psz, pwsz);
  6302. }
  6303. else
  6304. {
  6305. _PrintError(hrNew, psz);
  6306. }
  6307. if (S_OK == hrOld)
  6308. {
  6309. //save only oldest err
  6310. hrOld = hrNew;
  6311. }
  6312. }
  6313. return hrOld;
  6314. }
  6315. // This function only replaces suffixes!!!
  6316. HRESULT ReplaceStringsInURLs(
  6317. LPCWSTR pcwszSanitizedName,
  6318. LPCWSTR pcwszRegEntry,
  6319. LPCWSTR pcwszReplaced,
  6320. LPCWSTR pcwszReplacement)
  6321. {
  6322. HRESULT hr;
  6323. LPWSTR pOrig = NULL;
  6324. void * pMod = NULL;
  6325. DWORD dwLen;
  6326. CMultiSz szzValue;
  6327. hr = myGetCertRegMultiStrValue(
  6328. pcwszSanitizedName,
  6329. NULL,
  6330. NULL,
  6331. pcwszRegEntry,
  6332. &pOrig);
  6333. _JumpIfErrorStr(hr, error, "myGetCertRegStrValue", pcwszRegEntry);
  6334. hr = szzValue.Unmarshal(pOrig);
  6335. _JumpIfError(hr, error, "CMultiSz::Unmarshal");
  6336. if (!szzValue.IsEmpty())
  6337. {
  6338. // walk through the list and replace
  6339. CMultiSzEnum szzValueEnum(szzValue);
  6340. CString *pStr;
  6341. for(pStr = szzValueEnum.Next();
  6342. pStr;
  6343. pStr = szzValueEnum.Next())
  6344. {
  6345. WCHAR *pchFound = wcsstr((LPCWSTR)*pStr, pcwszReplaced);
  6346. if(pchFound)
  6347. {
  6348. DBGPRINT((DBG_SS_CERTOCMI,
  6349. "Inserting %9 in %s", (LPCWSTR)*pStr));
  6350. LPWSTR pwszOld = pStr->Detach();
  6351. *pchFound = L'\0';
  6352. *pStr = pwszOld;
  6353. *pStr += pcwszReplacement;
  6354. LocalFree(pwszOld);
  6355. }
  6356. }
  6357. hr = szzValue.Marshal(pMod, dwLen);
  6358. _JumpIfError(hr, error, "CMultiSz::Marshal");
  6359. hr = mySetCertRegMultiStrValue(
  6360. pcwszSanitizedName,
  6361. NULL,
  6362. NULL,
  6363. pcwszRegEntry,
  6364. (LPCWSTR)pMod);
  6365. _JumpIfErrorStr(hr, error, "mySetCertRegMultiStrValue", pcwszRegEntry);
  6366. }
  6367. error:
  6368. LOCAL_FREE(pOrig);
  6369. LOCAL_FREE(pMod);
  6370. return hr;
  6371. }
  6372. HRESULT
  6373. UpgradePolicyCDPURLs(
  6374. IN WCHAR const *pwszSanitizedName)
  6375. {
  6376. HRESULT hr = S_OK;
  6377. HRESULT hr2;
  6378. WCHAR const **ppwsz;
  6379. DWORD const *pdw;
  6380. pdw = adwPolicyCDPEntriesToFix;
  6381. for (ppwsz = apwszPolicyCDPEntriesToFix; NULL != *ppwsz; ppwsz++, pdw++)
  6382. {
  6383. // all entries are multi-valued
  6384. hr2 = UpgradeRevocationURLReplaceParam(
  6385. TRUE,
  6386. TRUE,
  6387. pwszSanitizedName,
  6388. *ppwsz);
  6389. hr = myPrintIfError(hr2, hr, "UpgradeRevocationURLReplaceParam", *ppwsz);
  6390. hr2 = UpgradeMoveURLsLocation(
  6391. TRUE,
  6392. pwszSanitizedName,
  6393. *ppwsz,
  6394. REVEXT_CDPENABLE | *pdw);
  6395. hr = myPrintIfError(hr2, hr, "UpgradeMoveURLsLocation", *ppwsz);
  6396. }
  6397. hr2 = UpgradeRevocationURLRemoveParam(pwszSanitizedName, wszREGREVOCATIONURL);
  6398. hr = myPrintIfError(hr2, hr, "UpgradeRevocationURLRemoveParam", wszREGREVOCATIONURL);
  6399. hr2 = UpgradeCRLPath(pwszSanitizedName);
  6400. hr = myPrintIfError(hr2, hr, "UpgradeCRLPath", NULL);
  6401. hr2 = MergeCRLPath(pwszSanitizedName);
  6402. hr = myPrintIfError(hr2, hr, "MergeCRLPath", NULL);
  6403. {
  6404. // bug 446444: replace CDP attributes in LDAP format strings:
  6405. // ?certificateRevocationList?base?objectclass=cRLDistributionPoint -> %10
  6406. LPCWSTR pcwszReplacedCDPString =
  6407. L"?certificateRevocationList?base?objectclass=cRLDistributionPoint";
  6408. LPCWSTR pcwszReplacementCDPString =
  6409. L"%10";
  6410. hr2 = ReplaceStringsInURLs(
  6411. pwszSanitizedName,
  6412. wszREGCRLPUBLICATIONURLS,
  6413. pcwszReplacedCDPString,
  6414. pcwszReplacementCDPString);
  6415. hr = myPrintIfError(hr2, hr, "ReplaceStringsInURLs", NULL);
  6416. }
  6417. {
  6418. // bug 450583: insert %9 after %8 in "...%8.crl"
  6419. // ?certificateRevocationList?base?objectclass=cRLDistributionPoint -> %10
  6420. LPCWSTR pcwszReplacedCDPString =
  6421. L"%8.crl";
  6422. LPCWSTR pcwszReplacementCDPString =
  6423. L"%8%9.crl";
  6424. hr2 = ReplaceStringsInURLs(
  6425. pwszSanitizedName,
  6426. wszREGCRLPUBLICATIONURLS,
  6427. pcwszReplacedCDPString,
  6428. pcwszReplacementCDPString);
  6429. hr = myPrintIfError(hr2, hr, "ReplaceStringsInURLs", NULL);
  6430. }
  6431. return(hr);
  6432. }
  6433. // Order MUST be the same as adwPolicyAIAEntriesToFix
  6434. WCHAR const *apwszPolicyAIAEntriesToFix[] =
  6435. {
  6436. wszREGLDAPISSUERCERTURL_OLD, //"LDAPIssuerCertURL"
  6437. wszREGISSUERCERTURL_OLD, //"IssuerCertURL"
  6438. wszREGFTPISSUERCERTURL_OLD, //"FTPIssuerCertURL"
  6439. wszREGFILEISSUERCERTURL_OLD, //"FileIssuerCertURL"
  6440. NULL
  6441. };
  6442. // Order MUST be the same as apwszPolicyAIAEntriesToFix
  6443. DWORD adwPolicyAIAEntriesToFix[] =
  6444. {
  6445. ISSCERT_LDAPURL_OLD,
  6446. ISSCERT_HTTPURL_OLD,
  6447. ISSCERT_FTPURL_OLD,
  6448. ISSCERT_FILEURL_OLD,
  6449. 0
  6450. };
  6451. HRESULT
  6452. UpgradePolicyAIAURLs(
  6453. IN WCHAR const *pwszSanitizedName)
  6454. {
  6455. HRESULT hr = S_OK;
  6456. HRESULT hr2;
  6457. WCHAR const **ppwsz;
  6458. DWORD const *pdw;
  6459. pdw = adwPolicyAIAEntriesToFix;
  6460. for (ppwsz = apwszPolicyAIAEntriesToFix; NULL != *ppwsz; ppwsz++, pdw++)
  6461. {
  6462. // all entries are multi-valued
  6463. hr2 = UpgradeMoveURLsLocation(
  6464. FALSE,
  6465. pwszSanitizedName,
  6466. *ppwsz,
  6467. ISSCERT_ENABLE | *pdw);
  6468. hr = myPrintIfError(hr2, hr, "UpgradeMoveURLsLocation", *ppwsz);
  6469. }
  6470. {
  6471. // bug 446444: replace AIA attributes in LDAP format strings:
  6472. // ?cACertificate?base?objectclass=certificationAuthority -> %11
  6473. LPCWSTR pcwszReplacedCDPString =
  6474. L"?cACertificate?base?objectclass=certificationAuthority";
  6475. LPCWSTR pcwszReplacementCDPString =
  6476. L"%11";
  6477. hr2 = ReplaceStringsInURLs(
  6478. pwszSanitizedName,
  6479. wszREGCACERTPUBLICATIONURLS,
  6480. pcwszReplacedCDPString,
  6481. pcwszReplacementCDPString);
  6482. hr = myPrintIfError(hr2, hr, "ReplaceStringsInURLs", NULL);
  6483. }
  6484. return(hr);
  6485. }
  6486. HRESULT
  6487. UpgradeExitRevocationURLs(
  6488. IN WCHAR const *pwszSanitizedName)
  6489. {
  6490. WCHAR const **ppwsz;
  6491. for (ppwsz = apwszB3ExitEntriesToFix; NULL != *ppwsz; ppwsz++)
  6492. {
  6493. // all entries are single-valued
  6494. UpgradeRevocationURLReplaceParam(FALSE, FALSE, pwszSanitizedName, *ppwsz);
  6495. }
  6496. return(S_OK);
  6497. }
  6498. // following code to determine if current policy/exit modules are custom
  6499. // if find any custom module and assign it to
  6500. // pServer->pwszCustomPolicy/Exit
  6501. // otherwise pServer->pwszCustomPolicy/Exit = NULL means default as active
  6502. #define wszCERTSRV10POLICYPROGID L"CertificateAuthority.Policy"
  6503. #define wszCERTSRV10EXITPROGID L"CertificateAuthority.Exit"
  6504. #define wszCLSID L"ClsID\\"
  6505. #define wszINPROCSERVER32 L"\\InprocServer32"
  6506. HRESULT
  6507. DetermineServerCustomModule(
  6508. PER_COMPONENT_DATA *pComp,
  6509. IN BOOL fPolicy)
  6510. {
  6511. HRESULT hr;
  6512. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  6513. // init
  6514. if (fPolicy)
  6515. {
  6516. if (NULL != pServer->pwszCustomPolicy)
  6517. {
  6518. LocalFree(pServer->pwszCustomPolicy);
  6519. pServer->pwszCustomPolicy = NULL;
  6520. }
  6521. }
  6522. else
  6523. {
  6524. if (NULL != pServer->pwszzCustomExit)
  6525. {
  6526. LocalFree(pServer->pwszzCustomExit);
  6527. pServer->pwszzCustomExit = NULL;
  6528. }
  6529. }
  6530. // build to build
  6531. // to pass what is the current active policy
  6532. if (fPolicy)
  6533. {
  6534. // policy module
  6535. hr = myGetCertRegStrValue(
  6536. pServer->pwszSanitizedName,
  6537. wszREGKEYPOLICYMODULES,
  6538. NULL,
  6539. wszREGACTIVE,
  6540. &pServer->pwszCustomPolicy);
  6541. _JumpIfError(hr, done, "myGetCertRegStrValue");
  6542. }
  6543. else
  6544. {
  6545. // exit module
  6546. hr = myGetCertRegMultiStrValue(
  6547. pServer->pwszSanitizedName,
  6548. wszREGKEYEXITMODULES,
  6549. NULL,
  6550. wszREGACTIVE,
  6551. &pServer->pwszzCustomExit);
  6552. _JumpIfError(hr, done, "myGetCertRegStrValue");
  6553. }
  6554. done:
  6555. hr = S_OK;
  6556. //error:
  6557. return hr;
  6558. }
  6559. HRESULT
  6560. UpgradeServerRegEntries(
  6561. PER_COMPONENT_DATA *pComp)
  6562. {
  6563. HRESULT hr;
  6564. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  6565. WCHAR *pwszCRLPeriodString = NULL;
  6566. DWORD Count;
  6567. CSASSERT(
  6568. NULL != pServer->pwszSanitizedName &&
  6569. NULL != pServer->pccUpgradeCert);
  6570. // Description:
  6571. // - if upgrade and get this point, all necessary data structure
  6572. // should be loaded and created in LoadAndDetermineServerUpgradeInfo()
  6573. // - in this module, check all different upgrade cases,
  6574. // upgrade (move) reg entries
  6575. // - remove old unused reg entries if upgrade
  6576. // Note: each of above steps applys from config level down to ca then
  6577. // to policy, etc.
  6578. // - lastly call CreateServerRegEntries with upgrade flag
  6579. // CONFIGURATION LEVEL
  6580. // CA LEVEL
  6581. hr = myGetCARegHashCount(
  6582. pServer->pwszSanitizedName,
  6583. CSRH_CASIGCERT,
  6584. &Count);
  6585. _JumpIfError(hr, error, "myGetCARegHashCount");
  6586. if (0 == Count)
  6587. {
  6588. hr = mySetCARegHash(
  6589. pServer->pwszSanitizedName,
  6590. CSRH_CASIGCERT,
  6591. 0, // iCert
  6592. pServer->pccUpgradeCert);
  6593. _JumpIfError(hr, error, "mySetCARegHash");
  6594. }
  6595. // bug 446444: add ENUM_TELETEXT_UTF8 on upgrade
  6596. {
  6597. DWORD dwForceTeletex;
  6598. hr = myGetCertRegDWValue(
  6599. pServer->pwszSanitizedName,
  6600. NULL,
  6601. NULL,
  6602. wszREGFORCETELETEX,
  6603. (DWORD *) &dwForceTeletex);
  6604. if(S_OK==hr)
  6605. {
  6606. dwForceTeletex |= ENUM_TELETEX_UTF8;
  6607. hr = mySetCertRegDWValue(
  6608. pServer->pwszSanitizedName,
  6609. NULL,
  6610. NULL,
  6611. wszREGFORCETELETEX,
  6612. dwForceTeletex);
  6613. _JumpIfErrorStr(hr, error, "mySetCertRegDWValue", wszREGFORCETELETEX);
  6614. }
  6615. }
  6616. // POLICY LEVEL
  6617. {
  6618. //could fix two things, 1) W2K from B3 needs fixing token plus 2) or
  6619. // 2) W2K needs fix CDP location
  6620. hr = UpgradePolicyCDPURLs(pServer->pwszSanitizedName);
  6621. _PrintIfError(hr, "UpgradePolicyCDPURLs");
  6622. hr = UpgradePolicyAIAURLs(pServer->pwszSanitizedName);
  6623. _PrintIfError(hr, "UpgradePolicyAIAURLs");
  6624. hr = UpgradeExitRevocationURLs(pServer->pwszSanitizedName);
  6625. _PrintIfError(hr, "UpgradeExitRevocationURLs");
  6626. //UNDONE, we need move url for cdp and aia under policy to ca level
  6627. }
  6628. // EXIT LEVEL
  6629. // DELETE OLD AND UNUSED ENTRIES
  6630. hr = CreateServerRegEntries(TRUE, pComp);
  6631. _JumpIfError(hr, error, "CreateServerRegEntries");
  6632. // hr = S_OK;
  6633. error:
  6634. if (NULL != pwszCRLPeriodString)
  6635. {
  6636. LocalFree(pwszCRLPeriodString);
  6637. }
  6638. CSILOG(hr, IDS_LOG_UPGRADE_SERVER_REG, NULL, NULL, NULL);
  6639. return(hr);
  6640. }
  6641. HRESULT
  6642. RegisterAndUnRegisterDLLs(
  6643. IN DWORD Flags,
  6644. IN PER_COMPONENT_DATA *pComp,
  6645. IN HWND hwnd)
  6646. {
  6647. HRESULT hr;
  6648. HMODULE hMod = NULL;
  6649. typedef HRESULT (STDAPICALLTYPE FNDLLREGISTERSERVER)(VOID);
  6650. FNDLLREGISTERSERVER *pfnRegister;
  6651. CHAR const *pszFuncName;
  6652. REGISTERDLL const *prd;
  6653. WCHAR wszString[MAX_PATH];
  6654. UINT errmode = 0;
  6655. BOOL fCoInit = FALSE;
  6656. hr = CoInitialize(NULL);
  6657. if (S_OK != hr && S_FALSE != hr)
  6658. {
  6659. _JumpError(hr, error, "CoInitialize");
  6660. }
  6661. fCoInit = TRUE;
  6662. errmode = SetErrorMode(SEM_FAILCRITICALERRORS);
  6663. pszFuncName = 0 == (RD_UNREGISTER & Flags)?
  6664. aszRegisterServer[0] : aszRegisterServer[1];
  6665. for (prd = g_aRegisterDll; NULL != prd->pwszDllName; prd++)
  6666. {
  6667. if ((Flags & RD_UNREGISTER) &&
  6668. ((Flags & RD_SKIPUNREGPOLICY) && (prd->Flags & RD_SKIPUNREGPOLICY) ||
  6669. (Flags & RD_SKIPUNREGEXIT) && (prd->Flags & RD_SKIPUNREGEXIT)))
  6670. {
  6671. // case of upgrade path & this dll doesn't want to unreg
  6672. continue;
  6673. }
  6674. if (Flags & prd->Flags)
  6675. {
  6676. if (NULL != g_pwszArgvPath)
  6677. {
  6678. wcscpy(wszString, g_pwszArgvPath);
  6679. if (L'\0' != wszString[0] &&
  6680. L'\\' != wszString[wcslen(wszString) - 1])
  6681. {
  6682. wcscat(wszString, L"\\");
  6683. }
  6684. }
  6685. else
  6686. {
  6687. wcscpy(wszString, pComp->pwszSystem32);
  6688. }
  6689. wcscat(wszString, prd->pwszDllName);
  6690. hMod = LoadLibrary(wszString);
  6691. if (NULL == hMod)
  6692. {
  6693. hr = myHLastError();
  6694. if (0 == (RD_UNREGISTER & Flags) &&
  6695. (!(RD_WHISTLER & prd->Flags) || IsWhistler()))
  6696. {
  6697. SaveCustomMessage(pComp, wszString);
  6698. CertErrorMessageBox(
  6699. pComp->hInstance,
  6700. pComp->fUnattended,
  6701. hwnd,
  6702. IDS_ERR_DLLFUNCTION_CALL,
  6703. hr,
  6704. wszString);
  6705. CSILOG(hr, IDS_LOG_DLLS_REGISTERED, wszString, NULL, NULL);
  6706. _JumpErrorStr(hr, error, "LoadLibrary", wszString);
  6707. }
  6708. hr = S_OK;
  6709. continue;
  6710. }
  6711. pfnRegister = (FNDLLREGISTERSERVER *) GetProcAddress(
  6712. hMod,
  6713. pszFuncName);
  6714. if (NULL == pfnRegister)
  6715. {
  6716. hr = myHLastError();
  6717. _JumpErrorStr(hr, error, "GetProcAddress", wszString);
  6718. }
  6719. __try
  6720. {
  6721. hr = (*pfnRegister)();
  6722. }
  6723. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  6724. {
  6725. }
  6726. FreeLibrary(hMod);
  6727. hMod = NULL;
  6728. if (S_OK != hr)
  6729. {
  6730. CSILOG(
  6731. hr,
  6732. (RD_UNREGISTER & Flags)?
  6733. IDS_LOG_DLLS_UNREGISTERED : IDS_LOG_DLLS_REGISTERED,
  6734. wszString,
  6735. NULL,
  6736. NULL);
  6737. if (0 == (RD_UNREGISTER & Flags))
  6738. {
  6739. CertErrorMessageBox(
  6740. pComp->hInstance,
  6741. pComp->fUnattended,
  6742. hwnd,
  6743. IDS_ERR_DLLFUNCTION_CALL,
  6744. hr,
  6745. wszString);
  6746. _JumpErrorStr(hr, error, "DllRegisterServer", wszString);
  6747. }
  6748. else
  6749. {
  6750. _PrintErrorStr(hr, "DllUnregisterServer", wszString);
  6751. }
  6752. }
  6753. }
  6754. }
  6755. hr = S_OK;
  6756. error:
  6757. if (NULL != hMod)
  6758. {
  6759. FreeLibrary(hMod);
  6760. }
  6761. SetErrorMode(errmode);
  6762. if (fCoInit)
  6763. {
  6764. CoUninitialize();
  6765. }
  6766. if (S_OK == hr)
  6767. {
  6768. CSILOG(
  6769. hr,
  6770. (RD_UNREGISTER & Flags)?
  6771. IDS_LOG_DLLS_UNREGISTERED : IDS_LOG_DLLS_REGISTERED,
  6772. NULL,
  6773. NULL,
  6774. NULL);
  6775. }
  6776. return(hr);
  6777. }
  6778. HRESULT
  6779. CreateProgramGroups(
  6780. BOOL fClient,
  6781. PER_COMPONENT_DATA *pComp,
  6782. HWND hwnd)
  6783. {
  6784. HRESULT hr;
  6785. PROGRAMENTRY const *ppe;
  6786. WCHAR const *pwszLinkName = NULL;
  6787. DWORD Flags = fClient? PE_CLIENT : PE_SERVER;
  6788. DBGPRINT((
  6789. DBG_SS_CERTOCMI,
  6790. "CreateProgramGroups: %ws\n",
  6791. fClient? L"Client" : L"Server"));
  6792. for (ppe = g_aProgramEntry; ppe < &g_aProgramEntry[CPROGRAMENTRY]; ppe++)
  6793. {
  6794. if ((Flags & ppe->Flags) && 0 == (PE_DELETEONLY & ppe->Flags))
  6795. {
  6796. WCHAR const *pwszGroupName;
  6797. WCHAR const *pwszDescription;
  6798. WCHAR awc[MAX_PATH];
  6799. WCHAR const *pwszArgs;
  6800. wcscpy(awc, pComp->pwszSystem32);
  6801. wcscat(awc, ppe->pwszExeName);
  6802. pwszArgs = fClient? ppe->pwszClientArgs : ppe->pwszServerArgs;
  6803. if (NULL != pwszArgs)
  6804. {
  6805. wcscat(awc, L" ");
  6806. wcscat(awc, pwszArgs);
  6807. }
  6808. pwszLinkName = myLoadResourceString(ppe->uiLinkName);
  6809. if (NULL == pwszLinkName)
  6810. {
  6811. hr = myHLastError();
  6812. _JumpError(hr, error, "myLoadResourceString");
  6813. }
  6814. pwszGroupName = NULL;
  6815. if (0 != ppe->uiGroupName)
  6816. {
  6817. pwszGroupName = myLoadResourceString(ppe->uiGroupName);
  6818. if (NULL == pwszGroupName)
  6819. {
  6820. hr = myHLastError();
  6821. _JumpError(hr, error, "myLoadResourceString");
  6822. }
  6823. }
  6824. pwszDescription = NULL;
  6825. if (0 != ppe->uiDescription)
  6826. {
  6827. pwszDescription = myLoadResourceString(ppe->uiDescription);
  6828. if (NULL == pwszDescription)
  6829. {
  6830. hr = myHLastError();
  6831. _JumpError(hr, error, "myLoadResourceString");
  6832. }
  6833. }
  6834. if (!CreateLinkFile(
  6835. ppe->csidl, // CSIDL_*
  6836. pwszGroupName, // IN LPCSTR lpSubDirectory
  6837. pwszLinkName, // IN LPCSTR lpFileName
  6838. awc, // IN LPCSTR lpCommandLine
  6839. NULL, // IN LPCSTR lpIconPath
  6840. 0, // IN INT iIconIndex
  6841. NULL, // IN LPCSTR lpWorkingDirectory
  6842. 0, // IN WORD wHotKey
  6843. SW_SHOWNORMAL, // IN INT iShowCmd
  6844. pwszDescription)) // IN LPCSTR lpDescription
  6845. {
  6846. hr = myHLastError();
  6847. _PrintErrorStr(hr, "CreateLinkFile", awc);
  6848. _JumpErrorStr(hr, error, "CreateLinkFile", pwszLinkName);
  6849. }
  6850. }
  6851. }
  6852. hr = S_OK;
  6853. error:
  6854. if (S_OK != hr)
  6855. {
  6856. CertErrorMessageBox(
  6857. pComp->hInstance,
  6858. pComp->fUnattended,
  6859. hwnd,
  6860. IDS_ERR_CREATELINK,
  6861. hr,
  6862. pwszLinkName);
  6863. pComp->fShownErr = TRUE;
  6864. }
  6865. CSILOG(hr, IDS_LOG_PROGRAM_GROUPS, NULL, NULL, NULL);
  6866. return(hr);
  6867. }
  6868. HRESULT
  6869. MakeRevocationPage(
  6870. PER_COMPONENT_DATA *pComp,
  6871. IN WCHAR const *pwszFile)
  6872. {
  6873. HRESULT hr;
  6874. WCHAR *pwszASP = NULL;
  6875. WCHAR *pwszConfig = NULL;
  6876. HANDLE hFile = NULL;
  6877. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  6878. #define wszASP1 \
  6879. L"<%\r\n" \
  6880. L"Response.ContentType = \"application/x-netscape-revocation\"\r\n" \
  6881. L"serialnumber = Request.QueryString\r\n" \
  6882. L"set Admin = Server.CreateObject(\"CertificateAuthority.Admin\")\r\n" \
  6883. L"\r\n" \
  6884. L"stat = Admin.IsValidCertificate(\""
  6885. #define wszASP2 \
  6886. L"\", serialnumber)\r\n" \
  6887. L"\r\n" \
  6888. L"if stat = 3 then Response.Write(\"0\") else Response.Write(\"1\") end if\r\n" \
  6889. L"%>\r\n"
  6890. hr = myFormConfigString(pComp->pwszServerName,
  6891. pServer->pwszSanitizedName,
  6892. &pwszConfig);
  6893. _JumpIfError(hr, error, "myFormConfigString");
  6894. pwszASP = (WCHAR *) LocalAlloc(
  6895. LMEM_FIXED,
  6896. (WSZARRAYSIZE(wszASP1) +
  6897. wcslen(pwszConfig) +
  6898. WSZARRAYSIZE(wszASP2) + 1) * sizeof(WCHAR));
  6899. _JumpIfOutOfMemory(hr, error, pwszASP);
  6900. wcscpy(pwszASP, wszASP1);
  6901. wcscat(pwszASP, pwszConfig);
  6902. wcscat(pwszASP, wszASP2);
  6903. hFile = CreateFile(
  6904. pwszFile, // lpFileName
  6905. GENERIC_WRITE, // dwDesiredAccess
  6906. 0, // dwShareMode
  6907. NULL, // lpSecurityAttributes
  6908. CREATE_ALWAYS, // dwCreationDisposition
  6909. 0, // dwFlagsAndAttributes
  6910. 0); // hTemplateFile
  6911. if (INVALID_HANDLE_VALUE == hFile)
  6912. {
  6913. hr = HRESULT_FROM_WIN32(ERROR_OPEN_FAILED);
  6914. _JumpError(hr, error, "CreateFile");
  6915. }
  6916. hr = myStringToAnsiFile(hFile, pwszASP, MAXDWORD);
  6917. error:
  6918. if (hFile)
  6919. CloseHandle(hFile);
  6920. if (NULL != pwszASP)
  6921. {
  6922. LocalFree(pwszASP);
  6923. }
  6924. if (NULL != pwszConfig)
  6925. {
  6926. LocalFree(pwszConfig);
  6927. }
  6928. return(hr);
  6929. }
  6930. VOID
  6931. setupDeleteFile(
  6932. IN WCHAR const *pwszDir,
  6933. IN WCHAR const *pwszFile)
  6934. {
  6935. HRESULT hr;
  6936. WCHAR *pwszFilePath = NULL;
  6937. hr = myBuildPathAndExt(pwszDir, pwszFile, NULL, &pwszFilePath);
  6938. _JumpIfError(hr, error, "myBuildPathAndExt");
  6939. if (!DeleteFile(pwszFilePath))
  6940. {
  6941. hr = myHLastError();
  6942. _PrintErrorStr2(hr, "DeleteFile", pwszFilePath, hr);
  6943. }
  6944. error:
  6945. if (NULL != pwszFilePath)
  6946. {
  6947. LocalFree(pwszFilePath);
  6948. }
  6949. }
  6950. //+------------------------------------------------------------------------
  6951. // Function: RenameMiscTargets(. . . .)
  6952. //
  6953. // Synopsis: Handles various renaming jobs from the names that things
  6954. // are given at installation time to the names that they need
  6955. // in their new homes to run properly.
  6956. //
  6957. // Arguments: None
  6958. //
  6959. // Returns: DWORD error code.
  6960. //
  6961. // History: 3/21/97 JerryK Created
  6962. //-------------------------------------------------------------------------
  6963. HRESULT
  6964. RenameMiscTargets(
  6965. HWND hwnd,
  6966. PER_COMPONENT_DATA *pComp,
  6967. BOOL fServer)
  6968. {
  6969. HRESULT hr = S_OK;
  6970. WCHAR wszAspPath[MAX_PATH]; wszAspPath[0] = L'\0';
  6971. WCHAR wszCertSrv[MAX_PATH]; wszCertSrv[0] = L'\0';
  6972. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  6973. if (fServer)
  6974. {
  6975. // Create nsrev_<CA Name>.asp
  6976. BuildPath(
  6977. wszCertSrv,
  6978. ARRAYSIZE(wszCertSrv),
  6979. pComp->pwszSystem32,
  6980. wszCERTENROLLSHAREPATH);
  6981. BuildPath(
  6982. wszAspPath,
  6983. ARRAYSIZE(wszAspPath),
  6984. wszCertSrv,
  6985. L"nsrev_");
  6986. wcscat(wszAspPath, pServer->pwszSanitizedName);
  6987. wcscat(wszAspPath, TEXT(".asp"));
  6988. CSASSERT(wcslen(wszAspPath) < ARRAYSIZE(wszAspPath));
  6989. hr = MakeRevocationPage(pComp, wszAspPath);
  6990. if (S_OK != hr)
  6991. {
  6992. CertErrorMessageBox(
  6993. pComp->hInstance,
  6994. pComp->fUnattended,
  6995. hwnd,
  6996. IDS_ERR_CREATEFILE,
  6997. hr,
  6998. wszAspPath);
  6999. _JumpError(hr, error, "MakeRevocationPage");
  7000. }
  7001. }
  7002. error:
  7003. return(hr);
  7004. }
  7005. HRESULT
  7006. CreateCertificateService(
  7007. PER_COMPONENT_DATA *pComp,
  7008. HWND hwnd)
  7009. {
  7010. HRESULT hr;
  7011. WCHAR const *pwszDisplayName;
  7012. SERVICE_DESCRIPTION sd;
  7013. SC_HANDLE hSCManager = NULL;
  7014. SC_HANDLE hSC = NULL;
  7015. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  7016. if (NULL != pServer->pwszSharedFolder)
  7017. {
  7018. // add entry
  7019. hr = CreateConfigFiles(pServer->pwszSharedFolder, pComp, FALSE);
  7020. if (S_OK != hr)
  7021. {
  7022. CertErrorMessageBox(
  7023. pComp->hInstance,
  7024. pComp->fUnattended,
  7025. hwnd,
  7026. IDS_ERR_CREATECERTSRVFILE,
  7027. hr,
  7028. pServer->pwszSharedFolder);
  7029. _JumpError(hr, error, "CreateConfigFiles");
  7030. }
  7031. }
  7032. if (NULL != g_pwszArgvPath)
  7033. {
  7034. wcscpy(g_wszServicePath, g_pwszArgvPath);
  7035. if (L'\0' != g_wszServicePath[0] &&
  7036. L'\\' != g_wszServicePath[wcslen(g_wszServicePath) - 1])
  7037. {
  7038. wcscat(g_wszServicePath, L"\\");
  7039. }
  7040. }
  7041. else
  7042. {
  7043. wcscpy(g_wszServicePath, pComp->pwszSystem32);
  7044. }
  7045. wcscat(g_wszServicePath, wszCERTSRVEXENAME);
  7046. hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  7047. if (NULL == hSCManager)
  7048. {
  7049. hr = myHLastError();
  7050. _JumpError(hr, error, "OpenSCManager");
  7051. }
  7052. if (NULL == g_pwszNoService)
  7053. {
  7054. pwszDisplayName = myLoadResourceString(IDS_CA_SERVICEDISPLAYNAME);
  7055. if (NULL == pwszDisplayName)
  7056. {
  7057. hr = myHLastError();
  7058. _JumpError(hr, error, "myLoadResourceString");
  7059. }
  7060. sd.lpDescription = const_cast<WCHAR *>(myLoadResourceString(
  7061. IDS_CA_SERVICEDESCRIPTION));
  7062. if (NULL == sd.lpDescription)
  7063. {
  7064. hr = myHLastError();
  7065. _JumpError(hr, error, "myLoadResourceString");
  7066. }
  7067. hSC = CreateService(
  7068. hSCManager, // hSCManager
  7069. wszSERVICE_NAME, // lpServiceName
  7070. pwszDisplayName, // lpDisplayName
  7071. SERVICE_ALL_ACCESS, // dwDesiredAccess
  7072. SERVICE_WIN32_OWN_PROCESS| // dwServiceType
  7073. (pServer->fInteractiveService?
  7074. SERVICE_INTERACTIVE_PROCESS:0),
  7075. SERVICE_AUTO_START, // dwStartType
  7076. SERVICE_ERROR_NORMAL, // dwErrorControl
  7077. g_wszServicePath, // lpBinaryPathName
  7078. NULL, // lpLoadOrderGroup
  7079. NULL, // lplpdwTagId
  7080. NULL, // lpDependencies
  7081. NULL, // lpServiceStartName
  7082. NULL); // lpPassword
  7083. if (NULL == hSC)
  7084. {
  7085. hr = myHLastError();
  7086. if (HRESULT_FROM_WIN32(ERROR_DUPLICATE_SERVICE_NAME) != hr &&
  7087. HRESULT_FROM_WIN32(ERROR_SERVICE_EXISTS) != hr)
  7088. {
  7089. CertErrorMessageBox(
  7090. pComp->hInstance,
  7091. pComp->fUnattended,
  7092. hwnd,
  7093. IDS_ERR_CREATESERVICE,
  7094. hr,
  7095. wszSERVICE_NAME);
  7096. _JumpError(hr, error, "CreateService");
  7097. }
  7098. }
  7099. if (!ChangeServiceConfig2(
  7100. hSC, // hService
  7101. SERVICE_CONFIG_DESCRIPTION, // dwInfoLevel
  7102. (VOID *) &sd)) // lpInfo
  7103. {
  7104. // This error is not critical.
  7105. hr = myHLastError();
  7106. _PrintError(hr, "ChangeServiceConfig2");
  7107. }
  7108. }
  7109. // add event log message DLL (ok, it's really an EXE) as a message source
  7110. hr = myAddLogSourceToRegistry(g_wszServicePath, wszSERVICE_NAME);
  7111. if (S_OK != hr)
  7112. {
  7113. CertErrorMessageBox(
  7114. pComp->hInstance,
  7115. pComp->fUnattended,
  7116. hwnd,
  7117. IDS_ERR_ADDSOURCETOREGISTRY,
  7118. hr,
  7119. NULL);
  7120. _JumpError(hr, error, "AddLogSourceToRegistry");
  7121. }
  7122. error:
  7123. if (NULL != hSC)
  7124. {
  7125. CloseServiceHandle(hSC);
  7126. }
  7127. if (NULL != hSCManager)
  7128. {
  7129. CloseServiceHandle(hSCManager);
  7130. }
  7131. CSILOG(hr, IDS_LOG_CREATE_SERVICE, NULL, NULL, NULL);
  7132. return(hr);
  7133. }
  7134. HRESULT
  7135. DeleteProgramGroups(
  7136. IN BOOL fAll)
  7137. {
  7138. HRESULT hr;
  7139. PROGRAMENTRY const *ppe;
  7140. WCHAR const *pwszLinkName;
  7141. WCHAR const *pwszGroupName;
  7142. for (ppe = g_aProgramEntry; ppe < &g_aProgramEntry[CPROGRAMENTRY]; ppe++)
  7143. {
  7144. if (fAll || (PE_DELETEONLY & ppe->Flags))
  7145. {
  7146. pwszLinkName = myLoadResourceString(ppe->uiLinkName);
  7147. if (NULL == pwszLinkName)
  7148. {
  7149. hr = myHLastError();
  7150. _PrintError(hr, "myLoadResourceString");
  7151. continue;
  7152. }
  7153. pwszGroupName = NULL;
  7154. if (0 != ppe->uiGroupName)
  7155. {
  7156. pwszGroupName = myLoadResourceString(ppe->uiGroupName);
  7157. if (NULL == pwszGroupName)
  7158. {
  7159. hr = myHLastError();
  7160. _PrintError(hr, "myLoadResourceString");
  7161. continue;
  7162. }
  7163. }
  7164. if (!DeleteLinkFile(
  7165. ppe->csidl, // CSIDL_*
  7166. pwszGroupName, // IN LPCSTR lpSubDirectory
  7167. pwszLinkName, // IN LPCSTR lpFileName
  7168. FALSE)) // IN BOOL fDeleteSubDirectory
  7169. {
  7170. hr = myHLastError();
  7171. _PrintError3(
  7172. hr,
  7173. "DeleteLinkFile",
  7174. HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
  7175. HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND));
  7176. }
  7177. }
  7178. }
  7179. pwszGroupName = myLoadResourceString(IDS_STARTMENU_CERTSERVER);
  7180. if (NULL == pwszGroupName)
  7181. {
  7182. hr = myHLastError();
  7183. _PrintError(hr, "myLoadResourceString");
  7184. }
  7185. else if (!DeleteGroup(pwszGroupName, TRUE))
  7186. {
  7187. hr = myHLastError();
  7188. _PrintError(hr, "DeleteGroup");
  7189. }
  7190. hr = S_OK;
  7191. //error:
  7192. return(hr);
  7193. }
  7194. HRESULT
  7195. CancelCertsrvInstallation(
  7196. HWND hwnd,
  7197. PER_COMPONENT_DATA *pComp)
  7198. {
  7199. static BOOL s_fCancelled = FALSE;
  7200. HRESULT hr;
  7201. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  7202. if (s_fCancelled)
  7203. {
  7204. goto done;
  7205. }
  7206. if (IS_SERVER_INSTALL & pComp->dwInstallStatus)
  7207. {
  7208. // uninstall will remove reg entries and others
  7209. PreUninstallCore(hwnd, pComp);
  7210. // Note, GUI mode, we allow re-try post setup in case of cancel or failure
  7211. // but unattended mode, only allow once
  7212. UninstallCore(hwnd, pComp, 0, 0, FALSE, FALSE, !pComp->fUnattended);
  7213. if (pComp->fUnattended)
  7214. {
  7215. hr = SetSetupStatus(
  7216. NULL,
  7217. SETUP_CLIENT_FLAG | SETUP_SERVER_FLAG,
  7218. FALSE);
  7219. }
  7220. }
  7221. if (NULL != pServer)
  7222. {
  7223. if (NULL == pServer->pccExistingCert)
  7224. {
  7225. if (pServer->fSavedCAInDS)
  7226. {
  7227. // remove ca entry from ds
  7228. hr = RemoveCAInDS(pServer->pwszSanitizedName);
  7229. if (S_OK == hr)
  7230. {
  7231. pServer->fSavedCAInDS = FALSE;
  7232. }
  7233. else
  7234. {
  7235. _PrintError(hr, "RemoveCAInDS");
  7236. }
  7237. }
  7238. }
  7239. // delete the new key container, if necessary.
  7240. ClearKeyContainerName(pServer);
  7241. DisableVRootsAndShares(pComp->fCreatedVRoot, pServer->fCreatedShare);
  7242. }
  7243. DBGPRINT((DBG_SS_CERTOCM, "Certsrv setup is cancelled.\n"));
  7244. s_fCancelled = TRUE; // only once
  7245. done:
  7246. hr = S_OK;
  7247. //error:
  7248. CSILOG(hr, IDS_LOG_CANCEL_INSTALL, NULL, NULL, NULL);
  7249. return hr;
  7250. }
  7251. // Returns true if the specified period is valid. For year it
  7252. // should be in the VP_MIN,VP_MAX range. For days/weeks/months,
  7253. // we define a separate upper limit to be consistent with the
  7254. // attended setup which restricts the edit box to 4 digits.
  7255. bool IsValidPeriod(const CASERVERSETUPINFO *pServer)
  7256. {
  7257. return VP_MIN <= pServer->dwValidityPeriodCount &&
  7258. !(ENUM_PERIOD_YEARS == pServer->enumValidityPeriod &&
  7259. VP_MAX < pServer->dwValidityPeriodCount) &&
  7260. !(ENUM_PERIOD_YEARS != pServer->enumValidityPeriod &&
  7261. VP_MAX_DAYS_WEEKS_MONTHS < pServer->dwValidityPeriodCount);
  7262. }