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.

4720 lines
120 KiB

  1. #include <nt.h>
  2. #include <ntrtl.h>
  3. #include <nturtl.h>
  4. #include <windows.h>
  5. #include <ole2.h>
  6. #include <stdio.h>
  7. #include <dsrole.h>
  8. #include <scesetup.h>
  9. #include <iads.h>
  10. #include <adshlp.h>
  11. #include <winldap.h>
  12. #include <oaidl.h>
  13. #include <Adshlp.h>
  14. #include <adserr.h>
  15. #include <Sddl.h>
  16. #include <Aclapi.h>
  17. #include <initguid.h>
  18. #include <Gpedit.h>
  19. #include <atlbase.h>
  20. #include <Ntdsapi.h>
  21. #include <secedit.h>
  22. #include "resource.h"
  23. #include <Lmshare.h>
  24. #include <lm.h>
  25. #include <oleauto.h>
  26. #include <adsopenflags.h>
  27. #include <Dsgetdc.h>
  28. #include <sclgntfy.h>
  29. #include <Wincrypt.h>
  30. #include <strsafe.h>
  31. #define PCOMMON_IMPL
  32. #include "pcommon.h"
  33. #include <locale.h>
  34. #include <winnlsp.h>
  35. #if DBG
  36. #define dbgprint wprintf
  37. #else
  38. #define dbgprint
  39. #endif // DBG
  40. #define DIFF(d) ((ULONG)(d))
  41. #define TARGET_ARG L"/target:"
  42. #define TARGET_ARG_LENGTH (sizeof(TARGET_ARG) - sizeof(WCHAR))
  43. #define TARGET_ARG_COUNT (TARGET_ARG_LENGTH/sizeof(WCHAR))
  44. #define TARGET_ARG_DOMAIN L"domain"
  45. #define TARGET_ARG_DC L"dc"
  46. #define TARGET_ARG_BOTH L"both"
  47. #define TARGET_ARG_IGNORE_SCHEMA L"/ignoreschema"
  48. #define STRING_SD L"D:P(A;CIOI;GRGX;;;AU)(A;CIOI;GRGX;;;SO)(A;CIOI;GA;;;BA)(A;CIOI;GA;;;SY)(A;CIOI;GA;;;CO)(A;CIOI;GRGWGXSD;;;PA)"
  49. #define DDP_USEREXT L"[{3060E8D0-7020-11D2-842D-00C04FA372D4}{3060E8CE-7020-11D2-842D-00C04FA372D4}]"
  50. #define DDP_MACHEXT L"[{35378EAC-683F-11D2-A89A-00C04FBBCFA2}{53D6AB1B-2488-11D1-A28C-00C04FB94F17}][{827D319E-6EAC-11D2-A4EA-00C04F79F83A}{803E14A0-B4FB-11D0-A0D0-00A0C90F574B}][{B1BE8D72-6EAC-11D2-A4EA-00C04F79F83A}{53D6AB1B-2488-11D1-A28C-00C04FB94F17}]"
  51. #define DDC_MACHEXT L"[{827D319E-6EAC-11D2-A4EA-00C04F79F83A}{803E14A0-B4FB-11D0-A0D0-00A0C90F574B}]"
  52. #define DDP_DS_SD L"O:DAG:DAD:P(A;CI;RPWPCCDCLCLOLORCWOWDSDDTSW;;;DA)(A;CI;RPWPCCDCLCLOLORCWOWDSDDTSW;;;EA)(A;CIIO;RPWPCCDCLCLOLORCWOWDSDDTSW;;;CO)(A;CI;RPWPCCDCLCLORCWOWDSDDTSW;;;SY)(A;CI;RPLCLORC;;;AU)(OA;CI;CR;edacfd8f-ffb3-11d1-b41d-00a0c968f939;;AU)(A;CI;LCRPLORC;;;ED)"
  53. #define DDCP_DS_SD L"O:DAG:DAD:P(A;CI;RPWPCCDCLCLOLORCWOWDSDDTSW;;;DA)(A;CI;RPWPCCDCLCLOLORCWOWDSDDTSW;;;EA)(A;CIIO;RPWPCCDCLCLOLORCWOWDSDDTSW;;;CO)(A;CI;RPWPCCDCLCLORCWOWDSDDTSW;;;SY)(A;CI;RPLCLORC;;;AU)(OA;CI;CR;edacfd8f-ffb3-11d1-b41d-00a0c968f939;;AU)(A;CI;LCRPLORC;;;ED)"
  54. #define SCHEMA_VERSION 30
  55. #define MAX_EFS_KEY 255
  56. #define MAX_VERSION_LENGTH 10
  57. #define FILE_GPTINI L"\\gpt.ini"
  58. #define FILE_GPTTMPLINF L"\\MACHINE\\Microsoft\\Windows NT\\SecEdit\\GptTmpl.inf"
  59. // Default Domain Policy need not be localized and can be hard-coded
  60. #define DDP L"Default Domain Policy"
  61. #define DEFAULT_DC_POLICY_NAME L"Default Domain Controllers Policy"
  62. extern "C" {
  63. typedef HRESULT (STDAPICALLTYPE *DLLREGISTERSERVER)(void);
  64. }
  65. typedef enum policyTypeTag{
  66. DEFAULT_DOMAIN_POLICY, DEFAULT_DOMAIN_CONTROLLER_POLICY
  67. } POLICYTYPE;
  68. #define DOMAIN_GUID L"{31B2F340-016D-11D2-945F-00C04FB984F9}"
  69. #define DC_GUID L"{6AC1786C-016F-11D2-945F-00C04FB984F9}"
  70. struct GLOBALS {
  71. WCHAR* Banner1;
  72. WCHAR* Banner2;
  73. WCHAR* ErrorNotAdmin;
  74. WCHAR* ErrorNoAD;
  75. WCHAR* ErrorContinue;
  76. WCHAR* ErrorBadSysVol;
  77. WCHAR* DispDDP;
  78. WCHAR* DispDDCP;
  79. WCHAR* DispBoth;
  80. WCHAR* ToolFailed;
  81. WCHAR* CreateEFS;
  82. WCHAR* DirCreate;
  83. WCHAR* DirDelete;
  84. WCHAR* InvalidEFS;
  85. WCHAR* DSDelete;
  86. WCHAR* DSAttrib;
  87. WCHAR* DSLinkDO;
  88. WCHAR* DSLinkDDP;
  89. WCHAR* DirRead;
  90. WCHAR* DirWrite;
  91. WCHAR* DDPSuccess;
  92. WCHAR* DDCPSuccess;
  93. WCHAR* WarnURA;
  94. WCHAR* IgnSchSwitch;
  95. WCHAR* GenDSErr;
  96. WCHAR* DSCreate;
  97. WCHAR* EFSAccessDenied;
  98. WCHAR* WrongSchema;
  99. WCHAR* TargetSwitch;
  100. WCHAR* CharYes;
  101. WCHAR* RestoreIgnoredGPOFail;
  102. WCHAR SysVolPath[MAX_PATH];
  103. WCHAR *DomainNamingContext;
  104. LONG lDDCPVersionNo;
  105. LONG lDDPVersionNo;
  106. LPGROUPPOLICYOBJECT pGPO;
  107. SECURITY_DESCRIPTOR *pDDPSecDesc;
  108. SECURITY_DESCRIPTOR *pDDCPSecDesc;
  109. DSROLE_PRIMARY_DOMAIN_INFO_BASIC * pDomainInfo;
  110. BOOL hasEFSInfo;
  111. BOOL bIgnoreSchema;
  112. enum {
  113. RESTORE_DOMAIN = 1 ,
  114. RESTORE_DC = 2,
  115. RESTORE_BOTH = 3
  116. } RestoreType;
  117. HRESULT Init();
  118. GLOBALS();
  119. ~GLOBALS();
  120. };
  121. class CGPOFile
  122. {
  123. public:
  124. CGPOFile( WCHAR* wszGPOPath );
  125. ~CGPOFile();
  126. DWORD
  127. Backup();
  128. DWORD
  129. Restore();
  130. WCHAR*
  131. GetPath();
  132. private:
  133. WCHAR* _wszFullPath;
  134. BYTE* _pFileData;
  135. DWORD _cbFileSize;
  136. };
  137. class CIgnoredGPO
  138. {
  139. public:
  140. CIgnoredGPO(
  141. WCHAR* wszGPOId,
  142. WCHAR* wszGPOName );
  143. ~CIgnoredGPO();
  144. DWORD
  145. Backup();
  146. DWORD
  147. Restore();
  148. private:
  149. DWORD
  150. InitializeErrorText(
  151. WCHAR* wszGPOName );
  152. CGPOFile* _pGptIniFile;
  153. CGPOFile* _pGptTmplFile;
  154. WCHAR* _wszError;
  155. };
  156. GLOBALS _global;
  157. GLOBALS * global = &_global;
  158. HRESULT
  159. IsDomainController (
  160. OUT BOOL *pDomainController
  161. );
  162. HRESULT
  163. _LoadString (
  164. OUT WCHAR*& pwsz,
  165. IN UINT nID
  166. );
  167. void
  168. PrintError(
  169. DWORD pwzError
  170. );
  171. void
  172. PrintError(
  173. WCHAR *lpStr1,
  174. WCHAR *lpStr2
  175. );
  176. void
  177. DisplayError(
  178. WCHAR *pwzError
  179. );
  180. extern "C" DWORD SetSysvolSecurityFromDSSecurity(
  181. LPTSTR lpFileSysPath,
  182. SECURITY_INFORMATION si,
  183. PSECURITY_DESCRIPTOR pSD
  184. );
  185. BOOL
  186. FilePresent(WCHAR *szFileName)
  187. {
  188. FILE *fPtr = NULL;
  189. fPtr = _wfopen(szFileName, L"r");
  190. if (NULL == fPtr)
  191. {
  192. return FALSE;
  193. }
  194. fclose(fPtr);
  195. return TRUE;
  196. }
  197. HRESULT GetDomainFQDN(LPWSTR szDomainDNSName,
  198. LPWSTR *pszDomainFQDN)
  199. /*++
  200. Routine Description:
  201. This function gets the domain FQDN given the dns domain name
  202. Arguments:
  203. [in] szDomainDNSName - DNS Domain Name
  204. [out] pszDomainFQDN - Domain FQDN
  205. Memory need to be freed for pszDomainFQDN using LocalFree.
  206. Return Value:
  207. S_OK on success. Corresponding error codes on failures
  208. --*/
  209. {
  210. HRESULT hr;
  211. LPWSTR pDomainNames[1];
  212. LPWSTR szDNSDomain = NULL;
  213. DWORD dwErr;
  214. DS_NAME_RESULT *pDSNameResult = NULL;
  215. LPWSTR szDomainFQDN = NULL;
  216. ULONG ulSize;
  217. //
  218. // ALlocate a buffer to add in a '/' at the end
  219. // szDomainDNSName + '/' + '\0';
  220. //
  221. ulSize = lstrlen(szDomainDNSName) + 1 + 1;
  222. szDNSDomain = (LPWSTR)LocalAlloc(LPTR, sizeof(WCHAR)*ulSize);
  223. if (!szDNSDomain)
  224. {
  225. hr = E_OUTOFMEMORY;
  226. goto end;
  227. }
  228. hr = StringCchPrintf(szDNSDomain, ulSize, L"%s/", szDomainDNSName);
  229. if (FAILED(hr))
  230. {
  231. goto end;
  232. }
  233. pDomainNames[0] = szDNSDomain;
  234. //
  235. // Call DsCrackNames to convert
  236. //
  237. dwErr = DsCrackNames(NULL, DS_NAME_FLAG_SYNTACTICAL_ONLY,
  238. DS_CANONICAL_NAME, DS_FQDN_1779_NAME,
  239. 1, pDomainNames, &pDSNameResult);
  240. if ( (dwErr != DS_NAME_NO_ERROR) || (!pDSNameResult) || (pDSNameResult->cItems != 1))
  241. {
  242. if ( (!pDSNameResult) || (pDSNameResult->cItems != 1) )
  243. {
  244. //
  245. // We don't expect this to happen at all
  246. //
  247. dbgprint(L"GetDomainDN: DsCrackNames failed with error 0x%x", E_UNEXPECTED);
  248. hr = E_UNEXPECTED;
  249. goto end;
  250. }
  251. else
  252. {
  253. dbgprint(L"GetDomainDN: DsCrackNames failed with error %d", dwErr);
  254. hr = HRESULT_FROM_WIN32(dwErr);
  255. goto end;
  256. }
  257. }
  258. if (pDSNameResult->rItems[0].status != DS_NAME_NO_ERROR)
  259. {
  260. dwErr = pDSNameResult->rItems[0].status;
  261. dbgprint(L"GetDomainDN: DsCrackNames failed with error %d", dwErr);
  262. hr = HRESULT_FROM_WIN32(dwErr);
  263. goto end;
  264. }
  265. //
  266. // We have a valid FQDN. allocate and copy
  267. // pDSNameResult->rItems[0].pName + '\0'
  268. //
  269. ulSize = lstrlen(pDSNameResult->rItems[0].pName) + 1;
  270. szDomainFQDN = (LPWSTR)LocalAlloc(LPTR, sizeof(WCHAR) * ulSize);
  271. if (!szDomainFQDN)
  272. {
  273. DsFreeNameResult(pDSNameResult);
  274. hr = E_OUTOFMEMORY;
  275. goto end;
  276. }
  277. hr = StringCchCopy(szDomainFQDN, ulSize, pDSNameResult->rItems[0].pName);
  278. if (FAILED(hr))
  279. {
  280. DsFreeNameResult(pDSNameResult);
  281. goto end;
  282. }
  283. dbgprint(L"GetDomainDN: Domain FQDN of domain %s = %s\n", szDomainDNSName, szDomainFQDN);
  284. DsFreeNameResult(pDSNameResult);
  285. *pszDomainFQDN = szDomainFQDN;
  286. hr = S_OK;
  287. end:
  288. if (NULL != szDNSDomain)
  289. {
  290. LocalFree(szDNSDomain);
  291. }
  292. return hr;
  293. }
  294. HRESULT
  295. SetObjectSecurityDescriptor(
  296. LPWSTR szObjectPath,
  297. SE_OBJECT_TYPE seObjectType,
  298. SECURITY_DESCRIPTOR *pSecurityDescriptor)
  299. /*++
  300. Routine Description:
  301. This ia thin wrapper around GetNamedSecurityInfo
  302. returns it (in self-relative format). A new buffer is LocalAlloced for this
  303. security descriptor. The caller is responsible for LocalFreeing it.
  304. Arguments:
  305. [in] szObjectPath - Path to the object.
  306. [in] seObjectType - Type of the object
  307. [in] pSecurityDescriptor - Receives a pointer to the security descriptor.
  308. Return Value:
  309. S_OK on success.
  310. On failure the corresponding error code will be returned.
  311. Any API calls that are made in this function might fail and these error
  312. codes will be returned directly.
  313. --*/
  314. {
  315. HRESULT hr = S_OK;
  316. DWORD dwErr;
  317. PACL pDacl = NULL;
  318. BOOL bDaclPresent;
  319. BOOL bDaclDefaulted;
  320. PACL pSacl = NULL;
  321. BOOL bSaclPresent;
  322. BOOL bSaclDefaulted;
  323. PSID pSidGroup;
  324. BOOL bGroupDefaulted;
  325. PSID pSidOwner;
  326. BOOL bOwnerDefaulted;
  327. if (!GetSecurityDescriptorDacl(pSecurityDescriptor, &bDaclPresent, &pDacl, &bDaclDefaulted))
  328. {
  329. hr = HRESULT_FROM_WIN32(GetLastError());
  330. dbgprint(L"GetSecurityDescriptorDacl failed with 0x%x.", hr);
  331. return hr;
  332. }
  333. if (!GetSecurityDescriptorSacl(pSecurityDescriptor, &bSaclPresent, &pSacl, &bSaclDefaulted))
  334. {
  335. hr = HRESULT_FROM_WIN32(GetLastError());
  336. dbgprint(L"GetSecurityDescriptorSacl failed with 0x%x.", hr);
  337. return hr;
  338. }
  339. if (!GetSecurityDescriptorGroup(pSecurityDescriptor, &pSidGroup, &bGroupDefaulted))
  340. {
  341. hr = HRESULT_FROM_WIN32(GetLastError());
  342. dbgprint( L"GetSecurityDescriptorGroup failed with 0x%x.", hr);
  343. return hr;
  344. }
  345. if (!GetSecurityDescriptorOwner(pSecurityDescriptor, &pSidOwner, &bOwnerDefaulted))
  346. {
  347. hr = HRESULT_FROM_WIN32(GetLastError());
  348. dbgprint(L"GetSecurityDescriptorOwner failed with 0x%x.", hr);
  349. return hr;
  350. }
  351. dwErr = SetNamedSecurityInfo(szObjectPath,
  352. seObjectType,
  353. DACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
  354. pSidOwner,
  355. pSidGroup,
  356. pDacl,
  357. pSacl
  358. );
  359. if (dwErr != ERROR_SUCCESS)
  360. {
  361. hr = HRESULT_FROM_WIN32(dwErr);
  362. dbgprint(L"SetNamedSecurityInfo for %s failed with 0x%x.", szObjectPath, hr);
  363. return hr;
  364. }
  365. return S_OK;
  366. }
  367. HRESULT SetDSSecurityDescriptor (
  368. POLICYTYPE pType
  369. )
  370. {
  371. WCHAR *szDsObjectName = NULL;
  372. ULONG uSDSize;
  373. BOOL bError;
  374. HRESULT hr;
  375. SECURITY_DESCRIPTOR *pSD;
  376. ULONG ulSize;
  377. ulSize = lstrlen(L"LDAP://CN=%s,CN=Policies,CN=System,%s") + lstrlen(DOMAIN_GUID) + lstrlen(global->DomainNamingContext) + 1 ;
  378. szDsObjectName = (WCHAR *) LocalAlloc( LPTR, sizeof(WCHAR) * ulSize);
  379. if( NULL == szDsObjectName )
  380. {
  381. return E_OUTOFMEMORY;
  382. }
  383. if (DEFAULT_DOMAIN_POLICY == pType)
  384. {
  385. hr = StringCchPrintf( szDsObjectName,
  386. ulSize,
  387. L"CN=%s,CN=Policies,CN=System,%s",
  388. DOMAIN_GUID,
  389. global->DomainNamingContext) ;
  390. if (FAILED(hr))
  391. {
  392. PrintError(hr);
  393. goto end;
  394. }
  395. // Convert the string to a security descriptor
  396. bError = ConvertStringSecurityDescriptorToSecurityDescriptor (DDP_DS_SD ,
  397. SDDL_REVISION_1,
  398. (PSECURITY_DESCRIPTOR *) &pSD,
  399. &uSDSize) ;
  400. global->pDDPSecDesc = pSD;
  401. }
  402. else
  403. {
  404. hr = StringCchPrintf( szDsObjectName,
  405. ulSize,
  406. L"CN=%s,CN=Policies,CN=System,%s",
  407. DC_GUID,
  408. global->DomainNamingContext) ;
  409. if (FAILED(hr))
  410. {
  411. PrintError(hr);
  412. goto end;
  413. }
  414. // Convert the string to a security descriptor
  415. bError = ConvertStringSecurityDescriptorToSecurityDescriptor (DDCP_DS_SD ,
  416. SDDL_REVISION_1,
  417. (PSECURITY_DESCRIPTOR *) &pSD,
  418. &uSDSize) ;
  419. global->pDDCPSecDesc = pSD;
  420. }
  421. if ( bError != TRUE)
  422. {
  423. hr = HRESULT_FROM_WIN32(GetLastError());
  424. dbgprint(L"ConvertStringSecurityDescriptorToSecurityDescriptor failed 0x%x", hr);
  425. PrintError(szDsObjectName,global->DSAttrib);
  426. goto end;
  427. }
  428. // then set it to corresponding value
  429. hr = SetObjectSecurityDescriptor(szDsObjectName,
  430. SE_DS_OBJECT,
  431. pSD);
  432. if (FAILED(hr))
  433. {
  434. dbgprint(L"SetDSSecurityDescriptor: SetObjectSecurityDescriptor failed with %x\n", hr);
  435. PrintError(szDsObjectName,global->DSAttrib);
  436. PrintError(hr);
  437. goto end;
  438. }
  439. hr = S_OK;
  440. end:
  441. if (NULL != szDsObjectName)
  442. {
  443. LocalFree(szDsObjectName);
  444. }
  445. return hr;
  446. }
  447. //
  448. // Gets the version number present in the file / DS
  449. //
  450. HRESULT GetVersionNumber (
  451. POLICYTYPE polType)
  452. {
  453. WCHAR *szFileOrDSName = NULL;
  454. ULONG uLength;
  455. WCHAR szBuffer[MAX_VERSION_LENGTH];
  456. LONG lVersionNo = 0;
  457. WORD wUserVersionNo;
  458. WORD wMachineVersionNo;
  459. DWORD dwRetVal;
  460. DWORD dwError;
  461. HRESULT hr;
  462. CComPtr<IADs> pADs;
  463. CComVariant Var;
  464. CComBSTR VersionNumber(L"VersionNumber");
  465. if ( ! VersionNumber )
  466. {
  467. return E_OUTOFMEMORY;
  468. }
  469. //
  470. // Length of the allocated buffer is more than required, since it is the sum of the file path and ds path
  471. //
  472. uLength = lstrlen(global->SysVolPath)+ lstrlen(global->pDomainInfo->DomainNameDns) + lstrlen(DOMAIN_GUID) + lstrlen(L"\\policies") + lstrlen(FILE_GPTINI) +
  473. lstrlen( L"LDAP://CN=%s,CN=Policies,CN=System,%s") + lstrlen( DOMAIN_GUID) + lstrlen(global->DomainNamingContext) + 1;
  474. szFileOrDSName = ( WCHAR *) LocalAlloc(LPTR, sizeof(WCHAR) * uLength);
  475. if(NULL == szFileOrDSName)
  476. {
  477. hr = E_OUTOFMEMORY;
  478. goto end;
  479. }
  480. hr = StringCchPrintf(szFileOrDSName,
  481. uLength,
  482. L"%s\\%s\\Policies\\%s" FILE_GPTINI,
  483. global->SysVolPath,
  484. global->pDomainInfo->DomainNameDns,
  485. ( DEFAULT_DOMAIN_POLICY == polType ) ? DOMAIN_GUID : DC_GUID);
  486. if (FAILED(hr))
  487. {
  488. PrintError(hr);
  489. goto end;
  490. }
  491. //
  492. // Get the version number from the sysvol directory
  493. //
  494. dwRetVal = GetPrivateProfileString ( L"General",
  495. L"Version",
  496. L"-1",
  497. szBuffer,
  498. MAX_VERSION_LENGTH,
  499. szFileOrDSName);
  500. if( dwRetVal > 0 )
  501. {
  502. //
  503. // The casewhere szBuffer has a negetive number will be
  504. // taken care of inside the for loop
  505. //
  506. for(int i = 0; szBuffer[i] != L'\0' && i < MAX_VERSION_LENGTH ; i++)
  507. {
  508. if (!isdigit(szBuffer[i]))
  509. {
  510. lVersionNo = 0;
  511. break;
  512. }
  513. lVersionNo *= 10;
  514. lVersionNo += szBuffer[i] - L'0';
  515. }
  516. if ( MAX_VERSION_LENGTH == i )
  517. {
  518. lVersionNo = 0;
  519. }
  520. }
  521. else
  522. {
  523. dwError = GetLastError();
  524. if ( ERROR_ACCESS_DENIED == dwError )
  525. {
  526. dbgprint(L"GetVersonNumber:GetPrivateProfileString failed with error %x\n, dwError");
  527. PrintError(szFileOrDSName, global->DirRead);
  528. hr = HRESULT_FROM_WIN32(dwError);
  529. goto end;
  530. }
  531. else if (dwError != ERROR_FILE_NOT_FOUND && dwError != ERROR_PATH_NOT_FOUND)
  532. {
  533. //
  534. // If dwError is either ERROR_FILE_NOT_FOUND or ERROR_PATH_NOT_FOUND,
  535. // lVersionNo will have its initialized value
  536. //
  537. dbgprint(L"GetVersonNumber:GetPrivateProfileString failed with error %x\n, dwError");
  538. PrintError(dwError);
  539. hr = HRESULT_FROM_WIN32(dwError);
  540. goto end;
  541. }
  542. }
  543. wUserVersionNo = HIWORD(lVersionNo);
  544. wMachineVersionNo = LOWORD(lVersionNo);
  545. //
  546. // Get the version number from the DS
  547. //
  548. hr = StringCchPrintf( szFileOrDSName,
  549. uLength,
  550. L"LDAP://CN=%s,CN=Policies,CN=System,%s",
  551. ( DEFAULT_DOMAIN_POLICY == polType ) ? DOMAIN_GUID : DC_GUID,
  552. global->DomainNamingContext) ;
  553. if (FAILED(hr))
  554. {
  555. PrintError(hr);
  556. goto end;
  557. }
  558. hr = AdminToolsOpenObject(szFileOrDSName, NULL, NULL, ADS_SECURE_AUTHENTICATION | ADS_SERVER_BIND, IID_IADs, (void**)&pADs);
  559. if ( SUCCEEDED(hr) )
  560. {
  561. hr = pADs->GetInfo();
  562. if ( SUCCEEDED(hr) )
  563. {
  564. Var.Clear();
  565. hr = pADs->Get(VersionNumber, &Var);
  566. if(SUCCEEDED(hr))
  567. {
  568. lVersionNo = Var.lVal;
  569. }
  570. else
  571. {
  572. lVersionNo = 0;
  573. }
  574. }
  575. else
  576. {
  577. dbgprint(L"AdminToolsOpenObject Failed with error %x\n", hr);
  578. PrintError(hr);
  579. goto end;
  580. }
  581. }
  582. else if ( hr != (HRESULT_FROM_WIN32(ERROR_DS_NO_SUCH_OBJECT)))
  583. {
  584. dbgprint(L"AdminToolsOpenObject failed %x on %s\n", hr, szFileOrDSName);
  585. PrintError(szFileOrDSName, global->GenDSErr);
  586. goto end;
  587. }
  588. else
  589. {
  590. lVersionNo = 0;
  591. }
  592. wUserVersionNo = max( wUserVersionNo, HIWORD(lVersionNo)) + 1;
  593. wMachineVersionNo = max( wMachineVersionNo, LOWORD(lVersionNo)) + 1;
  594. lVersionNo = (((LONG) wUserVersionNo) << 16) + wMachineVersionNo;
  595. if (DEFAULT_DOMAIN_POLICY == polType)
  596. {
  597. global->lDDPVersionNo = lVersionNo;
  598. }
  599. else
  600. {
  601. global->lDDCPVersionNo = lVersionNo;
  602. }
  603. hr = S_OK;
  604. end:
  605. LocalFree(szFileOrDSName);
  606. return hr;
  607. }
  608. //
  609. // Gives a pointer to beginnening of the last the substring that
  610. // does not contain a '/'
  611. //
  612. LPWSTR CheckSlash (LPWSTR lpDir)
  613. {
  614. LPWSTR lpEnd;
  615. lpEnd = lpDir + lstrlen(lpDir);
  616. if ( lpDir != lpEnd && *(lpEnd - 1) != L'\\')
  617. {
  618. *lpEnd = L'\\';
  619. lpEnd++;
  620. *lpEnd = L'\0';
  621. }
  622. return lpEnd;
  623. }
  624. //********************************************************************************************
  625. //
  626. // RegDelnodeExceptEFS()
  627. //
  628. // Deletes a registry key and all it's subkeys / values except EFS Certificates
  629. //
  630. // hKeyRoot - Root key
  631. // bEFSFound - Indicates whether EFS keys were found
  632. //
  633. //*********************************************************************************************
  634. HRESULT
  635. RegDelnodeExceptEFS(
  636. IN HKEY hKeyRoot,
  637. OUT BOOL & bEFSFound
  638. )
  639. {
  640. LONG Status;
  641. HKEY hSubKey;
  642. DWORD MaxCchSubKey = 0;
  643. DWORD EnumIndex;
  644. PWCHAR pwszEnumKeyName;
  645. WCHAR wszSubKey[72]; // enough to hold a path consisting of the following parts
  646. PWCHAR apwszSubKeyNames[] = { L"Software", L"Policies", L"Microsoft", L"SystemCertificates", L"EFS" };
  647. bEFSFound = FALSE;
  648. wszSubKey[0] = 0;
  649. for (DWORD SubKeyIndex = 0; SubKeyIndex < sizeof(apwszSubKeyNames)/sizeof(apwszSubKeyNames[0]); SubKeyIndex++ )
  650. {
  651. hSubKey = 0;
  652. pwszEnumKeyName = 0;
  653. Status = RegOpenKeyEx( hKeyRoot, wszSubKey, 0, KEY_ALL_ACCESS, &hSubKey );
  654. if ( ERROR_SUCCESS == Status )
  655. {
  656. Status = RegQueryInfoKey( hSubKey, 0, 0, 0, 0, &MaxCchSubKey, 0, 0, 0, 0, 0, 0 );
  657. MaxCchSubKey++;
  658. }
  659. if ( ERROR_SUCCESS == Status )
  660. {
  661. pwszEnumKeyName = new WCHAR[MaxCchSubKey];
  662. if ( ! pwszEnumKeyName )
  663. Status = ERROR_OUTOFMEMORY;
  664. }
  665. for (EnumIndex = 0; ERROR_SUCCESS == Status;)
  666. {
  667. DWORD CchSubKey;
  668. CchSubKey = MaxCchSubKey;
  669. Status = RegEnumKeyEx(
  670. hSubKey,
  671. EnumIndex,
  672. pwszEnumKeyName,
  673. &CchSubKey,
  674. NULL,
  675. NULL,
  676. NULL,
  677. NULL );
  678. if ( ERROR_SUCCESS == Status )
  679. {
  680. if ( CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, apwszSubKeyNames[SubKeyIndex], -1, pwszEnumKeyName, -1) == CSTR_EQUAL )
  681. {
  682. EnumIndex++;
  683. continue;
  684. }
  685. Status = RegDelnode( hSubKey, pwszEnumKeyName );
  686. }
  687. }
  688. if ( hSubKey )
  689. RegCloseKey( hSubKey );
  690. if ( pwszEnumKeyName )
  691. delete [] pwszEnumKeyName;
  692. if ( ERROR_NO_MORE_ITEMS == Status )
  693. Status = ERROR_SUCCESS;
  694. if ( Status != ERROR_SUCCESS )
  695. break;
  696. StringCbCat( wszSubKey, sizeof(wszSubKey), apwszSubKeyNames[SubKeyIndex] );
  697. StringCbCat( wszSubKey, sizeof(wszSubKey), L"\\" );
  698. }
  699. if ( Status != ERROR_SUCCESS )
  700. return HRESULT_FROM_WIN32(Status);
  701. if ( EnumIndex != 0 )
  702. {
  703. bEFSFound = TRUE;
  704. }
  705. else
  706. {
  707. RegDelnode( hKeyRoot, L"Software" );
  708. }
  709. return S_OK;
  710. }
  711. HRESULT SetPolicySecurityInfo (LPTSTR lpFileSysPath)
  712. {
  713. PACL pDacl = NULL;
  714. BOOL bAclPresent, bDefaulted;
  715. DWORD dwError = ERROR_SUCCESS;
  716. PSECURITY_DESCRIPTOR pSD = NULL;
  717. ULONG uSize;
  718. SECURITY_INFORMATION si = (DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION);
  719. if ( !ConvertStringSecurityDescriptorToSecurityDescriptorW(STRING_SD,SDDL_REVISION_1, &pSD, &uSize) )
  720. {
  721. dwError = GetLastError();
  722. dbgprint(L"SetPolicySecurityInfo: ConvertStringSecurityDescriptorToSecurityDescriptor failed with %d", dwError);
  723. goto end;
  724. }
  725. //
  726. // Get the DACL
  727. //
  728. if (!GetSecurityDescriptorDacl (pSD, &bAclPresent, &pDacl, &bDefaulted))
  729. {
  730. dwError = GetLastError();
  731. dbgprint(L"SetPolicySecurityInfo: GetSecurityDescriptorDacl failed with %d", dwError);
  732. goto end;
  733. }
  734. //
  735. // Set the access control information for the file system portion
  736. //
  737. dwError = SetNamedSecurityInfo(lpFileSysPath, SE_FILE_OBJECT, si, NULL, NULL, pDacl, NULL);
  738. end:
  739. if (pSD != NULL)
  740. {
  741. LocalFree(pSD);
  742. }
  743. if( dwError != ERROR_SUCCESS)
  744. {
  745. PrintError(dwError);
  746. }
  747. return HRESULT_FROM_WIN32(dwError);
  748. }
  749. HRESULT DeleteContainerFromDS(WCHAR *szContainerName, IADsContainer *pADsContainer)
  750. {
  751. HRESULT hr;
  752. CComPtr<IEnumVARIANT> pEnumVariant;
  753. CComPtr<IUnknown> pUnknown;
  754. VARIANT var;
  755. CComPtr<IDispatch> pDisp;
  756. CComPtr<IADsDeleteOps> pADsDeleteOps;
  757. ULONG uNoEleReturned;
  758. hr = pADsContainer->get__NewEnum( &pUnknown);
  759. if (FAILED(hr))
  760. {
  761. dbgprint(L"dbg: get_NewEnum failed with error %x on %s", hr, szContainerName);
  762. goto end;
  763. }
  764. hr = pUnknown->QueryInterface(IID_IEnumVARIANT, (void **) &pEnumVariant);
  765. if (FAILED(hr))
  766. {
  767. dbgprint(L"dbg: QueryInterface failed with error %x in function DeleteContainerFromDS", hr);
  768. goto end;
  769. }
  770. while(TRUE)
  771. {
  772. hr = pEnumVariant->Next( 1, &var, &uNoEleReturned);
  773. if ( FAILED(hr) )
  774. {
  775. dbgprint(L"dbg: Call to Next failed with error %x", hr);
  776. goto end;
  777. }
  778. else if (0 == uNoEleReturned)
  779. {
  780. break;
  781. }
  782. pDisp = V_DISPATCH( &var );
  783. hr = pDisp->QueryInterface(IID_IADsDeleteOps, (void **) &pADsDeleteOps);
  784. if (FAILED(hr))
  785. {
  786. dbgprint(L"dbg: Could not fetch pointer to interface IID_IADsDeleteOps in function DeleteContainerFromDS- error %x", hr);
  787. goto end;
  788. }
  789. hr = pADsDeleteOps->DeleteObject(0);
  790. if (FAILED(hr))
  791. {
  792. dbgprint(L"dbg: DeleteObject failed with error %x in function DeleteContainerFromDS", hr);
  793. goto end;
  794. }
  795. }
  796. end:
  797. return hr;
  798. }
  799. HRESULT ResetContainerFromDS (
  800. WCHAR *szContainerName,
  801. IADs *pADsParent
  802. )
  803. {
  804. HRESULT hr;
  805. CComPtr<IADsContainer> pADsContainer;
  806. hr = AdminToolsOpenObject(szContainerName, NULL, NULL, ADS_SECURE_AUTHENTICATION | ADS_SERVER_BIND, IID_IADsContainer, (void**)&pADsContainer);
  807. if ( FAILED(hr) )
  808. {
  809. CComBSTR GroupPolicyContainerName(L"groupPolicyContainer");
  810. if ( ! GroupPolicyContainerName )
  811. {
  812. hr = E_OUTOFMEMORY;
  813. PrintError(hr);
  814. goto end;
  815. }
  816. if (E_ADS_BAD_PATHNAME == hr)
  817. {
  818. CComPtr<IDispatch> pDisp;
  819. CComPtr<IADs> pADs;
  820. hr = pADsParent->QueryInterface(IID_IADsContainer, (void **) &pADsContainer);
  821. if (FAILED(hr))
  822. {
  823. dbgprint(L"dbg: Create failed with %x on parent %s\n", hr, szContainerName);
  824. PrintError(szContainerName, global->DSCreate);
  825. goto end;
  826. }
  827. CComBSTR ContainerNameString(szContainerName);
  828. if ( ! ContainerNameString )
  829. {
  830. hr = E_OUTOFMEMORY;
  831. dbgprint(L"dbg: Create failed %x on %s\n", hr, szContainerName);
  832. PrintError(szContainerName, global->DSCreate);
  833. goto end;
  834. }
  835. hr = pADsContainer->Create(GroupPolicyContainerName, ContainerNameString, &pDisp);
  836. if (FAILED(hr))
  837. {
  838. dbgprint(L"dbg: Create failed %x on %s\n", hr, szContainerName);
  839. PrintError(szContainerName, global->DSCreate);
  840. goto end;
  841. }
  842. hr = pDisp->QueryInterface(IID_IADs, (void**)&pADs);
  843. if (FAILED(hr))
  844. {
  845. dbgprint(L"dbg: Query Interface failed %x for Creating IID_IADS\n", hr);
  846. PrintError(szContainerName, global->DSCreate);
  847. goto end;
  848. }
  849. hr = pADs->SetInfo();
  850. if (FAILED(hr))
  851. {
  852. dbgprint(L"SetInfo returned error %x on %s", hr, szContainerName);
  853. PrintError(szContainerName, global->DSCreate);
  854. goto end;
  855. }
  856. }
  857. else
  858. {
  859. dbgprint(L"AdminToolsOpenObject returned error %x on %s", hr, szContainerName);
  860. PrintError(szContainerName, global->GenDSErr);
  861. goto end;
  862. }
  863. }
  864. else
  865. {
  866. hr = DeleteContainerFromDS(szContainerName, pADsContainer);
  867. if( FAILED(hr))
  868. {
  869. dbgprint(L"DeleteContainerFromDS returned error %x on %s", hr, szContainerName);
  870. PrintError(szContainerName, global->DSDelete);
  871. goto end;
  872. }
  873. }
  874. end:
  875. return hr;
  876. }
  877. HRESULT
  878. IsDomainController(
  879. OUT BOOL *pDomainController
  880. )
  881. {
  882. DWORD dwError;
  883. dwError = DsRoleGetPrimaryDomainInformation( NULL, DsRolePrimaryDomainInfoBasic, (PBYTE *)&global->pDomainInfo );
  884. if (dwError != ERROR_SUCCESS)
  885. {
  886. dbgprint(L"IsDomainController: DsRoleGetPrimaryDomainInformationfailed");
  887. PrintError(dwError);
  888. return( HRESULT_FROM_WIN32(dwError) );
  889. }
  890. if ((global->pDomainInfo->MachineRole == DsRole_RoleBackupDomainController ||
  891. global->pDomainInfo->MachineRole == DsRole_RolePrimaryDomainController) &&
  892. (global->pDomainInfo->Flags & DSROLE_PRIMARY_DS_RUNNING) != 0)
  893. {
  894. *pDomainController = TRUE;
  895. }
  896. else
  897. {
  898. *pDomainController = FALSE;
  899. }
  900. return S_OK;
  901. } // IsDomainController
  902. HRESULT
  903. LookupMembership (
  904. WCHAR *Name,
  905. OUT BOOL *pAdmin
  906. )
  907. {
  908. #define MAX_SID_LENGTH (1024*4)
  909. DWORD dwError;
  910. BOOL bError;
  911. PSID pSid = NULL;
  912. // Initialize the out parameter
  913. *pAdmin = FALSE;
  914. // Get the sid of the domain admin / enterprise admin group.
  915. bError = ConvertStringSidToSid(Name, &pSid);
  916. if (FALSE == bError || NULL == pSid)
  917. {
  918. dwError = GetLastError();
  919. dbgprint(L"LookupMembership: ConvertStringSidToSid failed");
  920. goto end;
  921. }
  922. // check to see if that SID is in our current SD (aka user)
  923. bError = CheckTokenMembership(NULL, pSid, pAdmin);
  924. if (bError == FALSE)
  925. {
  926. dwError = GetLastError();
  927. goto end;
  928. }
  929. dwError = ERROR_SUCCESS;
  930. end:
  931. if (pSid != NULL)
  932. {
  933. LocalFree(pSid);
  934. }
  935. if( dwError != ERROR_SUCCESS)
  936. {
  937. PrintError(dwError);
  938. }
  939. return HRESULT_FROM_WIN32(dwError) ;
  940. } // LookupMembership()
  941. HRESULT
  942. IsAdmin (
  943. OUT BOOL *pAdmin
  944. )
  945. {
  946. HRESULT hr;
  947. WCHAR Name[8];
  948. // Initialize the out parameter
  949. *pAdmin = FALSE;
  950. hr = StringCbCopy(&Name[0], sizeof(Name), L"DA");
  951. if (FAILED(hr))
  952. {
  953. PrintError(hr);
  954. goto end;
  955. }
  956. hr = LookupMembership(Name, pAdmin);
  957. if ( FAILED(hr) )
  958. {
  959. dbgprint(L"IsAdmin: CheckAccountName returned error %x", hr);
  960. PrintError(hr);
  961. goto end;
  962. }
  963. if(TRUE == *pAdmin)
  964. {
  965. goto end;
  966. }
  967. hr = StringCbCopy(&Name[0], sizeof(Name), L"EA");
  968. if (FAILED(hr))
  969. {
  970. PrintError(hr);
  971. goto end;
  972. }
  973. hr = LookupMembership(Name, pAdmin);
  974. if ( FAILED(hr) )
  975. {
  976. // We are not printing error in this case, since this function
  977. // may not be supported in pre wistler servers
  978. dbgprint(L"IsAdmin: CheckAccountName returned error %x", hr);
  979. goto end;
  980. }
  981. end:
  982. return hr;
  983. } // IsAdmin
  984. HRESULT
  985. GLOBALS::Init()
  986. {
  987. HRESULT hr;
  988. hr = _LoadString(this->ErrorBadSysVol, IDS_BADSYSVOL);
  989. if (FAILED(hr))
  990. {
  991. hr = HRESULT_FROM_WIN32(GetLastError());
  992. goto end;
  993. }
  994. hr = _LoadString(this->Banner1, IDS_BANNER1);
  995. if (FAILED(hr))
  996. {
  997. hr = HRESULT_FROM_WIN32(GetLastError());
  998. goto end;
  999. }
  1000. hr = _LoadString(this->Banner2, IDS_BANNER2);
  1001. if (FAILED(hr))
  1002. {
  1003. hr = HRESULT_FROM_WIN32(GetLastError());
  1004. goto end;
  1005. }
  1006. hr = _LoadString(this->ErrorContinue, IDS_CONTINUE);
  1007. if (FAILED(hr))
  1008. {
  1009. hr = HRESULT_FROM_WIN32(GetLastError());
  1010. goto end;
  1011. }
  1012. hr = _LoadString(this->ErrorNoAD, IDS_NOAD);
  1013. if (FAILED(hr))
  1014. {
  1015. hr = HRESULT_FROM_WIN32(GetLastError());
  1016. goto end;
  1017. }
  1018. hr = _LoadString(this->ErrorNotAdmin, IDS_NOTADMIN);
  1019. if (FAILED(hr))
  1020. {
  1021. hr = HRESULT_FROM_WIN32(GetLastError());
  1022. goto end;
  1023. }
  1024. hr = _LoadString(this->DispDDP, IDS_DISPDDP);
  1025. if (FAILED(hr))
  1026. {
  1027. hr = HRESULT_FROM_WIN32(GetLastError());
  1028. goto end;
  1029. }
  1030. hr = _LoadString(this->DispDDCP, IDS_DISPDDCP);
  1031. if (FAILED(hr))
  1032. {
  1033. hr = HRESULT_FROM_WIN32(GetLastError());
  1034. goto end;
  1035. }
  1036. hr = _LoadString(this->DispBoth, IDS_DISPBOTH);
  1037. if (FAILED(hr))
  1038. {
  1039. hr = HRESULT_FROM_WIN32(GetLastError());
  1040. goto end;
  1041. }
  1042. hr = _LoadString(this->ToolFailed, IDS_TOOLFAILED);
  1043. if (FAILED(hr))
  1044. {
  1045. hr = HRESULT_FROM_WIN32(GetLastError());
  1046. goto end;
  1047. }
  1048. hr = _LoadString(this->CreateEFS, IDS_CREATEEFS);
  1049. if (FAILED(hr))
  1050. {
  1051. hr = HRESULT_FROM_WIN32(GetLastError());
  1052. goto end;
  1053. }
  1054. hr = _LoadString(this->DirCreate, IDS_DIRCREATE);
  1055. if (FAILED(hr))
  1056. {
  1057. hr = HRESULT_FROM_WIN32(GetLastError());
  1058. goto end;
  1059. }
  1060. hr = _LoadString(this->DirDelete, IDS_DIRDELETE);
  1061. if (FAILED(hr))
  1062. {
  1063. hr = HRESULT_FROM_WIN32(GetLastError());
  1064. goto end;
  1065. }
  1066. hr = _LoadString(this->InvalidEFS, IDS_INVALIDEFS);
  1067. if (FAILED(hr))
  1068. {
  1069. hr = HRESULT_FROM_WIN32(GetLastError());
  1070. goto end;
  1071. }
  1072. hr = _LoadString(this->DSDelete, IDS_DSDELETE);
  1073. if (FAILED(hr))
  1074. {
  1075. hr = HRESULT_FROM_WIN32(GetLastError());
  1076. goto end;
  1077. }
  1078. hr = _LoadString(this->DSAttrib, IDS_DSATTRIB);
  1079. if (FAILED(hr))
  1080. {
  1081. hr = HRESULT_FROM_WIN32(GetLastError());
  1082. goto end;
  1083. }
  1084. hr = _LoadString(this->DSLinkDO, IDS_DSLINKDO);
  1085. if (FAILED(hr))
  1086. {
  1087. hr = HRESULT_FROM_WIN32(GetLastError());
  1088. goto end;
  1089. }
  1090. hr = _LoadString(this->DSLinkDDP, IDS_DSLINKDDP);
  1091. if (FAILED(hr))
  1092. {
  1093. hr = HRESULT_FROM_WIN32(GetLastError());
  1094. goto end;
  1095. }
  1096. hr = _LoadString(this->DirRead, IDS_DIRREAD);
  1097. if (FAILED(hr))
  1098. {
  1099. hr = HRESULT_FROM_WIN32(GetLastError());
  1100. goto end;
  1101. }
  1102. hr = _LoadString(this->DirWrite, IDS_DIRWRITE);
  1103. if (FAILED(hr))
  1104. {
  1105. hr = HRESULT_FROM_WIN32(GetLastError());
  1106. goto end;
  1107. }
  1108. hr = _LoadString(this->DDPSuccess, IDS_DDPSUCCESS);
  1109. if (FAILED(hr))
  1110. {
  1111. hr = HRESULT_FROM_WIN32(GetLastError());
  1112. goto end;
  1113. }
  1114. hr = _LoadString(this->DDCPSuccess, IDS_DDCPSUCCESS);
  1115. if (FAILED(hr))
  1116. {
  1117. hr = HRESULT_FROM_WIN32(GetLastError());
  1118. goto end;
  1119. }
  1120. hr = _LoadString(this->WarnURA, IDS_WARNURA);
  1121. if (FAILED(hr))
  1122. {
  1123. hr = HRESULT_FROM_WIN32(GetLastError());
  1124. goto end;
  1125. }
  1126. hr = _LoadString(this->IgnSchSwitch, IDS_IGNSCHSWITCH);
  1127. if (FAILED(hr))
  1128. {
  1129. hr = HRESULT_FROM_WIN32(GetLastError());
  1130. goto end;
  1131. }
  1132. hr = _LoadString(this->GenDSErr, IDS_GENDSERR);
  1133. if (FAILED(hr))
  1134. {
  1135. hr = HRESULT_FROM_WIN32(GetLastError());
  1136. goto end;
  1137. }
  1138. hr = _LoadString(this->DSCreate, IDS_DSCREATE);
  1139. if (FAILED(hr))
  1140. {
  1141. hr = HRESULT_FROM_WIN32(GetLastError());
  1142. goto end;
  1143. }
  1144. hr = _LoadString(this->EFSAccessDenied, IDS_EFSACCESSDENIED);
  1145. if (FAILED(hr))
  1146. {
  1147. hr = HRESULT_FROM_WIN32(GetLastError());
  1148. goto end;
  1149. }
  1150. hr = _LoadString(this->WrongSchema, IDS_WRONGSCHEMA);
  1151. if (FAILED(hr))
  1152. {
  1153. hr = HRESULT_FROM_WIN32(GetLastError());
  1154. goto end;
  1155. }
  1156. hr = _LoadString(this->TargetSwitch, IDS_TARGETSWITCH);
  1157. if (FAILED(hr))
  1158. {
  1159. hr = HRESULT_FROM_WIN32(GetLastError());
  1160. goto end;
  1161. }
  1162. hr = _LoadString(this->CharYes, IDS_CHARYES);
  1163. if (FAILED(hr))
  1164. {
  1165. hr = HRESULT_FROM_WIN32(GetLastError());
  1166. goto end;
  1167. }
  1168. hr = _LoadString(this->RestoreIgnoredGPOFail, IDS_RESTORE_FAIL);
  1169. if (FAILED(hr))
  1170. {
  1171. hr = HRESULT_FROM_WIN32(GetLastError());
  1172. goto end;
  1173. }
  1174. // all done
  1175. hr = S_OK;
  1176. end:
  1177. if ( FAILED(hr) )
  1178. {
  1179. PrintError(hr);
  1180. }
  1181. return hr;
  1182. } // GLOBALS::Init
  1183. GLOBALS::GLOBALS()
  1184. {
  1185. EFSAccessDenied = NULL;
  1186. Banner1 = NULL;
  1187. Banner2 = NULL;
  1188. ErrorNotAdmin = NULL;
  1189. ErrorNoAD = NULL;
  1190. ErrorContinue = NULL;
  1191. ErrorBadSysVol = NULL;
  1192. DispDDP = NULL;
  1193. DispDDCP = NULL;
  1194. DispBoth = NULL;
  1195. ToolFailed = NULL;
  1196. CreateEFS = NULL;
  1197. DirCreate = NULL;
  1198. DirDelete = NULL;
  1199. InvalidEFS = NULL;
  1200. DSDelete = NULL;
  1201. DSAttrib = NULL;
  1202. DSLinkDO = NULL;
  1203. DSLinkDDP = NULL;
  1204. DirRead = NULL;
  1205. DirWrite = NULL;
  1206. DDPSuccess = NULL;
  1207. DDCPSuccess = NULL;
  1208. WarnURA = NULL;
  1209. IgnSchSwitch = NULL;
  1210. GenDSErr = NULL;
  1211. DSCreate = NULL;
  1212. CharYes = NULL;
  1213. RestoreIgnoredGPOFail = NULL;
  1214. pGPO = NULL;
  1215. pDDPSecDesc = NULL;
  1216. pDDCPSecDesc = NULL;
  1217. DomainNamingContext = NULL;
  1218. pDomainInfo = NULL;
  1219. hasEFSInfo = FALSE;
  1220. bIgnoreSchema = FALSE;
  1221. }
  1222. GLOBALS::~GLOBALS()
  1223. {
  1224. if (this->pDomainInfo != NULL)
  1225. {
  1226. DsRoleFreeMemory(this->pDomainInfo);
  1227. this->pDomainInfo = NULL;
  1228. }
  1229. if ( NULL != DomainNamingContext )
  1230. {
  1231. LocalFree(DomainNamingContext);
  1232. }
  1233. if ( pDDPSecDesc != NULL )
  1234. {
  1235. LocalFree(pDDPSecDesc);
  1236. }
  1237. if ( pDDCPSecDesc != NULL )
  1238. {
  1239. LocalFree(pDDCPSecDesc);
  1240. }
  1241. delete [] EFSAccessDenied;
  1242. delete [] Banner1;
  1243. delete [] Banner2;
  1244. delete [] ErrorNotAdmin;
  1245. delete [] ErrorNoAD;
  1246. delete [] ErrorContinue;
  1247. delete [] ErrorBadSysVol;
  1248. delete [] DispDDP;
  1249. delete [] DispDDCP;
  1250. delete [] DispBoth;
  1251. delete [] ToolFailed;
  1252. delete [] CreateEFS;
  1253. delete [] DirCreate;
  1254. delete [] DirDelete;
  1255. delete [] InvalidEFS;
  1256. delete [] DSDelete;
  1257. delete [] DSAttrib;
  1258. delete [] DSLinkDO;
  1259. delete [] DSLinkDDP;
  1260. delete [] DirRead;
  1261. delete [] DirWrite;
  1262. delete [] DDPSuccess;
  1263. delete [] DDCPSuccess;
  1264. delete [] WarnURA;
  1265. delete [] IgnSchSwitch;
  1266. delete [] GenDSErr;
  1267. delete [] DSCreate;
  1268. delete [] WrongSchema;
  1269. delete [] TargetSwitch;
  1270. delete [] CharYes;
  1271. delete [] RestoreIgnoredGPOFail;
  1272. }
  1273. HRESULT
  1274. _LoadString(
  1275. OUT WCHAR*& pwsz,
  1276. IN UINT nID
  1277. )
  1278. {
  1279. HRESULT hr;
  1280. hr = S_OK;
  1281. pwsz = new WCHAR [ 2048 ];
  1282. if ( ! pwsz )
  1283. {
  1284. return E_OUTOFMEMORY;
  1285. }
  1286. UINT nLen = ::LoadString(GetModuleHandle(NULL), nID, pwsz, 2048);
  1287. if (nLen == 0)
  1288. {
  1289. hr = HRESULT_FROM_WIN32(GetLastError());
  1290. delete [] pwsz;
  1291. pwsz = NULL;
  1292. }
  1293. return hr;
  1294. }
  1295. void
  1296. PrintError(
  1297. DWORD dwError
  1298. )
  1299. {
  1300. BOOL bResult;
  1301. ULONG dwSize = 0;
  1302. WCHAR *lpBuffer;
  1303. bResult = FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  1304. NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), (PWSTR ) &lpBuffer, dwSize, NULL);
  1305. if ( 0 == bResult )
  1306. {
  1307. return;
  1308. }
  1309. if ( lpBuffer != NULL )
  1310. {
  1311. DisplayError(lpBuffer);
  1312. LocalFree(lpBuffer);
  1313. }
  1314. return;
  1315. } //PrintError
  1316. void
  1317. PrintError(
  1318. WCHAR *lpStr1,
  1319. WCHAR *lpStr2
  1320. )
  1321. {
  1322. WCHAR *lpTotStr = NULL;
  1323. //
  1324. // Here, lpStr2 is a format string. So, no memory is needed for terminating
  1325. // since lpStr2 contains %s character.
  1326. //
  1327. ULONG uSize = lstrlen(lpStr1) + lstrlen(lpStr2) ;
  1328. lpTotStr = (WCHAR *) LocalAlloc(LPTR, sizeof(WCHAR) * uSize);
  1329. if (NULL == lpTotStr)
  1330. {
  1331. return;
  1332. }
  1333. //
  1334. // Here lpStr2 contains one '%ls'...
  1335. // Ignore error here, since error occured while printing error.
  1336. //
  1337. (void) StringCchPrintf(lpTotStr, uSize, lpStr2, lpStr1);
  1338. DisplayError(lpTotStr);
  1339. LocalFree(lpTotStr);
  1340. return;
  1341. }
  1342. void
  1343. PrintError(
  1344. WCHAR *lpMes,
  1345. DWORD dwError
  1346. )
  1347. {
  1348. BOOL bResult;
  1349. ULONG dwSize = 0;
  1350. WCHAR *lpBuffer;
  1351. bResult = FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  1352. NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), (PWSTR ) &lpBuffer, dwSize, NULL);
  1353. if ( 0 == bResult )
  1354. {
  1355. return;
  1356. }
  1357. if ( lpBuffer != NULL )
  1358. {
  1359. WCHAR *lpTotBuf;
  1360. ULONG uSize;
  1361. //
  1362. // lpMes + lpBuffer + ' ' + ':' + '\0'
  1363. //
  1364. uSize = lstrlen(lpMes) + lstrlen(lpBuffer) + 1 + 1 + 1;
  1365. lpTotBuf = (WCHAR *) LocalAlloc(LPTR, sizeof(WCHAR)*uSize);
  1366. if(NULL == lpTotBuf)
  1367. {
  1368. LocalFree(lpBuffer);
  1369. return;
  1370. }
  1371. //
  1372. // Ignore error here, since error occured while printing error.
  1373. //
  1374. (void) StringCchPrintf(lpTotBuf, uSize, L"%s :%s", lpMes, lpBuffer);
  1375. DisplayError(lpTotBuf);
  1376. LocalFree(lpBuffer);
  1377. LocalFree(lpTotBuf);
  1378. }
  1379. return;
  1380. } //PrintError
  1381. void
  1382. DisplayError (
  1383. WCHAR *lpBuffer
  1384. )
  1385. {
  1386. BOOL bError;
  1387. CONSOLE_SCREEN_BUFFER_INFO Info;
  1388. BOOL RestoreColor = FALSE;
  1389. HANDLE ErrorOut = NULL;
  1390. ULONG Length;
  1391. ErrorOut = GetStdHandle(STD_ERROR_HANDLE);
  1392. if (ErrorOut == INVALID_HANDLE_VALUE)
  1393. {
  1394. ErrorOut = NULL;
  1395. }
  1396. if (ErrorOut != NULL)
  1397. {
  1398. bError = GetConsoleScreenBufferInfo(ErrorOut, &Info);
  1399. if (bError != FALSE)
  1400. {
  1401. bError = SetConsoleTextAttribute( ErrorOut, FOREGROUND_RED | FOREGROUND_INTENSITY |
  1402. ((Info.wAttributes & BACKGROUND_RED) ? 0 : (Info.wAttributes & 0xf0) ) );
  1403. if (bError != FALSE)
  1404. {
  1405. RestoreColor = TRUE;
  1406. }
  1407. }
  1408. bError = WriteConsole(ErrorOut, lpBuffer, lstrlen(lpBuffer), &Length, NULL);
  1409. // ignore error
  1410. }
  1411. bError = MessageBeep(MB_ICONEXCLAMATION);
  1412. // ignore error
  1413. if (RestoreColor)
  1414. {
  1415. bError = SetConsoleTextAttribute(ErrorOut, Info.wAttributes);
  1416. // ignore error
  1417. }
  1418. } // DisplayError
  1419. HRESULT SaveEFSCerts()
  1420. {
  1421. HRESULT hr;
  1422. GUID g_guidRegExt = REGISTRY_EXTENSION_GUID;
  1423. GUID clsidDomain;
  1424. hr = CLSIDFromString(DOMAIN_GUID,
  1425. &clsidDomain);
  1426. if (FAILED(hr))
  1427. {
  1428. PrintError(hr);
  1429. goto end;
  1430. }
  1431. hr = global->pGPO->Save(TRUE, TRUE, &g_guidRegExt, &clsidDomain);
  1432. if ( FAILED(hr) )
  1433. {
  1434. PrintError(DDP, global->CreateEFS);
  1435. goto end;
  1436. }
  1437. //
  1438. // The Save method automatically increases the version number value in the DS.
  1439. // So, increment this value so that DS and sysvol will have the same version number
  1440. global->lDDPVersionNo++;
  1441. hr = S_OK;
  1442. end:
  1443. return hr;
  1444. } // SaveEFSCerts
  1445. HRESULT CreateEFSCerts(void)
  1446. {
  1447. DWORD dwError;
  1448. HRESULT hr;
  1449. PUCHAR pRecoveryPolicyBlob = NULL;
  1450. ULONG ulBlobSize;
  1451. PCCERT_CONTEXT pCertContext = NULL;
  1452. HKEY hKeyPolicyRoot;
  1453. HKEY hKey;
  1454. ULONG dwDisposition;
  1455. HCERTSTORE hCertStore = NULL;
  1456. WCHAR *szAdsiPath = NULL;
  1457. PDOMAIN_CONTROLLER_INFO pDcInfo = NULL;
  1458. hr = CoCreateInstance(CLSID_GroupPolicyObject,
  1459. NULL,
  1460. CLSCTX_SERVER,
  1461. IID_IGroupPolicyObject,
  1462. (void **)&(global->pGPO));
  1463. if ( FAILED(hr) )
  1464. {
  1465. PrintError(hr);
  1466. goto end;
  1467. }
  1468. //
  1469. // Get the current DC name
  1470. //
  1471. dwError = DsGetDcName(NULL,
  1472. global->pDomainInfo->DomainNameDns,
  1473. NULL,
  1474. NULL,
  1475. DS_IS_DNS_NAME,
  1476. &pDcInfo);
  1477. if(dwError != ERROR_SUCCESS)
  1478. {
  1479. PrintError(dwError);
  1480. hr = HRESULT_FROM_WIN32(dwError);
  1481. goto end;
  1482. }
  1483. if (*(pDcInfo->DomainControllerName) != L'\\' || *(pDcInfo->DomainControllerName + 1) != L'\\')
  1484. {
  1485. hr = E_FAIL;
  1486. goto end;
  1487. }
  1488. ULONG ulNoChars = sizeof(L"LDAP://%s/CN=%s,CN=Policies,CN=System,%s")/sizeof(WCHAR) +
  1489. lstrlen(pDcInfo->DomainControllerName+2) +
  1490. sizeof(DOMAIN_GUID)/sizeof(WCHAR) +
  1491. lstrlen(global->DomainNamingContext);
  1492. szAdsiPath = (WCHAR *) LocalAlloc(LPTR, sizeof(WCHAR) * ulNoChars);
  1493. if (!szAdsiPath)
  1494. {
  1495. hr = E_OUTOFMEMORY;
  1496. PrintError(hr);
  1497. goto end;
  1498. }
  1499. hr = StringCchPrintf(szAdsiPath,
  1500. ulNoChars,
  1501. L"LDAP://%s/CN=%s,CN=Policies,CN=System,%s",
  1502. pDcInfo->DomainControllerName+2,
  1503. DOMAIN_GUID,
  1504. global->DomainNamingContext);
  1505. ASSERT(SUCCEEDED(hr));
  1506. //
  1507. // Open the GPO Object
  1508. //
  1509. hr = global->pGPO->OpenDSGPO(szAdsiPath,
  1510. GPO_OPEN_LOAD_REGISTRY);
  1511. if (FAILED(hr))
  1512. {
  1513. PrintError(hr);
  1514. goto end;
  1515. }
  1516. //
  1517. // Get the registry key for the machine section
  1518. //
  1519. hr = global->pGPO->GetRegistryKey(GPO_SECTION_MACHINE, &hKeyPolicyRoot);
  1520. if (FAILED(hr))
  1521. {
  1522. PrintError(DDP, global->InvalidEFS);
  1523. dbgprint(L"dbg: CreateEFSCerts: GetRegistryKey failed with 0x%x\n", hr);
  1524. goto end;
  1525. }
  1526. dwError = GenerateDefaultEFSRecoveryPolicy (&pRecoveryPolicyBlob,
  1527. &ulBlobSize,
  1528. &pCertContext);
  1529. if (dwError != ERROR_SUCCESS)
  1530. {
  1531. dbgprint(L"dbg: CreateEFSCerts: GenerateDefaultEFSRecoveryPolicy failed with 0x%x\n", dwError);
  1532. hr = HRESULT_FROM_WIN32(dwError);
  1533. goto end;
  1534. }
  1535. //
  1536. // Add the EFS cert to the cert store of this GPO
  1537. //
  1538. CERT_SYSTEM_STORE_RELOCATE_PARA paraRelocate;
  1539. paraRelocate.hKeyBase = hKeyPolicyRoot;
  1540. paraRelocate.pwszSystemStore = L"EFS";
  1541. hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
  1542. 0,
  1543. NULL,
  1544. CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY |
  1545. CERT_SYSTEM_STORE_RELOCATE_FLAG,
  1546. (void *)&paraRelocate
  1547. );
  1548. if ( hCertStore )
  1549. {
  1550. BOOL bError;
  1551. bError = CertAddCertificateContextToStore(
  1552. hCertStore,
  1553. pCertContext, // pCertContext,
  1554. CERT_STORE_ADD_ALWAYS,
  1555. NULL
  1556. );
  1557. if (!bError)
  1558. {
  1559. hr = HRESULT_FROM_WIN32(GetLastError());
  1560. goto end;
  1561. }
  1562. }
  1563. else
  1564. {
  1565. hr = HRESULT_FROM_WIN32 (GetLastError());
  1566. }
  1567. dwError = RegCreateKeyEx (hKeyPolicyRoot,
  1568. CERT_EFSBLOB_REGPATH,
  1569. 0,
  1570. TEXT("REG_SZ"),
  1571. REG_OPTION_NON_VOLATILE,
  1572. KEY_ALL_ACCESS,
  1573. NULL,
  1574. &hKey,
  1575. NULL);
  1576. if (dwError != ERROR_SUCCESS)
  1577. {
  1578. hr = HRESULT_FROM_WIN32 (dwError);
  1579. goto end;
  1580. }
  1581. dwError = RegSetValueEx (hKey,
  1582. CERT_EFSBLOB_VALUE_NAME,
  1583. 0,
  1584. REG_BINARY,
  1585. (PBYTE) pRecoveryPolicyBlob, // EfsBlob
  1586. ulBlobSize);
  1587. hr = HRESULT_FROM_WIN32 (dwError);
  1588. end:
  1589. if (szAdsiPath)
  1590. {
  1591. LocalFree(szAdsiPath);
  1592. }
  1593. if (hCertStore)
  1594. {
  1595. CertCloseStore(hCertStore, 0);
  1596. }
  1597. if (pCertContext)
  1598. {
  1599. CertFreeCertificateContext(pCertContext);
  1600. }
  1601. if (pRecoveryPolicyBlob)
  1602. {
  1603. free (pRecoveryPolicyBlob);
  1604. }
  1605. return hr;
  1606. }
  1607. HRESULT
  1608. CreateFolder(
  1609. PWSTR pFolderPath
  1610. )
  1611. {
  1612. DWORD dwError;
  1613. dbgprint(L"dbg: CreateFolder(%s)\n", pFolderPath);
  1614. if (CreateDirectory(pFolderPath, NULL) == FALSE)
  1615. {
  1616. dwError = GetLastError();
  1617. if (dwError != ERROR_ALREADY_EXISTS)
  1618. {
  1619. PrintError(pFolderPath, global->DirCreate);
  1620. return HRESULT_FROM_WIN32(dwError);
  1621. }
  1622. }
  1623. return S_OK;
  1624. } // CreateFolder
  1625. HRESULT
  1626. CreateSecurityTemplate (
  1627. WCHAR *szSrcFile,
  1628. WCHAR *szDestFile
  1629. )
  1630. {
  1631. DWORD dwError;
  1632. DWORD rc=ERROR_SUCCESS;
  1633. PVOID hProfile=NULL;
  1634. PSCE_PROFILE_INFO pSceInfo=NULL;
  1635. rc = SceOpenProfile(
  1636. szSrcFile,
  1637. SCE_INF_FORMAT,
  1638. &hProfile
  1639. );
  1640. if (rc != SCESTATUS_SUCCESS)
  1641. {
  1642. dwError = GetLastError();
  1643. goto end;
  1644. }
  1645. //
  1646. // load informatin from the template
  1647. //
  1648. rc = SceGetSecurityProfileInfo(
  1649. hProfile,
  1650. SCE_ENGINE_SCP,
  1651. AREA_ALL,
  1652. &pSceInfo,
  1653. NULL
  1654. );
  1655. if (rc != SCESTATUS_SUCCESS)
  1656. {
  1657. dwError = GetLastError();
  1658. goto end;
  1659. }
  1660. rc = SceWriteSecurityProfileInfo(
  1661. szDestFile,
  1662. AREA_ALL,
  1663. pSceInfo,
  1664. NULL
  1665. );
  1666. if (rc != SCESTATUS_SUCCESS)
  1667. {
  1668. dwError = GetLastError();
  1669. goto end;
  1670. }
  1671. rc = SceFreeProfileMemory(pSceInfo);
  1672. if (rc != SCESTATUS_SUCCESS)
  1673. {
  1674. dwError = GetLastError();
  1675. goto end;
  1676. }
  1677. dwError = ERROR_SUCCESS;
  1678. end:
  1679. if ( NULL != hProfile )
  1680. {
  1681. SceCloseProfile(&hProfile);
  1682. }
  1683. if ( dwError != ERROR_SUCCESS )
  1684. {
  1685. PrintError(dwError);
  1686. }
  1687. return HRESULT_FROM_WIN32(dwError);
  1688. }
  1689. HRESULT
  1690. CreateSysVolDomain(
  1691. )
  1692. {
  1693. DWORD dwError;
  1694. HRESULT hr;
  1695. WCHAR *TempPath = NULL;
  1696. HANDLE PolFile = NULL;
  1697. HMODULE Module = NULL;
  1698. ULONG uTempPathLen = 0;
  1699. BOOL bError;
  1700. //
  1701. // The string that TempPath will be like
  1702. // <sysvolpath>\<domain name>\policies\<domain guid>\Microsoft\windows NT\\secedit
  1703. // Memory is allocated for each directory name and for '\' if needed.
  1704. //
  1705. uTempPathLen = lstrlen(global->SysVolPath) + 1 + lstrlen(global->pDomainInfo->DomainNameDns) + lstrlen(L"\\policies")
  1706. + 1+lstrlen(DOMAIN_GUID)+ lstrlen(L"\\MACHINE\\registry.pol") + lstrlen(L"\\Microsoft\\Windows NT\\secedit")
  1707. + lstrlen(L"\\USER\\Microsoft\\RemoteInstll\\oscfilter.ini") + 1;
  1708. TempPath = (WCHAR*) LocalAlloc ( LPTR, uTempPathLen * sizeof(WCHAR));
  1709. if(NULL == TempPath)
  1710. {
  1711. hr = E_OUTOFMEMORY;
  1712. goto end;
  1713. }
  1714. hr = StringCchPrintf(TempPath,
  1715. uTempPathLen,
  1716. L"%s\\%s\\Policies",
  1717. global->SysVolPath,
  1718. global->pDomainInfo->DomainNameDns);
  1719. if (FAILED(hr))
  1720. {
  1721. goto end;
  1722. }
  1723. hr = CreateFolder(TempPath);
  1724. if (FAILED(hr))
  1725. {
  1726. goto end;
  1727. }
  1728. hr = SetPolicySecurityInfo(TempPath);
  1729. if ( FAILED(hr) )
  1730. {
  1731. goto end;
  1732. }
  1733. hr = StringCchCat(TempPath, uTempPathLen, L"\\");
  1734. if (FAILED(hr))
  1735. {
  1736. goto end;
  1737. }
  1738. hr = StringCchCat(TempPath, uTempPathLen, DOMAIN_GUID);
  1739. if (FAILED(hr))
  1740. {
  1741. goto end;
  1742. }
  1743. hr = CreateFolder(TempPath);
  1744. if (FAILED(hr))
  1745. {
  1746. goto end;
  1747. }
  1748. // Set security info for this directory
  1749. dwError = SetSysvolSecurityFromDSSecurity(
  1750. TempPath,
  1751. DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION ,
  1752. global->pDDPSecDesc);
  1753. if (dwError != ERROR_SUCCESS)
  1754. {
  1755. hr = HRESULT_FROM_WIN32(dwError);
  1756. goto end;
  1757. }
  1758. hr = StringCchCat(TempPath, uTempPathLen, L"\\MACHINE");
  1759. if (FAILED(hr))
  1760. {
  1761. goto end;
  1762. }
  1763. hr = CreateFolder(TempPath);
  1764. if (FAILED(hr))
  1765. {
  1766. goto end;
  1767. }
  1768. hr = StringCchCat(TempPath, uTempPathLen, L"\\Microsoft");
  1769. if (FAILED(hr))
  1770. {
  1771. goto end;
  1772. }
  1773. hr = CreateFolder(TempPath);
  1774. if (FAILED(hr))
  1775. {
  1776. goto end;
  1777. }
  1778. hr = StringCchCat(TempPath, uTempPathLen, L"\\Windows NT");
  1779. if (FAILED(hr))
  1780. {
  1781. goto end;
  1782. }
  1783. hr = CreateFolder(TempPath);
  1784. if (FAILED(hr))
  1785. {
  1786. goto end;
  1787. }
  1788. hr = StringCchCat(TempPath, uTempPathLen, L"\\SecEdit");
  1789. if (FAILED(hr))
  1790. {
  1791. goto end;
  1792. }
  1793. hr = CreateFolder(TempPath);
  1794. if (FAILED(hr))
  1795. {
  1796. goto end;
  1797. }
  1798. hr = StringCchPrintf(TempPath, uTempPathLen, L"%s\\%s\\Policies\\%s\\USER", global->SysVolPath, global->pDomainInfo->DomainNameDns , DOMAIN_GUID);
  1799. if (FAILED(hr))
  1800. {
  1801. goto end;
  1802. }
  1803. hr = CreateFolder(TempPath);
  1804. if (FAILED(hr))
  1805. {
  1806. goto end;
  1807. }
  1808. hr = StringCchCat(TempPath, uTempPathLen, L"\\Microsoft");
  1809. if (FAILED(hr))
  1810. {
  1811. goto end;
  1812. }
  1813. hr = CreateFolder(TempPath);
  1814. if (FAILED(hr))
  1815. {
  1816. goto end;
  1817. }
  1818. hr = StringCchCat(TempPath, uTempPathLen, L"\\RemoteInstall");
  1819. if (FAILED(hr))
  1820. {
  1821. goto end;
  1822. }
  1823. hr = CreateFolder(TempPath);
  1824. if (FAILED(hr))
  1825. {
  1826. goto end;
  1827. }
  1828. hr = StringCchCat(TempPath, uTempPathLen, L"\\oscfilter.ini");
  1829. if (FAILED(hr))
  1830. {
  1831. goto end;
  1832. }
  1833. bError = WritePrivateProfileString(L"choice", L"custom", L"0", TempPath);
  1834. if (bError == FALSE)
  1835. {
  1836. hr = HRESULT_FROM_WIN32(GetLastError());
  1837. goto end;
  1838. }
  1839. bError = WritePrivateProfileString(L"choice", L"tools", L"0", TempPath);
  1840. if (bError == FALSE)
  1841. {
  1842. hr = HRESULT_FROM_WIN32(GetLastError());
  1843. goto end;
  1844. }
  1845. bError = WritePrivateProfileString(L"choice", L"restart", L"0", TempPath);
  1846. if (bError == FALSE)
  1847. {
  1848. hr = HRESULT_FROM_WIN32(GetLastError());
  1849. goto end;
  1850. }
  1851. hr = S_OK;
  1852. end:
  1853. if (NULL != TempPath)
  1854. {
  1855. LocalFree (TempPath);
  1856. }
  1857. if (PolFile != NULL)
  1858. {
  1859. CloseHandle(PolFile);
  1860. PolFile = NULL;
  1861. }
  1862. if (Module != NULL)
  1863. {
  1864. FreeLibrary(Module);
  1865. Module = NULL;
  1866. }
  1867. if (FAILED(hr))
  1868. {
  1869. PrintError(hr);
  1870. }
  1871. return hr;
  1872. } // CreateSysVolDomain
  1873. HRESULT
  1874. CreateSysVolController(
  1875. )
  1876. {
  1877. DWORD dwError;
  1878. HRESULT hr;
  1879. WCHAR *TempPath = NULL;
  1880. ULONG uTempPathLen = 0;
  1881. //
  1882. // The string that TempPath will be holding will be like
  1883. // <sysvolpath>\domain name>\policies\<guid>\MACHINE\Microsoft\windows NT\SecEdit
  1884. // Memory is allocated for each directory name and for '\' if needed.
  1885. //
  1886. uTempPathLen = lstrlen(global->SysVolPath) + 1 + lstrlen(global->pDomainInfo->DomainNameDns ) + lstrlen(L"\\Policies")
  1887. + 1 + lstrlen(DC_GUID) + lstrlen (L"\\MACHINE\\Microsoft\\windows NT\\SecEdit") + lstrlen(L"\\USER") + 1;
  1888. TempPath = (WCHAR *) LocalAlloc( LPTR, sizeof(WCHAR) * uTempPathLen);
  1889. if ( NULL == TempPath )
  1890. {
  1891. hr = E_OUTOFMEMORY;
  1892. goto end;
  1893. }
  1894. hr = StringCchPrintf(TempPath,
  1895. uTempPathLen,
  1896. L"%s\\%s\\Policies\\%s",
  1897. global->SysVolPath,
  1898. global->pDomainInfo->DomainNameDns ,
  1899. DC_GUID);
  1900. if (FAILED(hr))
  1901. {
  1902. goto end;
  1903. }
  1904. hr = CreateFolder(TempPath);
  1905. if (FAILED(hr))
  1906. {
  1907. goto end;
  1908. }
  1909. // Set security info for this directory
  1910. dwError = SetSysvolSecurityFromDSSecurity(
  1911. TempPath,
  1912. DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION ,
  1913. global->pDDCPSecDesc);
  1914. if (dwError != ERROR_SUCCESS)
  1915. {
  1916. PrintError(dwError);
  1917. hr = HRESULT_FROM_WIN32(dwError);
  1918. goto end;
  1919. }
  1920. hr = StringCchCat(TempPath, uTempPathLen, L"\\MACHINE");
  1921. if (FAILED(hr))
  1922. {
  1923. goto end;
  1924. }
  1925. hr = CreateFolder(TempPath);
  1926. if (FAILED(hr))
  1927. {
  1928. goto end;
  1929. }
  1930. hr = StringCchCat(TempPath, uTempPathLen, L"\\Microsoft");
  1931. if (FAILED(hr))
  1932. {
  1933. goto end;
  1934. }
  1935. hr = CreateFolder(TempPath);
  1936. if (FAILED(hr))
  1937. {
  1938. goto end;
  1939. }
  1940. hr = StringCchCat(TempPath, uTempPathLen, L"\\Windows NT");
  1941. if (FAILED(hr))
  1942. {
  1943. goto end;
  1944. }
  1945. hr = CreateFolder(TempPath);
  1946. if (FAILED(hr))
  1947. {
  1948. goto end;
  1949. }
  1950. hr = StringCchCat(TempPath, uTempPathLen, L"\\SecEdit");
  1951. if (FAILED(hr))
  1952. {
  1953. goto end;
  1954. }
  1955. hr = CreateFolder(TempPath);
  1956. if (FAILED(hr))
  1957. {
  1958. goto end;
  1959. }
  1960. hr = StringCchPrintf(TempPath,
  1961. uTempPathLen,
  1962. L"%s\\%s\\Policies\\%s\\USER",
  1963. global->SysVolPath,
  1964. global->pDomainInfo->DomainNameDns ,
  1965. DC_GUID);
  1966. if (FAILED(hr))
  1967. {
  1968. goto end;
  1969. }
  1970. hr = CreateFolder(TempPath);
  1971. if (FAILED(hr))
  1972. {
  1973. goto end;
  1974. }
  1975. end:
  1976. if ( TempPath != NULL)
  1977. {
  1978. LocalFree (TempPath);
  1979. }
  1980. return hr;
  1981. } // CreateSysVolController
  1982. HRESULT
  1983. BackupEfsCert(
  1984. )
  1985. {
  1986. HRESULT hr;
  1987. WCHAR sz[1024];
  1988. HKEY hKey = 0;
  1989. DWORD dwError;
  1990. FILETIME fileTime;
  1991. DWORD dwSubKeySize;
  1992. ULONG uEnumIndex=0;
  1993. WCHAR *TempPath = NULL;
  1994. ULONG uLength;
  1995. BOOL bError;
  1996. PDOMAIN_CONTROLLER_INFO pDcInfo = NULL;
  1997. hr = CoCreateInstance(CLSID_GroupPolicyObject,
  1998. NULL,
  1999. CLSCTX_SERVER,
  2000. IID_IGroupPolicyObject,
  2001. (void **)&(global->pGPO));
  2002. if ( FAILED(hr) )
  2003. {
  2004. PrintError(hr);
  2005. goto end;
  2006. }
  2007. //
  2008. // Get the current DC name
  2009. //
  2010. dwError = DsGetDcName(NULL,
  2011. global->pDomainInfo->DomainNameDns,
  2012. NULL,
  2013. NULL,
  2014. DS_IS_DNS_NAME,
  2015. &pDcInfo);
  2016. if(dwError != ERROR_SUCCESS)
  2017. {
  2018. PrintError(dwError);
  2019. hr = HRESULT_FROM_WIN32(dwError);
  2020. goto end;
  2021. }
  2022. //
  2023. // Create the USER subdirectory under defaultdomainpolicy, if that don't exist
  2024. // This will make sure that opendsgpo will not fail due to the obsence of USER directory
  2025. // Here, the temppath will hold a string like \\machine\\registry.pol, or \\user\\registry.pol
  2026. // Memory is allocated for each directory name and for '\' if needed.
  2027. // More memory is assigned then actually needed
  2028. //
  2029. uLength = lstrlen(global->SysVolPath) + 1 + lstrlen(global->pDomainInfo->DomainNameDns) + lstrlen( L"\\Policies")
  2030. + 1 + lstrlen(DOMAIN_GUID) + lstrlen(L"\\USER") + lstrlen(L"\\MACHINE\\Registry.pol") + 1;
  2031. TempPath = (WCHAR *) LocalAlloc( LPTR, sizeof(WCHAR) * uLength);
  2032. if ( NULL == TempPath )
  2033. {
  2034. hr = E_OUTOFMEMORY;
  2035. PrintError(hr);
  2036. goto end;
  2037. }
  2038. hr = StringCchPrintf(TempPath,
  2039. uLength,
  2040. L"%s\\%s\\Policies\\%s\\USER",
  2041. global->SysVolPath,
  2042. global->pDomainInfo->DomainNameDns ,
  2043. DOMAIN_GUID);
  2044. if (FAILED(hr))
  2045. {
  2046. PrintError(hr);
  2047. goto end;
  2048. }
  2049. bError = CreateDirectory(TempPath, NULL);
  2050. if ( FALSE == bError )
  2051. {
  2052. dwError = GetLastError();
  2053. if(ERROR_ALREADY_EXISTS == dwError )
  2054. {
  2055. hr = StringCchCat (TempPath, uLength, L"\\Registry.pol");
  2056. if (FAILED(hr))
  2057. {
  2058. PrintError(hr);
  2059. goto end;
  2060. }
  2061. //
  2062. // Delete so that corrupt registry.pol does not cause an error
  2063. //
  2064. (void) DeleteFile (TempPath);
  2065. }
  2066. else if (dwError != ERROR_PATH_NOT_FOUND)
  2067. {
  2068. if ( ERROR_ACCESS_DENIED == dwError )
  2069. {
  2070. PrintError(TempPath, global->DirCreate);
  2071. }
  2072. else
  2073. {
  2074. PrintError(dwError);
  2075. }
  2076. hr = HRESULT_FROM_WIN32(dwError);
  2077. goto end;
  2078. }
  2079. }
  2080. //
  2081. // Open the GPO Object
  2082. //
  2083. if (*(pDcInfo->DomainControllerName) != L'\\' || *(pDcInfo->DomainControllerName + 1) != L'\\')
  2084. {
  2085. hr = E_FAIL;
  2086. goto end;
  2087. }
  2088. hr = StringCchPrintf(sz,
  2089. sizeof(sz)/sizeof(sz[0]),
  2090. L"LDAP://%s/CN=%s,CN=Policies,CN=System,%s",
  2091. pDcInfo->DomainControllerName+2,
  2092. DOMAIN_GUID,
  2093. global->DomainNamingContext);
  2094. if (FAILED(hr))
  2095. {
  2096. PrintError(hr);
  2097. goto end;
  2098. }
  2099. hr = global->pGPO->OpenDSGPO(sz,
  2100. GPO_OPEN_LOAD_REGISTRY);
  2101. if (FAILED(hr))
  2102. {
  2103. if ((HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr) || (HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER) == hr))
  2104. {
  2105. //
  2106. // ERROR_INVALID_PARAMETER is returned when registry key is bigger than maximum
  2107. // acceptable value: bug 631804
  2108. // ERROR_PATH_NOT_FOUND is returned when sysvol\policies or sysvol\policies\<GPO>
  2109. // directory is not present
  2110. //
  2111. //
  2112. global->pGPO->Release();
  2113. global->pGPO = NULL;
  2114. global->hasEFSInfo = FALSE;
  2115. hr = S_OK;
  2116. }
  2117. else if (HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) == hr)
  2118. {
  2119. WCHAR *szAccessDenied = NULL;
  2120. hr = StringCchPrintf(TempPath,
  2121. uLength,
  2122. L"%s\\%s\\Policies\\%s\\MACHINE\\Registry.pol",
  2123. global->SysVolPath,
  2124. global->pDomainInfo->DomainNameDns ,
  2125. DOMAIN_GUID);
  2126. if (FAILED(hr))
  2127. {
  2128. PrintError(hr);
  2129. goto end;
  2130. }
  2131. //
  2132. // No memory for terminating \0 is required since global->EFSAccessDenied is a format string.
  2133. // global->EFSAccessDenied + TempPath + sz
  2134. uLength = lstrlen(global->EFSAccessDenied) + lstrlen(TempPath) + sizeof(sz)/sizeof(sz[0]) ;
  2135. szAccessDenied = (WCHAR *) LocalAlloc(LPTR, sizeof(WCHAR) * uLength);
  2136. if ( NULL == szAccessDenied )
  2137. {
  2138. hr = E_OUTOFMEMORY;
  2139. PrintError(hr);
  2140. goto end;
  2141. }
  2142. hr = StringCchPrintf(szAccessDenied, uLength, global->EFSAccessDenied, TempPath, sz);
  2143. if (FAILED(hr))
  2144. {
  2145. PrintError(hr);
  2146. goto end;
  2147. }
  2148. DisplayError(szAccessDenied);
  2149. LocalFree(szAccessDenied);
  2150. }
  2151. else
  2152. {
  2153. PrintError(DDP, global->InvalidEFS);
  2154. PrintError(hr);
  2155. }
  2156. goto end;
  2157. }
  2158. //
  2159. // Get the registry key for the machine section
  2160. //
  2161. hr = global->pGPO->GetRegistryKey(GPO_SECTION_MACHINE, &hKey);
  2162. if (FAILED(hr))
  2163. {
  2164. PrintError(DDP, global->InvalidEFS);
  2165. PrintError(hr);
  2166. goto end;
  2167. }
  2168. //
  2169. // Delete all the keys except EFS certs
  2170. //
  2171. hr = RegDelnodeExceptEFS(hKey, global->hasEFSInfo);
  2172. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
  2173. {
  2174. global->hasEFSInfo = FALSE;
  2175. global->pGPO->Release();
  2176. global->pGPO = NULL;
  2177. hr = S_OK;
  2178. }
  2179. if ( hr != S_OK )
  2180. {
  2181. PrintError(DDP, global->InvalidEFS);
  2182. PrintError(hr);
  2183. }
  2184. end:
  2185. if (pDcInfo)
  2186. {
  2187. NetApiBufferFree(pDcInfo);
  2188. }
  2189. if(TempPath != NULL)
  2190. {
  2191. LocalFree(TempPath);
  2192. }
  2193. if( hKey != 0)
  2194. {
  2195. RegCloseKey(hKey);
  2196. }
  2197. return hr;
  2198. } // BackupEfsCert
  2199. HRESULT
  2200. DeleteTree(
  2201. PWSTR pPath
  2202. )
  2203. {
  2204. DWORD dwError;
  2205. BOOL bError;
  2206. HRESULT hr;
  2207. WCHAR *TempPath = NULL;
  2208. HANDLE FindHandle = NULL;
  2209. WIN32_FIND_DATA FindData;
  2210. ULONG ulSize;
  2211. //
  2212. // TempPath will be in the form <pPath>\<File Name>
  2213. // pPath + '\' + File Name + '\0'
  2214. //
  2215. ulSize = lstrlen(pPath)+ 1 + MAX_PATH + 1;
  2216. TempPath = (WCHAR *) LocalAlloc(LPTR, sizeof(WCHAR) * ulSize );
  2217. if ( NULL == TempPath)
  2218. {
  2219. hr = E_OUTOFMEMORY;
  2220. PrintError(hr);
  2221. goto end;
  2222. }
  2223. dbgprint(L"dbg: DeleteTree(%s)\n", pPath);
  2224. hr = StringCchPrintf(TempPath, ulSize, L"%s\\*", pPath);
  2225. if (FAILED(hr))
  2226. {
  2227. goto end;
  2228. }
  2229. FindHandle = FindFirstFile(TempPath, &FindData);
  2230. if (FindHandle == INVALID_HANDLE_VALUE)
  2231. {
  2232. FindHandle = NULL;
  2233. }
  2234. if (NULL == FindHandle )
  2235. {
  2236. dwError = GetLastError();
  2237. hr = HRESULT_FROM_WIN32(dwError);
  2238. if ( HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr )
  2239. {
  2240. hr = S_OK;
  2241. }
  2242. else
  2243. {
  2244. PrintError(TempPath, global->DirDelete);
  2245. }
  2246. goto end;
  2247. }
  2248. while (TRUE) {
  2249. // is this a special file?
  2250. if (FindData.cFileName[0] == L'.' )
  2251. {
  2252. goto next_file;
  2253. }
  2254. // no? delete it
  2255. hr = StringCchPrintf(TempPath, ulSize, L"%s\\%s", pPath, FindData.cFileName);
  2256. if (FAILED(hr))
  2257. {
  2258. goto end;
  2259. }
  2260. if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  2261. {
  2262. // recurse.
  2263. hr = DeleteTree(TempPath);
  2264. if (FAILED(hr))
  2265. {
  2266. goto end;
  2267. }
  2268. }
  2269. else
  2270. {
  2271. // delete
  2272. dbgprint(L"dbg: DeleteFile(%s)\n", TempPath);
  2273. SetFileAttributes(TempPath, FILE_ATTRIBUTE_NORMAL);
  2274. bError = DeleteFile(TempPath);
  2275. if (bError == FALSE)
  2276. {
  2277. dwError = GetLastError();
  2278. PrintError(TempPath, global->DirDelete);
  2279. hr = HRESULT_FROM_WIN32(dwError);
  2280. goto end;
  2281. }
  2282. }
  2283. next_file:
  2284. bError = FindNextFile(FindHandle, &FindData);
  2285. if (bError == FALSE)
  2286. {
  2287. hr = HRESULT_FROM_WIN32(GetLastError());
  2288. if (hr == HRESULT_FROM_WIN32(ERROR_NO_MORE_FILES))
  2289. {
  2290. hr = S_OK;
  2291. break;
  2292. }
  2293. else
  2294. {
  2295. goto end;
  2296. }
  2297. }
  2298. }
  2299. // and remove the directory now
  2300. dbgprint(L"dbg: RemoveDirectory(%s)\n", pPath);
  2301. bError = RemoveDirectory(pPath);
  2302. if (bError == FALSE)
  2303. {
  2304. dwError = GetLastError();
  2305. hr = HRESULT_FROM_WIN32(dwError);
  2306. if (hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION) || hr == HRESULT_FROM_WIN32(ERROR_DIR_NOT_EMPTY))
  2307. {
  2308. hr = S_OK;
  2309. }
  2310. else
  2311. {
  2312. PrintError(pPath, global->DirDelete);
  2313. goto end;
  2314. }
  2315. }
  2316. hr = S_OK;
  2317. end:
  2318. LocalFree(TempPath);
  2319. if (FindHandle != NULL)
  2320. {
  2321. FindClose(FindHandle);
  2322. FindHandle = NULL;
  2323. }
  2324. return hr;
  2325. } // DeleteTree
  2326. HRESULT
  2327. CheckDSSchemaVersion(
  2328. BOOL *bResult
  2329. )
  2330. {
  2331. WCHAR sz[256];
  2332. WCHAR szSchema[256];
  2333. CComPtr<IADs> pADs;
  2334. CComVariant Var;
  2335. HRESULT hr;
  2336. CComBSTR ObjectVersion(L"objectVersion");
  2337. CComBSTR SchemaNamingContext( L"schemaNamingContext" );
  2338. if ( ! SchemaNamingContext ||
  2339. ! ObjectVersion )
  2340. {
  2341. hr = E_OUTOFMEMORY;
  2342. PrintError(hr);
  2343. goto end;
  2344. }
  2345. hr = StringCchCopy(sz, sizeof(sz)/sizeof(sz[0]), L"LDAP://rootDSE");
  2346. if (FAILED(hr))
  2347. {
  2348. PrintError(hr);
  2349. goto end;
  2350. }
  2351. hr = AdminToolsOpenObject(sz, NULL, NULL, ADS_SECURE_AUTHENTICATION | ADS_SERVER_BIND, IID_IADs, (void**)&pADs);
  2352. if (FAILED(hr))
  2353. {
  2354. dbgprint(L"dbg: AdminToolsOpenObject failed %x on %s\n", hr, sz);
  2355. PrintError(sz, global->GenDSErr);
  2356. goto end;
  2357. }
  2358. hr = pADs->GetInfo();
  2359. if (FAILED(hr))
  2360. {
  2361. dbgprint(L"dbg: GetInfo failed on rootDSE %x\n", hr);
  2362. PrintError(sz, global->GenDSErr);
  2363. goto end;
  2364. }
  2365. hr = pADs->Get(SchemaNamingContext, &Var);
  2366. if (FAILED(hr))
  2367. {
  2368. dbgprint(L"dbg: failed to get rootDomainNamingContext %x \n", hr);
  2369. PrintError(sz, global->GenDSErr);
  2370. goto end;
  2371. }
  2372. hr = Var.ChangeType(VT_BSTR);
  2373. if (FAILED(hr))
  2374. {
  2375. dbgprint(L"dbg: ChangeType failed to BSTR %x\n", hr);
  2376. PrintError(hr);
  2377. goto end;
  2378. }
  2379. hr = StringCchPrintf(szSchema, sizeof(szSchema)/sizeof(szSchema[0]), L"LDAP://%s", Var.bstrVal);
  2380. if (FAILED(hr))
  2381. {
  2382. PrintError(hr);
  2383. goto end;
  2384. }
  2385. hr = AdminToolsOpenObject(szSchema, NULL, NULL, ADS_SECURE_AUTHENTICATION | ADS_SERVER_BIND, IID_IADs, (void**)&pADs);
  2386. if (FAILED(hr))
  2387. {
  2388. dbgprint(L"dbg: AdminToolsOpenObject failed %x on %s\n", hr, szSchema);
  2389. PrintError(hr);
  2390. PrintError(szSchema, global->GenDSErr);
  2391. goto end;
  2392. }
  2393. hr = pADs->GetInfo();
  2394. if (FAILED(hr))
  2395. {
  2396. dbgprint(L"dbg: GetInfo failed on rootDSE %x\n", hr);
  2397. PrintError(szSchema, global->GenDSErr);
  2398. goto end;
  2399. }
  2400. Var.Clear();
  2401. hr = pADs->Get(ObjectVersion, &Var);
  2402. if (FAILED(hr))
  2403. {
  2404. dbgprint(L"dbg: failed to get schemaDomainNamingContext %x \n", hr);
  2405. PrintError(hr);
  2406. PrintError(szSchema, global->GenDSErr);
  2407. goto end;
  2408. }
  2409. if (SCHEMA_VERSION == Var.lVal)
  2410. {
  2411. *bResult = TRUE;
  2412. }
  2413. else
  2414. {
  2415. *bResult = FALSE;
  2416. }
  2417. end:
  2418. return hr;
  2419. }
  2420. // clean the domains GPO
  2421. // clean the controller GPO
  2422. HRESULT
  2423. CleanPolicyObjects(
  2424. )
  2425. {
  2426. HRESULT hr;
  2427. WCHAR sz[1024];
  2428. CComPtr<IADs> pADs;
  2429. CComVariant Var;
  2430. CComBSTR GroupPolicyContainerName(L"groupPolicyContainer");
  2431. CComBSTR DisplayName(L"displayName");
  2432. CComBSTR GPOFlags(L"flags");
  2433. CComBSTR GPCFileSysPath(L"gPCFileSysPath");
  2434. CComBSTR GPCFunctionalityVersion(L"gPCFunctionalityVersion");
  2435. CComBSTR VersionNumber(L"VersionNumber");
  2436. CComBSTR GPCUserExtensionNames(L"gPCUserExtensionNames");
  2437. CComBSTR GPCMachineExtensionNames(L"gPCMachineExtensionNames");
  2438. CComBSTR GPCWQLFilter(L"gPCWQLFilter");
  2439. if ( ! GroupPolicyContainerName ||
  2440. ! DisplayName ||
  2441. ! GPCFileSysPath ||
  2442. ! GPCFunctionalityVersion ||
  2443. ! VersionNumber ||
  2444. ! GPCUserExtensionNames ||
  2445. ! GPCMachineExtensionNames ||
  2446. ! GPCWQLFilter )
  2447. {
  2448. hr = E_OUTOFMEMORY;
  2449. PrintError(hr);
  2450. goto end;
  2451. }
  2452. if (global->RestoreType & GLOBALS::RESTORE_DOMAIN)
  2453. {
  2454. hr = StringCchPrintf( sz,
  2455. sizeof(sz)/sizeof(sz[0]),
  2456. L"LDAP://CN=%s,CN=Policies,CN=System,%s",
  2457. DOMAIN_GUID,
  2458. global->DomainNamingContext) ;
  2459. if (FAILED(hr))
  2460. {
  2461. PrintError(hr);
  2462. goto end;
  2463. }
  2464. pADs.Release();
  2465. hr = AdminToolsOpenObject(sz, NULL, NULL, ADS_SECURE_AUTHENTICATION | ADS_SERVER_BIND, IID_IADs, (void**)&pADs);
  2466. if ( FAILED(hr) && hr != (HRESULT_FROM_WIN32(ERROR_DS_NO_SUCH_OBJECT)))
  2467. {
  2468. dbgprint(L"dbg: AdminToolsOpenObject failed %x on %s\n", hr, sz);
  2469. PrintError(sz, global->GenDSErr);
  2470. goto end;
  2471. }
  2472. else
  2473. {
  2474. CComPtr<IADsContainer> pFolder;
  2475. CComPtr<IDispatch> pDisp;
  2476. hr = StringCchPrintf( sz,
  2477. sizeof(sz)/sizeof(sz[0]),
  2478. L"LDAP://CN=Policies,CN=System,%s",
  2479. global->DomainNamingContext) ;
  2480. if (FAILED(hr))
  2481. {
  2482. PrintError(hr);
  2483. goto end;
  2484. }
  2485. hr = AdminToolsOpenObject(sz, NULL, NULL, ADS_SECURE_AUTHENTICATION | ADS_SERVER_BIND, IID_IADsContainer, (void**)&pFolder);
  2486. if (FAILED(hr))
  2487. {
  2488. dbgprint(L"dbg: AdminToolsOpenObject failed %x on %s\n", hr, sz);
  2489. PrintError(sz, global->DSCreate);
  2490. goto end;
  2491. }
  2492. hr = StringCchPrintf( sz,
  2493. sizeof(sz)/sizeof(sz[0]),
  2494. L"CN=%s",
  2495. DOMAIN_GUID );
  2496. if (FAILED(hr))
  2497. {
  2498. PrintError(hr);
  2499. goto end;
  2500. }
  2501. {
  2502. CComBSTR ContainerPath(sz);
  2503. if ( ContainerPath )
  2504. {
  2505. hr = pFolder->Create(GroupPolicyContainerName, ContainerPath, &pDisp);
  2506. }
  2507. else
  2508. {
  2509. hr = E_OUTOFMEMORY;
  2510. }
  2511. if (FAILED(hr))
  2512. {
  2513. dbgprint(L"dbg: Create failed %x on %s\n", hr, sz);
  2514. PrintError(sz, global->DSCreate);
  2515. goto end;
  2516. }
  2517. }
  2518. hr = pDisp->QueryInterface(IID_IADs, (void**)&pADs);
  2519. if (FAILED(hr))
  2520. {
  2521. dbgprint(L"dbg: Query Interface failed %x for Creating IID_IADS\n", hr);
  2522. PrintError(sz, global->DSCreate);
  2523. goto end;
  2524. }
  2525. }
  2526. hr = StringCchPrintf( sz,
  2527. sizeof(sz)/sizeof(sz[0]),
  2528. L"LDAP://CN=Machine,CN=%s,CN=Policies,CN=System,%s",
  2529. DOMAIN_GUID,
  2530. global->DomainNamingContext) ;
  2531. if (FAILED(hr))
  2532. {
  2533. PrintError(hr);
  2534. goto end;
  2535. }
  2536. hr = ResetContainerFromDS(sz, pADs);
  2537. if (FAILED(hr))
  2538. {
  2539. dbgprint(L"ResetContainerFromDS failed %x on %s\n", hr, sz);
  2540. goto end;
  2541. }
  2542. hr = StringCchPrintf( sz,
  2543. sizeof(sz)/sizeof(sz[0]),
  2544. L"LDAP://CN=User,CN=%s,CN=Policies,CN=System,%s",
  2545. DOMAIN_GUID,
  2546. global->DomainNamingContext) ;
  2547. if (FAILED(hr))
  2548. {
  2549. PrintError(hr);
  2550. goto end;
  2551. }
  2552. hr = ResetContainerFromDS(sz, pADs);
  2553. if (FAILED(hr))
  2554. {
  2555. dbgprint(L"ResetContainerFromDS failed %x on %s\n", hr, sz);
  2556. goto end;
  2557. }
  2558. hr = StringCchPrintf( sz,
  2559. sizeof(sz)/sizeof(sz[0]),
  2560. L"LDAP://CN=%s,CN=Policies,CN=System,%s",
  2561. DOMAIN_GUID,
  2562. global->DomainNamingContext) ;
  2563. if (FAILED(hr))
  2564. {
  2565. PrintError(hr);
  2566. goto end;
  2567. }
  2568. hr = ADsGetObject(sz, IID_IADs, (void**)&pADs);
  2569. if (FAILED(hr))
  2570. {
  2571. dbgprint(L"dbg: AdminToolsOpenObject failed %x on %s\n", hr, sz);
  2572. PrintError(sz,global->GenDSErr);
  2573. goto end;
  2574. }
  2575. // clean the display name (displayName)
  2576. // strip any WQL filters to <not set> (gPCWQLFilter)
  2577. Var.Clear();
  2578. Var.ChangeType(VT_BSTR);
  2579. Var.bstrVal = SysAllocString(L"Default Domain Policy");
  2580. if ( Var.bstrVal )
  2581. {
  2582. hr = pADs->Put(DisplayName, Var);
  2583. }
  2584. else
  2585. {
  2586. hr = E_OUTOFMEMORY;
  2587. }
  2588. if (FAILED(hr))
  2589. {
  2590. dbgprint(L"dbg: Put failed on displayName %x\n", hr);
  2591. PrintError(sz,global->DSAttrib);
  2592. goto end;
  2593. }
  2594. // reset flags to 0 (flags)
  2595. Var.Clear();
  2596. Var.ChangeType(VT_I4);
  2597. Var.lVal = 0;
  2598. hr = pADs->Put(GPOFlags, Var);
  2599. if (FAILED(hr))
  2600. {
  2601. dbgprint(L"dbg: Put failed on flags %x\n", hr);
  2602. PrintError(sz,global->DSAttrib);
  2603. goto end;
  2604. }
  2605. // set the filesys path (gPCFileSysPath)
  2606. hr = StringCchPrintf( sz,
  2607. sizeof(sz)/sizeof(sz[0]),
  2608. L"\\\\%s\\sysvol\\%s\\Policies\\%s",
  2609. global->pDomainInfo->DomainNameDns,
  2610. global->pDomainInfo->DomainNameDns,
  2611. DOMAIN_GUID );
  2612. if (FAILED(hr))
  2613. {
  2614. PrintError(hr);
  2615. goto end;
  2616. }
  2617. Var.Clear();
  2618. Var.ChangeType(VT_BSTR);
  2619. Var.bstrVal = SysAllocString(sz);
  2620. if ( Var.bstrVal )
  2621. {
  2622. hr = pADs->Put(GPCFileSysPath, Var);
  2623. }
  2624. else
  2625. {
  2626. hr = E_OUTOFMEMORY;
  2627. }
  2628. if (FAILED(hr))
  2629. {
  2630. dbgprint(L"dbg: Put failed on gPCFileSysPath %x\n", hr);
  2631. PrintError(sz,global->DSAttrib);
  2632. goto end;
  2633. }
  2634. // set the version to 2 (gPCFunctionalityVersion)
  2635. Var.Clear();
  2636. Var.ChangeType(VT_I4);
  2637. Var.lVal = 2;
  2638. hr = pADs->Put(GPCFunctionalityVersion, Var);
  2639. if (FAILED(hr))
  2640. {
  2641. dbgprint(L"dbg: Put failed on gPCFunctionalityVersion %x\n", hr);
  2642. PrintError(sz,global->DSAttrib);
  2643. goto end;
  2644. }
  2645. //
  2646. // Increment the version number
  2647. //
  2648. Var.Clear();
  2649. Var.ChangeType(VT_I4);
  2650. Var.lVal = global->lDDPVersionNo;
  2651. hr = pADs->Put(VersionNumber, Var);
  2652. if( FAILED(hr))
  2653. {
  2654. dbgprint(L"dbg: Put failed on version number %x\n", hr);
  2655. PrintError(sz,global->DSAttrib);
  2656. goto end;
  2657. }
  2658. //
  2659. // set the extensions (gPCUserExtensionNames)
  2660. //
  2661. Var.Clear();
  2662. Var.ChangeType(VT_BSTR);
  2663. Var.bstrVal = SysAllocString(DDP_USEREXT);
  2664. if ( Var.bstrVal )
  2665. {
  2666. hr = pADs->Put(GPCUserExtensionNames, Var);
  2667. }
  2668. else
  2669. {
  2670. hr = E_OUTOFMEMORY;
  2671. }
  2672. if( FAILED(hr))
  2673. {
  2674. dbgprint(L"dbg: Put failed on gPCUserExtensionNames %x\n", hr);
  2675. PrintError(sz,global->DSAttrib);
  2676. goto end;
  2677. }
  2678. //
  2679. // set the extensions (gPCMachineExtensionNames)
  2680. //
  2681. Var.Clear();
  2682. Var.ChangeType(VT_BSTR);
  2683. Var.bstrVal = SysAllocString(DDP_MACHEXT);
  2684. if ( Var.bstrVal )
  2685. {
  2686. hr = pADs->Put(GPCMachineExtensionNames, Var);
  2687. }
  2688. else
  2689. {
  2690. hr = E_OUTOFMEMORY;
  2691. }
  2692. if( FAILED(hr))
  2693. {
  2694. dbgprint(L"dbg: Put failed on gPCMachineExtensionNames %x\n", hr);
  2695. PrintError(sz,global->DSAttrib);
  2696. goto end;
  2697. }
  2698. // strip any WQL filters to <not set> (gPCWQLFilter)
  2699. Var.Clear();
  2700. Var.ChangeType(VT_BSTR);
  2701. Var.bstrVal = NULL;
  2702. hr = pADs->PutEx(ADS_PROPERTY_CLEAR, GPCWQLFilter, Var);
  2703. if (FAILED(hr))
  2704. {
  2705. dbgprint(L"Put failed on gPCWQLFilter %x\n", hr);
  2706. PrintError(sz,global->DSAttrib);
  2707. goto end;
  2708. }
  2709. // and update it
  2710. hr = pADs->SetInfo();
  2711. if (FAILED(hr))
  2712. {
  2713. dbgprint(L"dbg: SetInfo failed %x\n", hr);
  2714. PrintError(sz,global->DSAttrib);
  2715. goto end;
  2716. }
  2717. }
  2718. if (global->RestoreType & GLOBALS::RESTORE_DC)
  2719. {
  2720. hr = StringCchPrintf( sz,
  2721. sizeof(sz)/sizeof(sz[0]),
  2722. L"LDAP://CN=%s,CN=Policies,CN=System,%s",
  2723. DC_GUID,
  2724. global->DomainNamingContext) ;
  2725. if (FAILED(hr))
  2726. {
  2727. PrintError(hr);
  2728. goto end;
  2729. }
  2730. hr = AdminToolsOpenObject(sz, NULL, NULL, ADS_SECURE_AUTHENTICATION | ADS_SERVER_BIND, IID_IADs, (void**)&pADs);
  2731. if ( FAILED(hr) && hr != (HRESULT_FROM_WIN32(ERROR_DS_NO_SUCH_OBJECT)) )
  2732. {
  2733. dbgprint(L"dbg: AdminToolsOpenObject failed %x on %s\n", hr, sz);
  2734. PrintError(sz,global->GenDSErr);
  2735. goto end;
  2736. }
  2737. else
  2738. {
  2739. CComPtr<IADsContainer> pFolder;
  2740. CComPtr<IDispatch> pDisp;
  2741. hr = StringCchPrintf( sz,
  2742. sizeof(sz)/sizeof(sz[0]),
  2743. L"LDAP://CN=Policies,CN=System,%s",
  2744. global->DomainNamingContext) ;
  2745. if (FAILED(hr))
  2746. {
  2747. PrintError(hr);
  2748. goto end;
  2749. }
  2750. hr = AdminToolsOpenObject(sz, NULL, NULL, ADS_SECURE_AUTHENTICATION | ADS_SERVER_BIND, IID_IADsContainer, (void**)&pFolder);
  2751. if (FAILED(hr))
  2752. {
  2753. dbgprint(L"dbg: AdminToolsOpenObject failed %x on %s\n", hr, sz);
  2754. PrintError(sz,global->GenDSErr);
  2755. goto end;
  2756. }
  2757. hr = StringCchPrintf( sz,
  2758. sizeof(sz)/sizeof(sz[0]),
  2759. L"CN=%s",
  2760. DC_GUID );
  2761. if (FAILED(hr))
  2762. {
  2763. PrintError(hr);
  2764. goto end;
  2765. }
  2766. {
  2767. CComBSTR ContainerPath(sz);
  2768. if ( ContainerPath )
  2769. {
  2770. hr = pFolder->Create(GroupPolicyContainerName, ContainerPath, &pDisp);
  2771. }
  2772. else
  2773. {
  2774. hr = E_OUTOFMEMORY;
  2775. }
  2776. if (FAILED(hr))
  2777. {
  2778. dbgprint(L"dbg: Create failed %x on %s\n", hr, sz);
  2779. PrintError(sz,global->DSCreate);
  2780. goto end;
  2781. }
  2782. }
  2783. hr = pDisp->QueryInterface(IID_IADs, (void**)&pADs);
  2784. if (FAILED(hr))
  2785. {
  2786. dbgprint(L"dbg: Query Interface failed %x for Creating IID_IADS\n", hr);
  2787. PrintError(sz,global->DSCreate);
  2788. goto end;
  2789. }
  2790. }
  2791. hr = StringCchPrintf( sz,
  2792. sizeof(sz)/sizeof(sz[0]),
  2793. L"LDAP://CN=Machine,CN=%s,CN=Policies,CN=System,%s",
  2794. DC_GUID,
  2795. global->DomainNamingContext) ;
  2796. if (FAILED(hr))
  2797. {
  2798. PrintError(hr);
  2799. goto end;
  2800. }
  2801. hr = ResetContainerFromDS(sz, pADs);
  2802. if (FAILED(hr))
  2803. {
  2804. dbgprint(L"ResetContainerFromDS failed %x on %s\n", hr, sz);
  2805. goto end;
  2806. }
  2807. hr = StringCchPrintf( sz,
  2808. sizeof(sz)/sizeof(sz[0]),
  2809. L"LDAP://CN=User,CN=%s,CN=Policies,CN=System,%s",
  2810. DC_GUID,
  2811. global->DomainNamingContext) ;
  2812. if (FAILED(hr))
  2813. {
  2814. PrintError(hr);
  2815. goto end;
  2816. }
  2817. hr = ResetContainerFromDS(sz, pADs);
  2818. if (FAILED(hr))
  2819. {
  2820. dbgprint(L"ResetContainerFromDS failed %x on %s\n", hr, sz);
  2821. goto end;
  2822. }
  2823. hr = StringCchPrintf( sz,
  2824. sizeof(sz)/sizeof(sz[0]),
  2825. L"LDAP://CN=%s,CN=Policies,CN=System,%s",
  2826. DC_GUID,
  2827. global->DomainNamingContext) ;
  2828. if (FAILED(hr))
  2829. {
  2830. PrintError(hr);
  2831. goto end;
  2832. }
  2833. hr = ADsGetObject(sz, IID_IADs, (void**)&pADs);
  2834. if (FAILED(hr))
  2835. {
  2836. dbgprint(L"dbg: AdminToolsOpenObject failed %x on %s\n", hr, sz);
  2837. PrintError(sz,global->GenDSErr);
  2838. goto end;
  2839. }
  2840. // clean the display name (displayName)
  2841. // strip any WQL filters to <not set> (gPCWQLFilter)
  2842. Var.Clear();
  2843. Var.ChangeType(VT_BSTR);
  2844. Var.bstrVal = SysAllocString(DEFAULT_DC_POLICY_NAME);
  2845. if ( Var.bstrVal )
  2846. {
  2847. hr = pADs->Put(DisplayName, Var);
  2848. }
  2849. else
  2850. {
  2851. hr = E_OUTOFMEMORY;
  2852. }
  2853. if (FAILED(hr))
  2854. {
  2855. dbgprint(L"dbg: Put failed on displayName %x\n", hr);
  2856. PrintError(sz, global->DSAttrib);
  2857. goto end;
  2858. }
  2859. // reset flags to 0 (flags)
  2860. Var.Clear();
  2861. Var.ChangeType(VT_I4);
  2862. Var.lVal = 0;
  2863. hr = pADs->Put(GPOFlags, Var);
  2864. if (FAILED(hr))
  2865. {
  2866. dbgprint(L"dbg: Put failed on flags %x\n", hr);
  2867. PrintError(sz,global->DSAttrib);
  2868. goto end;
  2869. }
  2870. // set the filesys path (gPCFileSysPath)
  2871. hr = StringCchPrintf( sz,
  2872. sizeof(sz)/sizeof(sz[0]),
  2873. L"\\\\%s\\sysvol\\%s\\Policies\\%s",
  2874. global->pDomainInfo->DomainNameDns,
  2875. global->pDomainInfo->DomainNameDns,
  2876. DC_GUID );
  2877. if (FAILED(hr))
  2878. {
  2879. PrintError(hr);
  2880. goto end;
  2881. }
  2882. Var.Clear();
  2883. Var.ChangeType(VT_BSTR);
  2884. Var.bstrVal = SysAllocString(sz);
  2885. if ( Var.bstrVal )
  2886. {
  2887. hr = pADs->Put(GPCFileSysPath, Var);
  2888. }
  2889. else
  2890. {
  2891. hr = E_OUTOFMEMORY;
  2892. }
  2893. if (FAILED(hr))
  2894. {
  2895. dbgprint(L"dbg: Put failed on gPCFileSysPath %x\n", hr);
  2896. PrintError(sz,global->DSAttrib);
  2897. goto end;
  2898. }
  2899. // set the version to 2 (gPCFunctionalityVersion)
  2900. Var.Clear();
  2901. Var.ChangeType(VT_I4);
  2902. Var.lVal = 2;
  2903. hr = pADs->Put(GPCFunctionalityVersion, Var);
  2904. if (FAILED(hr))
  2905. {
  2906. dbgprint(L"dbg: Put failed on gPCFunctionalityVersion %x\n", hr);
  2907. PrintError(sz,global->DSAttrib);
  2908. goto end;
  2909. }
  2910. //
  2911. // Increment the version number
  2912. //
  2913. Var.Clear();
  2914. Var.ChangeType(VT_I4);
  2915. Var.lVal = global->lDDCPVersionNo;
  2916. hr = pADs->Put(VersionNumber, Var);
  2917. if( FAILED(hr))
  2918. {
  2919. dbgprint(L"dbg: Put failed on version number %x\n", hr);
  2920. PrintError(sz,global->DSAttrib);
  2921. goto end;
  2922. }
  2923. //
  2924. // Set the (gPCUserExtensionNames) to <not set>
  2925. //
  2926. Var.Clear();
  2927. Var.ChangeType(VT_BSTR);
  2928. Var.bstrVal = NULL ;
  2929. hr = pADs->PutEx(ADS_PROPERTY_CLEAR, GPCUserExtensionNames, Var);
  2930. if (FAILED(hr))
  2931. {
  2932. dbgprint(L"dbg: Put failed on gPCUserExtensionNames %x\n", hr);
  2933. PrintError(sz,global->DSAttrib);
  2934. goto end;
  2935. }
  2936. //
  2937. // set the extensions (gPCMachineExtensionNames)
  2938. //
  2939. Var.Clear();
  2940. Var.ChangeType(VT_BSTR);
  2941. Var.bstrVal = SysAllocString(DDC_MACHEXT);
  2942. if ( Var.bstrVal )
  2943. {
  2944. hr = pADs->Put(GPCMachineExtensionNames, Var);
  2945. }
  2946. else
  2947. {
  2948. hr = E_OUTOFMEMORY;
  2949. }
  2950. if( FAILED(hr))
  2951. {
  2952. dbgprint(L"dbg: Put failed on gPCMachineExtensionNames %x\n", hr);
  2953. PrintError(sz,global->DSAttrib);
  2954. goto end;
  2955. }
  2956. // strip any WQL filters to <not set> (gPCWQLFilter)
  2957. Var.Clear();
  2958. Var.ChangeType(VT_BSTR);
  2959. Var.bstrVal = NULL;
  2960. hr = pADs->PutEx(ADS_PROPERTY_CLEAR, GPCWQLFilter, Var);
  2961. if (FAILED(hr))
  2962. {
  2963. dbgprint(L"dbg: Put failed on gPCWQLFilter %x\n", hr);
  2964. PrintError(sz,global->DSAttrib);
  2965. goto end;
  2966. }
  2967. // and update it
  2968. hr = pADs->SetInfo();
  2969. if (FAILED(hr))
  2970. {
  2971. dbgprint(L"dbg: SetInfo failed %x\n", hr);
  2972. PrintError(sz,global->DSAttrib);
  2973. goto end;
  2974. }
  2975. }
  2976. hr = S_OK;
  2977. end:
  2978. return hr;
  2979. } // CleanPolicyObjects
  2980. CIgnoredGPO::CIgnoredGPO(
  2981. WCHAR* wszGPOID,
  2982. WCHAR* wszGPOName ) :
  2983. _pGptIniFile( NULL ),
  2984. _pGptTmplFile( NULL ),
  2985. _wszError( NULL )
  2986. {
  2987. //
  2988. // Note -- we handle errors in the constructor by leaving members
  2989. // set to NULL -- if these are NULL, other methods will fail
  2990. //
  2991. WCHAR* wszGptTmplPath = NULL;
  2992. WCHAR* wszGptIniPath = NULL;
  2993. ULONG uLength = 0;
  2994. uLength = lstrlen(global->SysVolPath) + 1 + lstrlen(global->pDomainInfo->DomainNameDns) + lstrlen(L"\\Policies")
  2995. + 1 + lstrlen(wszGPOID) + lstrlen(FILE_GPTTMPLINF)
  2996. + lstrlen(FILE_GPTINI) + 1;
  2997. wszGptTmplPath = (WCHAR*) LocalAlloc( LPTR, uLength * sizeof(WCHAR) );
  2998. if( NULL == wszGptTmplPath )
  2999. {
  3000. goto CIgnoredGPO_CIgnoredGPO_Exit;
  3001. }
  3002. wszGptIniPath = (WCHAR*) LocalAlloc( LPTR, uLength * sizeof(WCHAR) );
  3003. if( NULL == wszGptIniPath )
  3004. {
  3005. goto CIgnoredGPO_CIgnoredGPO_Exit;
  3006. }
  3007. HRESULT hr;
  3008. hr = StringCchPrintf(
  3009. wszGptTmplPath,
  3010. uLength,
  3011. L"%s\\%s\\Policies\\%s" FILE_GPTTMPLINF,
  3012. global->SysVolPath,
  3013. global->pDomainInfo->DomainNameDns,
  3014. wszGPOID);
  3015. ASSERT( SUCCEEDED(hr) );
  3016. hr = StringCchPrintf(
  3017. wszGptIniPath,
  3018. uLength,
  3019. L"%s\\%s\\Policies\\%s" FILE_GPTINI,
  3020. global->SysVolPath,
  3021. global->pDomainInfo->DomainNameDns,
  3022. wszGPOID );
  3023. ASSERT( SUCCEEDED(hr) );
  3024. _pGptTmplFile = new CGPOFile( wszGptTmplPath );
  3025. if ( _pGptTmplFile )
  3026. {
  3027. DWORD Status = InitializeErrorText(
  3028. wszGPOName );
  3029. if ( ERROR_SUCCESS == Status )
  3030. {
  3031. _pGptIniFile = new CGPOFile( wszGptIniPath );
  3032. }
  3033. }
  3034. CIgnoredGPO_CIgnoredGPO_Exit:
  3035. if ( wszGptIniPath )
  3036. {
  3037. LocalFree( wszGptIniPath );
  3038. }
  3039. if ( wszGptTmplPath )
  3040. {
  3041. LocalFree( wszGptTmplPath );
  3042. }
  3043. } // CIgnoredGPO::CIgnoredGPO
  3044. CIgnoredGPO::~CIgnoredGPO()
  3045. {
  3046. delete _pGptIniFile;
  3047. delete _pGptTmplFile;
  3048. LocalFree( _wszError );
  3049. }
  3050. DWORD
  3051. CIgnoredGPO::Backup()
  3052. {
  3053. DWORD Status = ERROR_SUCCESS;
  3054. //
  3055. // Detect failure in the constructor by checking
  3056. // that necessary members are properly initialized to non-NULL values
  3057. //
  3058. if ( ! _pGptIniFile || ! _pGptTmplFile )
  3059. {
  3060. Status = ERROR_OUTOFMEMORY;
  3061. goto CIgnoredGPO_Backup_CleanupAndExit;
  3062. }
  3063. Status = _pGptIniFile->Backup();
  3064. if ( ERROR_SUCCESS != Status )
  3065. {
  3066. dbgprint(L"Failed to back up gpt.ini file\n");
  3067. goto CIgnoredGPO_Backup_CleanupAndExit;
  3068. }
  3069. Status = _pGptTmplFile->Backup();
  3070. if ( ERROR_SUCCESS != Status )
  3071. {
  3072. dbgprint(L"Failed to back up gpttmpl.inf file\n");
  3073. goto CIgnoredGPO_Backup_CleanupAndExit;
  3074. }
  3075. CIgnoredGPO_Backup_CleanupAndExit:
  3076. return Status;
  3077. } // CIgnoredGPO::Backup
  3078. DWORD
  3079. CIgnoredGPO::Restore()
  3080. {
  3081. DWORD Status = ERROR_SUCCESS;
  3082. DWORD StatusIniFile;
  3083. DWORD StatusTmplFile;
  3084. StatusIniFile = _pGptIniFile->Restore();
  3085. StatusTmplFile = _pGptTmplFile->Restore();
  3086. if ( ERROR_SUCCESS != StatusIniFile )
  3087. {
  3088. Status = StatusIniFile;
  3089. dbgprint(L"Failed to restore gpt.ini");
  3090. }
  3091. else if ( ERROR_SUCCESS != StatusTmplFile )
  3092. {
  3093. Status = StatusTmplFile;
  3094. DisplayError(_wszError);
  3095. }
  3096. if ( ERROR_SUCCESS != StatusTmplFile )
  3097. {
  3098. dbgprint(L"Failed to restore gpttmpl.inf\n");
  3099. }
  3100. return Status;
  3101. } // CIgnoredGPO::Restore
  3102. DWORD
  3103. CIgnoredGPO::InitializeErrorText(
  3104. WCHAR* wszGPOName )
  3105. {
  3106. //
  3107. // global->RestoreIgnoredGPOFail + GPTTmplPath + GPOName + 1
  3108. //
  3109. DWORD uLength = lstrlen(global->RestoreIgnoredGPOFail) + lstrlen(_pGptTmplFile->GetPath()) + lstrlen(wszGPOName) + 1;
  3110. _wszError = (WCHAR *) LocalAlloc(LPTR, sizeof(WCHAR) * uLength);
  3111. if ( NULL == _wszError )
  3112. {
  3113. return ERROR_OUTOFMEMORY;
  3114. }
  3115. HRESULT hr = StringCchPrintf(_wszError, uLength, global->RestoreIgnoredGPOFail, _pGptTmplFile->GetPath(), wszGPOName);
  3116. ASSERT(SUCCEEDED(hr));
  3117. return ERROR_SUCCESS;
  3118. }
  3119. CGPOFile::CGPOFile( WCHAR* wszFilePath ) :
  3120. _wszFullPath( NULL ),
  3121. _pFileData( NULL ),
  3122. _cbFileSize( 0 )
  3123. {
  3124. //
  3125. // Note -- we handle errors in the constructor by leaving the path
  3126. // set to NULL -- if this is NULL, other methods will fail
  3127. //
  3128. DWORD cchPath = lstrlen( wszFilePath ) + 1;
  3129. _wszFullPath = (WCHAR*) LocalAlloc( LPTR, cchPath * sizeof( *_wszFullPath ) );
  3130. if ( NULL == _wszFullPath )
  3131. {
  3132. return;
  3133. }
  3134. HRESULT hr;
  3135. hr = StringCchCopy(
  3136. _wszFullPath,
  3137. cchPath,
  3138. wszFilePath );
  3139. ASSERT( SUCCEEDED(hr) );
  3140. } // CGPOFile::CGPOFile
  3141. CGPOFile::~CGPOFile()
  3142. {
  3143. if ( _wszFullPath )
  3144. {
  3145. LocalFree( _wszFullPath );
  3146. }
  3147. if ( _pFileData )
  3148. {
  3149. LocalFree( _pFileData );
  3150. }
  3151. }
  3152. DWORD
  3153. CGPOFile::Backup()
  3154. {
  3155. DWORD Status = ERROR_SUCCESS;
  3156. HANDLE hFile = NULL;
  3157. //
  3158. // Detect failure in the constructor by checking
  3159. // that necessary path members is properly initialized to a non-NULL value
  3160. //
  3161. if ( NULL == _wszFullPath )
  3162. {
  3163. Status = ERROR_OUTOFMEMORY;
  3164. goto CGPOFile_Backup_CleanupAndExit;
  3165. }
  3166. hFile = CreateFile(
  3167. _wszFullPath,
  3168. GENERIC_READ,
  3169. FILE_SHARE_READ,
  3170. NULL,
  3171. OPEN_EXISTING,
  3172. 0,
  3173. NULL);
  3174. if ( INVALID_HANDLE_VALUE == hFile )
  3175. {
  3176. Status = GetLastError();
  3177. if ( ( ERROR_FILE_NOT_FOUND == Status ) ||
  3178. ( ERROR_PATH_NOT_FOUND == Status ) )
  3179. {
  3180. Status = ERROR_SUCCESS;
  3181. }
  3182. hFile = NULL;
  3183. goto CGPOFile_Backup_CleanupAndExit;
  3184. }
  3185. DWORD cbFileSize;
  3186. DWORD cbFileSizeHigh;
  3187. cbFileSize = GetFileSize(
  3188. hFile,
  3189. &cbFileSizeHigh);
  3190. if ( -1 == cbFileSize )
  3191. {
  3192. Status = GetLastError();
  3193. goto CGPOFile_Backup_CleanupAndExit;
  3194. }
  3195. if ( 0 != cbFileSizeHigh )
  3196. {
  3197. Status = ERROR_INVALID_DATA;
  3198. goto CGPOFile_Backup_CleanupAndExit;
  3199. }
  3200. _pFileData = (BYTE*) LocalAlloc( LPTR, cbFileSize );
  3201. if ( NULL == _pFileData )
  3202. {
  3203. Status = ERROR_OUTOFMEMORY;
  3204. goto CGPOFile_Backup_CleanupAndExit;
  3205. }
  3206. BOOL bReadSucceeded;
  3207. DWORD cbRead;
  3208. bReadSucceeded = ReadFile(
  3209. hFile,
  3210. _pFileData,
  3211. cbFileSize,
  3212. &cbRead,
  3213. NULL);
  3214. if ( ! bReadSucceeded )
  3215. {
  3216. Status = GetLastError();
  3217. goto CGPOFile_Backup_CleanupAndExit;
  3218. }
  3219. //
  3220. // Don't set this to non-zero until we've successfully read the file --
  3221. // this way a call to Restore() will do nothing if any of these operations
  3222. // have failed (it won't try to write back bogus data)
  3223. //
  3224. _cbFileSize = cbFileSize;
  3225. CGPOFile_Backup_CleanupAndExit:
  3226. if ( NULL != hFile )
  3227. {
  3228. CloseHandle( hFile );
  3229. }
  3230. return Status;
  3231. } // CGPOFile::Backup
  3232. DWORD
  3233. CGPOFile::Restore()
  3234. {
  3235. DWORD Status = ERROR_SUCCESS;
  3236. HANDLE hFile = NULL;
  3237. //
  3238. // Zero sized files are invalid, so if we are called with this, we know
  3239. // the file did not exist and does not need to be restored (or we couldn't
  3240. // back up the file, in which case we shouldn't try to restore anything)
  3241. //
  3242. if ( 0 == _cbFileSize )
  3243. {
  3244. goto RestoreGPOFile_CleanupAndExit;
  3245. }
  3246. hFile = CreateFile(
  3247. _wszFullPath,
  3248. GENERIC_WRITE,
  3249. FILE_SHARE_READ,
  3250. NULL,
  3251. OPEN_EXISTING,
  3252. 0,
  3253. NULL);
  3254. if ( INVALID_HANDLE_VALUE == hFile )
  3255. {
  3256. Status = GetLastError();
  3257. goto RestoreGPOFile_CleanupAndExit;
  3258. }
  3259. BOOL bWriteSucceeded;
  3260. //
  3261. // First we need to truncate the file to 0 -- otherwise,
  3262. // if the file is larger than the data we're about to write, the
  3263. // extra data in the current version of the file will still exist
  3264. // when we're done.
  3265. //
  3266. bWriteSucceeded = SetEndOfFile( hFile );
  3267. if ( ! bWriteSucceeded )
  3268. {
  3269. Status = GetLastError();
  3270. goto RestoreGPOFile_CleanupAndExit;
  3271. }
  3272. DWORD dwWritten;
  3273. bWriteSucceeded = WriteFile(
  3274. hFile,
  3275. _pFileData,
  3276. _cbFileSize,
  3277. &dwWritten,
  3278. NULL);
  3279. if ( ! bWriteSucceeded )
  3280. {
  3281. Status = GetLastError();
  3282. goto RestoreGPOFile_CleanupAndExit;
  3283. }
  3284. RestoreGPOFile_CleanupAndExit:
  3285. if ( NULL != hFile )
  3286. {
  3287. CloseHandle( hFile );
  3288. }
  3289. return Status;
  3290. } // CGPOFile::Restore
  3291. WCHAR*
  3292. CGPOFile::GetPath()
  3293. {
  3294. return _wszFullPath;
  3295. } // CGPOFile::GetPath
  3296. int
  3297. _cdecl
  3298. wmain(
  3299. int argc,
  3300. WCHAR ** argv
  3301. )
  3302. {
  3303. DWORD dwError;
  3304. BOOL bError;
  3305. HRESULT hr = E_FAIL;
  3306. BOOL bIsDomain;
  3307. BOOL bIsAdmin;
  3308. WCHAR sz[256];
  3309. ULONG Length;
  3310. ULONG Type;
  3311. WCHAR *TempPath = NULL;
  3312. WCHAR *szProfilePath = NULL;
  3313. HKEY Key = NULL;
  3314. BOOL UnknownArgs = FALSE;
  3315. LONG lError;
  3316. LPBYTE pShareName = NULL;
  3317. WCHAR szVersionNo[MAX_VERSION_LENGTH];
  3318. NET_API_STATUS netapiStatus;
  3319. dbgprint(L"dbg: wmain started !\n");
  3320. WCHAR achCodePage[13] = L".OCP";
  3321. UINT CodePage = GetConsoleOutputCP();
  3322. //
  3323. // Set locale to the default
  3324. //
  3325. if ( 0 != CodePage )
  3326. {
  3327. _ultow( CodePage, achCodePage + 1, 10 );
  3328. }
  3329. _wsetlocale(LC_ALL, achCodePage);
  3330. SetThreadUILanguage(0);
  3331. hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
  3332. if (FAILED(hr))
  3333. {
  3334. PrintError(hr);
  3335. goto end;
  3336. }
  3337. global->RestoreType = GLOBALS::RESTORE_BOTH;
  3338. hr = global->Init();
  3339. if (FAILED(hr))
  3340. {
  3341. PrintError(hr);
  3342. goto end;
  3343. }
  3344. if (argc > 1 && argv[1] != NULL)
  3345. {
  3346. int iIndex = 1;
  3347. if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, argv[1], -1, L"/?", -1) == CSTR_EQUAL)
  3348. {
  3349. wprintf(global->Banner1);
  3350. wprintf(global->TargetSwitch);
  3351. wprintf(global->IgnSchSwitch);
  3352. hr = S_OK;
  3353. goto end;
  3354. }
  3355. Length = lstrlen(argv[1]);
  3356. if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, argv[1], -1, TARGET_ARG_IGNORE_SCHEMA, -1) == CSTR_EQUAL)
  3357. {
  3358. global->bIgnoreSchema = TRUE;
  3359. iIndex = 2;
  3360. }
  3361. // check if a target was specified
  3362. if (argc == iIndex + 1 && argv[iIndex] != NULL)
  3363. {
  3364. Length = lstrlen(argv[iIndex]);
  3365. if ( Length >= TARGET_ARG_COUNT &&
  3366. CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, argv[iIndex], TARGET_ARG_COUNT, TARGET_ARG, TARGET_ARG_COUNT) == CSTR_EQUAL)
  3367. {
  3368. WCHAR * p = &argv[iIndex][TARGET_ARG_COUNT];
  3369. if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, p, -1, TARGET_ARG_DOMAIN, -1) == CSTR_EQUAL)
  3370. {
  3371. global->RestoreType = GLOBALS::RESTORE_DOMAIN;
  3372. }
  3373. else if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, p, -1, TARGET_ARG_DC, -1) == CSTR_EQUAL)
  3374. {
  3375. global->RestoreType = GLOBALS::RESTORE_DC;
  3376. }
  3377. else if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, p, -1, TARGET_ARG_BOTH, -1) == CSTR_EQUAL)
  3378. {
  3379. global->RestoreType = GLOBALS::RESTORE_BOTH;
  3380. }
  3381. else
  3382. {
  3383. UnknownArgs = TRUE;
  3384. }
  3385. }
  3386. else
  3387. {
  3388. UnknownArgs = TRUE;
  3389. }
  3390. }
  3391. else if(argc > iIndex)
  3392. {
  3393. UnknownArgs = TRUE;
  3394. }
  3395. }
  3396. // print the banner
  3397. wprintf(global->Banner1);
  3398. wprintf(global->Banner2);
  3399. if (UnknownArgs)
  3400. {
  3401. hr = E_INVALIDARG;
  3402. PrintError(hr);
  3403. goto end;
  3404. }
  3405. if ( FALSE == global->bIgnoreSchema)
  3406. {
  3407. BOOL bSchemaVerCompat;
  3408. hr = CheckDSSchemaVersion( &bSchemaVerCompat);
  3409. if ( FAILED(hr))
  3410. {
  3411. dbgprint(L"CheckDSSchemaVersion Failed");
  3412. goto end;
  3413. }
  3414. if (FALSE == bSchemaVerCompat)
  3415. {
  3416. hr = E_FAIL;
  3417. DisplayError(global->WrongSchema);
  3418. goto end;
  3419. }
  3420. }
  3421. dbgprint(L"dbg: Choice is %d\n", global->RestoreType);
  3422. // check to see if we are on a domain controller.
  3423. hr = IsDomainController(&bIsDomain);
  3424. if (FAILED(hr))
  3425. {
  3426. PrintError(hr);
  3427. goto end;
  3428. }
  3429. if (bIsDomain == FALSE)
  3430. {
  3431. DisplayError(global->ErrorNoAD);
  3432. hr = S_OK;
  3433. goto end;
  3434. }
  3435. // Copy the domain name
  3436. hr = GetDomainFQDN(global->pDomainInfo->DomainNameDns, &(global->DomainNamingContext));
  3437. if (FAILED(hr))
  3438. {
  3439. PrintError(hr);
  3440. goto end;
  3441. }
  3442. // check to see if we are a member of domain/enterprise admins
  3443. hr = IsAdmin(&bIsAdmin);
  3444. if (FAILED(hr))
  3445. {
  3446. goto end;
  3447. }
  3448. if (FALSE == bIsAdmin)
  3449. {
  3450. DisplayError(global->ErrorNotAdmin);
  3451. hr = S_OK;
  3452. goto end;
  3453. }
  3454. switch(global->RestoreType)
  3455. {
  3456. case GLOBALS::RESTORE_DOMAIN:
  3457. wprintf(global->DispDDP);
  3458. break;
  3459. case GLOBALS::RESTORE_DC:
  3460. wprintf(global->DispDDCP);
  3461. break;
  3462. case GLOBALS::RESTORE_BOTH:
  3463. wprintf(global->DispBoth);
  3464. break;
  3465. default:
  3466. break;
  3467. }
  3468. wprintf(global->pDomainInfo->DomainNameDns);
  3469. wprintf(L"\n");
  3470. // is he sure ?
  3471. WCHAR szFirstChar[2];
  3472. // Here the first character of the user's input is converted as a string to compare with another string
  3473. szFirstChar[1] = L'\0';
  3474. do
  3475. {
  3476. wprintf(global->ErrorContinue);
  3477. szFirstChar[0] = getwchar();
  3478. if (L'\n' != szFirstChar[0] )
  3479. {
  3480. if ( CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, global->CharYes, -1, szFirstChar, -1) != CSTR_EQUAL )
  3481. {
  3482. // The case where szFirstChar[0] is WEOF is also handled here
  3483. hr = S_OK;
  3484. goto end;
  3485. }
  3486. else
  3487. {
  3488. // Skip until carriage return character
  3489. // We do this because we do not want to take the input until the user presses carriage return
  3490. do{
  3491. szFirstChar[0] = getwchar();
  3492. }while( szFirstChar[0] != '\n' && szFirstChar[0] != WEOF);
  3493. break;
  3494. }
  3495. }
  3496. // Prompt user again if user enters only carriage return
  3497. // This case is handled by going through this while loop again
  3498. } while(TRUE);
  3499. szFirstChar[1] = '\0';
  3500. wprintf(global->WarnURA);
  3501. do
  3502. {
  3503. wprintf(global->ErrorContinue);
  3504. szFirstChar[0] = getwchar();
  3505. if (L'\n' != szFirstChar[0] )
  3506. {
  3507. if ( CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, global->CharYes, -1, szFirstChar, -1) != CSTR_EQUAL )
  3508. {
  3509. hr = S_OK;
  3510. goto end;
  3511. }
  3512. else
  3513. {
  3514. do{
  3515. szFirstChar[0] = getwchar();
  3516. }while( szFirstChar[0] != '\n' && szFirstChar[0] != WEOF);
  3517. break;
  3518. }
  3519. }
  3520. } while(TRUE);
  3521. // check the state of the sysvol
  3522. // find out where the sysvol is .
  3523. netapiStatus = NetShareGetInfo(NULL, L"sysvol", 2, &pShareName);
  3524. if ( NERR_Success == netapiStatus )
  3525. {
  3526. hr = StringCchCopy(global->SysVolPath, MAX_PATH, ((SHARE_INFO_2 *) pShareName )->shi2_path);
  3527. if (FAILED(hr))
  3528. {
  3529. PrintError(hr);
  3530. goto end;
  3531. }
  3532. NetApiBufferFree(pShareName);
  3533. }
  3534. else
  3535. {
  3536. DisplayError(global->ErrorBadSysVol);
  3537. hr = HRESULT_FROM_WIN32(netapiStatus);
  3538. goto end;
  3539. }
  3540. dbgprint(L"dbg: sysvol = '%s'\n", global->SysVolPath);
  3541. //
  3542. // Get the version Number from filesystem and DS
  3543. //
  3544. if (global->RestoreType & GLOBALS::RESTORE_DOMAIN)
  3545. {
  3546. hr = GetVersionNumber(DEFAULT_DOMAIN_POLICY);
  3547. if (FAILED(hr))
  3548. {
  3549. dbgprint(L"GetversionNo failed with error %x\n", hr);
  3550. goto end;
  3551. }
  3552. }
  3553. if (global->RestoreType & GLOBALS::RESTORE_DC)
  3554. {
  3555. hr = GetVersionNumber(DEFAULT_DOMAIN_CONTROLLER_POLICY);
  3556. if (FAILED(hr))
  3557. {
  3558. dbgprint(L"GetversionNo failed with error %x\n", hr);
  3559. goto end;
  3560. }
  3561. }
  3562. if ( global->RestoreType & GLOBALS::RESTORE_DOMAIN )
  3563. {
  3564. hr = SetDSSecurityDescriptor(DEFAULT_DOMAIN_POLICY);
  3565. if (FAILED(hr))
  3566. {
  3567. goto end;
  3568. }
  3569. }
  3570. if ( global->RestoreType & GLOBALS::RESTORE_DC )
  3571. {
  3572. hr = SetDSSecurityDescriptor(DEFAULT_DOMAIN_CONTROLLER_POLICY);
  3573. if (FAILED(hr))
  3574. {
  3575. goto end;
  3576. }
  3577. }
  3578. // clean the domains GPO
  3579. // clean the controller GPO
  3580. hr = CleanPolicyObjects();
  3581. if (FAILED(hr))
  3582. {
  3583. goto end;
  3584. }
  3585. //
  3586. // The string that TempPath will be holding will be like
  3587. // <sysvolpath>\<domain name>\policies\<guid>
  3588. // Memory is allocated for each directory name and for '\' if needed.
  3589. //
  3590. ULONG uLength = 0;
  3591. uLength = lstrlen(global->SysVolPath) + 1 + lstrlen(global->pDomainInfo->DomainNameDns) + lstrlen(L"\\Policies")
  3592. + 1 + lstrlen(DOMAIN_GUID) + lstrlen(FILE_GPTTMPLINF)
  3593. + lstrlen(FILE_GPTINI) + 1;
  3594. TempPath = (WCHAR*) LocalAlloc( LPTR, uLength * sizeof(WCHAR) );
  3595. if(NULL == TempPath)
  3596. {
  3597. hr = E_OUTOFMEMORY;
  3598. PrintError(hr);
  3599. goto end;
  3600. }
  3601. // now we need to clean + recreate the file system sysvol files+folders
  3602. // first, delete the tree's
  3603. if (global->RestoreType & GLOBALS::RESTORE_DOMAIN)
  3604. {
  3605. // see if we have an EFS cert to backup
  3606. hr = BackupEfsCert();
  3607. if ( FAILED(hr) )
  3608. {
  3609. goto end;
  3610. }
  3611. hr = StringCchPrintf( TempPath,
  3612. uLength,
  3613. L"%s\\%s\\Policies\\%s",
  3614. global->SysVolPath,
  3615. global->pDomainInfo->DomainNameDns,
  3616. DOMAIN_GUID );
  3617. if (FAILED(hr))
  3618. {
  3619. PrintError(hr);
  3620. goto end;
  3621. }
  3622. hr = DeleteTree(TempPath);
  3623. if (FAILED(hr))
  3624. {
  3625. goto end;
  3626. }
  3627. }
  3628. if (global->RestoreType & GLOBALS::RESTORE_DC)
  3629. {
  3630. hr = StringCchPrintf( TempPath,
  3631. uLength,
  3632. L"%s\\%s\\Policies\\%s",
  3633. global->SysVolPath,
  3634. global->pDomainInfo->DomainNameDns,
  3635. DC_GUID );
  3636. if (FAILED(hr))
  3637. {
  3638. PrintError(hr);
  3639. goto end;
  3640. }
  3641. hr = DeleteTree(TempPath);
  3642. if (FAILED(hr))
  3643. {
  3644. goto end;
  3645. }
  3646. }
  3647. // create fresh policy directory
  3648. // + put security permisions on these files + folders
  3649. if (global->RestoreType & GLOBALS::RESTORE_DOMAIN)
  3650. {
  3651. hr = CreateSysVolDomain();
  3652. if (FAILED(hr))
  3653. {
  3654. goto end;
  3655. }
  3656. if (!global->hasEFSInfo)
  3657. {
  3658. hr = CreateEFSCerts();
  3659. if (FAILED(hr))
  3660. {
  3661. PrintError(DDP, global->CreateEFS);
  3662. PrintError(hr);
  3663. goto end;
  3664. }
  3665. }
  3666. hr = SaveEFSCerts();
  3667. if (FAILED(hr))
  3668. {
  3669. goto end;
  3670. }
  3671. }
  3672. if (global->RestoreType & GLOBALS::RESTORE_DC)
  3673. {
  3674. hr = CreateSysVolController();
  3675. if (FAILED(hr))
  3676. {
  3677. goto end;
  3678. }
  3679. }
  3680. // for some strange reason the setup helper thinks sysvol should be
  3681. // one level higher than it really is
  3682. hr = StringCchCopy(TempPath, uLength, global->SysVolPath);
  3683. if (FAILED(hr))
  3684. {
  3685. PrintError(hr);
  3686. goto end;
  3687. }
  3688. Length = lstrlen(TempPath);
  3689. do {
  3690. Length -= 1;
  3691. } while (TempPath[Length] != L'\\');
  3692. TempPath[Length] = UNICODE_NULL;
  3693. {
  3694. WCHAR* wszIgnoredGPOId = NULL;
  3695. WCHAR* wszIgnoredGPOName = NULL;
  3696. CIgnoredGPO* pIgnoredGPO = NULL;
  3697. dwError = ERROR_SUCCESS;
  3698. if ( ! ( global->RestoreType & GLOBALS::RESTORE_DOMAIN) )
  3699. {
  3700. wszIgnoredGPOId = DOMAIN_GUID;
  3701. wszIgnoredGPOName = DDP;
  3702. }
  3703. else if ( ! ( global->RestoreType & GLOBALS::RESTORE_DC) )
  3704. {
  3705. wszIgnoredGPOId = DC_GUID;
  3706. wszIgnoredGPOName = DEFAULT_DC_POLICY_NAME;
  3707. }
  3708. if ( wszIgnoredGPOId )
  3709. {
  3710. pIgnoredGPO = new CIgnoredGPO( wszIgnoredGPOId, wszIgnoredGPOName );
  3711. if ( pIgnoredGPO )
  3712. {
  3713. dwError = pIgnoredGPO->Backup();
  3714. }
  3715. else
  3716. {
  3717. dwError = ERROR_OUTOFMEMORY;
  3718. }
  3719. }
  3720. if ( ERROR_SUCCESS == dwError )
  3721. {
  3722. dwError = SceDcPromoCreateGPOsInSysvol( global->pDomainInfo->DomainNameDns,
  3723. TempPath,
  3724. 0,
  3725. NULL );
  3726. if ( pIgnoredGPO )
  3727. {
  3728. DWORD RestoreError = pIgnoredGPO->Restore();
  3729. if ( ERROR_SUCCESS != RestoreError )
  3730. {
  3731. dbgprint(L"Failed to restore ignored gpo id %s with error %X\n", wszIgnoredGPOId, RestoreError );
  3732. if ( ERROR_SUCCESS == dwError )
  3733. {
  3734. dwError = RestoreError;
  3735. }
  3736. }
  3737. }
  3738. delete pIgnoredGPO;
  3739. }
  3740. }
  3741. if (dwError != 0 )
  3742. {
  3743. PrintError(dwError);
  3744. hr = HRESULT_FROM_WIN32(dwError);
  3745. dbgprint(L"SceDcPromoCreateGPOsInSysvol failed %X\n", hr);
  3746. goto end;
  3747. }
  3748. if ( global->RestoreType & GLOBALS::RESTORE_DC )
  3749. {
  3750. ULONG ulProfilePathLength;
  3751. //
  3752. // profile path + '\inf\defdcgpo' + '\0'
  3753. //
  3754. ulProfilePathLength = MAX_PATH + lstrlen(L"\\inf\\defdcgpo.inf") + 1;
  3755. szProfilePath = (WCHAR *) LocalAlloc( LPTR, sizeof(WCHAR) * ulProfilePathLength);
  3756. if ( NULL == szProfilePath )
  3757. {
  3758. hr = E_OUTOFMEMORY;
  3759. PrintError(hr);
  3760. goto end;
  3761. }
  3762. Length = GetWindowsDirectory(szProfilePath, MAX_PATH);
  3763. if (0 == Length)
  3764. {
  3765. hr = HRESULT_FROM_WIN32(dwError);
  3766. dbgprint(L"GetWindowsDirectory failed %X\n", hr);
  3767. LocalFree(szProfilePath);
  3768. goto end;
  3769. }
  3770. hr = StringCchPrintf(szProfilePath, ulProfilePathLength, L"%s\\inf\\defdcgpo.inf", szProfilePath);
  3771. if (FAILED(hr))
  3772. {
  3773. PrintError(hr);
  3774. goto end;
  3775. }
  3776. if ( FilePresent(szProfilePath) )
  3777. {
  3778. hr = StringCchPrintf(TempPath,
  3779. uLength,
  3780. L"%s\\%s\\Policies\\%s" FILE_GPTTMPLINF,
  3781. global->SysVolPath,
  3782. global->pDomainInfo->DomainNameDns,
  3783. DC_GUID);
  3784. if (FAILED(hr))
  3785. {
  3786. PrintError(hr);
  3787. goto end;
  3788. }
  3789. hr = CreateSecurityTemplate(szProfilePath, TempPath);
  3790. if (FAILED(hr))
  3791. {
  3792. hr = HRESULT_FROM_WIN32(dwError);
  3793. dbgprint(L"createSecurityTemplate failed %X\n", hr);
  3794. LocalFree(szProfilePath);
  3795. goto end;
  3796. }
  3797. }
  3798. LocalFree(szProfilePath);
  3799. }
  3800. if (global->RestoreType & GLOBALS::RESTORE_DOMAIN)
  3801. {
  3802. hr = StringCchPrintf(TempPath,
  3803. uLength,
  3804. L"%s\\%s\\Policies\\%s" FILE_GPTINI,
  3805. global->SysVolPath,
  3806. global->pDomainInfo->DomainNameDns,
  3807. DOMAIN_GUID );
  3808. if (FAILED(hr))
  3809. {
  3810. PrintError(hr);
  3811. goto end;
  3812. }
  3813. hr = StringCchPrintf(szVersionNo,
  3814. MAX_VERSION_LENGTH,
  3815. L"%d",
  3816. global->lDDPVersionNo);
  3817. if (FAILED(hr))
  3818. {
  3819. PrintError(hr);
  3820. goto end;
  3821. }
  3822. bError = WritePrivateProfileString(L"General", L"Version", szVersionNo, TempPath);
  3823. if (bError == FALSE)
  3824. {
  3825. dwError = GetLastError();
  3826. PrintError(TempPath, global->DirWrite);
  3827. hr = HRESULT_FROM_WIN32(dwError);
  3828. goto end;
  3829. }
  3830. }
  3831. if (global->RestoreType & GLOBALS::RESTORE_DC)
  3832. {
  3833. hr = StringCchPrintf(TempPath,
  3834. uLength,
  3835. L"%s\\%s\\Policies\\%s" FILE_GPTINI,
  3836. global->SysVolPath,
  3837. global->pDomainInfo->DomainNameDns,
  3838. DC_GUID );
  3839. if (FAILED(hr))
  3840. {
  3841. PrintError(hr);
  3842. goto end;
  3843. }
  3844. hr = StringCchPrintf(szVersionNo,
  3845. MAX_VERSION_LENGTH,
  3846. L"%d",
  3847. global->lDDCPVersionNo);
  3848. if (FAILED(hr))
  3849. {
  3850. PrintError(hr);
  3851. goto end;
  3852. }
  3853. bError = WritePrivateProfileString(L"General", L"Version", szVersionNo, TempPath);
  3854. if (bError == FALSE)
  3855. {
  3856. dwError = GetLastError();
  3857. PrintError(TempPath, global->DirWrite);
  3858. hr = HRESULT_FROM_WIN32(dwError);
  3859. goto end;
  3860. }
  3861. }
  3862. if (global->RestoreType & GLOBALS::RESTORE_DOMAIN)
  3863. {
  3864. wprintf(global->DDPSuccess);
  3865. }
  3866. if (global->RestoreType & GLOBALS::RESTORE_DC)
  3867. {
  3868. wprintf(global->DDCPSuccess);
  3869. }
  3870. hr = S_OK;
  3871. end:
  3872. if(TempPath != NULL)
  3873. {
  3874. LocalFree(TempPath);
  3875. }
  3876. if (Key != NULL)
  3877. {
  3878. RegCloseKey(Key);
  3879. Key = NULL;
  3880. }
  3881. if (FAILED(hr))
  3882. {
  3883. wprintf(global->ToolFailed);
  3884. }
  3885. if (global->pGPO)
  3886. {
  3887. global->pGPO->Release();
  3888. }
  3889. CoUninitialize();
  3890. return hr;
  3891. } // wmain