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.

2847 lines
80 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. wcscpy(ValueToSet+1, 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. ScepLookupWellKnownName(
  359. pName->Name,
  360. LsaPolicy,
  361. &SidString ) ) {
  362. pa[i].Name = SidString;
  363. pa[i].bFree = TRUE;
  364. Len = wcslen(SidString);
  365. }
  366. else {
  367. pa[i].Name = pName->Name;
  368. pa[i].bFree = FALSE;
  369. Len = wcslen(pName->Name);
  370. }
  371. pa[i].Len = Len;
  372. TotalSize += Len + 1;
  373. i++;
  374. } else {
  375. TotalSize += wcslen(pName->Name)+1;
  376. }
  377. }
  378. TotalSize ++;
  379. if ( SCESTATUS_SUCCESS == rc ) {
  380. if ( TotalSize > 1 ) {
  381. Value = (PWSTR)ScepAlloc( 0, (TotalSize+1)*sizeof(WCHAR));
  382. if ( Value == NULL )
  383. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  384. }
  385. }
  386. if ( SCESTATUS_SUCCESS == rc ) {
  387. if ( TotalSize > 1 ) {
  388. pTemp = Value;
  389. if ( dwWriteOption & SCE_WRITE_CONVERT ) {
  390. for (j=0; j<i; j++) {
  391. if ( pa[j].Name ) {
  392. if ( Status == 3 ) {
  393. ScepLogOutput2(2, 0, pa[j].Name);
  394. }
  395. wcsncpy(pTemp, pa[j].Name, pa[j].Len);
  396. pTemp += pa[j].Len;
  397. *pTemp = L'\0';
  398. pTemp++;
  399. }
  400. }
  401. } else {
  402. for ( pName=NameList; pName != NULL; pName = pName->Next ) {
  403. if ( pName->Name == NULL ) {
  404. continue;
  405. }
  406. if ( Status == 3 ) {
  407. ScepLogOutput2(2, 0, pName->Name);
  408. }
  409. Len = wcslen(pName->Name);
  410. wcsncpy(pTemp, pName->Name, Len);
  411. pTemp += Len;
  412. *pTemp = L'\0';
  413. pTemp++;
  414. }
  415. }
  416. *pTemp = L'\0';
  417. } else
  418. TotalSize = 0;
  419. if ( TotalSize > 0 || (dwWriteOption & SCE_WRITE_EMPTY_LIST) ) {
  420. rc = SceJetSetLine(
  421. hSection,
  422. Name,
  423. FALSE,
  424. Value,
  425. TotalSize*sizeof(WCHAR),
  426. 0
  427. );
  428. switch ( Status ) {
  429. case 1:
  430. ScepLogOutput3(2, 0, SCEDLL_STATUS_MISMATCH, Name);
  431. break;
  432. case 3: // no analyze, already printed
  433. break;
  434. case 2:
  435. ScepLogOutput3(2, 0, SCEDLL_STATUS_NC, Name);
  436. break;
  437. }
  438. #ifdef SCE_DBG
  439. if ( Value != NULL )
  440. wprintf(L"rc=%d, Section: %d, %s=%s\n", rc, (DWORD)(hSection->SectionID), Name, Value);
  441. else
  442. wprintf(L"rc=%d, Section: %d, %s=", rc, (DWORD)(hSection->SectionID), Name);
  443. #endif
  444. }
  445. if ( Value != NULL )
  446. ScepFree(Value);
  447. }
  448. if ( pa ) {
  449. for ( j=0; j<i; j++ ) {
  450. if ( pa[j].Name && pa[j].bFree ) {
  451. ScepFree(pa[j].Name);
  452. }
  453. }
  454. ScepFree(pa);
  455. }
  456. return(rc);
  457. }
  458. SCESTATUS
  459. ScepWriteNameStatusListValue(
  460. IN PSCESECTION hSection,
  461. IN PWSTR Name,
  462. IN PSCE_NAME_STATUS_LIST NameList,
  463. IN BOOL SaveEmptyList,
  464. IN INT Status
  465. )
  466. /* ++
  467. Routine Description:
  468. This routine writes a key with a list of values to the JET section. The list
  469. of values is saved in a MULTI-SZ format which is separated by a NULL char and
  470. terminated by 2 NULLs. If the list is NULL, nothing is saved unless
  471. SaveEmptyList is set to TRUE, where a NULL value is saved with the key.
  472. The format in each string in the MULTI-SZ value is a 2 bytes Status field
  473. followed by the Name field. This structure is primarily used for privileges
  474. Arguments:
  475. hSection - the JET hsection handle
  476. Name - The key name
  477. NameList - the list of values
  478. SaveEmptyList - TRUE = save NULL value if the list is empty
  479. FALSE = DO NOT save if the list is empty
  480. Return Value:
  481. SCESTATUS_SUCCESS
  482. SCESTATUS_NOT_ENOUGH_RESOURCE
  483. SCESTATUS returned from SceJetSetLine
  484. -- */
  485. {
  486. SCESTATUS rc=SCESTATUS_SUCCESS;
  487. DWORD TotalSize=0;
  488. PWSTR Value=NULL;
  489. PSCE_NAME_STATUS_LIST pName;
  490. PWSTR pTemp=NULL;
  491. DWORD Len;
  492. for ( pName=NameList; pName != NULL; pName = pName->Next ) {
  493. //
  494. // Privilege value is stored in 2 bytes
  495. //
  496. TotalSize += 2;
  497. if ( pName->Name != NULL)
  498. TotalSize += wcslen(pName->Name);
  499. TotalSize ++;
  500. }
  501. TotalSize ++;
  502. if ( TotalSize > 1 ) {
  503. Value = (PWSTR)ScepAlloc( 0, (TotalSize+1)*sizeof(WCHAR));
  504. if ( Value == NULL )
  505. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  506. pTemp = Value;
  507. for ( pName=NameList; pName != NULL; pName = pName->Next ) {
  508. swprintf(pTemp, L"%02d", pName->Status);
  509. pTemp += 2;
  510. if ( pName->Name != NULL ) {
  511. Len = wcslen(pName->Name);
  512. wcsncpy(pTemp, pName->Name, Len);
  513. pTemp += Len;
  514. }
  515. *pTemp = L'\0';
  516. pTemp++;
  517. }
  518. *pTemp = L'\0';
  519. } else
  520. TotalSize = 0;
  521. if ( TotalSize > 0 || SaveEmptyList ) {
  522. rc = SceJetSetLine(
  523. hSection,
  524. Name,
  525. FALSE,
  526. Value,
  527. TotalSize*sizeof(WCHAR),
  528. 0
  529. );
  530. if ( Status == 1 )
  531. ScepLogOutput3(2, 0, SCEDLL_STATUS_MISMATCH, Name);
  532. else if ( Status == 2 ) {
  533. ScepLogOutput3(2, 0, SCEDLL_STATUS_NC, Name);
  534. }
  535. #ifdef SCE_DBG
  536. wprintf(L"rc=%d, Section: %d, %s=%s\n", rc, (DWORD)(hSection->SectionID), Name, Value);
  537. #endif
  538. if ( Value != NULL )
  539. ScepFree(Value);
  540. }
  541. return(rc);
  542. }
  543. SCESTATUS
  544. ScepWriteSecurityDescriptorValue(
  545. IN PSCESECTION hSection,
  546. IN PWSTR Name,
  547. IN PSECURITY_DESCRIPTOR pSD,
  548. IN SECURITY_INFORMATION SeInfo
  549. )
  550. /* ++
  551. Routine Description:
  552. This routine writes a key with security descriptor value to the JET section.
  553. The security descriptor is converted into text format based on the secrurity
  554. information passed in.
  555. Arguments:
  556. hSection - the JET hsection handle
  557. Name - The key name
  558. pSD - The security descriptor
  559. SeInfo - the part of the security information to save
  560. Return Value:
  561. SCESTATUS_SUCCESS
  562. SCESTATUS_NOT_ENOUGH_RESOURCE
  563. SCESTATUS returned from SceJetSetLine
  564. -- */
  565. {
  566. SCESTATUS rc=SCESTATUS_SUCCESS;
  567. PWSTR SDspec=NULL;
  568. ULONG SDsize = 0;
  569. if ( hSection == NULL || Name == NULL ) {
  570. return(SCESTATUS_INVALID_PARAMETER);
  571. }
  572. if ( pSD != NULL && SeInfo != 0 ) {
  573. rc = ConvertSecurityDescriptorToText (
  574. pSD,
  575. SeInfo,
  576. &SDspec,
  577. &SDsize
  578. );
  579. if ( rc == NO_ERROR ) {
  580. rc = ScepCompareAndSaveStringValue(
  581. hSection,
  582. Name,
  583. NULL,
  584. SDspec,
  585. SDsize*sizeof(WCHAR)
  586. );
  587. ScepFree(SDspec);
  588. }
  589. }
  590. #ifdef SCE_DBG
  591. wprintf(L"SD==>rc=%d, Section: %d, %s\n", rc, (DWORD)(hSection->SectionID), Name);
  592. #endif
  593. return(rc);
  594. }
  595. SCESTATUS
  596. ScepDuplicateTable(
  597. IN PSCECONTEXT hProfile,
  598. IN SCEJET_TABLE_TYPE TableType,
  599. IN LPSTR DupTableName,
  600. OUT PSCE_ERROR_LOG_INFO *pErrlog
  601. )
  602. /* ++
  603. Routine Description:
  604. This routine copies table structure and data from a SCP/SMP/SAP table to
  605. a table specified by DupTableName. This is used for the SAP table backup.
  606. Arguments:
  607. hProfile - the JET database handle
  608. TableType - the table type -SCEJET_TABLE_SCP
  609. SCEJET_TABLE_SAP
  610. SCEJET_TABLE_SMP
  611. DupTableName - The new table's name
  612. pErrlog - the error list
  613. Return Value:
  614. SCESTATUS_SUCCESS
  615. -- */
  616. {
  617. JET_ERR JetErr;
  618. SCESTATUS rc;
  619. SCECONTEXT hProfile2;
  620. PSCESECTION hSection1=NULL;
  621. PSCESECTION hSection2=NULL;
  622. DOUBLE SectionID=0, SaveID=0;
  623. DWORD Actual;
  624. PWSTR KeyName=NULL;
  625. PWSTR Value=NULL;
  626. DWORD KeyLen=0;
  627. DWORD ValueLen=0;
  628. if ( hProfile == NULL ) {
  629. return(SCESTATUS_INVALID_PARAMETER);
  630. }
  631. //
  632. // Create a SCP section handle. the section ID is a dummy one
  633. //
  634. rc = SceJetOpenSection(
  635. hProfile,
  636. (DOUBLE)1,
  637. TableType,
  638. &hSection1
  639. );
  640. if ( rc != SCESTATUS_SUCCESS ) {
  641. ScepBuildErrorLogInfo( ScepSceStatusToDosError(rc), pErrlog,
  642. SCEERR_OPEN, L"SectionID 1");
  643. return(rc);
  644. }
  645. memset(&hProfile2, '\0', sizeof(SCECONTEXT));
  646. hProfile2.JetSessionID = hProfile->JetSessionID;
  647. hProfile2.JetDbID = hProfile->JetDbID;
  648. //
  649. // Delete the dup table then create it
  650. //
  651. SceJetDeleteTable(
  652. &hProfile2,
  653. DupTableName,
  654. TableType
  655. );
  656. rc = SceJetCreateTable(
  657. &hProfile2,
  658. DupTableName,
  659. TableType,
  660. SCEJET_CREATE_IN_BUFFER,
  661. NULL,
  662. NULL
  663. );
  664. if ( rc != SCESTATUS_SUCCESS ) {
  665. ScepBuildErrorLogInfo( ScepSceStatusToDosError(rc), pErrlog,
  666. SCEERR_CREATE, L"backup table");
  667. goto Cleanup;
  668. }
  669. //
  670. // Move to the first line of the SCP table
  671. //
  672. JetErr = JetMove(hSection1->JetSessionID, hSection1->JetTableID, JET_MoveFirst, 0);
  673. while (JetErr == SCESTATUS_SUCCESS ) {
  674. //
  675. // get section ID
  676. //
  677. JetErr = JetRetrieveColumn(
  678. hSection1->JetSessionID,
  679. hSection1->JetTableID,
  680. hSection1->JetColumnSectionID,
  681. (void *)&SectionID,
  682. 8,
  683. &Actual,
  684. 0,
  685. NULL
  686. );
  687. if ( JetErr != JET_errSuccess ) {
  688. ScepBuildErrorLogInfo( ERROR_READ_FAULT, pErrlog,
  689. SCEERR_QUERY_INFO,
  690. L"sectionID");
  691. rc = SceJetJetErrorToSceStatus(JetErr);
  692. break;
  693. }
  694. #ifdef SCE_DBG
  695. printf("SectionID=%d, JetErr=%d\n", (DWORD)SectionID, JetErr);
  696. #endif
  697. //
  698. // Prepare this Scep section
  699. //
  700. if ( SectionID != SaveID ) {
  701. SaveID = SectionID;
  702. //
  703. // Prepare this section
  704. //
  705. rc = SceJetOpenSection(
  706. &hProfile2,
  707. SectionID,
  708. TableType,
  709. &hSection2
  710. );
  711. if ( rc != SCESTATUS_SUCCESS ) {
  712. ScepBuildErrorLogInfo( ScepSceStatusToDosError(rc), pErrlog,
  713. SCEERR_OPEN_ID,
  714. (DWORD)SectionID);
  715. break;
  716. }
  717. }
  718. //
  719. // get buffer size for key and value
  720. //
  721. rc = SceJetGetValue(
  722. hSection1,
  723. SCEJET_CURRENT,
  724. NULL,
  725. NULL,
  726. 0,
  727. &KeyLen,
  728. NULL,
  729. 0,
  730. &ValueLen);
  731. if ( rc != SCESTATUS_SUCCESS ) {
  732. ScepBuildErrorLogInfo(ScepSceStatusToDosError(rc), pErrlog,
  733. SCEERR_QUERY_VALUE, L"current row");
  734. break;
  735. }
  736. //
  737. // allocate memory
  738. //
  739. if ( KeyLen > 0 ) {
  740. KeyName = (PWSTR)ScepAlloc( LMEM_ZEROINIT, KeyLen+2);
  741. if ( KeyName == NULL ) {
  742. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  743. break;
  744. }
  745. }
  746. if ( ValueLen > 0 ) {
  747. Value = (PWSTR)ScepAlloc( LMEM_ZEROINIT, ValueLen+2);
  748. if ( Value == NULL ) {
  749. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  750. break;
  751. }
  752. }
  753. //
  754. // get key and value
  755. //
  756. rc = SceJetGetValue(
  757. hSection1,
  758. SCEJET_CURRENT,
  759. NULL,
  760. KeyName,
  761. KeyLen,
  762. &KeyLen,
  763. Value,
  764. ValueLen,
  765. &ValueLen);
  766. if ( rc != SCESTATUS_SUCCESS ) {
  767. ScepBuildErrorLogInfo(ScepSceStatusToDosError(rc), pErrlog,
  768. SCEERR_QUERY_VALUE,
  769. L"current row");
  770. break;
  771. }
  772. #ifdef SCE_DBG
  773. wprintf(L"\t%s=%s, rc=%d\n", KeyName, Value, rc);
  774. #endif
  775. //
  776. // set this line to the dup table
  777. //
  778. rc = SceJetSetLine(
  779. hSection2,
  780. KeyName,
  781. TRUE,
  782. Value,
  783. ValueLen,
  784. 0
  785. );
  786. if ( rc != SCESTATUS_SUCCESS ) {
  787. ScepBuildErrorLogInfo(ScepSceStatusToDosError(rc), pErrlog,
  788. SCEERR_WRITE_INFO,
  789. KeyName);
  790. break;
  791. }
  792. ScepFree(KeyName);
  793. KeyName = NULL;
  794. ScepFree(Value);
  795. Value = NULL;
  796. //
  797. // Move to next line in the SCP table
  798. //
  799. JetErr = JetMove(hSection1->JetSessionID, hSection1->JetTableID, JET_MoveNext, 0);
  800. }
  801. Cleanup:
  802. if ( rc != SCESTATUS_SUCCESS ) {
  803. //
  804. // error occurs. Clean up the dup table
  805. //
  806. #ifdef SCE_DBG
  807. printf("Error occurs. delete the dup table.\n");
  808. #endif
  809. SceJetDeleteTable(
  810. &hProfile2,
  811. DupTableName,
  812. TableType
  813. );
  814. }
  815. if ( KeyName != NULL )
  816. ScepFree(KeyName);
  817. if ( Value != NULL )
  818. ScepFree(Value);
  819. SceJetCloseSection(&hSection1, TRUE);
  820. SceJetCloseSection(&hSection2, TRUE);
  821. return(rc);
  822. }
  823. SCESTATUS
  824. ScepAddToPrivList(
  825. IN PSCE_NAME_STATUS_LIST *pPrivList,
  826. IN DWORD Rights,
  827. IN PWSTR Name,
  828. IN DWORD Len
  829. )
  830. /* ++
  831. Routine Description:
  832. This routine adds a privilege with optional group name to the list of
  833. privilege assignments
  834. Arguments:
  835. pPrivList - the privilege list to add to. The structure of this list is
  836. Status -- The privilege value
  837. Name -- The group's name where the priv is assigned
  838. if Name is NULL, the privilege is directly assigned
  839. Rights - The privilege(s) assigned through group Name
  840. Name - The group's name
  841. Len - The group's name length
  842. Return Value:
  843. SCESTATUS_SUCCESS
  844. SCESTATUS_INVALID_PARAMETER
  845. SCESTATUS_NOT_ENOUGH_RESOURCE
  846. -- */
  847. {
  848. PSCE_NAME_STATUS_LIST pTemp;
  849. LONG i;
  850. if ( pPrivList == NULL ) {
  851. return(SCESTATUS_INVALID_PARAMETER);
  852. }
  853. for ( i=31; i>=0; i-- )
  854. if ( Rights & (1 << i) ) {
  855. for ( pTemp=*pPrivList; pTemp != NULL; pTemp = pTemp->Next ) {
  856. if ( (DWORD)i == pTemp->Status )
  857. break;
  858. }
  859. if ( pTemp == NULL ) {
  860. //
  861. // add this one
  862. //
  863. pTemp = (PSCE_NAME_STATUS_LIST)ScepAlloc( LMEM_ZEROINIT, sizeof(SCE_NAME_STATUS_LIST));
  864. if ( pTemp == NULL )
  865. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  866. if ( Name != NULL && Len > 0 ) {
  867. pTemp->Name = (PWSTR)ScepAlloc( LMEM_ZEROINIT, (Len+1)*sizeof(WCHAR));
  868. if ( pTemp->Name == NULL) {
  869. ScepFree(pTemp);
  870. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  871. }
  872. wcsncpy(pTemp->Name, Name, Len);
  873. }
  874. #ifdef SCE_DBG
  875. wprintf(L"Add %d %s to privilege list\n", i, pTemp->Name);
  876. #endif
  877. pTemp->Status = i;
  878. pTemp->Next = *pPrivList;
  879. *pPrivList = pTemp;
  880. pTemp = NULL;
  881. }
  882. }
  883. return(SCESTATUS_SUCCESS);
  884. }
  885. SCESTATUS
  886. ScepOpenPrevPolicyContext(
  887. IN PSCECONTEXT hProfile,
  888. OUT PSCECONTEXT *phPrevProfile
  889. )
  890. {
  891. if ( hProfile == NULL || phPrevProfile == NULL ) {
  892. return(SCESTATUS_INVALID_PARAMETER);
  893. }
  894. *phPrevProfile = (PSCECONTEXT)LocalAlloc( LMEM_ZEROINIT, sizeof(SCECONTEXT));
  895. if ( *phPrevProfile == NULL ) {
  896. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  897. }
  898. memcpy( *phPrevProfile, hProfile, sizeof(SCECONTEXT));
  899. DWORD ScpType = hProfile->Type;
  900. (*phPrevProfile)->Type &= ~(SCEJET_MERGE_TABLE_2 | SCEJET_MERGE_TABLE_1);
  901. SCESTATUS rc;
  902. //
  903. // now open the previous policy table
  904. //
  905. if ( ( ScpType & SCEJET_MERGE_TABLE_2 ) ) {
  906. //
  907. // the second table is the current one
  908. // so the first table is the previous one
  909. //
  910. rc = SceJetOpenTable(
  911. *phPrevProfile,
  912. "SmTblScp",
  913. SCEJET_TABLE_SCP,
  914. SCEJET_OPEN_READ_ONLY,
  915. NULL
  916. );
  917. (*phPrevProfile)->Type |= SCEJET_MERGE_TABLE_1;
  918. } else {
  919. rc = SceJetOpenTable(
  920. *phPrevProfile,
  921. "SmTblScp2",
  922. SCEJET_TABLE_SCP,
  923. SCEJET_OPEN_READ_ONLY,
  924. NULL
  925. );
  926. (*phPrevProfile)->Type |= SCEJET_MERGE_TABLE_2;
  927. }
  928. /*
  929. if ( SCESTATUS_SUCCESS == rc ) {
  930. JET_COLUMNID ColGpoID = (JET_COLUMNID)JET_tableidNil;
  931. JET_ERR JetErr;
  932. JET_COLUMNDEF ColumnGpoIDDef;
  933. JetErr = JetGetTableColumnInfo(
  934. (*phPrevProfile)->JetSessionID,
  935. (*phPrevProfile)->JetScpID,
  936. "GpoID",
  937. (VOID *)&ColumnGpoIDDef,
  938. sizeof(JET_COLUMNDEF),
  939. JET_ColInfo
  940. );
  941. if ( JET_errSuccess == JetErr ) {
  942. ColGpoID = ColumnGpoIDDef.columnid;
  943. } // else ignore error
  944. // temp storage for the column ID
  945. (*phPrevProfile)->JetSapValueID = ColGpoID;
  946. }
  947. */
  948. if ( rc != SCESTATUS_SUCCESS ) {
  949. LocalFree(*phPrevProfile);
  950. *phPrevProfile = NULL;
  951. }
  952. return(rc);
  953. }
  954. SCESTATUS
  955. ScepClosePrevPolicyContext(
  956. IN OUT PSCECONTEXT *phProfile
  957. )
  958. {
  959. if ( phProfile && *phProfile ) {
  960. //
  961. // just free the table because all other info are copied from the
  962. // current policy context and will be freed there
  963. //
  964. if ( (*phProfile)->JetScpID != JET_tableidNil ) {
  965. if ( (*phProfile)->JetScpID != (*phProfile)->JetSmpID ) {
  966. JetCloseTable(
  967. (*phProfile)->JetSessionID,
  968. (*phProfile)->JetScpID
  969. );
  970. }
  971. }
  972. LocalFree(*phProfile);
  973. *phProfile = NULL;
  974. }
  975. return(SCESTATUS_SUCCESS);
  976. }
  977. SCESTATUS
  978. ScepCopyLocalToMergeTable(
  979. IN PSCECONTEXT hProfile,
  980. IN DWORD Options,
  981. IN DWORD CopyOptions,
  982. OUT PSCE_ERROR_LOG_INFO *pErrlog
  983. )
  984. /* ++
  985. Routine Description:
  986. This routine populate data from SCP table into SMP table. All data except
  987. those in the account profiles section(s) in SCP table will be copied over
  988. to SMP table. Account profiles section is converted into User List section
  989. format.
  990. Arguments:
  991. hProfile - the JET database handle
  992. Return Value:
  993. SCESTATUS_SUCCESS
  994. -- */
  995. {
  996. JET_ERR JetErr;
  997. SCESTATUS rc;
  998. PSCESECTION hSectionScp=NULL;
  999. PSCESECTION hSectionSmp=NULL;
  1000. PSCESECTION hSectionPrevScp=NULL;
  1001. PSCECONTEXT hPrevProfile=NULL;
  1002. DOUBLE SectionID=0, SavedID=0;
  1003. DWORD Actual;
  1004. BOOL bCopyIt=FALSE;
  1005. BOOL bCopyThisLine;
  1006. BOOL bConvert=FALSE; // to convert privilege accounts
  1007. PWSTR KeyName=NULL;
  1008. PWSTR Value=NULL;
  1009. DWORD KeyLen=0;
  1010. DWORD ValueLen=0;
  1011. WCHAR SectionName[256];
  1012. if ( hProfile == NULL ) {
  1013. return(SCESTATUS_INVALID_PARAMETER);
  1014. }
  1015. if ( hProfile->JetScpID == hProfile->JetSmpID ) {
  1016. // if it's the same table, return - shouldn't happen
  1017. return(SCESTATUS_SUCCESS);
  1018. }
  1019. if ( hProfile->JetSapID == JET_tableidNil ) {
  1020. // tattoo table doesn't exist, return - shouldn't happen
  1021. return(SCESTATUS_SUCCESS);
  1022. }
  1023. //
  1024. // get previous policy propagation info (if any)
  1025. //
  1026. if ( !(CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ) {
  1027. rc = ScepOpenPrevPolicyContext(hProfile, &hPrevProfile);
  1028. if ( SCESTATUS_RECORD_NOT_FOUND == rc ||
  1029. SCESTATUS_PROFILE_NOT_FOUND == rc ) {
  1030. //
  1031. // the table doesn't exist - no previous policy prop
  1032. // do not need to copy anything, just quit
  1033. //
  1034. return(SCESTATUS_SUCCESS);
  1035. }
  1036. }
  1037. //
  1038. // Create a SMP section handle. the section ID is a dummy one
  1039. //
  1040. rc = SceJetOpenSection(
  1041. hProfile,
  1042. (DOUBLE)1,
  1043. (CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ? SCEJET_TABLE_SMP : SCEJET_TABLE_TATTOO,
  1044. &hSectionSmp
  1045. );
  1046. if ( rc != SCESTATUS_SUCCESS ) {
  1047. ScepBuildErrorLogInfo( ScepSceStatusToDosError(rc), pErrlog,
  1048. SCEERR_OPEN,
  1049. (CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ? L"SMP" : L"TATTOO");
  1050. if (hPrevProfile) ScepClosePrevPolicyContext(&hPrevProfile);
  1051. return(rc);
  1052. }
  1053. LSA_HANDLE LsaPolicy=NULL;
  1054. PWSTR pszNewValue=NULL;
  1055. DWORD NewLen=0;
  1056. //
  1057. // Move to the first line of the SCP table
  1058. //
  1059. JetErr = JetMove(hSectionSmp->JetSessionID, hSectionSmp->JetTableID, JET_MoveFirst, 0);
  1060. while (JetErr == SCESTATUS_SUCCESS ) {
  1061. //
  1062. // get section ID
  1063. //
  1064. JetErr = JetRetrieveColumn(
  1065. hSectionSmp->JetSessionID,
  1066. hSectionSmp->JetTableID,
  1067. hSectionSmp->JetColumnSectionID,
  1068. (void *)&SectionID,
  1069. 8,
  1070. &Actual,
  1071. 0,
  1072. NULL
  1073. );
  1074. if ( JetErr != JET_errSuccess ) {
  1075. ScepBuildErrorLogInfo( ERROR_READ_FAULT, pErrlog,
  1076. SCEERR_QUERY_INFO, L"sectionID");
  1077. rc = SceJetJetErrorToSceStatus(JetErr);
  1078. break;
  1079. }
  1080. #ifdef SCE_DBG
  1081. printf("SectionID=%d, JetErr=%d\n", (DWORD)SectionID, JetErr);
  1082. #endif
  1083. if ( SectionID != SavedID ) {
  1084. //
  1085. // a new section. Look for the section's name to see if this section
  1086. // is to be converted
  1087. //
  1088. SavedID = SectionID;
  1089. Actual = 510;
  1090. memset(SectionName, '\0', 512);
  1091. rc = SceJetGetSectionNameByID(
  1092. hProfile,
  1093. SectionID,
  1094. SectionName,
  1095. &Actual
  1096. );
  1097. if ( rc != SCESTATUS_SUCCESS ) {
  1098. ScepBuildErrorLogInfo( ERROR_BAD_FORMAT, pErrlog,
  1099. SCEERR_CANT_FIND_SECTION,
  1100. (DWORD)SectionID
  1101. );
  1102. break;
  1103. }
  1104. if ( Actual > 0 )
  1105. SectionName[Actual/sizeof(TCHAR)] = L'\0';
  1106. #ifdef SCE_DBG
  1107. wprintf(L"SectionName=%s\n", SectionName);
  1108. #endif
  1109. //
  1110. // Compare section name with domain sections to convert
  1111. //
  1112. bCopyIt = TRUE;
  1113. bConvert = FALSE;
  1114. if ( (CopyOptions & SCE_LOCAL_POLICY_DC) ) {
  1115. //
  1116. // do not copy user rights if it's on a domain controller
  1117. //
  1118. if ( _wcsicmp(szPrivilegeRights, SectionName) == 0 ||
  1119. _wcsicmp(szSystemAccess, SectionName) == 0 ||
  1120. _wcsicmp(szKerberosPolicy, SectionName) == 0 ||
  1121. _wcsicmp(szAuditEvent, SectionName) == 0 ||
  1122. _wcsicmp(szGroupMembership, SectionName) == 0 ) {
  1123. bCopyIt = FALSE;
  1124. } else if ( (CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ) {
  1125. //
  1126. // migrate registry values only
  1127. //
  1128. if ( _wcsicmp(szRegistryValues, SectionName) != 0 )
  1129. bCopyIt = FALSE;
  1130. }
  1131. } else if ( (CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ) {
  1132. //
  1133. // non DCs, should migrate all local policies
  1134. //
  1135. if ( _wcsicmp(szPrivilegeRights, SectionName) == 0 ) {
  1136. bConvert = TRUE;
  1137. } else if ( (_wcsicmp(szSystemAccess, SectionName) != 0) &&
  1138. (_wcsicmp(szKerberosPolicy, SectionName) != 0) &&
  1139. (_wcsicmp(szRegistryValues, SectionName) != 0) &&
  1140. (_wcsicmp(szAuditEvent, SectionName) != 0) ) {
  1141. bCopyIt = FALSE;
  1142. }
  1143. }
  1144. /*
  1145. if ( ( Options & SCE_NOCOPY_DOMAIN_POLICY) &&
  1146. ( (_wcsicmp(szSystemAccess, SectionName) == 0) ||
  1147. (_wcsicmp(szKerberosPolicy, SectionName) == 0) ) ) {
  1148. bCopyIt = FALSE;
  1149. } else if ( (_wcsicmp(szGroupMembership, SectionName) == 0) ||
  1150. (_wcsicmp(szRegistryKeys, SectionName) == 0) ||
  1151. (_wcsicmp(szFileSecurity, SectionName) == 0) ||
  1152. (_wcsicmp(szServiceGeneral, SectionName) == 0) ||
  1153. (_wcsicmp(szAuditApplicationLog, SectionName) == 0) ||
  1154. (_wcsicmp(szAuditSecurityLog, SectionName) == 0) ||
  1155. (_wcsicmp(szAuditSystemLog, SectionName) == 0) ||
  1156. (_wcsicmp(szAttachments, SectionName) == 0) ||
  1157. (_wcsicmp(szDSSecurity, SectionName) == 0)
  1158. ) {
  1159. // do not copy areas other than account policy and local policy
  1160. bCopyIt = FALSE;
  1161. } else {
  1162. bCopyIt = TRUE;
  1163. */
  1164. if ( bCopyIt ) {
  1165. //
  1166. // Prepare this Scep section
  1167. //
  1168. rc = SceJetOpenSection(
  1169. hProfile,
  1170. SectionID,
  1171. (CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ? SCEJET_TABLE_TATTOO : SCEJET_TABLE_SCP,
  1172. &hSectionScp
  1173. );
  1174. if ( rc != SCESTATUS_SUCCESS ) {
  1175. ScepBuildErrorLogInfo( ScepSceStatusToDosError(rc), pErrlog,
  1176. SCEERR_OPEN_ID,
  1177. (DWORD)SectionID);
  1178. break;
  1179. }
  1180. if ( (CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ) {
  1181. //
  1182. // open current policy propagation table
  1183. // do not care error here
  1184. //
  1185. SceJetOpenSection(
  1186. hProfile,
  1187. SectionID,
  1188. SCEJET_TABLE_SCP,
  1189. &hSectionPrevScp
  1190. );
  1191. /* // should always copy tattoo value to the merged table
  1192. // even if the setting doesn't exist in previous policy prop
  1193. // this is to handle the dependent settings such as
  1194. // retention perild and retention days
  1195. } else if ( hPrevProfile ) {
  1196. //
  1197. // open previous policy propagation table
  1198. // do not care error here
  1199. //
  1200. SceJetOpenSection(
  1201. hPrevProfile,
  1202. SectionID,
  1203. SCEJET_TABLE_SCP,
  1204. &hSectionPrevScp
  1205. );
  1206. */
  1207. }
  1208. }
  1209. }
  1210. if ( bCopyIt ) {
  1211. //
  1212. // get buffer size for key and value
  1213. //
  1214. rc = SceJetGetValue(
  1215. hSectionSmp,
  1216. SCEJET_CURRENT,
  1217. NULL,
  1218. NULL,
  1219. 0,
  1220. &KeyLen,
  1221. NULL,
  1222. 0,
  1223. &ValueLen);
  1224. if ( rc != SCESTATUS_SUCCESS ) {
  1225. ScepBuildErrorLogInfo(ScepSceStatusToDosError(rc), pErrlog,
  1226. SCEERR_QUERY_VALUE, L"current row");
  1227. break;
  1228. }
  1229. //
  1230. // allocate memory
  1231. //
  1232. if ( KeyLen > 0 ) {
  1233. KeyName = (PWSTR)ScepAlloc( LMEM_ZEROINIT, KeyLen+2);
  1234. if ( KeyName == NULL ) {
  1235. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1236. break;
  1237. }
  1238. }
  1239. if ( ValueLen > 0 ) {
  1240. Value = (PWSTR)ScepAlloc( LMEM_ZEROINIT, ValueLen+2);
  1241. if ( Value == NULL ) {
  1242. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1243. break;
  1244. }
  1245. }
  1246. //
  1247. // get key and value
  1248. //
  1249. rc = SceJetGetValue(
  1250. hSectionSmp,
  1251. SCEJET_CURRENT,
  1252. NULL,
  1253. KeyName,
  1254. KeyLen,
  1255. &KeyLen,
  1256. Value,
  1257. ValueLen,
  1258. &ValueLen);
  1259. if ( rc != SCESTATUS_SUCCESS ) {
  1260. ScepBuildErrorLogInfo(ScepSceStatusToDosError(rc), pErrlog,
  1261. SCEERR_QUERY_VALUE, L"current row");
  1262. break;
  1263. }
  1264. #ifdef SCE_DBG
  1265. wprintf(L"\t%s=%s, rc=%d\n", KeyName, Value, rc);
  1266. #endif
  1267. bCopyThisLine = TRUE;
  1268. //
  1269. // check if this key exist in the previous prop
  1270. //
  1271. if ( hSectionPrevScp ) {
  1272. rc = SceJetSeek(
  1273. hSectionPrevScp,
  1274. KeyName,
  1275. KeyLen,
  1276. SCEJET_SEEK_EQ_NO_CASE
  1277. );
  1278. if ( SCESTATUS_RECORD_NOT_FOUND == rc ||
  1279. (hSectionPrevScp->JetColumnGpoID == 0) ) {
  1280. bCopyThisLine = FALSE;
  1281. } else if ( SCESTATUS_SUCCESS == rc && (CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ) {
  1282. //
  1283. // found. Let's check if this setting was from a GPO
  1284. // if in migration (build tattoo), a setting was not
  1285. // defined in GPO doesn't need a tattoo value
  1286. //
  1287. // for policy prop case, there may be undo settings in
  1288. // previous policy prop and they weren't reset successfully
  1289. // in previous prop. In this case, we still want to continue
  1290. // reset these settings. So these settings should be copied
  1291. // from the tattoo table to this policy table regardless if
  1292. // there is a domain setting defined for it in the previous
  1293. // policy propagation.
  1294. //
  1295. LONG GpoID = 0;
  1296. (void)JetRetrieveColumn(
  1297. hSectionPrevScp->JetSessionID,
  1298. hSectionPrevScp->JetTableID,
  1299. hSectionPrevScp->JetColumnGpoID,
  1300. (void *)&GpoID,
  1301. 4,
  1302. &Actual,
  1303. 0,
  1304. NULL
  1305. );
  1306. if ( GpoID == 0 ) {
  1307. //
  1308. // this is not a setting from a GPO
  1309. //
  1310. bCopyThisLine = FALSE;
  1311. }
  1312. }
  1313. rc = SCESTATUS_SUCCESS;
  1314. }
  1315. if ( bCopyThisLine ) {
  1316. // Ignore tattoo memberof entries, but leave an empty
  1317. // value so that group membership processing code can detect
  1318. // there is an entry in tattoo table.
  1319. if(NULL != Value &&
  1320. _wcsicmp(szGroupMembership, SectionName) == 0 &&
  1321. ScepWcstrr(KeyName, szMemberof) &&
  1322. !(CopyOptions & SCE_LOCAL_POLICY_MIGRATE))
  1323. {
  1324. *Value = L'\0';
  1325. ValueLen = sizeof(WCHAR);
  1326. }
  1327. if ( bConvert ) {
  1328. rc = ScepConvertFreeTextAccountToSid(
  1329. &LsaPolicy,
  1330. Value,
  1331. ValueLen/sizeof(WCHAR),
  1332. &pszNewValue,
  1333. &NewLen
  1334. );
  1335. if ( rc == SCESTATUS_SUCCESS &&
  1336. pszNewValue ) {
  1337. ScepFree(Value);
  1338. Value = pszNewValue;
  1339. ValueLen = NewLen*sizeof(WCHAR);
  1340. pszNewValue = NULL;
  1341. } // if failed to convert, just use the name format
  1342. }
  1343. //
  1344. // Process group membership section and restore any relative SIDs "#-RSID" to
  1345. // "*S-domain SID-RSID". Do not apply during upgrade.
  1346. //
  1347. if ( _wcsicmp(szGroupMembership, SectionName) == 0 &&
  1348. !(CopyOptions & SCE_LOCAL_POLICY_MIGRATE) ) {
  1349. rc = ScepConvertRelativeSidAccountToSid(
  1350. &LsaPolicy,
  1351. Value,
  1352. ValueLen/sizeof(WCHAR),
  1353. &pszNewValue,
  1354. &NewLen
  1355. );
  1356. if ( rc == SCESTATUS_SUCCESS &&
  1357. pszNewValue ) {
  1358. ScepFree(Value);
  1359. Value = pszNewValue;
  1360. ValueLen = NewLen*sizeof(WCHAR);
  1361. pszNewValue = NULL;
  1362. }
  1363. }
  1364. //
  1365. // set this line to the SCP table
  1366. //
  1367. rc = SceJetSetLine(
  1368. hSectionScp,
  1369. KeyName,
  1370. TRUE,
  1371. Value,
  1372. ValueLen,
  1373. 0
  1374. );
  1375. if ( rc != SCESTATUS_SUCCESS ) {
  1376. ScepBuildErrorLogInfo(ScepSceStatusToDosError(rc), pErrlog,
  1377. SCEERR_WRITE_INFO,
  1378. KeyName);
  1379. break;
  1380. }
  1381. }
  1382. ScepFree(KeyName);
  1383. KeyName = NULL;
  1384. ScepFree(Value);
  1385. Value = NULL;
  1386. }
  1387. //
  1388. // Move to next line in the SCP table
  1389. //
  1390. JetErr = JetMove(hSectionSmp->JetSessionID, hSectionSmp->JetTableID, JET_MoveNext, 0);
  1391. }
  1392. if ( KeyName != NULL )
  1393. ScepFree(KeyName);
  1394. if ( Value != NULL )
  1395. ScepFree(Value);
  1396. SceJetCloseSection(&hSectionScp, TRUE);
  1397. SceJetCloseSection(&hSectionSmp, TRUE);
  1398. if ( hSectionPrevScp ) {
  1399. SceJetCloseSection(&hSectionPrevScp, TRUE);
  1400. }
  1401. if (hPrevProfile)
  1402. ScepClosePrevPolicyContext(&hPrevProfile);
  1403. if ( LsaPolicy ) {
  1404. LsaClose(LsaPolicy);
  1405. }
  1406. return(rc);
  1407. }
  1408. SCESTATUS
  1409. ScepWriteObjectSecurity(
  1410. IN PSCECONTEXT hProfile,
  1411. IN SCETYPE ProfileType,
  1412. IN AREA_INFORMATION Area,
  1413. IN PSCE_OBJECT_SECURITY ObjSecurity
  1414. )
  1415. /*
  1416. Get security for a single object
  1417. */
  1418. {
  1419. SCESTATUS rc;
  1420. PCWSTR SectionName=NULL;
  1421. PSCESECTION hSection=NULL;
  1422. DWORD SDsize, Win32Rc;
  1423. PWSTR SDspec=NULL;
  1424. if ( hProfile == NULL ||
  1425. ObjSecurity == NULL ||
  1426. ObjSecurity->Name == NULL ) {
  1427. return(SCESTATUS_INVALID_PARAMETER);
  1428. }
  1429. switch (Area) {
  1430. case AREA_REGISTRY_SECURITY:
  1431. SectionName = szRegistryKeys;
  1432. break;
  1433. case AREA_FILE_SECURITY:
  1434. SectionName = szFileSecurity;
  1435. break;
  1436. #if 0
  1437. case AREA_DS_OBJECTS:
  1438. SectionName = szDSSecurity;
  1439. break;
  1440. #endif
  1441. default:
  1442. return(SCESTATUS_INVALID_PARAMETER);
  1443. }
  1444. rc = ScepOpenSectionForName(
  1445. hProfile,
  1446. ProfileType,
  1447. SectionName,
  1448. &hSection
  1449. );
  1450. if ( rc == SCESTATUS_SUCCESS ) {
  1451. //
  1452. // convert security descriptor
  1453. //
  1454. Win32Rc = ConvertSecurityDescriptorToText (
  1455. ObjSecurity->pSecurityDescriptor,
  1456. ObjSecurity->SeInfo,
  1457. &SDspec,
  1458. &SDsize
  1459. );
  1460. if ( Win32Rc == NO_ERROR ) {
  1461. if ( Area == AREA_DS_OBJECTS ) {
  1462. //
  1463. // ds needs to convert name
  1464. //
  1465. rc = ScepDosErrorToSceStatus(
  1466. ScepSaveDsStatusToSection(
  1467. ObjSecurity->Name,
  1468. ObjSecurity->IsContainer,
  1469. ObjSecurity->Status,
  1470. SDspec,
  1471. SDsize
  1472. ) );
  1473. } else {
  1474. rc = ScepSaveObjectString(
  1475. hSection,
  1476. ObjSecurity->Name,
  1477. ObjSecurity->IsContainer,
  1478. ObjSecurity->Status,
  1479. SDspec,
  1480. SDsize
  1481. );
  1482. }
  1483. } else
  1484. rc = ScepDosErrorToSceStatus(Win32Rc);
  1485. }
  1486. SceJetCloseSection( &hSection, TRUE);
  1487. if (SDspec)
  1488. ScepFree(SDspec);
  1489. return(rc);
  1490. }
  1491. SCESTATUS
  1492. ScepTattooCheckAndUpdateArray(
  1493. IN OUT SCE_TATTOO_KEYS *pTattooKeys,
  1494. IN OUT DWORD *pcTattooKeys,
  1495. IN PWSTR KeyName,
  1496. IN DWORD ConfigOptions,
  1497. IN DWORD dwValue
  1498. )
  1499. /*
  1500. Description:
  1501. Add a new entry into the array which holds system (tatto) values for the settings
  1502. The input/output buffer pTattooKeys is allocated outside this routine.
  1503. */
  1504. {
  1505. if ( pTattooKeys == NULL || pcTattooKeys == NULL ||
  1506. KeyName == NULL ) {
  1507. return(SCESTATUS_INVALID_PARAMETER);
  1508. }
  1509. if ( !(ConfigOptions & SCE_POLICY_TEMPLATE) ) {
  1510. return(SCESTATUS_SUCCESS);
  1511. }
  1512. pTattooKeys[*pcTattooKeys].KeyName = KeyName;
  1513. pTattooKeys[*pcTattooKeys].KeyLen = wcslen(KeyName);
  1514. pTattooKeys[*pcTattooKeys].DataType = 'D';
  1515. pTattooKeys[*pcTattooKeys].SaveValue = dwValue;
  1516. pTattooKeys[*pcTattooKeys].Value = NULL;
  1517. // ScepLogOutput3(3,0, SCESRV_POLICY_TATTOO_ADD, KeyName, *pcTattooKeys);
  1518. (*pcTattooKeys)++;
  1519. return(SCESTATUS_SUCCESS);
  1520. }
  1521. SCESTATUS
  1522. ScepTattooOpenPolicySections(
  1523. IN PSCECONTEXT hProfile,
  1524. IN PCWSTR SectionName,
  1525. OUT PSCESECTION *phSectionDomain,
  1526. OUT PSCESECTION *phSectionTattoo
  1527. )
  1528. /*
  1529. Open the table/sections for the merged policy and the undo settings
  1530. */
  1531. {
  1532. if ( hProfile == NULL || SectionName == NULL ||
  1533. phSectionDomain == NULL || phSectionTattoo == NULL ) {
  1534. return(SCESTATUS_INVALID_PARAMETER);
  1535. }
  1536. SCESTATUS rCode;
  1537. DOUBLE SectionID;
  1538. *phSectionDomain = NULL;
  1539. *phSectionTattoo = NULL;
  1540. //
  1541. // open the section for both tattoo table and effective policy table
  1542. // get section id first
  1543. //
  1544. rCode = SceJetGetSectionIDByName(
  1545. hProfile,
  1546. SectionName,
  1547. &SectionID
  1548. );
  1549. if ( rCode == SCESTATUS_SUCCESS ) {
  1550. // open effective policy table
  1551. rCode = SceJetOpenSection(
  1552. hProfile,
  1553. SectionID,
  1554. SCEJET_TABLE_SCP,
  1555. phSectionDomain
  1556. );
  1557. if ( rCode == SCESTATUS_SUCCESS ) {
  1558. // open tattoo table
  1559. rCode = SceJetOpenSection(
  1560. hProfile,
  1561. SectionID,
  1562. SCEJET_TABLE_TATTOO,
  1563. phSectionTattoo
  1564. );
  1565. if ( rCode != SCESTATUS_SUCCESS ) {
  1566. SceJetCloseSection(phSectionDomain, TRUE);
  1567. *phSectionDomain = NULL;
  1568. }
  1569. }
  1570. }
  1571. //
  1572. // log tattoo process
  1573. //
  1574. if ( rCode != 0 )
  1575. ScepLogOutput3(1, 0,
  1576. SCESRV_POLICY_TATTOO_PREPARE,
  1577. ScepSceStatusToDosError(rCode),
  1578. SectionName);
  1579. return(rCode);
  1580. }
  1581. SCESTATUS
  1582. ScepTattooManageOneStringValue(
  1583. IN PSCESECTION hSectionDomain,
  1584. IN PSCESECTION hSectionTattoo,
  1585. IN PWSTR KeyName,
  1586. IN DWORD KeyLen OPTIONAL,
  1587. IN PWSTR Value,
  1588. IN DWORD ValueLen,
  1589. IN DWORD rc
  1590. )
  1591. {
  1592. if ( hSectionDomain == NULL || hSectionTattoo == NULL ||
  1593. KeyName == NULL || Value == NULL )
  1594. return(SCESTATUS_INVALID_PARAMETER);
  1595. PWSTR pNewValue=NULL;
  1596. DWORD NewLen=ValueLen;
  1597. SCESTATUS rCode;
  1598. if (Value && (ValueLen == 0) ) NewLen = wcslen(Value);
  1599. if ( NewLen ) {
  1600. //
  1601. // the buffer passed may not be NULL terminated
  1602. //
  1603. pNewValue = (PWSTR)ScepAlloc(LPTR,(NewLen+1)*sizeof(WCHAR));
  1604. if ( pNewValue == NULL ) return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  1605. wcsncpy(pNewValue, Value, NewLen);
  1606. }
  1607. SCE_TATTOO_KEYS theKey;
  1608. theKey.KeyName = KeyName;
  1609. theKey.KeyLen = (KeyLen == 0) ? wcslen(KeyName) : KeyLen;
  1610. theKey.Value = pNewValue;
  1611. theKey.SaveValue = NewLen;
  1612. theKey.DataType = 'S';
  1613. rCode = ScepTattooManageValues(hSectionDomain, hSectionTattoo, &theKey, 1, rc);
  1614. if ( pNewValue ) ScepFree(pNewValue);
  1615. return(rCode);
  1616. }
  1617. SCESTATUS
  1618. ScepTattooManageOneIntValue(
  1619. IN PSCESECTION hSectionDomain,
  1620. IN PSCESECTION hSectionTattoo,
  1621. IN PWSTR KeyName,
  1622. IN DWORD KeyLen OPTIONAL,
  1623. IN DWORD Value,
  1624. IN DWORD rc
  1625. )
  1626. {
  1627. if ( hSectionDomain == NULL || hSectionTattoo == NULL || KeyName == NULL )
  1628. return(SCESTATUS_INVALID_PARAMETER);
  1629. SCE_TATTOO_KEYS theKey;
  1630. theKey.KeyName = KeyName;
  1631. theKey.KeyLen = (KeyLen == 0) ? wcslen(KeyName) : KeyLen;
  1632. theKey.SaveValue = Value;
  1633. theKey.DataType = 'D';
  1634. theKey.Value = NULL;
  1635. return(ScepTattooManageValues(hSectionDomain, hSectionTattoo, &theKey, 1, rc));
  1636. }
  1637. SCESTATUS
  1638. ScepTattooManageOneIntValueWithDependency(
  1639. IN PSCESECTION hSectionDomain,
  1640. IN PSCESECTION hSectionTattoo,
  1641. IN PWSTR DependentKeyName,
  1642. IN DWORD DependentKeyLen OPTIONAL,
  1643. IN PWSTR SaveKeyName,
  1644. IN DWORD Value,
  1645. IN DWORD rc
  1646. )
  1647. {
  1648. if ( hSectionDomain == NULL || hSectionTattoo == NULL ||
  1649. SaveKeyName == NULL || DependentKeyName == NULL)
  1650. return(SCESTATUS_INVALID_PARAMETER);
  1651. SCE_TATTOO_KEYS theKey;
  1652. theKey.KeyName = DependentKeyName;
  1653. theKey.KeyLen = (DependentKeyLen == 0) ? wcslen(DependentKeyName) : DependentKeyLen;
  1654. theKey.SaveValue = Value;
  1655. theKey.DataType = 'L';
  1656. theKey.Value = SaveKeyName;
  1657. return(ScepTattooManageValues(hSectionDomain, hSectionTattoo, &theKey, 1, rc));
  1658. }
  1659. SCESTATUS
  1660. ScepTattooManageOneRegistryValue(
  1661. IN PSCESECTION hSectionDomain,
  1662. IN PSCESECTION hSectionTattoo,
  1663. IN PWSTR KeyName,
  1664. IN DWORD KeyLen OPTIONAL,
  1665. IN PSCE_REGISTRY_VALUE_INFO pOneRegValue,
  1666. IN DWORD rc
  1667. )
  1668. {
  1669. if ( hSectionDomain == NULL || hSectionTattoo == NULL ||
  1670. KeyName == NULL || pOneRegValue == NULL )
  1671. return(SCESTATUS_INVALID_PARAMETER);
  1672. SCESTATUS rCode;
  1673. SCE_TATTOO_KEYS theKey;
  1674. theKey.KeyName = KeyName;
  1675. theKey.KeyLen = (KeyLen == 0) ? wcslen(KeyName) : KeyLen;
  1676. theKey.Value = (PWSTR)pOneRegValue;
  1677. theKey.SaveValue = 0;
  1678. theKey.DataType = 'R';
  1679. rCode = ScepTattooManageValues(hSectionDomain, hSectionTattoo, &theKey, 1, rc);
  1680. return(rCode);
  1681. }
  1682. SCESTATUS
  1683. ScepTattooManageOneMemberListValue(
  1684. IN PSCESECTION hSectionDomain,
  1685. IN PSCESECTION hSectionTattoo,
  1686. IN PWSTR GroupName,
  1687. IN DWORD GroupLen OPTIONAL,
  1688. IN PSCE_NAME_LIST pNameList,
  1689. IN BOOL bDeleteOnly,
  1690. IN DWORD rc
  1691. )
  1692. {
  1693. if ( hSectionDomain == NULL || hSectionTattoo == NULL ||
  1694. GroupName == NULL )
  1695. return(SCESTATUS_INVALID_PARAMETER);
  1696. SCESTATUS rCode;
  1697. SCE_TATTOO_KEYS theKey;
  1698. DWORD Len=GroupLen;
  1699. if ( Len == 0 ) Len = wcslen(GroupName);
  1700. Len += wcslen(szMembers);
  1701. PWSTR KeyString = (PWSTR)ScepAlloc(0, (Len+1)*sizeof(WCHAR));
  1702. if ( KeyString != NULL ) {
  1703. swprintf(KeyString, L"%s%s", GroupName, szMembers);
  1704. theKey.KeyName = KeyString;
  1705. theKey.KeyLen = Len;
  1706. theKey.Value = (PWSTR)pNameList;
  1707. theKey.SaveValue = bDeleteOnly ? 1 : 0;
  1708. theKey.DataType = 'M';
  1709. rCode = ScepTattooManageValues(hSectionDomain, hSectionTattoo, &theKey, 1, rc);
  1710. ScepFree(KeyString);
  1711. } else {
  1712. rCode = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1713. }
  1714. return(rCode);
  1715. }
  1716. SCESTATUS
  1717. ScepTattooReadOneMemberOfListValue(
  1718. IN PSCESECTION hSectionTattoo,
  1719. IN PSID pGroupSid,
  1720. OUT PSCE_NAME_LIST *ppTattooList
  1721. )
  1722. {
  1723. SCESTATUS rc = SCESTATUS_SUCCESS;
  1724. PWSTR pszGroupSid = NULL;
  1725. PWSTR pszKeyName = NULL;
  1726. DWORD dwValueLen = 0;
  1727. PWSTR pszValue = NULL;
  1728. PWSTR pszTemp;
  1729. // Build the key name in format "*SID_memberof"
  1730. rc = ScepDosErrorToSceStatus(
  1731. ScepConvertSidToPrefixStringSid(
  1732. pGroupSid, &pszGroupSid));
  1733. if(SCESTATUS_SUCCESS == rc)
  1734. {
  1735. pszKeyName = (PWSTR)ScepAlloc(0,
  1736. (wcslen(pszGroupSid)+wcslen(szMemberof)+1)*sizeof(WCHAR));
  1737. if(!pszKeyName)
  1738. {
  1739. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1740. }
  1741. }
  1742. if(SCESTATUS_SUCCESS == rc)
  1743. {
  1744. wcscpy(pszKeyName, pszGroupSid);
  1745. wcscat(pszKeyName, szMemberof);
  1746. }
  1747. // retrieve memberof data from tattoo table
  1748. rc = SceJetGetValue(
  1749. hSectionTattoo,
  1750. SCEJET_EXACT_MATCH_NO_CASE,
  1751. pszKeyName,
  1752. NULL,
  1753. 0,
  1754. NULL,
  1755. NULL,
  1756. 0,
  1757. &dwValueLen);
  1758. if(SCESTATUS_SUCCESS == rc)
  1759. {
  1760. pszValue = (PWSTR)ScepAlloc( LMEM_ZEROINIT, dwValueLen+2);
  1761. if(!pszValue)
  1762. {
  1763. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1764. }
  1765. }
  1766. if(SCESTATUS_SUCCESS == rc)
  1767. {
  1768. rc = SceJetGetValue(
  1769. hSectionTattoo,
  1770. SCEJET_EXACT_MATCH_NO_CASE,
  1771. pszKeyName,
  1772. NULL,
  1773. 0,
  1774. NULL,
  1775. pszValue,
  1776. dwValueLen,
  1777. &dwValueLen);
  1778. }
  1779. // build the memberof name list
  1780. if(SCESTATUS_SUCCESS == rc)
  1781. {
  1782. pszTemp = pszValue;
  1783. while(pszTemp && pszTemp[0])
  1784. {
  1785. rc = ScepAddToNameList(ppTattooList,
  1786. pszTemp,
  1787. 0);
  1788. if(STATUS_SUCCESS != rc)
  1789. {
  1790. rc = ScepDosErrorToSceStatus(rc);
  1791. break;
  1792. }
  1793. pszTemp += wcslen(pszTemp)+1;
  1794. }
  1795. if(SCESTATUS_SUCCESS == rc)
  1796. {
  1797. pszTemp = pszValue;
  1798. while(pszTemp && *pszTemp != L'\0')
  1799. {
  1800. DWORD dwLen = wcslen(pszTemp);
  1801. *(pszTemp+dwLen) = L',';
  1802. pszTemp = pszTemp+dwLen+1;
  1803. }
  1804. ScepLogOutput3(1, 0, SCEDLL_SCP_OLDTATTOO, pszValue);
  1805. }
  1806. }
  1807. if(pszGroupSid)
  1808. {
  1809. ScepFree(pszGroupSid);
  1810. }
  1811. if(pszKeyName)
  1812. {
  1813. ScepFree(pszKeyName);
  1814. }
  1815. if(pszValue)
  1816. {
  1817. ScepFree(pszValue);
  1818. }
  1819. return rc;
  1820. }
  1821. SCESTATUS
  1822. ScepTattooWriteOneMemberOfListValue(
  1823. IN PSCESECTION hSectionTattoo,
  1824. IN PSID pGroupSid,
  1825. IN PSCE_NAME_LIST pNameList
  1826. )
  1827. {
  1828. SCESTATUS rc = SCESTATUS_SUCCESS;
  1829. PWSTR pszGroupSid = NULL;
  1830. PWSTR pszKeyName = NULL;
  1831. PWSTR pszValue = NULL;
  1832. PWSTR pszTemp;
  1833. DWORD dwValueLen;
  1834. PSCE_NAME_LIST pName;
  1835. // Build the key name in format "*SID_memberof"
  1836. rc = ScepDosErrorToSceStatus(
  1837. ScepConvertSidToPrefixStringSid(
  1838. pGroupSid, &pszGroupSid));
  1839. if(SCESTATUS_SUCCESS == rc)
  1840. {
  1841. pszKeyName = (PWSTR)ScepAlloc(0,
  1842. (wcslen(pszGroupSid)+wcslen(szMemberof)+1)*sizeof(WCHAR));
  1843. if(!pszKeyName)
  1844. {
  1845. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1846. }
  1847. }
  1848. if(SCESTATUS_SUCCESS == rc)
  1849. {
  1850. wcscpy(pszKeyName, pszGroupSid);
  1851. wcscat(pszKeyName, szMemberof);
  1852. }
  1853. // if list is empty, delete entry from tattoo table
  1854. if(!pNameList)
  1855. {
  1856. rc = SceJetDelete(
  1857. hSectionTattoo,
  1858. pszKeyName,
  1859. FALSE,
  1860. SCEJET_DELETE_LINE_NO_CASE);
  1861. if(SCESTATUS_SUCCESS == rc)
  1862. {
  1863. ScepLogOutput3(1, 0, SCEDLL_SCP_DELETETATTOO);
  1864. }
  1865. // entry might not be there
  1866. if(SCESTATUS_RECORD_NOT_FOUND == rc)
  1867. {
  1868. rc = SCESTATUS_SUCCESS;
  1869. }
  1870. }
  1871. else // list is not empty, write new entry to tattoo table
  1872. {
  1873. // calculate value size
  1874. if(SCESTATUS_SUCCESS == rc)
  1875. {
  1876. dwValueLen = sizeof(WCHAR);
  1877. for(pName = pNameList; pName; pName = pName->Next)
  1878. {
  1879. dwValueLen += (wcslen(pName->Name)+1)*sizeof(WCHAR);
  1880. }
  1881. }
  1882. // allocate value
  1883. if(SCESTATUS_SUCCESS == rc)
  1884. {
  1885. pszValue = (PWSTR) ScepAlloc(LMEM_ZEROINIT, dwValueLen);
  1886. if(!pszValue)
  1887. {
  1888. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1889. }
  1890. }
  1891. // build value from list
  1892. if(SCESTATUS_SUCCESS == rc)
  1893. {
  1894. pszTemp = pszValue;
  1895. for(pName = pNameList; pName; pName = pName->Next)
  1896. {
  1897. wcscpy(pszTemp, pName->Name);
  1898. pszTemp += wcslen(pName->Name)+1;
  1899. }
  1900. *pszTemp = L'\0';
  1901. }
  1902. if(SCESTATUS_SUCCESS == rc)
  1903. {
  1904. rc = SceJetSetLine(
  1905. hSectionTattoo,
  1906. pszKeyName,
  1907. FALSE, // lowercase
  1908. pszValue,
  1909. dwValueLen,
  1910. 0); // no GPOID
  1911. }
  1912. // if successfull, convert multisz to comma separated and write to log
  1913. if(SCESTATUS_SUCCESS == rc)
  1914. {
  1915. pszTemp = pszValue;
  1916. while(pszTemp && *pszTemp != L'\0')
  1917. {
  1918. DWORD dwLen = wcslen(pszTemp);
  1919. *(pszTemp+dwLen) = L',';
  1920. pszTemp = pszTemp+dwLen+1;
  1921. }
  1922. ScepLogOutput3(1, 0, SCEDLL_SCP_NEWTATTOO, pszValue);
  1923. }
  1924. if(pszValue)
  1925. {
  1926. ScepFree(pszValue);
  1927. }
  1928. }
  1929. if(pszGroupSid)
  1930. {
  1931. ScepFree(pszGroupSid);
  1932. }
  1933. if(pszKeyName)
  1934. {
  1935. ScepFree(pszKeyName);
  1936. }
  1937. return(rc);
  1938. }
  1939. SCESTATUS
  1940. ScepTattooManageOneServiceValue(
  1941. IN PSCESECTION hSectionDomain,
  1942. IN PSCESECTION hSectionTattoo,
  1943. IN PWSTR ServiceName,
  1944. IN DWORD ServiceLen OPTIONAL,
  1945. IN PSCE_SERVICES pServiceNode,
  1946. IN DWORD rc
  1947. )
  1948. {
  1949. if ( hSectionDomain == NULL || hSectionTattoo == NULL ||
  1950. ServiceName == NULL )
  1951. return(SCESTATUS_INVALID_PARAMETER);
  1952. SCESTATUS rCode;
  1953. SCE_TATTOO_KEYS theKey;
  1954. theKey.KeyName = ServiceName;
  1955. theKey.KeyLen = (ServiceLen == 0) ? wcslen(ServiceName) : ServiceLen;
  1956. theKey.Value = (PWSTR)pServiceNode;
  1957. theKey.SaveValue = 0;
  1958. theKey.DataType = 'V';
  1959. rCode = ScepTattooManageValues(hSectionDomain, hSectionTattoo, &theKey, 1, rc);
  1960. return(rCode);
  1961. }
  1962. SCESTATUS
  1963. ScepTattooManageValues(
  1964. IN PSCESECTION hSectionDomain,
  1965. IN PSCESECTION hSectionTattoo,
  1966. IN SCE_TATTOO_KEYS *pTattooKeys,
  1967. IN DWORD cTattooKeys,
  1968. IN DWORD rc
  1969. )
  1970. /*
  1971. Description:
  1972. For each setting in the array, do the following:
  1973. 1) Check if the setting come from domain
  1974. 2) Check if there is a tattoo value already exist
  1975. 3) Save the new value from the array to the tattoo table if it doesn't exist
  1976. 4) Delete the tattoo value if the setting didn't come from domain and
  1977. it has been reset successfully
  1978. */
  1979. {
  1980. if ( hSectionDomain == NULL || hSectionTattoo == NULL ||
  1981. pTattooKeys == NULL || cTattooKeys == 0 ) {
  1982. return(SCESTATUS_INVALID_PARAMETER);
  1983. }
  1984. SCESTATUS rCode=SCESTATUS_SUCCESS;
  1985. SCESTATUS rc2;
  1986. BOOL bTattooExist,bDomainExist;
  1987. PWSTR KeyString=NULL;
  1988. PWSTR pTempKey;
  1989. for ( DWORD i=0; i<cTattooKeys; i++) {
  1990. if ( pTattooKeys[i].KeyName == NULL ) continue;
  1991. if ( pTattooKeys[i].DataType == 'L' && pTattooKeys[i].Value == NULL ) continue;
  1992. //
  1993. // check if this setting exists in the tattoo table
  1994. //
  1995. bTattooExist = FALSE;
  1996. rc2 = SCESTATUS_SUCCESS;
  1997. if ( SCESTATUS_SUCCESS == SceJetSeek(
  1998. hSectionTattoo,
  1999. pTattooKeys[i].KeyName,
  2000. pTattooKeys[i].KeyLen*sizeof(WCHAR),
  2001. SCEJET_SEEK_EQ_NO_CASE
  2002. ) ) {
  2003. bTattooExist = TRUE;
  2004. }
  2005. //
  2006. // check if the setting exists in the effective table
  2007. //
  2008. bDomainExist = FALSE;
  2009. if ( SCESTATUS_SUCCESS == SceJetSeek(
  2010. hSectionDomain,
  2011. pTattooKeys[i].KeyName,
  2012. pTattooKeys[i].KeyLen*sizeof(WCHAR),
  2013. SCEJET_SEEK_EQ_NO_CASE
  2014. ) ) {
  2015. if ( !bTattooExist ) {
  2016. //
  2017. // if there is no tattoo value but there is a setting in domain table
  2018. // this setting must come from domain
  2019. //
  2020. bDomainExist = TRUE;
  2021. } else if ( hSectionDomain->JetColumnGpoID > 0 ) {
  2022. //
  2023. // check if GpoID > 0
  2024. //
  2025. LONG GpoID = 0;
  2026. DWORD Actual;
  2027. JET_ERR JetErr;
  2028. JetErr = JetRetrieveColumn(
  2029. hSectionDomain->JetSessionID,
  2030. hSectionDomain->JetTableID,
  2031. hSectionDomain->JetColumnGpoID,
  2032. (void *)&GpoID,
  2033. 4,
  2034. &Actual,
  2035. 0,
  2036. NULL
  2037. );
  2038. if ( JET_errSuccess != JetErr ) {
  2039. //
  2040. // if the column is nil (no value), it will return warning
  2041. // but the buffer pGpoID is trashed
  2042. //
  2043. GpoID = 0;
  2044. }
  2045. if ( GpoID > 0 ) {
  2046. bDomainExist = TRUE;
  2047. }
  2048. }
  2049. }
  2050. //
  2051. // check if we need to save the tatto value or delete the tattoo value
  2052. //
  2053. if ( bDomainExist ) {
  2054. pTempKey = pTattooKeys[i].KeyName;
  2055. BOOL bSave = FALSE;
  2056. if ( pTattooKeys[i].DataType == 'M' && pTattooKeys[i].SaveValue == 1 ) {
  2057. //
  2058. // delete only for group membership, don't do anything in this case
  2059. //
  2060. } else if ( !bTattooExist ) {
  2061. //
  2062. // domain setting is defined (the first time)
  2063. // save the tattoo value
  2064. //
  2065. switch ( pTattooKeys[i].DataType ) {
  2066. case 'D':
  2067. if ( pTattooKeys[i].SaveValue != SCE_NO_VALUE ) {
  2068. rc2 = ScepCompareAndSaveIntValue(hSectionTattoo,
  2069. pTattooKeys[i].KeyName,
  2070. FALSE,
  2071. SCE_SNAPSHOT_VALUE,
  2072. pTattooKeys[i].SaveValue
  2073. );
  2074. bSave = TRUE;
  2075. }
  2076. break;
  2077. case 'L': // dependency DWORD type
  2078. pTempKey = pTattooKeys[i].Value;
  2079. if ( pTattooKeys[i].SaveValue != SCE_NO_VALUE ) {
  2080. rc2 = ScepCompareAndSaveIntValue(hSectionTattoo,
  2081. pTattooKeys[i].Value,
  2082. FALSE,
  2083. SCE_SNAPSHOT_VALUE,
  2084. pTattooKeys[i].SaveValue
  2085. );
  2086. bSave = TRUE;
  2087. }
  2088. break;
  2089. case 'S':
  2090. if ( pTattooKeys[i].Value ) {
  2091. rc2 = ScepCompareAndSaveStringValue(hSectionTattoo,
  2092. pTattooKeys[i].KeyName,
  2093. (PWSTR)(ULONG_PTR)SCE_SNAPSHOT_VALUE,
  2094. pTattooKeys[i].Value,
  2095. pTattooKeys[i].SaveValue*sizeof(WCHAR)
  2096. );
  2097. bSave = TRUE;
  2098. }
  2099. break;
  2100. case 'R': // registry values
  2101. if ( ((PSCE_REGISTRY_VALUE_INFO)(pTattooKeys[i].Value))->Value ) {
  2102. if ( REG_DWORD == ((PSCE_REGISTRY_VALUE_INFO)(pTattooKeys[i].Value))->ValueType ) {
  2103. DWORD RegData = _wtol(((PSCE_REGISTRY_VALUE_INFO)(pTattooKeys[i].Value))->Value);
  2104. rc2 = ScepSaveRegistryValue(hSectionTattoo,
  2105. pTattooKeys[i].KeyName,
  2106. REG_DWORD,
  2107. (PWSTR)&RegData,
  2108. sizeof(DWORD),
  2109. 0
  2110. );
  2111. } else {
  2112. rc2 = ScepSaveRegistryValue(hSectionTattoo,
  2113. pTattooKeys[i].KeyName,
  2114. ((PSCE_REGISTRY_VALUE_INFO)(pTattooKeys[i].Value))->ValueType,
  2115. ((PSCE_REGISTRY_VALUE_INFO)(pTattooKeys[i].Value))->Value,
  2116. wcslen(((PSCE_REGISTRY_VALUE_INFO)(pTattooKeys[i].Value))->Value)*sizeof(WCHAR),
  2117. 0
  2118. );
  2119. }
  2120. bSave = TRUE;
  2121. }
  2122. break;
  2123. case 'M': // group member list
  2124. // allow empty member list to be saved
  2125. rc2 = ScepWriteNameListValue(
  2126. NULL,
  2127. hSectionTattoo,
  2128. pTattooKeys[i].KeyName,
  2129. (PSCE_NAME_LIST)(pTattooKeys[i].Value),
  2130. SCE_WRITE_EMPTY_LIST,
  2131. 3
  2132. );
  2133. bSave = TRUE;
  2134. break;
  2135. case 'V': // service
  2136. if ( pTattooKeys[i].Value ) {
  2137. rc2 = ScepSetSingleServiceSetting(
  2138. hSectionTattoo,
  2139. (PSCE_SERVICES)(pTattooKeys[i].Value)
  2140. );
  2141. bSave = TRUE;
  2142. } else {
  2143. rc2 = SCESTATUS_INVALID_PARAMETER;
  2144. }
  2145. break;
  2146. default:
  2147. rc2 = SCESTATUS_INVALID_PARAMETER;
  2148. break;
  2149. }
  2150. if ( rc2 != SCESTATUS_SUCCESS ) {
  2151. ScepLogOutput3(1, 0, SCESRV_POLICY_TATTOO_ERROR_SETTING,
  2152. ScepSceStatusToDosError(rc2), pTempKey);
  2153. rCode = rc2;
  2154. } else if ( bSave ) {
  2155. ScepLogOutput3(2, 0, SCESRV_POLICY_TATTOO_CHECK, pTempKey);
  2156. }
  2157. } else {
  2158. //
  2159. // check if there is any value to save
  2160. //
  2161. switch ( pTattooKeys[i].DataType ) {
  2162. case 'D':
  2163. case 'L':
  2164. if ( pTattooKeys[i].SaveValue != SCE_NO_VALUE )
  2165. bSave = TRUE;
  2166. break;
  2167. case 'S':
  2168. case 'V':
  2169. if ( pTattooKeys[i].Value ) bSave = TRUE;
  2170. break;
  2171. case 'R':
  2172. if ( ((PSCE_REGISTRY_VALUE_INFO)(pTattooKeys[i].Value))->Value )
  2173. bSave = TRUE;
  2174. break;
  2175. }
  2176. if ( bSave )
  2177. ScepLogOutput3(3, 0, SCESRV_POLICY_TATTOO_EXIST, pTempKey);
  2178. }
  2179. } else {
  2180. pTempKey = (pTattooKeys[i].DataType == 'L') ? pTattooKeys[i].Value : pTattooKeys[i].KeyName;
  2181. if ( bTattooExist && ERROR_SUCCESS == rc ) {
  2182. //
  2183. // no domain setting defined
  2184. // tattoo setting has been reset, delete the tattoo value
  2185. // for dependency type, delete the right key
  2186. //
  2187. rc2 = SceJetDelete(hSectionTattoo,
  2188. pTempKey,
  2189. FALSE,
  2190. SCEJET_DELETE_LINE_NO_CASE);
  2191. if ( rc2 == SCESTATUS_RECORD_NOT_FOUND) rc2 = SCESTATUS_SUCCESS;
  2192. if ( rc2 != SCESTATUS_SUCCESS ) {
  2193. ScepLogOutput3(1, 0, SCESRV_POLICY_TATTOO_ERROR_REMOVE, ScepSceStatusToDosError(rc2), pTempKey);
  2194. rCode = rc2;
  2195. } else {
  2196. ScepLogOutput3(2, 0, SCESRV_POLICY_TATTOO_REMOVE_SETTING, pTempKey);
  2197. }
  2198. } else if ( bTattooExist ) {
  2199. //
  2200. // undo value wan't reset properly
  2201. //
  2202. ScepLogOutput3(1, 0, SCESRV_POLICY_TATTOO_ERROR_RESET, pTempKey, rc );
  2203. } else {
  2204. //
  2205. // there is no undo value
  2206. //
  2207. // ScepLogOutput3(3, 0, SCESRV_POLICY_TATTOO_NONEXIST, pTempKey );
  2208. }
  2209. }
  2210. }
  2211. return(rCode);
  2212. }
  2213. BOOL
  2214. ScepTattooIfQueryNeeded(
  2215. IN PSCESECTION hSectionDomain,
  2216. IN PSCESECTION hSectionTattoo,
  2217. IN PWSTR KeyName,
  2218. IN DWORD Len,
  2219. OUT BOOL *pbDomainExist,
  2220. OUT BOOL *pbTattooExist
  2221. )
  2222. {
  2223. if ( hSectionDomain == NULL || hSectionTattoo == NULL || KeyName == NULL || Len == 0 ) {
  2224. return FALSE;
  2225. }
  2226. //
  2227. // check if this setting exists in the tattoo table
  2228. //
  2229. BOOL bTattooExist = FALSE;
  2230. if ( SCESTATUS_SUCCESS == SceJetSeek(
  2231. hSectionTattoo,
  2232. KeyName,
  2233. Len*sizeof(WCHAR),
  2234. SCEJET_SEEK_EQ_NO_CASE
  2235. ) ) {
  2236. bTattooExist = TRUE;
  2237. }
  2238. //
  2239. // check if the setting exists in the effective table
  2240. //
  2241. BOOL bDomainExist = FALSE;
  2242. if ( SCESTATUS_SUCCESS == SceJetSeek(
  2243. hSectionDomain,
  2244. KeyName,
  2245. Len*sizeof(WCHAR),
  2246. SCEJET_SEEK_EQ_NO_CASE
  2247. ) ) {
  2248. if ( !bTattooExist ) {
  2249. //
  2250. // if there is no tattoo value but there is a setting in domain table
  2251. // this setting must come from domain
  2252. //
  2253. bDomainExist = TRUE;
  2254. } else if ( hSectionDomain->JetColumnGpoID > 0 ) {
  2255. //
  2256. // check if GpoID > 0
  2257. //
  2258. LONG GpoID = 0;
  2259. DWORD Actual;
  2260. JET_ERR JetErr;
  2261. JetErr = JetRetrieveColumn(
  2262. hSectionDomain->JetSessionID,
  2263. hSectionDomain->JetTableID,
  2264. hSectionDomain->JetColumnGpoID,
  2265. (void *)&GpoID,
  2266. 4,
  2267. &Actual,
  2268. 0,
  2269. NULL
  2270. );
  2271. if ( JET_errSuccess != JetErr ) {
  2272. //
  2273. // if the column is nil (no value), it will return warning
  2274. // but the buffer pGpoID is trashed
  2275. //
  2276. GpoID = 0;
  2277. }
  2278. if ( GpoID > 0 ) {
  2279. bDomainExist = TRUE;
  2280. }
  2281. }
  2282. }
  2283. //
  2284. // check if we need to save the tatto value or delete the tattoo value
  2285. //
  2286. if ( pbDomainExist ) *pbDomainExist = bDomainExist;
  2287. if ( pbTattooExist ) *pbTattooExist = bTattooExist;
  2288. if ( bDomainExist && !bTattooExist )
  2289. return TRUE;
  2290. return FALSE;
  2291. }
  2292. SCESTATUS
  2293. ScepDeleteOneSection(
  2294. IN PSCECONTEXT hProfile,
  2295. IN SCETYPE tblType,
  2296. IN PCWSTR SectionName
  2297. )
  2298. {
  2299. PSCESECTION hSection=NULL;
  2300. SCESTATUS rc;
  2301. rc = ScepOpenSectionForName(
  2302. hProfile,
  2303. tblType,
  2304. SectionName,
  2305. &hSection
  2306. );
  2307. if ( rc == SCESTATUS_SUCCESS ) {
  2308. rc = SceJetDelete( hSection, NULL, FALSE,SCEJET_DELETE_SECTION );
  2309. SceJetCloseSection(&hSection, TRUE );
  2310. }
  2311. if ( rc == SCESTATUS_RECORD_NOT_FOUND )
  2312. rc = SCESTATUS_SUCCESS;
  2313. return(rc);
  2314. }