Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2541 lines
70 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. pfset.cpp
  5. Abstract:
  6. Routines to set info to the jet database.
  7. Author:
  8. Jin Huang (jinhuang) 28-Oct-1996
  9. Revision History:
  10. --*/
  11. #include "headers.h"
  12. #include "serverp.h"
  13. #include "pfp.h"
  14. #include "regvalue.h"
  15. #pragma hdrstop
  16. //#define SCE_DBG 1
  17. SCESTATUS
  18. ScepOpenPrevPolicyContext(
  19. IN PSCECONTEXT hProfile,
  20. OUT PSCECONTEXT *phPrevProfile
  21. );
  22. SCESTATUS
  23. ScepClosePrevPolicyContext(
  24. IN OUT PSCECONTEXT *phProfile
  25. );
  26. SCESTATUS
  27. ScepStartANewSection(
  28. IN PSCECONTEXT hProfile,
  29. IN OUT PSCESECTION *hSection,
  30. IN SCEJET_TABLE_TYPE ProfileType,
  31. IN PCWSTR SectionName
  32. )
  33. /* ++
  34. Routine Description:
  35. This routine open a JET section by Name. If the section exists, it is
  36. opened, else it is created.
  37. Arguments:
  38. hProfile - The JET database handle
  39. hSection - the JET section handle to return
  40. ProfileType - the table to open
  41. SectionName - the JET section name
  42. Return Value:
  43. SCESTATUS_SUCCESS
  44. SCESTATUS returned from SceJetCloseSection,
  45. SceJetAddSection,
  46. SceJetOpenSection
  47. -- */
  48. {
  49. SCESTATUS rc=SCESTATUS_SUCCESS;
  50. DOUBLE SectionID;
  51. if ( *hSection != NULL ) {
  52. //
  53. // free the previous used section
  54. //
  55. rc = SceJetCloseSection( hSection, FALSE );
  56. }
  57. if ( rc == SCESTATUS_SUCCESS ) {
  58. //
  59. // SceJetAddSection will seek for the section name first.
  60. // if a match is found, the section id is returned, else add it.
  61. // this is good for SAP profile.
  62. //
  63. rc = SceJetAddSection(
  64. hProfile,
  65. SectionName,
  66. &SectionID
  67. );
  68. if ( rc == SCESTATUS_SUCCESS ) {
  69. rc = SceJetOpenSection(
  70. hProfile,
  71. SectionID,
  72. ProfileType,
  73. hSection
  74. );
  75. }
  76. }
  77. return( rc );
  78. }
  79. SCESTATUS
  80. ScepCompareAndSaveIntValue(
  81. IN PSCESECTION hSection,
  82. IN PWSTR Name,
  83. IN BOOL bReplaceExistOnly,
  84. IN DWORD BaseValue,
  85. IN DWORD CurrentValue
  86. )
  87. /* ++
  88. Routine Description:
  89. This routine compares DWORD value system settings with the baseline profile
  90. settings. If there is mismatch or unknown, the entry is saved in the SAP
  91. profile.
  92. Arguments:
  93. hSection - The JET section context
  94. Name - The entry name
  95. BaseLine- The baseline profile value to compare with
  96. CurrentValue - The current system setting (DWORD value)
  97. Return Value:
  98. SCESTATUS_SUCCESS
  99. SCESTATUS_INVALID_PARAMETER
  100. SCESTATUS returned from SceJetSetLine
  101. -- */
  102. {
  103. SCESTATUS rc;
  104. TCHAR StrValue[12];
  105. if ( Name == NULL )
  106. return(SCESTATUS_INVALID_PARAMETER);
  107. if ( CurrentValue == SCE_NO_VALUE ) {
  108. return(SCESTATUS_SUCCESS);
  109. }
  110. if ( ( CurrentValue == BaseValue) &&
  111. ( BaseValue != SCE_NO_VALUE) &&
  112. ( BaseValue != SCE_SNAPSHOT_VALUE) ) {
  113. return(SCESTATUS_SUCCESS);
  114. }
  115. if ( bReplaceExistOnly &&
  116. (BaseValue == SCE_NO_VALUE) ) {
  117. return(SCESTATUS_SUCCESS);
  118. }
  119. memset(StrValue, '\0', 24);
  120. //
  121. // either mismatched/unknown
  122. // Save this entry
  123. //
  124. swprintf(StrValue, L"%d", CurrentValue);
  125. rc = SceJetSetLine( hSection, Name, FALSE, StrValue, wcslen(StrValue)*2, 0);
  126. switch ( BaseValue ) {
  127. case SCE_SNAPSHOT_VALUE:
  128. ScepLogOutput2(2, 0, StrValue);
  129. break;
  130. case SCE_NO_VALUE:
  131. if ( CurrentValue == SCE_ERROR_VALUE ) {
  132. ScepLogOutput3(2, 0, SCEDLL_STATUS_ERROR, Name);
  133. } else {
  134. ScepLogOutput3(2, 0, SCEDLL_STATUS_NC, Name);
  135. }
  136. break;
  137. default:
  138. ScepLogOutput3(2, 0, SCEDLL_STATUS_MISMATCH, Name);
  139. break;
  140. }
  141. #ifdef SCE_DBG
  142. wprintf(L"rc=%d, Section: %d, %s=%d\n", rc, (DWORD)(hSection->SectionID), Name, CurrentValue);
  143. #endif
  144. return(rc);
  145. }
  146. SCESTATUS
  147. ScepCompareAndSaveStringValue(
  148. IN PSCESECTION hSection,
  149. IN PWSTR Name,
  150. IN PWSTR BaseValue,
  151. IN PWSTR CurrentValue,
  152. IN DWORD CurrentLen
  153. )
  154. /* ++
  155. Routine Description:
  156. This routine compares system settings in string with the baseline profile
  157. settings. If there is mismatch or unknown, the entry is saved in the SAP
  158. profile.
  159. Arguments:
  160. hSection - The section handle
  161. Name - The entry name
  162. BaseLine- The baseline profile value to compare with
  163. CurrentValue - The current system setting
  164. CurrentLen - The length of the current setting
  165. Return Value:
  166. SCESTATUS_SUCCESS
  167. SCESTATUS_INVALID_PARAMETER
  168. SCESTATUS returned from SceJetSetLine
  169. -- */
  170. {
  171. SCESTATUS rc;
  172. if ( Name == NULL )
  173. return(SCESTATUS_INVALID_PARAMETER);
  174. if ( CurrentValue == NULL )
  175. return(SCESTATUS_SUCCESS);
  176. rc = SceJetSetLine( hSection, Name, FALSE, CurrentValue, CurrentLen, 0);
  177. if ( BaseValue ) {
  178. if ( (ULONG_PTR)BaseValue == SCE_SNAPSHOT_VALUE ) {
  179. ScepLogOutput2(2, 0, CurrentValue);
  180. } else {
  181. ScepLogOutput3(2, 0, SCEDLL_STATUS_MISMATCH, Name);
  182. }
  183. } else {
  184. ScepLogOutput3(2, 0, SCEDLL_STATUS_NC, Name);
  185. }
  186. #ifdef SCE_DBG
  187. wprintf(L"rc=%d, Section: %d, %s=%s\n", rc, (DWORD)(hSection->SectionID), Name, CurrentValue);
  188. #endif
  189. return(rc);
  190. }
  191. SCESTATUS
  192. ScepSaveObjectString(
  193. IN PSCESECTION hSection,
  194. IN PWSTR Name,
  195. IN BOOL IsContainer,
  196. IN BYTE Flag,
  197. IN PWSTR Value OPTIONAL,
  198. IN DWORD ValueLen
  199. )
  200. /* ++
  201. Routine Description:
  202. This routine writes registry/file settings to the JET section. Registry/
  203. file setting includes a flag (mismatch/unknown) and the security
  204. descriptor in text format. The object setting is saved in the format of
  205. 1 byte flag followed by the Value.
  206. Arguments:
  207. hSection - the JET section handle
  208. Name - The entry name
  209. IsContainer - TRUE = The object is a container
  210. FALSE = The object is not a container
  211. Flag - the flag for object's setting
  212. 1 - Mismatch
  213. 0 - Unknown
  214. Value - The security descriptor in text
  215. ValueLen - the length of the text security descriptor
  216. Return Value:
  217. SCESTATUS_SUCCESS
  218. SCESTATUS_INVALID_PARAMETER
  219. SCESTATUS returned from SceJetSetLine
  220. -- */
  221. {
  222. SCESTATUS rc;
  223. DWORD Len;
  224. PWSTR ValueToSet=NULL;
  225. if ( hSection == NULL ||
  226. Name == NULL ) {
  227. return(SCESTATUS_INVALID_PARAMETER);
  228. }
  229. if ( Value != NULL )
  230. Len = ( ValueLen+1)*sizeof(WCHAR);
  231. else
  232. Len = sizeof(WCHAR);
  233. ValueToSet = (PWSTR)ScepAlloc( (UINT)0, Len+sizeof(WCHAR) );
  234. if ( ValueToSet == NULL )
  235. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  236. //
  237. // The first byte is the flag, the second byte is IsContainer (1,0)
  238. //
  239. *((BYTE *)ValueToSet) = Flag;
  240. *((CHAR *)ValueToSet+1) = IsContainer ? '1' : '0';
  241. if ( Value != NULL ) {
  242. swprintf(ValueToSet+1, L"%s", Value );
  243. ValueToSet[ValueLen+1] = L'\0'; //terminate this string
  244. } else {
  245. ValueToSet[1] = L'\0';
  246. }
  247. rc = SceJetSetLine( hSection, Name, FALSE, ValueToSet, Len, 0);
  248. switch ( Flag ) {
  249. case SCE_STATUS_CHILDREN_CONFIGURED:
  250. case SCE_STATUS_NOT_CONFIGURED:
  251. ScepLogOutput3(2, 0, SCEDLL_STATUS_NC, Name);
  252. break;
  253. case SCE_STATUS_ERROR_NOT_AVAILABLE:
  254. ScepLogOutput3(2, 0, SCEDLL_STATUS_ERROR, Name);
  255. break;
  256. case SCE_STATUS_GOOD:
  257. ScepLogOutput3(2, 0, SCEDLL_STATUS_MATCH, Name);
  258. break;
  259. case SCE_STATUS_NEW_SERVICE:
  260. ScepLogOutput3(2, 0, SCEDLL_STATUS_NEW, Name);
  261. break;
  262. case SCE_STATUS_NO_ACL_SUPPORT:
  263. ScepLogOutput3(2, 0, SCEDLL_STATUS_NOACL, Name);
  264. break;
  265. default:
  266. ScepLogOutput3(2, 0, SCEDLL_STATUS_MISMATCH, Name);
  267. break;
  268. }
  269. #ifdef SCE_DBG
  270. wprintf(L"rc=%d, Section: %d, %s=%s\n", rc, (DWORD)(hSection->SectionID), Name, ValueToSet);
  271. #endif
  272. ScepFree( ValueToSet );
  273. return( rc );
  274. }
  275. SCESTATUS
  276. ScepWriteNameListValue(
  277. IN LSA_HANDLE LsaPolicy OPTIONAL,
  278. IN PSCESECTION hSection,
  279. IN PWSTR Name,
  280. IN PSCE_NAME_LIST NameList,
  281. IN DWORD dwWriteOption,
  282. IN INT Status
  283. )
  284. /* ++
  285. Routine Description:
  286. This routine writes a key with a list of value to the JET section. The list
  287. of values is saved in a MULTI-SZ format which is separated by a NULL char and
  288. terminated by 2 NULLs. If the list is NULL, nothing is saved unless
  289. SaveEmptyList is set to TRUE, where a NULL value is saved with the key.
  290. Arguments:
  291. hSection - the JET hsection handle
  292. Name - The key name
  293. NameList - the list of values
  294. SaveEmptyList - TRUE = save NULL value if the list is empty
  295. FALSE = DO NOT save if the list is empty
  296. Return Value:
  297. SCESTATUS_SUCCESS
  298. SCESTATUS_NOT_ENOUGH_RESOURCE
  299. SCESTATUS returned from SceJetSetLine
  300. -- */
  301. { SCESTATUS rc=SCESTATUS_SUCCESS;
  302. DWORD TotalSize=0;
  303. PWSTR Value=NULL;
  304. PSCE_NAME_LIST pName;
  305. PWSTR pTemp=NULL;
  306. DWORD Len;
  307. DWORD i=0,j;
  308. DWORD cntAllocated=0;
  309. SCE_TEMP_NODE *tmpArray=NULL, *pa=NULL;
  310. PWSTR SidString = NULL;
  311. for ( pName=NameList; pName != NULL; pName = pName->Next ) {
  312. if ( pName->Name == NULL ) {
  313. continue;
  314. }
  315. if ( dwWriteOption & SCE_WRITE_CONVERT ) {
  316. if ( i >= cntAllocated ) {
  317. //
  318. // array is not enough, reallocate
  319. //
  320. tmpArray = (SCE_TEMP_NODE *)ScepAlloc(LPTR, (cntAllocated+16)*sizeof(SCE_TEMP_NODE));
  321. if ( tmpArray ) {
  322. //
  323. // move pointers from the old array to the new array
  324. //
  325. if ( pa ) {
  326. for ( j=0; j<cntAllocated; j++ ) {
  327. tmpArray[j].Name = pa[j].Name;
  328. tmpArray[j].Len = pa[j].Len;
  329. tmpArray[j].bFree = pa[j].bFree;
  330. }
  331. ScepFree(pa);
  332. }
  333. pa = tmpArray;
  334. tmpArray = NULL;
  335. cntAllocated += 16;
  336. } else {
  337. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  338. break;
  339. }
  340. }
  341. if ( LsaPolicy && wcschr(pName->Name, L'\\') ) {
  342. //
  343. // check if the name has a '\' in it, it should be translated to
  344. // *SID
  345. //
  346. pTemp = NULL;
  347. ScepConvertNameToSidString(LsaPolicy, pName->Name, FALSE, &pTemp, &Len);
  348. if ( pTemp ) {
  349. pa[i].Name = pTemp;
  350. pa[i].bFree = TRUE;
  351. } else {
  352. pa[i].Name = pName->Name;
  353. pa[i].bFree = FALSE;
  354. Len= wcslen(pName->Name);
  355. }
  356. }
  357. else if (dwWriteOption & SCE_WRITE_LOCAL_TABLE &&
  358. ScepLookupNameTable( pName->Name, &SidString ) ) {
  359. pa[i].Name = SidString;
  360. pa[i].bFree = TRUE;
  361. Len = wcslen(SidString);
  362. }
  363. else {
  364. pa[i].Name = pName->Name;
  365. pa[i].bFree = FALSE;
  366. Len = wcslen(pName->Name);
  367. }
  368. pa[i].Len = Len;
  369. TotalSize += Len + 1;
  370. i++;
  371. } else {
  372. TotalSize += wcslen(pName->Name)+1;
  373. }
  374. }
  375. TotalSize ++;
  376. if ( SCESTATUS_SUCCESS == rc ) {
  377. if ( TotalSize > 1 ) {
  378. Value = (PWSTR)ScepAlloc( 0, (TotalSize+1)*sizeof(WCHAR));
  379. if ( Value == NULL )
  380. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  381. }
  382. }
  383. if ( SCESTATUS_SUCCESS == rc ) {
  384. if ( TotalSize > 1 ) {
  385. pTemp = Value;
  386. if ( dwWriteOption & SCE_WRITE_CONVERT ) {
  387. for (j=0; j<i; j++) {
  388. if ( pa[j].Name ) {
  389. if ( Status == 3 ) {
  390. ScepLogOutput2(2, 0, pa[j].Name);
  391. }
  392. wcsncpy(pTemp, pa[j].Name, pa[j].Len);
  393. pTemp += pa[j].Len;
  394. *pTemp = L'\0';
  395. pTemp++;
  396. }
  397. }
  398. } else {
  399. for ( pName=NameList; pName != NULL; pName = pName->Next ) {
  400. if ( pName->Name == NULL ) {
  401. continue;
  402. }
  403. if ( Status == 3 ) {
  404. ScepLogOutput2(2, 0, pName->Name);
  405. }
  406. Len = wcslen(pName->Name);
  407. wcsncpy(pTemp, pName->Name, Len);
  408. pTemp += Len;
  409. *pTemp = L'\0';
  410. pTemp++;
  411. }
  412. }
  413. *pTemp = L'\0';
  414. } else
  415. TotalSize = 0;
  416. if ( TotalSize > 0 || (dwWriteOption & SCE_WRITE_EMPTY_LIST) ) {
  417. rc = SceJetSetLine(
  418. hSection,
  419. Name,
  420. FALSE,
  421. Value,
  422. TotalSize*sizeof(WCHAR),
  423. 0
  424. );
  425. switch ( Status ) {
  426. case 1:
  427. ScepLogOutput3(2, 0, SCEDLL_STATUS_MISMATCH, Name);
  428. break;
  429. case 3: // no analyze, already printed
  430. break;
  431. case 2:
  432. ScepLogOutput3(2, 0, SCEDLL_STATUS_NC, Name);
  433. break;
  434. }
  435. #ifdef SCE_DBG
  436. if ( Value != NULL )
  437. wprintf(L"rc=%d, Section: %d, %s=%s\n", rc, (DWORD)(hSection->SectionID), Name, Value);
  438. else
  439. wprintf(L"rc=%d, Section: %d, %s=", rc, (DWORD)(hSection->SectionID), Name);
  440. #endif
  441. }
  442. if ( Value != NULL )
  443. ScepFree(Value);
  444. }
  445. if ( pa ) {
  446. for ( j=0; j<i; j++ ) {
  447. if ( pa[j].Name && pa[j].bFree ) {
  448. ScepFree(pa[j].Name);
  449. }
  450. }
  451. ScepFree(pa);
  452. }
  453. return(rc);
  454. }
  455. SCESTATUS
  456. ScepWriteNameStatusListValue(
  457. IN PSCESECTION hSection,
  458. IN PWSTR Name,
  459. IN PSCE_NAME_STATUS_LIST NameList,
  460. IN BOOL SaveEmptyList,
  461. IN INT Status
  462. )
  463. /* ++
  464. Routine Description:
  465. This routine writes a key with a list of values to the JET section. The list
  466. of values is saved in a MULTI-SZ format which is separated by a NULL char and
  467. terminated by 2 NULLs. If the list is NULL, nothing is saved unless
  468. SaveEmptyList is set to TRUE, where a NULL value is saved with the key.
  469. The format in each string in the MULTI-SZ value is a 2 bytes Status field
  470. followed by the Name field. This structure is primarily used for privileges
  471. Arguments:
  472. hSection - the JET hsection handle
  473. Name - The key name
  474. NameList - the list of values
  475. SaveEmptyList - TRUE = save NULL value if the list is empty
  476. FALSE = DO NOT save if the list is empty
  477. Return Value:
  478. SCESTATUS_SUCCESS
  479. SCESTATUS_NOT_ENOUGH_RESOURCE
  480. SCESTATUS returned from SceJetSetLine
  481. -- */
  482. {
  483. SCESTATUS rc=SCESTATUS_SUCCESS;
  484. DWORD TotalSize=0;
  485. PWSTR Value=NULL;
  486. PSCE_NAME_STATUS_LIST pName;
  487. PWSTR pTemp=NULL;
  488. DWORD Len;
  489. for ( pName=NameList; pName != NULL; pName = pName->Next ) {
  490. //
  491. // Privilege value is stored in 2 bytes
  492. //
  493. TotalSize += 2;
  494. if ( pName->Name != NULL)
  495. TotalSize += wcslen(pName->Name);
  496. TotalSize ++;
  497. }
  498. TotalSize ++;
  499. if ( TotalSize > 1 ) {
  500. Value = (PWSTR)ScepAlloc( 0, (TotalSize+1)*sizeof(WCHAR));
  501. if ( Value == NULL )
  502. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  503. pTemp = Value;
  504. for ( pName=NameList; pName != NULL; pName = pName->Next ) {
  505. swprintf(pTemp, L"%02d", pName->Status);
  506. pTemp += 2;
  507. if ( pName->Name != NULL ) {
  508. Len = wcslen(pName->Name);
  509. wcsncpy(pTemp, pName->Name, Len);
  510. pTemp += Len;
  511. }
  512. *pTemp = L'\0';
  513. pTemp++;
  514. }
  515. *pTemp = L'\0';
  516. } else
  517. TotalSize = 0;
  518. if ( TotalSize > 0 || SaveEmptyList ) {
  519. rc = SceJetSetLine(
  520. hSection,
  521. Name,
  522. FALSE,
  523. Value,
  524. TotalSize*sizeof(WCHAR),
  525. 0
  526. );
  527. if ( Status == 1 )
  528. ScepLogOutput3(2, 0, SCEDLL_STATUS_MISMATCH, Name);
  529. else if ( Status == 2 ) {
  530. ScepLogOutput3(2, 0, SCEDLL_STATUS_NC, Name);
  531. }
  532. #ifdef SCE_DBG
  533. wprintf(L"rc=%d, Section: %d, %s=%s\n", rc, (DWORD)(hSection->SectionID), Name, Value);
  534. #endif
  535. if ( Value != NULL )
  536. ScepFree(Value);
  537. }
  538. return(rc);
  539. }
  540. SCESTATUS
  541. ScepWriteSecurityDescriptorValue(
  542. IN PSCESECTION hSection,
  543. IN PWSTR Name,
  544. IN PSECURITY_DESCRIPTOR pSD,
  545. IN SECURITY_INFORMATION SeInfo
  546. )
  547. /* ++
  548. Routine Description:
  549. This routine writes a key with security descriptor value to the JET section.
  550. The security descriptor is converted into text format based on the secrurity
  551. information passed in.
  552. Arguments:
  553. hSection - the JET hsection handle
  554. Name - The key name
  555. pSD - The security descriptor
  556. SeInfo - the part of the security information to save
  557. Return Value:
  558. SCESTATUS_SUCCESS
  559. SCESTATUS_NOT_ENOUGH_RESOURCE
  560. SCESTATUS returned from SceJetSetLine
  561. -- */
  562. {
  563. SCESTATUS rc=SCESTATUS_SUCCESS;
  564. PWSTR SDspec=NULL;
  565. ULONG SDsize = 0;
  566. if ( hSection == NULL || Name == NULL ) {
  567. return(SCESTATUS_INVALID_PARAMETER);
  568. }
  569. if ( pSD != NULL && SeInfo != 0 ) {
  570. rc = ConvertSecurityDescriptorToText (
  571. pSD,
  572. SeInfo,
  573. &SDspec,
  574. &SDsize
  575. );
  576. if ( rc == NO_ERROR ) {
  577. rc = ScepCompareAndSaveStringValue(
  578. hSection,
  579. Name,
  580. NULL,
  581. SDspec,
  582. SDsize*sizeof(WCHAR)
  583. );
  584. ScepFree(SDspec);
  585. }
  586. }
  587. #ifdef SCE_DBG
  588. wprintf(L"SD==>rc=%d, Section: %d, %s\n", rc, (DWORD)(hSection->SectionID), Name);
  589. #endif
  590. return(rc);
  591. }
  592. SCESTATUS
  593. ScepDuplicateTable(
  594. IN PSCECONTEXT hProfile,
  595. IN SCEJET_TABLE_TYPE TableType,
  596. IN LPSTR DupTableName,
  597. OUT PSCE_ERROR_LOG_INFO *pErrlog
  598. )
  599. /* ++
  600. Routine Description:
  601. This routine copies table structure and data from a SCP/SMP/SAP table to
  602. a table specified by DupTableName. This is used for the SAP table backup.
  603. Arguments:
  604. hProfile - the JET database handle
  605. TableType - the table type -SCEJET_TABLE_SCP
  606. SCEJET_TABLE_SAP
  607. SCEJET_TABLE_SMP
  608. DupTableName - The new table's name
  609. pErrlog - the error list
  610. Return Value:
  611. SCESTATUS_SUCCESS
  612. -- */
  613. {
  614. JET_ERR JetErr;
  615. SCESTATUS rc;
  616. SCECONTEXT hProfile2;
  617. PSCESECTION hSection1=NULL;
  618. PSCESECTION hSection2=NULL;
  619. DOUBLE SectionID=0, SaveID=0;
  620. DWORD Actual;
  621. PWSTR KeyName=NULL;
  622. PWSTR Value=NULL;
  623. DWORD KeyLen=0;
  624. DWORD ValueLen=0;
  625. if ( hProfile == NULL ) {
  626. return(SCESTATUS_INVALID_PARAMETER);
  627. }
  628. //
  629. // Create a SCP section handle. the section ID is a dummy one
  630. //
  631. rc = SceJetOpenSection(
  632. hProfile,
  633. (DOUBLE)1,
  634. TableType,
  635. &hSection1
  636. );
  637. if ( rc != SCESTATUS_SUCCESS ) {
  638. ScepBuildErrorLogInfo( ScepSceStatusToDosError(rc), pErrlog,
  639. SCEERR_OPEN, L"SectionID 1");
  640. return(rc);
  641. }
  642. memset(&hProfile2, '\0', sizeof(SCECONTEXT));
  643. hProfile2.JetSessionID = hProfile->JetSessionID;
  644. hProfile2.JetDbID = hProfile->JetDbID;
  645. //
  646. // Delete the dup table then create it
  647. //
  648. SceJetDeleteTable(
  649. &hProfile2,
  650. DupTableName,
  651. TableType
  652. );
  653. rc = SceJetCreateTable(
  654. &hProfile2,
  655. DupTableName,
  656. TableType,
  657. SCEJET_CREATE_IN_BUFFER,
  658. NULL,
  659. NULL
  660. );
  661. if ( rc != SCESTATUS_SUCCESS ) {
  662. ScepBuildErrorLogInfo( ScepSceStatusToDosError(rc), pErrlog,
  663. SCEERR_CREATE, L"backup table");
  664. goto Cleanup;
  665. }
  666. //
  667. // Move to the first line of the SCP table
  668. //
  669. JetErr = JetMove(hSection1->JetSessionID, hSection1->JetTableID, JET_MoveFirst, 0);
  670. while (JetErr == SCESTATUS_SUCCESS ) {
  671. //
  672. // get section ID
  673. //
  674. JetErr = JetRetrieveColumn(
  675. hSection1->JetSessionID,
  676. hSection1->JetTableID,
  677. hSection1->JetColumnSectionID,
  678. (void *)&SectionID,
  679. 8,
  680. &Actual,
  681. 0,
  682. NULL
  683. );
  684. if ( JetErr != JET_errSuccess ) {
  685. ScepBuildErrorLogInfo( ERROR_READ_FAULT, pErrlog,
  686. SCEERR_QUERY_INFO,
  687. L"sectionID");
  688. rc = SceJetJetErrorToSceStatus(JetErr);
  689. break;
  690. }
  691. #ifdef SCE_DBG
  692. printf("SectionID=%d, JetErr=%d\n", (DWORD)SectionID, JetErr);
  693. #endif
  694. //
  695. // Prepare this Scep section
  696. //
  697. if ( SectionID != SaveID ) {
  698. SaveID = SectionID;
  699. //
  700. // Prepare this section
  701. //
  702. rc = SceJetOpenSection(
  703. &hProfile2,
  704. SectionID,
  705. TableType,
  706. &hSection2
  707. );
  708. if ( rc != SCESTATUS_SUCCESS ) {
  709. ScepBuildErrorLogInfo( ScepSceStatusToDosError(rc), pErrlog,
  710. SCEERR_OPEN_ID,
  711. (DWORD)SectionID);
  712. break;
  713. }
  714. }
  715. //
  716. // get buffer size for key and value
  717. //
  718. rc = SceJetGetValue(
  719. hSection1,
  720. SCEJET_CURRENT,
  721. NULL,
  722. NULL,
  723. 0,
  724. &KeyLen,
  725. NULL,
  726. 0,
  727. &ValueLen);
  728. if ( rc != SCESTATUS_SUCCESS ) {
  729. ScepBuildErrorLogInfo(ScepSceStatusToDosError(rc), pErrlog,
  730. SCEERR_QUERY_VALUE, L"current row");
  731. break;
  732. }
  733. //
  734. // allocate memory
  735. //
  736. if ( KeyLen > 0 ) {
  737. KeyName = (PWSTR)ScepAlloc( LMEM_ZEROINIT, KeyLen+2);
  738. if ( KeyName == NULL ) {
  739. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  740. break;
  741. }
  742. }
  743. if ( ValueLen > 0 ) {
  744. Value = (PWSTR)ScepAlloc( LMEM_ZEROINIT, ValueLen+2);
  745. if ( Value == NULL ) {
  746. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  747. break;
  748. }
  749. }
  750. //
  751. // get key and value
  752. //
  753. rc = SceJetGetValue(
  754. hSection1,
  755. SCEJET_CURRENT,
  756. NULL,
  757. KeyName,
  758. KeyLen,
  759. &KeyLen,
  760. Value,
  761. ValueLen,
  762. &ValueLen);
  763. if ( rc != SCESTATUS_SUCCESS ) {
  764. ScepBuildErrorLogInfo(ScepSceStatusToDosError(rc), pErrlog,
  765. SCEERR_QUERY_VALUE,
  766. L"current row");
  767. break;
  768. }
  769. #ifdef SCE_DBG
  770. wprintf(L"\t%s=%s, rc=%d\n", KeyName, Value, rc);
  771. #endif
  772. //
  773. // set this line to the dup table
  774. //
  775. rc = SceJetSetLine(
  776. hSection2,
  777. KeyName,
  778. TRUE,
  779. Value,
  780. ValueLen,
  781. 0
  782. );
  783. if ( rc != SCESTATUS_SUCCESS ) {
  784. ScepBuildErrorLogInfo(ScepSceStatusToDosError(rc), pErrlog,
  785. SCEERR_WRITE_INFO,
  786. KeyName);
  787. break;
  788. }
  789. ScepFree(KeyName);
  790. KeyName = NULL;
  791. ScepFree(Value);
  792. Value = NULL;
  793. //
  794. // Move to next line in the SCP table
  795. //
  796. JetErr = JetMove(hSection1->JetSessionID, hSection1->JetTableID, JET_MoveNext, 0);
  797. }
  798. Cleanup:
  799. if ( rc != SCESTATUS_SUCCESS ) {
  800. //
  801. // error occurs. Clean up the dup table
  802. //
  803. #ifdef SCE_DBG
  804. printf("Error occurs. delete the dup table.\n");
  805. #endif
  806. SceJetDeleteTable(
  807. &hProfile2,
  808. DupTableName,
  809. TableType
  810. );
  811. }
  812. if ( KeyName != NULL )
  813. ScepFree(KeyName);
  814. if ( Value != NULL )
  815. ScepFree(Value);
  816. SceJetCloseSection(&hSection1, TRUE);
  817. SceJetCloseSection(&hSection2, TRUE);
  818. return(rc);
  819. }
  820. SCESTATUS
  821. ScepAddToPrivList(
  822. IN PSCE_NAME_STATUS_LIST *pPrivList,
  823. IN DWORD Rights,
  824. IN PWSTR Name,
  825. IN DWORD Len
  826. )
  827. /* ++
  828. Routine Description:
  829. This routine adds a privilege with optional group name to the list of
  830. privilege assignments
  831. Arguments:
  832. pPrivList - the privilege list to add to. The structure of this list is
  833. Status -- The privilege value
  834. Name -- The group's name where the priv is assigned
  835. if Name is NULL, the privilege is directly assigned
  836. Rights - The privilege(s) assigned through group Name
  837. Name - The group's name
  838. Len - The group's name length
  839. Return Value:
  840. SCESTATUS_SUCCESS
  841. SCESTATUS_INVALID_PARAMETER
  842. SCESTATUS_NOT_ENOUGH_RESOURCE
  843. -- */
  844. {
  845. PSCE_NAME_STATUS_LIST pTemp;
  846. LONG i;
  847. if ( pPrivList == NULL ) {
  848. return(SCESTATUS_INVALID_PARAMETER);
  849. }
  850. for ( i=31; i>=0; i-- )
  851. if ( Rights & (1 << i) ) {
  852. for ( pTemp=*pPrivList; pTemp != NULL; pTemp = pTemp->Next ) {
  853. if ( (DWORD)i == pTemp->Status )
  854. break;
  855. }
  856. if ( pTemp == NULL ) {
  857. //
  858. // add this one
  859. //
  860. pTemp = (PSCE_NAME_STATUS_LIST)ScepAlloc( LMEM_ZEROINIT, sizeof(SCE_NAME_STATUS_LIST));
  861. if ( pTemp == NULL )
  862. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  863. if ( Name != NULL && Len > 0 ) {
  864. pTemp->Name = (PWSTR)ScepAlloc( LMEM_ZEROINIT, (Len+1)*sizeof(WCHAR));
  865. if ( pTemp->Name == NULL) {
  866. ScepFree(pTemp);
  867. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  868. }
  869. wcsncpy(pTemp->Name, Name, Len);
  870. }
  871. #ifdef SCE_DBG
  872. wprintf(L"Add %d %s to privilege list\n", i, pTemp->Name);
  873. #endif
  874. pTemp->Status = i;
  875. pTemp->Next = *pPrivList;
  876. *pPrivList = pTemp;
  877. pTemp = NULL;
  878. }
  879. }
  880. return(SCESTATUS_SUCCESS);
  881. }
  882. SCESTATUS
  883. ScepOpenPrevPolicyContext(
  884. IN PSCECONTEXT hProfile,
  885. OUT PSCECONTEXT *phPrevProfile
  886. )
  887. {
  888. if ( hProfile == NULL || phPrevProfile == NULL ) {
  889. return(SCESTATUS_INVALID_PARAMETER);
  890. }
  891. *phPrevProfile = (PSCECONTEXT)LocalAlloc( LMEM_ZEROINIT, sizeof(SCECONTEXT));
  892. if ( *phPrevProfile == NULL ) {
  893. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  894. }
  895. memcpy( *phPrevProfile, hProfile, sizeof(SCECONTEXT));
  896. DWORD ScpType = hProfile->Type;
  897. (*phPrevProfile)->Type &= ~(SCEJET_MERGE_TABLE_2 | SCEJET_MERGE_TABLE_1);
  898. SCESTATUS rc;
  899. //
  900. // now open the previous policy table
  901. //
  902. if ( ( ScpType & SCEJET_MERGE_TABLE_2 ) ) {
  903. //
  904. // the second table is the current one
  905. // so the first table is the previous one
  906. //
  907. rc = SceJetOpenTable(
  908. *phPrevProfile,
  909. "SmTblScp",
  910. SCEJET_TABLE_SCP,
  911. SCEJET_OPEN_READ_ONLY,
  912. NULL
  913. );
  914. (*phPrevProfile)->Type |= SCEJET_MERGE_TABLE_1;
  915. } else {
  916. rc = SceJetOpenTable(
  917. *phPrevProfile,
  918. "SmTblScp2",
  919. SCEJET_TABLE_SCP,
  920. SCEJET_OPEN_READ_ONLY,
  921. NULL
  922. );
  923. (*phPrevProfile)->Type |= SCEJET_MERGE_TABLE_2;
  924. }
  925. /*
  926. if ( SCESTATUS_SUCCESS == rc ) {
  927. JET_COLUMNID ColGpoID = (JET_COLUMNID)JET_tableidNil;
  928. JET_ERR JetErr;
  929. JET_COLUMNDEF ColumnGpoIDDef;
  930. JetErr = JetGetTableColumnInfo(
  931. (*phPrevProfile)->JetSessionID,
  932. (*phPrevProfile)->JetScpID,
  933. "GpoID",
  934. (VOID *)&ColumnGpoIDDef,
  935. sizeof(JET_COLUMNDEF),
  936. JET_ColInfo
  937. );
  938. if ( JET_errSuccess == JetErr ) {
  939. ColGpoID = ColumnGpoIDDef.columnid;
  940. } // else ignore error
  941. // temp storage for the column ID
  942. (*phPrevProfile)->JetSapValueID = ColGpoID;
  943. }
  944. */
  945. if ( rc != SCESTATUS_SUCCESS ) {
  946. LocalFree(*phPrevProfile);
  947. *phPrevProfile = NULL;
  948. }
  949. return(rc);
  950. }
  951. SCESTATUS
  952. ScepClosePrevPolicyContext(
  953. IN OUT PSCECONTEXT *phProfile
  954. )
  955. {
  956. if ( phProfile && *phProfile ) {
  957. //
  958. // just free the table because all other info are copied from the
  959. // current policy context and will be freed there
  960. //
  961. if ( (*phProfile)->JetScpID != JET_tableidNil ) {
  962. if ( (*phProfile)->JetScpID != (*phProfile)->JetSmpID ) {
  963. JetCloseTable(
  964. (*phProfile)->JetSessionID,
  965. (*phProfile)->JetScpID
  966. );
  967. }
  968. }
  969. LocalFree(*phProfile);
  970. *phProfile = NULL;
  971. }
  972. return(SCESTATUS_SUCCESS);
  973. }
  974. SCESTATUS
  975. ScepCopyLocalToMergeTable(
  976. IN PSCECONTEXT hProfile,
  977. IN DWORD Options,
  978. IN DWORD CopyOptions,
  979. OUT PSCE_ERROR_LOG_INFO *pErrlog
  980. )
  981. /* ++
  982. Routine Description:
  983. This routine populate data from SCP table into SMP table. All data except
  984. those in the account profiles section(s) in SCP table will be copied over
  985. to SMP table. Account profiles section is converted into User List section
  986. format.
  987. Arguments:
  988. hProfile - the JET database handle
  989. Return Value:
  990. SCESTATUS_SUCCESS
  991. -- */
  992. {
  993. JET_ERR JetErr;
  994. SCESTATUS rc;
  995. PSCESECTION hSectionScp=NULL;
  996. PSCESECTION hSectionSmp=NULL;
  997. PSCESECTION hSectionPrevScp=NULL;
  998. PSCECONTEXT hPrevProfile=NULL;
  999. DOUBLE SectionID=0, SavedID=0;
  1000. DWORD Actual;
  1001. BOOL bCopyIt=FALSE;
  1002. BOOL bCopyThisLine;
  1003. BOOL bConvert=FALSE; // to convert privilege accounts
  1004. PWSTR KeyName=NULL;
  1005. PWSTR Value=NULL;
  1006. DWORD KeyLen=0;
  1007. DWORD ValueLen=0;
  1008. WCHAR SectionName[256];
  1009. if ( hProfile == NULL ) {
  1010. return(SCESTATUS_INVALID_PARAMETER);
  1011. }
  1012. if ( hProfile->JetScpID == hProfile->JetSmpID ) {
  1013. // if it's the same table, return - shouldn't happen
  1014. return(SCESTATUS_SUCCESS);
  1015. }
  1016. if ( hProfile->JetSapID == JET_tableidNil ) {
  1017. // tattoo table doesn't exist, return - shouldn't happen
  1018. return(SCESTATUS_SUCCESS);
  1019. }
  1020. //
  1021. // get previous policy propagation info (if any)
  1022. //
  1023. if ( !(CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ) {
  1024. rc = ScepOpenPrevPolicyContext(hProfile, &hPrevProfile);
  1025. if ( SCESTATUS_RECORD_NOT_FOUND == rc ||
  1026. SCESTATUS_PROFILE_NOT_FOUND == rc ) {
  1027. //
  1028. // the table doesn't exist - no previous policy prop
  1029. // do not need to copy anything, just quit
  1030. //
  1031. return(SCESTATUS_SUCCESS);
  1032. }
  1033. }
  1034. //
  1035. // Create a SMP section handle. the section ID is a dummy one
  1036. //
  1037. rc = SceJetOpenSection(
  1038. hProfile,
  1039. (DOUBLE)1,
  1040. (CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ? SCEJET_TABLE_SMP : SCEJET_TABLE_TATTOO,
  1041. &hSectionSmp
  1042. );
  1043. if ( rc != SCESTATUS_SUCCESS ) {
  1044. ScepBuildErrorLogInfo( ScepSceStatusToDosError(rc), pErrlog,
  1045. SCEERR_OPEN,
  1046. (CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ? L"SMP" : L"TATTOO");
  1047. if (hPrevProfile) ScepClosePrevPolicyContext(&hPrevProfile);
  1048. return(rc);
  1049. }
  1050. LSA_HANDLE LsaPolicy=NULL;
  1051. PWSTR pszNewValue=NULL;
  1052. DWORD NewLen=0;
  1053. //
  1054. // Move to the first line of the SCP table
  1055. //
  1056. JetErr = JetMove(hSectionSmp->JetSessionID, hSectionSmp->JetTableID, JET_MoveFirst, 0);
  1057. while (JetErr == SCESTATUS_SUCCESS ) {
  1058. //
  1059. // get section ID
  1060. //
  1061. JetErr = JetRetrieveColumn(
  1062. hSectionSmp->JetSessionID,
  1063. hSectionSmp->JetTableID,
  1064. hSectionSmp->JetColumnSectionID,
  1065. (void *)&SectionID,
  1066. 8,
  1067. &Actual,
  1068. 0,
  1069. NULL
  1070. );
  1071. if ( JetErr != JET_errSuccess ) {
  1072. ScepBuildErrorLogInfo( ERROR_READ_FAULT, pErrlog,
  1073. SCEERR_QUERY_INFO, L"sectionID");
  1074. rc = SceJetJetErrorToSceStatus(JetErr);
  1075. break;
  1076. }
  1077. #ifdef SCE_DBG
  1078. printf("SectionID=%d, JetErr=%d\n", (DWORD)SectionID, JetErr);
  1079. #endif
  1080. if ( SectionID != SavedID ) {
  1081. //
  1082. // a new section. Look for the section's name to see if this section
  1083. // is to be converted
  1084. //
  1085. SavedID = SectionID;
  1086. Actual = 510;
  1087. memset(SectionName, '\0', 512);
  1088. rc = SceJetGetSectionNameByID(
  1089. hProfile,
  1090. SectionID,
  1091. SectionName,
  1092. &Actual
  1093. );
  1094. if ( rc != SCESTATUS_SUCCESS ) {
  1095. ScepBuildErrorLogInfo( ERROR_BAD_FORMAT, pErrlog,
  1096. SCEERR_CANT_FIND_SECTION,
  1097. (DWORD)SectionID
  1098. );
  1099. break;
  1100. }
  1101. if ( Actual > 0 )
  1102. SectionName[Actual/sizeof(TCHAR)] = L'\0';
  1103. #ifdef SCE_DBG
  1104. wprintf(L"SectionName=%s\n", SectionName);
  1105. #endif
  1106. //
  1107. // Compare section name with domain sections to convert
  1108. //
  1109. bCopyIt = TRUE;
  1110. bConvert = FALSE;
  1111. if ( (CopyOptions & SCE_LOCAL_POLICY_DC) ) {
  1112. //
  1113. // do not copy user rights if it's on a domain controller
  1114. //
  1115. if ( _wcsicmp(szPrivilegeRights, SectionName) == 0 ||
  1116. _wcsicmp(szSystemAccess, SectionName) == 0 ||
  1117. _wcsicmp(szKerberosPolicy, SectionName) == 0 ||
  1118. _wcsicmp(szAuditEvent, SectionName) == 0 ||
  1119. _wcsicmp(szGroupMembership, SectionName) == 0 ) {
  1120. bCopyIt = FALSE;
  1121. } else if ( (CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ) {
  1122. //
  1123. // migrate registry values only
  1124. //
  1125. if ( _wcsicmp(szRegistryValues, SectionName) != 0 )
  1126. bCopyIt = FALSE;
  1127. }
  1128. } else if ( (CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ) {
  1129. //
  1130. // non DCs, should migrate all local policies
  1131. //
  1132. if ( _wcsicmp(szPrivilegeRights, SectionName) == 0 ) {
  1133. bConvert = TRUE;
  1134. } else if ( (_wcsicmp(szSystemAccess, SectionName) != 0) &&
  1135. (_wcsicmp(szKerberosPolicy, SectionName) != 0) &&
  1136. (_wcsicmp(szRegistryValues, SectionName) != 0) &&
  1137. (_wcsicmp(szAuditEvent, SectionName) != 0) ) {
  1138. bCopyIt = FALSE;
  1139. }
  1140. }
  1141. /*
  1142. if ( ( Options & SCE_NOCOPY_DOMAIN_POLICY) &&
  1143. ( (_wcsicmp(szSystemAccess, SectionName) == 0) ||
  1144. (_wcsicmp(szKerberosPolicy, SectionName) == 0) ) ) {
  1145. bCopyIt = FALSE;
  1146. } else if ( (_wcsicmp(szGroupMembership, SectionName) == 0) ||
  1147. (_wcsicmp(szRegistryKeys, SectionName) == 0) ||
  1148. (_wcsicmp(szFileSecurity, SectionName) == 0) ||
  1149. (_wcsicmp(szServiceGeneral, SectionName) == 0) ||
  1150. (_wcsicmp(szAuditApplicationLog, SectionName) == 0) ||
  1151. (_wcsicmp(szAuditSecurityLog, SectionName) == 0) ||
  1152. (_wcsicmp(szAuditSystemLog, SectionName) == 0) ||
  1153. (_wcsicmp(szAttachments, SectionName) == 0) ||
  1154. (_wcsicmp(szDSSecurity, SectionName) == 0)
  1155. ) {
  1156. // do not copy areas other than account policy and local policy
  1157. bCopyIt = FALSE;
  1158. } else {
  1159. bCopyIt = TRUE;
  1160. */
  1161. if ( bCopyIt ) {
  1162. //
  1163. // Prepare this Scep section
  1164. //
  1165. rc = SceJetOpenSection(
  1166. hProfile,
  1167. SectionID,
  1168. (CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ? SCEJET_TABLE_TATTOO : SCEJET_TABLE_SCP,
  1169. &hSectionScp
  1170. );
  1171. if ( rc != SCESTATUS_SUCCESS ) {
  1172. ScepBuildErrorLogInfo( ScepSceStatusToDosError(rc), pErrlog,
  1173. SCEERR_OPEN_ID,
  1174. (DWORD)SectionID);
  1175. break;
  1176. }
  1177. if ( (CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ) {
  1178. //
  1179. // open current policy propagation table
  1180. // do not care error here
  1181. //
  1182. SceJetOpenSection(
  1183. hProfile,
  1184. SectionID,
  1185. SCEJET_TABLE_SCP,
  1186. &hSectionPrevScp
  1187. );
  1188. /* // should always copy tattoo value to the merged table
  1189. // even if the setting doesn't exist in previous policy prop
  1190. // this is to handle the dependent settings such as
  1191. // retention perild and retention days
  1192. } else if ( hPrevProfile ) {
  1193. //
  1194. // open previous policy propagation table
  1195. // do not care error here
  1196. //
  1197. SceJetOpenSection(
  1198. hPrevProfile,
  1199. SectionID,
  1200. SCEJET_TABLE_SCP,
  1201. &hSectionPrevScp
  1202. );
  1203. */
  1204. }
  1205. }
  1206. }
  1207. if ( bCopyIt ) {
  1208. //
  1209. // get buffer size for key and value
  1210. //
  1211. rc = SceJetGetValue(
  1212. hSectionSmp,
  1213. SCEJET_CURRENT,
  1214. NULL,
  1215. NULL,
  1216. 0,
  1217. &KeyLen,
  1218. NULL,
  1219. 0,
  1220. &ValueLen);
  1221. if ( rc != SCESTATUS_SUCCESS ) {
  1222. ScepBuildErrorLogInfo(ScepSceStatusToDosError(rc), pErrlog,
  1223. SCEERR_QUERY_VALUE, L"current row");
  1224. break;
  1225. }
  1226. //
  1227. // allocate memory
  1228. //
  1229. if ( KeyLen > 0 ) {
  1230. KeyName = (PWSTR)ScepAlloc( LMEM_ZEROINIT, KeyLen+2);
  1231. if ( KeyName == NULL ) {
  1232. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1233. break;
  1234. }
  1235. }
  1236. if ( ValueLen > 0 ) {
  1237. Value = (PWSTR)ScepAlloc( LMEM_ZEROINIT, ValueLen+2);
  1238. if ( Value == NULL ) {
  1239. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1240. break;
  1241. }
  1242. }
  1243. //
  1244. // get key and value
  1245. //
  1246. rc = SceJetGetValue(
  1247. hSectionSmp,
  1248. SCEJET_CURRENT,
  1249. NULL,
  1250. KeyName,
  1251. KeyLen,
  1252. &KeyLen,
  1253. Value,
  1254. ValueLen,
  1255. &ValueLen);
  1256. if ( rc != SCESTATUS_SUCCESS ) {
  1257. ScepBuildErrorLogInfo(ScepSceStatusToDosError(rc), pErrlog,
  1258. SCEERR_QUERY_VALUE, L"current row");
  1259. break;
  1260. }
  1261. #ifdef SCE_DBG
  1262. wprintf(L"\t%s=%s, rc=%d\n", KeyName, Value, rc);
  1263. #endif
  1264. bCopyThisLine = TRUE;
  1265. //
  1266. // check if this key exist in the previous prop
  1267. //
  1268. if ( hSectionPrevScp ) {
  1269. rc = SceJetSeek(
  1270. hSectionPrevScp,
  1271. KeyName,
  1272. KeyLen,
  1273. SCEJET_SEEK_EQ_NO_CASE
  1274. );
  1275. if ( SCESTATUS_RECORD_NOT_FOUND == rc ||
  1276. (hSectionPrevScp->JetColumnGpoID == 0) ) {
  1277. bCopyThisLine = FALSE;
  1278. } else if ( SCESTATUS_SUCCESS == rc && (CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ) {
  1279. //
  1280. // found. Let's check if this setting was from a GPO
  1281. // if in migration (build tattoo), a setting was not
  1282. // defined in GPO doesn't need a tattoo value
  1283. //
  1284. // for policy prop case, there may be undo settings in
  1285. // previous policy prop and they weren't reset successfully
  1286. // in previous prop. In this case, we still want to continue
  1287. // reset these settings. So these settings should be copied
  1288. // from the tattoo table to this policy table regardless if
  1289. // there is a domain setting defined for it in the previous
  1290. // policy propagation.
  1291. //
  1292. LONG GpoID = 0;
  1293. ULONG Actual;
  1294. (void)JetRetrieveColumn(
  1295. hSectionPrevScp->JetSessionID,
  1296. hSectionPrevScp->JetTableID,
  1297. hSectionPrevScp->JetColumnGpoID,
  1298. (void *)&GpoID,
  1299. 4,
  1300. &Actual,
  1301. 0,
  1302. NULL
  1303. );
  1304. if ( GpoID == 0 ) {
  1305. //
  1306. // this is not a setting from a GPO
  1307. //
  1308. bCopyThisLine = FALSE;
  1309. }
  1310. }
  1311. rc = SCESTATUS_SUCCESS;
  1312. }
  1313. if ( bCopyThisLine ) {
  1314. if ( bConvert ) {
  1315. rc = ScepConvertFreeTextAccountToSid(
  1316. &LsaPolicy,
  1317. Value,
  1318. ValueLen/sizeof(WCHAR),
  1319. &pszNewValue,
  1320. &NewLen
  1321. );
  1322. if ( rc == SCESTATUS_SUCCESS &&
  1323. pszNewValue ) {
  1324. ScepFree(Value);
  1325. Value = pszNewValue;
  1326. ValueLen = NewLen*sizeof(WCHAR);
  1327. pszNewValue = NULL;
  1328. } // if failed to convert, just use the name format
  1329. }
  1330. //
  1331. // set this line to the SCP table
  1332. //
  1333. rc = SceJetSetLine(
  1334. hSectionScp,
  1335. KeyName,
  1336. TRUE,
  1337. Value,
  1338. ValueLen,
  1339. 0
  1340. );
  1341. if ( rc != SCESTATUS_SUCCESS ) {
  1342. ScepBuildErrorLogInfo(ScepSceStatusToDosError(rc), pErrlog,
  1343. SCEERR_WRITE_INFO,
  1344. KeyName);
  1345. break;
  1346. }
  1347. }
  1348. ScepFree(KeyName);
  1349. KeyName = NULL;
  1350. ScepFree(Value);
  1351. Value = NULL;
  1352. }
  1353. //
  1354. // Move to next line in the SCP table
  1355. //
  1356. JetErr = JetMove(hSectionSmp->JetSessionID, hSectionSmp->JetTableID, JET_MoveNext, 0);
  1357. }
  1358. if ( KeyName != NULL )
  1359. ScepFree(KeyName);
  1360. if ( Value != NULL )
  1361. ScepFree(Value);
  1362. SceJetCloseSection(&hSectionScp, TRUE);
  1363. SceJetCloseSection(&hSectionSmp, TRUE);
  1364. if ( hSectionPrevScp ) {
  1365. SceJetCloseSection(&hSectionPrevScp, TRUE);
  1366. }
  1367. if (hPrevProfile)
  1368. ScepClosePrevPolicyContext(&hPrevProfile);
  1369. if ( LsaPolicy ) {
  1370. LsaClose(LsaPolicy);
  1371. }
  1372. return(rc);
  1373. }
  1374. SCESTATUS
  1375. ScepWriteObjectSecurity(
  1376. IN PSCECONTEXT hProfile,
  1377. IN SCETYPE ProfileType,
  1378. IN AREA_INFORMATION Area,
  1379. IN PSCE_OBJECT_SECURITY ObjSecurity
  1380. )
  1381. /*
  1382. Get security for a single object
  1383. */
  1384. {
  1385. SCESTATUS rc;
  1386. PCWSTR SectionName=NULL;
  1387. PSCESECTION hSection=NULL;
  1388. DWORD SDsize, Win32Rc;
  1389. PWSTR SDspec=NULL;
  1390. if ( hProfile == NULL ||
  1391. ObjSecurity == NULL ||
  1392. ObjSecurity->Name == NULL ) {
  1393. return(SCESTATUS_INVALID_PARAMETER);
  1394. }
  1395. switch (Area) {
  1396. case AREA_REGISTRY_SECURITY:
  1397. SectionName = szRegistryKeys;
  1398. break;
  1399. case AREA_FILE_SECURITY:
  1400. SectionName = szFileSecurity;
  1401. break;
  1402. #if 0
  1403. case AREA_DS_OBJECTS:
  1404. SectionName = szDSSecurity;
  1405. break;
  1406. #endif
  1407. default:
  1408. return(SCESTATUS_INVALID_PARAMETER);
  1409. }
  1410. rc = ScepOpenSectionForName(
  1411. hProfile,
  1412. ProfileType,
  1413. SectionName,
  1414. &hSection
  1415. );
  1416. if ( rc == SCESTATUS_SUCCESS ) {
  1417. //
  1418. // convert security descriptor
  1419. //
  1420. Win32Rc = ConvertSecurityDescriptorToText (
  1421. ObjSecurity->pSecurityDescriptor,
  1422. ObjSecurity->SeInfo,
  1423. &SDspec,
  1424. &SDsize
  1425. );
  1426. if ( Win32Rc == NO_ERROR ) {
  1427. if ( Area == AREA_DS_OBJECTS ) {
  1428. //
  1429. // ds needs to convert name
  1430. //
  1431. rc = ScepDosErrorToSceStatus(
  1432. ScepSaveDsStatusToSection(
  1433. ObjSecurity->Name,
  1434. ObjSecurity->IsContainer,
  1435. ObjSecurity->Status,
  1436. SDspec,
  1437. SDsize
  1438. ) );
  1439. } else {
  1440. rc = ScepSaveObjectString(
  1441. hSection,
  1442. ObjSecurity->Name,
  1443. ObjSecurity->IsContainer,
  1444. ObjSecurity->Status,
  1445. SDspec,
  1446. SDsize
  1447. );
  1448. }
  1449. } else
  1450. rc = ScepDosErrorToSceStatus(Win32Rc);
  1451. }
  1452. SceJetCloseSection( &hSection, TRUE);
  1453. if (SDspec)
  1454. ScepFree(SDspec);
  1455. return(rc);
  1456. }
  1457. SCESTATUS
  1458. ScepTattooCheckAndUpdateArray(
  1459. IN OUT SCE_TATTOO_KEYS *pTattooKeys,
  1460. IN OUT DWORD *pcTattooKeys,
  1461. IN PWSTR KeyName,
  1462. IN DWORD ConfigOptions,
  1463. IN DWORD dwValue
  1464. )
  1465. /*
  1466. Description:
  1467. Add a new entry into the array which holds system (tatto) values for the settings
  1468. The input/output buffer pTattooKeys is allocated outside this routine.
  1469. */
  1470. {
  1471. if ( pTattooKeys == NULL || pcTattooKeys == NULL ||
  1472. KeyName == NULL ) {
  1473. return(SCESTATUS_INVALID_PARAMETER);
  1474. }
  1475. if ( !(ConfigOptions & SCE_POLICY_TEMPLATE) ) {
  1476. return(SCESTATUS_SUCCESS);
  1477. }
  1478. pTattooKeys[*pcTattooKeys].KeyName = KeyName;
  1479. pTattooKeys[*pcTattooKeys].KeyLen = wcslen(KeyName);
  1480. pTattooKeys[*pcTattooKeys].DataType = 'D';
  1481. pTattooKeys[*pcTattooKeys].SaveValue = dwValue;
  1482. pTattooKeys[*pcTattooKeys].Value = NULL;
  1483. // ScepLogOutput3(3,0, SCESRV_POLICY_TATTOO_ADD, KeyName, *pcTattooKeys);
  1484. (*pcTattooKeys)++;
  1485. return(SCESTATUS_SUCCESS);
  1486. }
  1487. SCESTATUS
  1488. ScepTattooOpenPolicySections(
  1489. IN PSCECONTEXT hProfile,
  1490. IN PCWSTR SectionName,
  1491. OUT PSCESECTION *phSectionDomain,
  1492. OUT PSCESECTION *phSectionTattoo
  1493. )
  1494. /*
  1495. Open the table/sections for the merged policy and the undo settings
  1496. */
  1497. {
  1498. if ( hProfile == NULL || SectionName == NULL ||
  1499. phSectionDomain == NULL || phSectionTattoo == NULL ) {
  1500. return(SCESTATUS_INVALID_PARAMETER);
  1501. }
  1502. SCESTATUS rCode;
  1503. DOUBLE SectionID;
  1504. *phSectionDomain = NULL;
  1505. *phSectionTattoo = NULL;
  1506. //
  1507. // open the section for both tattoo table and effective policy table
  1508. // get section id first
  1509. //
  1510. rCode = SceJetGetSectionIDByName(
  1511. hProfile,
  1512. SectionName,
  1513. &SectionID
  1514. );
  1515. if ( rCode == SCESTATUS_SUCCESS ) {
  1516. // open effective policy table
  1517. rCode = SceJetOpenSection(
  1518. hProfile,
  1519. SectionID,
  1520. SCEJET_TABLE_SCP,
  1521. phSectionDomain
  1522. );
  1523. if ( rCode == SCESTATUS_SUCCESS ) {
  1524. // open tattoo table
  1525. rCode = SceJetOpenSection(
  1526. hProfile,
  1527. SectionID,
  1528. SCEJET_TABLE_TATTOO,
  1529. phSectionTattoo
  1530. );
  1531. if ( rCode != SCESTATUS_SUCCESS ) {
  1532. SceJetCloseSection(phSectionDomain, TRUE);
  1533. *phSectionDomain = NULL;
  1534. }
  1535. }
  1536. }
  1537. //
  1538. // log tattoo process
  1539. //
  1540. if ( rCode != 0 )
  1541. ScepLogOutput3(1, 0,
  1542. SCESRV_POLICY_TATTOO_PREPARE,
  1543. ScepSceStatusToDosError(rCode),
  1544. SectionName);
  1545. return(rCode);
  1546. }
  1547. SCESTATUS
  1548. ScepTattooManageOneStringValue(
  1549. IN PSCESECTION hSectionDomain,
  1550. IN PSCESECTION hSectionTattoo,
  1551. IN PWSTR KeyName,
  1552. IN DWORD KeyLen OPTIONAL,
  1553. IN PWSTR Value,
  1554. IN DWORD ValueLen,
  1555. IN DWORD rc
  1556. )
  1557. {
  1558. if ( hSectionDomain == NULL || hSectionTattoo == NULL ||
  1559. KeyName == NULL || Value == NULL )
  1560. return(SCESTATUS_INVALID_PARAMETER);
  1561. PWSTR pNewValue=NULL;
  1562. DWORD NewLen=ValueLen;
  1563. SCESTATUS rCode;
  1564. if (Value && (ValueLen == 0) ) NewLen = wcslen(Value);
  1565. if ( NewLen ) {
  1566. //
  1567. // the buffer passed may not be NULL terminated
  1568. //
  1569. pNewValue = (PWSTR)ScepAlloc(LPTR,(NewLen+1)*sizeof(WCHAR));
  1570. if ( pNewValue == NULL ) return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  1571. wcsncpy(pNewValue, Value, NewLen);
  1572. }
  1573. SCE_TATTOO_KEYS theKey;
  1574. theKey.KeyName = KeyName;
  1575. theKey.KeyLen = (KeyLen == 0) ? wcslen(KeyName) : KeyLen;
  1576. theKey.Value = pNewValue;
  1577. theKey.SaveValue = NewLen;
  1578. theKey.DataType = 'S';
  1579. rCode = ScepTattooManageValues(hSectionDomain, hSectionTattoo, &theKey, 1, rc);
  1580. if ( pNewValue ) ScepFree(pNewValue);
  1581. return(rCode);
  1582. }
  1583. SCESTATUS
  1584. ScepTattooManageOneIntValue(
  1585. IN PSCESECTION hSectionDomain,
  1586. IN PSCESECTION hSectionTattoo,
  1587. IN PWSTR KeyName,
  1588. IN DWORD KeyLen OPTIONAL,
  1589. IN DWORD Value,
  1590. IN DWORD rc
  1591. )
  1592. {
  1593. if ( hSectionDomain == NULL || hSectionTattoo == NULL || KeyName == NULL )
  1594. return(SCESTATUS_INVALID_PARAMETER);
  1595. SCE_TATTOO_KEYS theKey;
  1596. theKey.KeyName = KeyName;
  1597. theKey.KeyLen = (KeyLen == 0) ? wcslen(KeyName) : KeyLen;
  1598. theKey.SaveValue = Value;
  1599. theKey.DataType = 'D';
  1600. theKey.Value = NULL;
  1601. return(ScepTattooManageValues(hSectionDomain, hSectionTattoo, &theKey, 1, rc));
  1602. }
  1603. SCESTATUS
  1604. ScepTattooManageOneIntValueWithDependency(
  1605. IN PSCESECTION hSectionDomain,
  1606. IN PSCESECTION hSectionTattoo,
  1607. IN PWSTR DependentKeyName,
  1608. IN DWORD DependentKeyLen OPTIONAL,
  1609. IN PWSTR SaveKeyName,
  1610. IN DWORD Value,
  1611. IN DWORD rc
  1612. )
  1613. {
  1614. if ( hSectionDomain == NULL || hSectionTattoo == NULL ||
  1615. SaveKeyName == NULL || DependentKeyName == NULL)
  1616. return(SCESTATUS_INVALID_PARAMETER);
  1617. SCE_TATTOO_KEYS theKey;
  1618. theKey.KeyName = DependentKeyName;
  1619. theKey.KeyLen = (DependentKeyLen == 0) ? wcslen(DependentKeyName) : DependentKeyLen;
  1620. theKey.SaveValue = Value;
  1621. theKey.DataType = 'L';
  1622. theKey.Value = SaveKeyName;
  1623. return(ScepTattooManageValues(hSectionDomain, hSectionTattoo, &theKey, 1, rc));
  1624. }
  1625. SCESTATUS
  1626. ScepTattooManageOneRegistryValue(
  1627. IN PSCESECTION hSectionDomain,
  1628. IN PSCESECTION hSectionTattoo,
  1629. IN PWSTR KeyName,
  1630. IN DWORD KeyLen OPTIONAL,
  1631. IN PSCE_REGISTRY_VALUE_INFO pOneRegValue,
  1632. IN DWORD rc
  1633. )
  1634. {
  1635. if ( hSectionDomain == NULL || hSectionTattoo == NULL ||
  1636. KeyName == NULL || pOneRegValue == NULL )
  1637. return(SCESTATUS_INVALID_PARAMETER);
  1638. SCESTATUS rCode;
  1639. SCE_TATTOO_KEYS theKey;
  1640. theKey.KeyName = KeyName;
  1641. theKey.KeyLen = (KeyLen == 0) ? wcslen(KeyName) : KeyLen;
  1642. theKey.Value = (PWSTR)pOneRegValue;
  1643. theKey.SaveValue = 0;
  1644. theKey.DataType = 'R';
  1645. rCode = ScepTattooManageValues(hSectionDomain, hSectionTattoo, &theKey, 1, rc);
  1646. return(rCode);
  1647. }
  1648. SCESTATUS
  1649. ScepTattooManageOneMemberListValue(
  1650. IN PSCESECTION hSectionDomain,
  1651. IN PSCESECTION hSectionTattoo,
  1652. IN PWSTR GroupName,
  1653. IN DWORD GroupLen OPTIONAL,
  1654. IN PSCE_NAME_LIST pNameList,
  1655. IN BOOL bDeleteOnly,
  1656. IN DWORD rc
  1657. )
  1658. {
  1659. if ( hSectionDomain == NULL || hSectionTattoo == NULL ||
  1660. GroupName == NULL )
  1661. return(SCESTATUS_INVALID_PARAMETER);
  1662. SCESTATUS rCode;
  1663. SCE_TATTOO_KEYS theKey;
  1664. DWORD Len=GroupLen;
  1665. if ( Len == 0 ) Len = wcslen(GroupName);
  1666. Len += wcslen(szMembers);
  1667. PWSTR KeyString = (PWSTR)ScepAlloc(0, (Len+1)*sizeof(WCHAR));
  1668. if ( KeyString != NULL ) {
  1669. swprintf(KeyString, L"%s%s", GroupName, szMembers);
  1670. theKey.KeyName = KeyString;
  1671. theKey.KeyLen = Len;
  1672. theKey.Value = (PWSTR)pNameList;
  1673. theKey.SaveValue = bDeleteOnly ? 1 : 0;
  1674. theKey.DataType = 'M';
  1675. rCode = ScepTattooManageValues(hSectionDomain, hSectionTattoo, &theKey, 1, rc);
  1676. ScepFree(KeyString);
  1677. } else {
  1678. rCode = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1679. }
  1680. return(rCode);
  1681. }
  1682. SCESTATUS
  1683. ScepTattooManageOneServiceValue(
  1684. IN PSCESECTION hSectionDomain,
  1685. IN PSCESECTION hSectionTattoo,
  1686. IN PWSTR ServiceName,
  1687. IN DWORD ServiceLen OPTIONAL,
  1688. IN PSCE_SERVICES pServiceNode,
  1689. IN DWORD rc
  1690. )
  1691. {
  1692. if ( hSectionDomain == NULL || hSectionTattoo == NULL ||
  1693. ServiceName == NULL )
  1694. return(SCESTATUS_INVALID_PARAMETER);
  1695. SCESTATUS rCode;
  1696. SCE_TATTOO_KEYS theKey;
  1697. theKey.KeyName = ServiceName;
  1698. theKey.KeyLen = (ServiceLen == 0) ? wcslen(ServiceName) : ServiceLen;
  1699. theKey.Value = (PWSTR)pServiceNode;
  1700. theKey.SaveValue = 0;
  1701. theKey.DataType = 'V';
  1702. rCode = ScepTattooManageValues(hSectionDomain, hSectionTattoo, &theKey, 1, rc);
  1703. return(rCode);
  1704. }
  1705. SCESTATUS
  1706. ScepTattooManageValues(
  1707. IN PSCESECTION hSectionDomain,
  1708. IN PSCESECTION hSectionTattoo,
  1709. IN SCE_TATTOO_KEYS *pTattooKeys,
  1710. IN DWORD cTattooKeys,
  1711. IN DWORD rc
  1712. )
  1713. /*
  1714. Description:
  1715. For each setting in the array, do the following:
  1716. 1) Check if the setting come from domain
  1717. 2) Check if there is a tattoo value already exist
  1718. 3) Save the new value from the array to the tattoo table if it doesn't exist
  1719. 4) Delete the tattoo value if the setting didn't come from domain and
  1720. it has been reset successfully
  1721. */
  1722. {
  1723. if ( hSectionDomain == NULL || hSectionTattoo == NULL ||
  1724. pTattooKeys == NULL || cTattooKeys == 0 ) {
  1725. return(SCESTATUS_INVALID_PARAMETER);
  1726. }
  1727. SCESTATUS rCode=SCESTATUS_SUCCESS;
  1728. SCESTATUS rc2;
  1729. BOOL bTattooExist,bDomainExist;
  1730. PWSTR KeyString=NULL;
  1731. PWSTR pTempKey;
  1732. for ( DWORD i=0; i<cTattooKeys; i++) {
  1733. if ( pTattooKeys[i].KeyName == NULL ) continue;
  1734. if ( pTattooKeys[i].DataType == 'L' && pTattooKeys[i].Value == NULL ) continue;
  1735. //
  1736. // check if this setting exists in the tattoo table
  1737. //
  1738. bTattooExist = FALSE;
  1739. rc2 = SCESTATUS_SUCCESS;
  1740. if ( SCESTATUS_SUCCESS == SceJetSeek(
  1741. hSectionTattoo,
  1742. pTattooKeys[i].KeyName,
  1743. pTattooKeys[i].KeyLen*sizeof(WCHAR),
  1744. SCEJET_SEEK_EQ_NO_CASE
  1745. ) ) {
  1746. bTattooExist = TRUE;
  1747. }
  1748. //
  1749. // check if the setting exists in the effective table
  1750. //
  1751. bDomainExist = FALSE;
  1752. if ( SCESTATUS_SUCCESS == SceJetSeek(
  1753. hSectionDomain,
  1754. pTattooKeys[i].KeyName,
  1755. pTattooKeys[i].KeyLen*sizeof(WCHAR),
  1756. SCEJET_SEEK_EQ_NO_CASE
  1757. ) ) {
  1758. if ( !bTattooExist ) {
  1759. //
  1760. // if there is no tattoo value but there is a setting in domain table
  1761. // this setting must come from domain
  1762. //
  1763. bDomainExist = TRUE;
  1764. } else if ( hSectionDomain->JetColumnGpoID > 0 ) {
  1765. //
  1766. // check if GpoID > 0
  1767. //
  1768. LONG GpoID = 0;
  1769. DWORD Actual;
  1770. JET_ERR JetErr;
  1771. JetErr = JetRetrieveColumn(
  1772. hSectionDomain->JetSessionID,
  1773. hSectionDomain->JetTableID,
  1774. hSectionDomain->JetColumnGpoID,
  1775. (void *)&GpoID,
  1776. 4,
  1777. &Actual,
  1778. 0,
  1779. NULL
  1780. );
  1781. if ( JET_errSuccess != JetErr ) {
  1782. //
  1783. // if the column is nil (no value), it will return warning
  1784. // but the buffer pGpoID is trashed
  1785. //
  1786. GpoID = 0;
  1787. }
  1788. if ( GpoID > 0 ) {
  1789. bDomainExist = TRUE;
  1790. }
  1791. }
  1792. }
  1793. //
  1794. // check if we need to save the tatto value or delete the tattoo value
  1795. //
  1796. if ( bDomainExist ) {
  1797. pTempKey = pTattooKeys[i].KeyName;
  1798. BOOL bSave = FALSE;
  1799. if ( pTattooKeys[i].DataType == 'M' && pTattooKeys[i].SaveValue == 1 ) {
  1800. //
  1801. // delete only for group membership, don't do anything in this case
  1802. //
  1803. } else if ( !bTattooExist ) {
  1804. //
  1805. // domain setting is defined (the first time)
  1806. // save the tattoo value
  1807. //
  1808. switch ( pTattooKeys[i].DataType ) {
  1809. case 'D':
  1810. if ( pTattooKeys[i].SaveValue != SCE_NO_VALUE ) {
  1811. rc2 = ScepCompareAndSaveIntValue(hSectionTattoo,
  1812. pTattooKeys[i].KeyName,
  1813. FALSE,
  1814. SCE_SNAPSHOT_VALUE,
  1815. pTattooKeys[i].SaveValue
  1816. );
  1817. bSave = TRUE;
  1818. }
  1819. break;
  1820. case 'L': // dependency DWORD type
  1821. pTempKey = pTattooKeys[i].Value;
  1822. if ( pTattooKeys[i].SaveValue != SCE_NO_VALUE ) {
  1823. rc2 = ScepCompareAndSaveIntValue(hSectionTattoo,
  1824. pTattooKeys[i].Value,
  1825. FALSE,
  1826. SCE_SNAPSHOT_VALUE,
  1827. pTattooKeys[i].SaveValue
  1828. );
  1829. bSave = TRUE;
  1830. }
  1831. break;
  1832. case 'S':
  1833. if ( pTattooKeys[i].Value ) {
  1834. rc2 = ScepCompareAndSaveStringValue(hSectionTattoo,
  1835. pTattooKeys[i].KeyName,
  1836. (PWSTR)(ULONG_PTR)SCE_SNAPSHOT_VALUE,
  1837. pTattooKeys[i].Value,
  1838. pTattooKeys[i].SaveValue*sizeof(WCHAR)
  1839. );
  1840. bSave = TRUE;
  1841. }
  1842. break;
  1843. case 'R': // registry values
  1844. if ( ((PSCE_REGISTRY_VALUE_INFO)(pTattooKeys[i].Value))->Value ) {
  1845. if ( REG_DWORD == ((PSCE_REGISTRY_VALUE_INFO)(pTattooKeys[i].Value))->ValueType ) {
  1846. DWORD RegData = _wtol(((PSCE_REGISTRY_VALUE_INFO)(pTattooKeys[i].Value))->Value);
  1847. rc2 = ScepSaveRegistryValue(hSectionTattoo,
  1848. pTattooKeys[i].KeyName,
  1849. REG_DWORD,
  1850. (PWSTR)&RegData,
  1851. sizeof(DWORD),
  1852. 0
  1853. );
  1854. } else {
  1855. rc2 = ScepSaveRegistryValue(hSectionTattoo,
  1856. pTattooKeys[i].KeyName,
  1857. ((PSCE_REGISTRY_VALUE_INFO)(pTattooKeys[i].Value))->ValueType,
  1858. ((PSCE_REGISTRY_VALUE_INFO)(pTattooKeys[i].Value))->Value,
  1859. wcslen(((PSCE_REGISTRY_VALUE_INFO)(pTattooKeys[i].Value))->Value)*sizeof(WCHAR),
  1860. 0
  1861. );
  1862. }
  1863. bSave = TRUE;
  1864. }
  1865. break;
  1866. case 'M': // group member list
  1867. // allow empty member list to be saved
  1868. rc2 = ScepWriteNameListValue(
  1869. NULL,
  1870. hSectionTattoo,
  1871. pTattooKeys[i].KeyName,
  1872. (PSCE_NAME_LIST)(pTattooKeys[i].Value),
  1873. SCE_WRITE_EMPTY_LIST,
  1874. 3
  1875. );
  1876. bSave = TRUE;
  1877. break;
  1878. case 'V': // service
  1879. if ( pTattooKeys[i].Value ) {
  1880. rc2 = ScepSetSingleServiceSetting(
  1881. hSectionTattoo,
  1882. (PSCE_SERVICES)(pTattooKeys[i].Value)
  1883. );
  1884. bSave = TRUE;
  1885. } else {
  1886. rc2 = SCESTATUS_INVALID_PARAMETER;
  1887. }
  1888. break;
  1889. default:
  1890. rc2 = SCESTATUS_INVALID_PARAMETER;
  1891. break;
  1892. }
  1893. if ( rc2 != SCESTATUS_SUCCESS ) {
  1894. ScepLogOutput3(1, 0, SCESRV_POLICY_TATTOO_ERROR_SETTING,
  1895. ScepSceStatusToDosError(rc2), pTempKey);
  1896. rCode = rc2;
  1897. } else if ( bSave ) {
  1898. ScepLogOutput3(2, 0, SCESRV_POLICY_TATTOO_CHECK, pTempKey);
  1899. }
  1900. } else {
  1901. //
  1902. // check if there is any value to save
  1903. //
  1904. switch ( pTattooKeys[i].DataType ) {
  1905. case 'D':
  1906. case 'L':
  1907. if ( pTattooKeys[i].SaveValue != SCE_NO_VALUE )
  1908. bSave = TRUE;
  1909. break;
  1910. case 'S':
  1911. case 'V':
  1912. if ( pTattooKeys[i].Value ) bSave = TRUE;
  1913. break;
  1914. case 'R':
  1915. if ( ((PSCE_REGISTRY_VALUE_INFO)(pTattooKeys[i].Value))->Value )
  1916. bSave = TRUE;
  1917. break;
  1918. }
  1919. if ( bSave )
  1920. ScepLogOutput3(3, 0, SCESRV_POLICY_TATTOO_EXIST, pTempKey);
  1921. }
  1922. } else {
  1923. pTempKey = (pTattooKeys[i].DataType == 'L') ? pTattooKeys[i].Value : pTattooKeys[i].KeyName;
  1924. if ( bTattooExist && ERROR_SUCCESS == rc ) {
  1925. //
  1926. // no domain setting defined
  1927. // tattoo setting has been reset, delete the tattoo value
  1928. // for dependency type, delete the right key
  1929. //
  1930. rc2 = SceJetDelete(hSectionTattoo,
  1931. pTempKey,
  1932. FALSE,
  1933. SCEJET_DELETE_LINE_NO_CASE);
  1934. if ( rc2 == SCESTATUS_RECORD_NOT_FOUND) rc2 = SCESTATUS_SUCCESS;
  1935. if ( rc2 != SCESTATUS_SUCCESS ) {
  1936. ScepLogOutput3(1, 0, SCESRV_POLICY_TATTOO_ERROR_REMOVE, ScepSceStatusToDosError(rc2), pTempKey);
  1937. rCode = rc2;
  1938. } else {
  1939. ScepLogOutput3(2, 0, SCESRV_POLICY_TATTOO_REMOVE_SETTING, pTempKey);
  1940. }
  1941. } else if ( bTattooExist ) {
  1942. //
  1943. // undo value wan't reset properly
  1944. //
  1945. ScepLogOutput3(1, 0, SCESRV_POLICY_TATTOO_ERROR_RESET, pTempKey, rc );
  1946. } else {
  1947. //
  1948. // there is no undo value
  1949. //
  1950. // ScepLogOutput3(3, 0, SCESRV_POLICY_TATTOO_NONEXIST, pTempKey );
  1951. }
  1952. }
  1953. }
  1954. return(rCode);
  1955. }
  1956. BOOL
  1957. ScepTattooIfQueryNeeded(
  1958. IN PSCESECTION hSectionDomain,
  1959. IN PSCESECTION hSectionTattoo,
  1960. IN PWSTR KeyName,
  1961. IN DWORD Len,
  1962. OUT BOOL *pbDomainExist,
  1963. OUT BOOL *pbTattooExist
  1964. )
  1965. {
  1966. if ( hSectionDomain == NULL || hSectionTattoo == NULL || KeyName == NULL || Len == 0 ) {
  1967. return FALSE;
  1968. }
  1969. //
  1970. // check if this setting exists in the tattoo table
  1971. //
  1972. BOOL bTattooExist = FALSE;
  1973. if ( SCESTATUS_SUCCESS == SceJetSeek(
  1974. hSectionTattoo,
  1975. KeyName,
  1976. Len*sizeof(WCHAR),
  1977. SCEJET_SEEK_EQ_NO_CASE
  1978. ) ) {
  1979. bTattooExist = TRUE;
  1980. }
  1981. //
  1982. // check if the setting exists in the effective table
  1983. //
  1984. BOOL bDomainExist = FALSE;
  1985. if ( SCESTATUS_SUCCESS == SceJetSeek(
  1986. hSectionDomain,
  1987. KeyName,
  1988. Len*sizeof(WCHAR),
  1989. SCEJET_SEEK_EQ_NO_CASE
  1990. ) ) {
  1991. if ( !bTattooExist ) {
  1992. //
  1993. // if there is no tattoo value but there is a setting in domain table
  1994. // this setting must come from domain
  1995. //
  1996. bDomainExist = TRUE;
  1997. } else if ( hSectionDomain->JetColumnGpoID > 0 ) {
  1998. //
  1999. // check if GpoID > 0
  2000. //
  2001. LONG GpoID = 0;
  2002. DWORD Actual;
  2003. JET_ERR JetErr;
  2004. JetErr = JetRetrieveColumn(
  2005. hSectionDomain->JetSessionID,
  2006. hSectionDomain->JetTableID,
  2007. hSectionDomain->JetColumnGpoID,
  2008. (void *)&GpoID,
  2009. 4,
  2010. &Actual,
  2011. 0,
  2012. NULL
  2013. );
  2014. if ( JET_errSuccess != JetErr ) {
  2015. //
  2016. // if the column is nil (no value), it will return warning
  2017. // but the buffer pGpoID is trashed
  2018. //
  2019. GpoID = 0;
  2020. }
  2021. if ( GpoID > 0 ) {
  2022. bDomainExist = TRUE;
  2023. }
  2024. }
  2025. }
  2026. //
  2027. // check if we need to save the tatto value or delete the tattoo value
  2028. //
  2029. if ( pbDomainExist ) *pbDomainExist = bDomainExist;
  2030. if ( pbTattooExist ) *pbTattooExist = bTattooExist;
  2031. if ( bDomainExist && !bTattooExist )
  2032. return TRUE;
  2033. return FALSE;
  2034. }
  2035. SCESTATUS
  2036. ScepDeleteOneSection(
  2037. IN PSCECONTEXT hProfile,
  2038. IN SCETYPE tblType,
  2039. IN PCWSTR SectionName
  2040. )
  2041. {
  2042. PSCESECTION hSection=NULL;
  2043. SCESTATUS rc;
  2044. rc = ScepOpenSectionForName(
  2045. hProfile,
  2046. tblType,
  2047. SectionName,
  2048. &hSection
  2049. );
  2050. if ( rc == SCESTATUS_SUCCESS ) {
  2051. rc = SceJetDelete( hSection, NULL, FALSE,SCEJET_DELETE_SECTION );
  2052. SceJetCloseSection(&hSection, TRUE );
  2053. }
  2054. if ( rc == SCESTATUS_RECORD_NOT_FOUND )
  2055. rc = SCESTATUS_SUCCESS;
  2056. return(rc);
  2057. }