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.

6421 lines
180 KiB

  1. //depot/private/vishnup_branch/DS/security/services/scerpc/server/editsave.cpp#3 - edit change 1167 (text)
  2. /*++
  3. Copyright (c) 1996 Microsoft Corporation
  4. Module Name:
  5. editsave.c
  6. Abstract:
  7. APIs for UI to handle SMP (configuration) editing.
  8. Author:
  9. Jin Huang (jinhuang) 17-Jun-1996
  10. Revision History:
  11. jinhuang 28-Jan-1998 splitted to client-server
  12. --*/
  13. #include "serverp.h"
  14. #include <io.h>
  15. #include "pfp.h"
  16. #pragma hdrstop
  17. //
  18. // for whole buffer areas
  19. //
  20. SCESTATUS
  21. ScepUpdateSystemAccess(
  22. IN PSCECONTEXT hProfile,
  23. IN PSCE_PROFILE_INFO pInfo,
  24. IN PSCE_PROFILE_INFO pBufScep OPTIONAL,
  25. IN PSCE_PROFILE_INFO pBufSap OPTIONAL,
  26. IN DWORD dwMode
  27. );
  28. SCESTATUS
  29. ScepUpdateSystemAuditing(
  30. IN PSCECONTEXT hProfile,
  31. IN PSCE_PROFILE_INFO pInfo,
  32. IN PSCE_PROFILE_INFO pBufScep OPTIONAL,
  33. IN PSCE_PROFILE_INFO pBufSap OPTIONAL,
  34. IN DWORD dwMode
  35. );
  36. SCESTATUS
  37. ScepUpdateLogs(
  38. IN PSCECONTEXT hProfile,
  39. IN PSCE_PROFILE_INFO pInfo,
  40. IN PSCE_PROFILE_INFO pBufScep OPTIONAL,
  41. IN PSCE_PROFILE_INFO pBufSap OPTIONAL,
  42. IN DWORD dwMode
  43. );
  44. SCESTATUS
  45. ScepUpdateKerberos(
  46. IN PSCECONTEXT hProfile,
  47. IN PSCE_KERBEROS_TICKET_INFO pInfo,
  48. IN PSCE_KERBEROS_TICKET_INFO pBufScep OPTIONAL,
  49. IN PSCE_KERBEROS_TICKET_INFO pBufSap OPTIONAL,
  50. IN DWORD dwMode
  51. );
  52. SCESTATUS
  53. ScepUpdateRegistryValues(
  54. IN PSCECONTEXT hProfile,
  55. IN PSCE_PROFILE_INFO pInfo,
  56. IN PSCE_PROFILE_INFO pBufScep,
  57. IN PSCE_PROFILE_INFO pBufSap
  58. );
  59. SCESTATUS
  60. ScepSaveRegValueEntry(
  61. IN PSCESECTION hSection,
  62. IN PWSTR Name,
  63. IN PWSTR CurrentValue,
  64. IN DWORD dType,
  65. IN DWORD Status
  66. );
  67. SCESTATUS
  68. ScepUpdateFixValueSection(
  69. IN PSCECONTEXT hProfile,
  70. IN PSCE_PROFILE_INFO pInfo,
  71. IN PSCE_PROFILE_INFO pBufScep,
  72. IN PSCE_PROFILE_INFO pBufSap,
  73. IN SCE_KEY_LOOKUP *Keys,
  74. IN DWORD cKeys,
  75. IN PCWSTR SectionName,
  76. OUT PSCESECTION *hSecScep OPTIONAL,
  77. OUT PSCESECTION *hSecSap OPTIONAL
  78. );
  79. SCESTATUS
  80. ScepUpdateAccountName(
  81. IN PSCESECTION hSectionSmp,
  82. IN PSCESECTION hSectionSap,
  83. IN PCWSTR KeyName,
  84. IN PWSTR NewName OPTIONAL,
  85. IN PWSTR SmpName OPTIONAL,
  86. IN PWSTR SapName OPTIONAL
  87. );
  88. SCESTATUS
  89. ScepUpdatePrivileges(
  90. IN PSCECONTEXT hProfile,
  91. IN PSCE_PRIVILEGE_ASSIGNMENT pNewPriv,
  92. IN PSCE_PRIVILEGE_ASSIGNMENT *pScepPriv
  93. );
  94. SCESTATUS
  95. ScepUpdateGroupMembership(
  96. IN PSCECONTEXT hProfile,
  97. IN PSCE_GROUP_MEMBERSHIP pNewGroup,
  98. IN PSCE_GROUP_MEMBERSHIP *pScepGroup
  99. );
  100. SCESTATUS
  101. ScepGetKeyNameList(
  102. IN LSA_HANDLE LsaPolicy,
  103. IN PSCESECTION hSection,
  104. IN PWSTR Key,
  105. IN DWORD KeyLen,
  106. IN DWORD dwAccountFormat,
  107. OUT PSCE_NAME_LIST *pNameList
  108. );
  109. #define SCE_FLAG_UPDATE_PRIV 0
  110. #define SCE_FLAG_UPDATE_MEMBERS 1
  111. #define SCE_FLAG_UPDATE_MEMBEROF 2
  112. SCESTATUS
  113. ScepUpdateKeyNameList(
  114. IN LSA_HANDLE LsaPolicy,
  115. IN PSCESECTION hSectionSmp,
  116. IN PSCESECTION hSectionSap,
  117. IN PWSTR GroupName OPTIONAL,
  118. IN BOOL bScepExist,
  119. IN PWSTR KeyName,
  120. IN DWORD NameLen,
  121. IN PSCE_NAME_LIST pNewList,
  122. IN PSCE_NAME_LIST pScepList,
  123. IN DWORD flag
  124. );
  125. SCESTATUS
  126. ScepUpdateGeneralServices(
  127. IN PSCECONTEXT hProfile,
  128. IN PSCE_SERVICES pNewServices,
  129. IN PSCE_SERVICES *pScepServices
  130. );
  131. //
  132. // for object updates
  133. //
  134. SCESTATUS
  135. ScepObjectUpdateExistingNode(
  136. IN PSCESECTION hSectionSmp,
  137. IN PSCESECTION hSectionSap,
  138. IN PWSTR ObjectName,
  139. IN DWORD NameLen,
  140. IN SE_OBJECT_TYPE ObjectType,
  141. IN BYTE ConfigStatus,
  142. IN BOOL IsContainer,
  143. IN PSECURITY_DESCRIPTOR pSD,
  144. IN SECURITY_INFORMATION SeInfo,
  145. OUT PBYTE pAnalysisStatus
  146. );
  147. SCESTATUS
  148. ScepObjectGetKeySetting(
  149. IN PSCESECTION hSection,
  150. IN PWSTR ObjectName,
  151. OUT PBYTE Status,
  152. OUT PBOOL IsContainer OPTIONAL,
  153. OUT PSECURITY_DESCRIPTOR *pSecurityDescriptor OPTIONAL,
  154. OUT PSECURITY_INFORMATION SeInfo OPTIONAL
  155. );
  156. SCESTATUS
  157. ScepObjectSetKeySetting(
  158. IN PSCESECTION hSection,
  159. IN PWSTR ObjectName,
  160. IN BYTE Status,
  161. IN BOOL IsContainer,
  162. IN PSECURITY_DESCRIPTOR pSD,
  163. IN SECURITY_INFORMATION SeInfo,
  164. IN BOOL bOverwrite
  165. );
  166. SCESTATUS
  167. ScepObjectCompareKeySetting(
  168. IN PSCESECTION hSectionSap,
  169. IN PWSTR ObjectName,
  170. IN SE_OBJECT_TYPE ObjectType,
  171. IN BOOL IsContainer,
  172. IN PSECURITY_DESCRIPTOR pSD,
  173. IN SECURITY_INFORMATION SeInfo,
  174. IN PSECURITY_DESCRIPTOR pScepSD,
  175. OUT PBYTE pAnalysisStatus
  176. );
  177. SCESTATUS
  178. ScepObjectDeleteScepAndAllChildren(
  179. IN PSCESECTION hSectionSmp,
  180. IN PSCESECTION hSectionSap,
  181. IN PWSTR ObjectName,
  182. IN BOOL IsContainer,
  183. IN BYTE StatusToRaise
  184. );
  185. SCESTATUS
  186. ScepObjectAdjustNode(
  187. IN PSCESECTION hSectionSmp,
  188. IN PSCESECTION hSectionSap,
  189. IN PWSTR ObjectName,
  190. IN DWORD NameLen,
  191. IN SE_OBJECT_TYPE ObjectType,
  192. IN BYTE ConfigStatus,
  193. IN BOOL IsContainer,
  194. IN PSECURITY_DESCRIPTOR pSD,
  195. IN SECURITY_INFORMATION SeInfo,
  196. IN BOOL bAdd,
  197. OUT PBYTE pAnalysisStatus
  198. );
  199. #define SCE_OBJECT_TURNOFF_IGNORE 0x1L
  200. #define SCE_OBJECT_SEARCH_JUNCTION 0x2L
  201. SCESTATUS
  202. ScepObjectAdjustParentStatus(
  203. IN PSCESECTION hSectionSmp,
  204. IN PSCESECTION hSectionSap,
  205. IN PWSTR ObjectName,
  206. IN DWORD NameLen,
  207. IN WCHAR Delim,
  208. IN INT Level,
  209. IN BYTE Flag,
  210. OUT PINT ParentLevel,
  211. OUT PBYTE ParentStatus OPTIONAL,
  212. OUT PWSTR ParentName OPTIONAL
  213. );
  214. SCESTATUS
  215. ScepObjectHasAnyChild(
  216. IN PSCESECTION hSection,
  217. IN PWSTR ObjectName,
  218. IN DWORD NameLen,
  219. IN WCHAR Delim,
  220. OUT PBOOL bpHasChild
  221. );
  222. SCESTATUS
  223. ScepObjectRaiseChildrenInBetween(
  224. IN PSCESECTION hSectionSmp,
  225. IN PSCESECTION hSectionSap,
  226. IN PWSTR ObjectName,
  227. IN DWORD NameLen,
  228. IN BOOL IsContainer,
  229. IN BYTE Status,
  230. IN BOOL bChangeStatusOnly
  231. );
  232. SCESTATUS
  233. ScepObjectRaiseNodesInPath(
  234. IN PSCESECTION hSectionSap,
  235. IN PWSTR ObjectName,
  236. IN DWORD NameLen,
  237. IN INT StartLevel,
  238. IN INT EndLevel,
  239. IN WCHAR Delim,
  240. IN BYTE Status
  241. );
  242. SCESTATUS
  243. ScepGetFullNameInLevel(
  244. IN PCWSTR ObjectFullName,
  245. IN DWORD Level,
  246. IN WCHAR Delim,
  247. IN BOOL bWithLastDelim,
  248. OUT PWSTR Buffer,
  249. OUT PBOOL LastOne
  250. );
  251. SCESTATUS
  252. ScepObjectTotalLevel(
  253. IN PWSTR ObjectName,
  254. IN WCHAR Delim,
  255. OUT PINT pLevel
  256. );
  257. SCESTATUS
  258. ScepUpdateLocalSection(
  259. IN PSCECONTEXT hProfile,
  260. IN PSCE_PROFILE_INFO pInfo,
  261. IN SCE_KEY_LOOKUP *Keys,
  262. IN DWORD cKeys,
  263. IN PCWSTR SectionName,
  264. IN DWORD dwMode
  265. );
  266. SCESTATUS
  267. ScepUpdateLocalAccountName(
  268. IN PSCECONTEXT hProfile,
  269. IN PCWSTR KeyName,
  270. IN PWSTR NewName OPTIONAL
  271. );
  272. SCESTATUS
  273. ScepUpdateLocalRegValues(
  274. IN PSCECONTEXT hProfile,
  275. IN PSCE_PROFILE_INFO pInfo,
  276. IN DWORD dwMode
  277. );
  278. SCESTATUS
  279. ScepUpdateLocalPrivileges(
  280. IN PSCECONTEXT hProfile,
  281. IN PSCE_PRIVILEGE_ASSIGNMENT pNewPriv,
  282. IN DWORD dwMode
  283. );
  284. DWORD
  285. ScepQueryAnalysisStatus(
  286. IN PSCESECTION hSection,
  287. IN PWSTR KeyName,
  288. IN DWORD NameLen
  289. );
  290. DWORD
  291. ScepConvertNameListFormat(
  292. IN LSA_HANDLE LsaHandle,
  293. IN PSCE_NAME_LIST pInList,
  294. IN DWORD FromFormat,
  295. IN DWORD ToFormat,
  296. OUT PSCE_NAME_LIST *ppOutList
  297. );
  298. DWORD
  299. ScepConvertPrivilegeList(
  300. IN LSA_HANDLE LsaHandle,
  301. IN PSCE_PRIVILEGE_ASSIGNMENT pFromList,
  302. IN DWORD FromFormat,
  303. IN DWORD ToFormat,
  304. OUT PSCE_PRIVILEGE_ASSIGNMENT *ppToList
  305. );
  306. //
  307. // implementations
  308. //
  309. SCESTATUS
  310. ScepUpdateDatabaseInfo(
  311. IN PSCECONTEXT hProfile,
  312. IN AREA_INFORMATION Area,
  313. IN PSCE_PROFILE_INFO pInfo
  314. )
  315. /*
  316. Routine Description:
  317. Update SMP section and "compute" analysis status to determine related
  318. changes for SAP section. For rules on computing, refer to spec objedit.doc
  319. This routine should work for areas security policy, privileges, and
  320. group membership
  321. Arguements:
  322. hProfile - the jet database handle
  323. Area - The areas to update
  324. pInfo - the buffer containing modified SMP information
  325. Return Value:
  326. SCESTATUS
  327. */
  328. {
  329. SCESTATUS rc;
  330. PSCE_PROFILE_INFO pBufScep=NULL;
  331. PSCE_ERROR_LOG_INFO Errlog=NULL;
  332. PSCE_PROFILE_INFO pBufSap=NULL;
  333. if ( hProfile == NULL || pInfo == NULL ) {
  334. return(SCESTATUS_INVALID_PARAMETER);
  335. }
  336. if ( Area & ~( AREA_SECURITY_POLICY | AREA_PRIVILEGES |
  337. AREA_GROUP_MEMBERSHIP | AREA_SYSTEM_SERVICE ) ) {
  338. return(SCESTATUS_INVALID_PARAMETER);
  339. }
  340. //
  341. // get original SMP information
  342. //
  343. rc = ScepGetDatabaseInfo(
  344. hProfile,
  345. SCE_ENGINE_SMP,
  346. Area,
  347. SCE_ACCOUNT_SID_STRING,
  348. &pBufScep,
  349. &Errlog
  350. );
  351. ScepLogWriteError(Errlog, 1);
  352. ScepFreeErrorLog(Errlog );
  353. Errlog = NULL;
  354. if ( rc != SCESTATUS_SUCCESS ) {
  355. return(rc);
  356. }
  357. rc = SceJetStartTransaction( hProfile );
  358. if ( rc == SCESTATUS_SUCCESS ) {
  359. if ( Area & AREA_SECURITY_POLICY ) {
  360. //
  361. // security policy area, get SAP information
  362. //
  363. rc = ScepGetDatabaseInfo(
  364. hProfile,
  365. SCE_ENGINE_SAP,
  366. AREA_SECURITY_POLICY,
  367. 0,
  368. &pBufSap,
  369. &Errlog
  370. );
  371. ScepLogWriteError(Errlog, 1);
  372. ScepFreeErrorLog(Errlog );
  373. Errlog = NULL;
  374. if ( rc == SCESTATUS_SUCCESS ) {
  375. //
  376. // Update system access section
  377. //
  378. rc = ScepUpdateSystemAccess(hProfile,
  379. pInfo,
  380. pBufScep,
  381. pBufSap,
  382. 0);
  383. if ( rc == SCESTATUS_SUCCESS) {
  384. //
  385. // Update system auditing section
  386. //
  387. rc = ScepUpdateSystemAuditing(hProfile,
  388. pInfo,
  389. pBufScep,
  390. pBufSap,
  391. 0);
  392. if ( rc == SCESTATUS_SUCCESS) {
  393. //
  394. // Update log sections
  395. //
  396. rc = ScepUpdateLogs(hProfile,
  397. pInfo,
  398. pBufScep,
  399. pBufSap,
  400. 0);
  401. if ( rc == SCESTATUS_SUCCESS && pInfo->pKerberosInfo ) {
  402. //
  403. // Update kerberos policy
  404. //
  405. rc = ScepUpdateKerberos(hProfile,
  406. pInfo->pKerberosInfo,
  407. pBufScep->pKerberosInfo,
  408. pBufSap->pKerberosInfo,
  409. 0);
  410. }
  411. if ( rc == SCESTATUS_SUCCESS ) {
  412. //
  413. // update registry values
  414. //
  415. rc = ScepUpdateRegistryValues(hProfile,
  416. pInfo,
  417. pBufScep,
  418. pBufSap
  419. );
  420. }
  421. //
  422. // Note: policy attachment is not updated through this API
  423. //
  424. }
  425. }
  426. SceFreeProfileMemory(pBufSap);
  427. }
  428. if ( rc != SCESTATUS_SUCCESS ) {
  429. goto Cleanup;
  430. }
  431. }
  432. if ( Area & AREA_PRIVILEGES ) {
  433. //
  434. // privileges area
  435. //
  436. rc = ScepUpdatePrivileges(hProfile,
  437. pInfo->OtherInfo.smp.pPrivilegeAssignedTo,
  438. &(pBufScep->OtherInfo.smp.pPrivilegeAssignedTo)
  439. );
  440. if ( rc != SCESTATUS_SUCCESS ) {
  441. goto Cleanup;
  442. }
  443. }
  444. if ( Area & AREA_GROUP_MEMBERSHIP ) {
  445. //
  446. // group membership area
  447. //
  448. rc = ScepUpdateGroupMembership(hProfile,
  449. pInfo->pGroupMembership,
  450. &(pBufScep->pGroupMembership)
  451. );
  452. }
  453. if ( Area & AREA_SYSTEM_SERVICE ) {
  454. //
  455. // system service general setting area
  456. //
  457. rc = ScepUpdateGeneralServices(hProfile,
  458. pInfo->pServices,
  459. &(pBufScep->pServices)
  460. );
  461. }
  462. if ( rc == SCESTATUS_SUCCESS ) {
  463. //
  464. // needs return code for commiting the transaction
  465. //
  466. rc = SceJetCommitTransaction(hProfile, 0);
  467. }
  468. if ( rc != SCESTATUS_SUCCESS ) {
  469. SceJetRollback(hProfile, 0);
  470. }
  471. }
  472. Cleanup:
  473. SceFreeProfileMemory(pBufScep);
  474. return(rc);
  475. }
  476. SCESTATUS
  477. ScepUpdateSystemAccess(
  478. IN PSCECONTEXT hProfile,
  479. IN PSCE_PROFILE_INFO pInfo,
  480. IN PSCE_PROFILE_INFO pBufScep OPTIONAL,
  481. IN PSCE_PROFILE_INFO pBufSap OPTIONAL,
  482. IN DWORD dwMode
  483. )
  484. /*
  485. Routine Description:
  486. Update system access section
  487. Arguements:
  488. hProfile - the jet database handle
  489. pInfo - the changed info buffer
  490. pBufScep - the original SMP buffer
  491. pBufSap - the SAP buffer
  492. Return Value:
  493. SCESTATUS
  494. */
  495. {
  496. SCE_KEY_LOOKUP AccessLookup[] = {
  497. {(PWSTR)TEXT("MinimumPasswordAge"), offsetof(struct _SCE_PROFILE_INFO, MinimumPasswordAge), 'D'},
  498. {(PWSTR)TEXT("MaximumPasswordAge"), offsetof(struct _SCE_PROFILE_INFO, MaximumPasswordAge), 'D'},
  499. {(PWSTR)TEXT("MinimumPasswordLength"), offsetof(struct _SCE_PROFILE_INFO, MinimumPasswordLength), 'D'},
  500. {(PWSTR)TEXT("PasswordComplexity"), offsetof(struct _SCE_PROFILE_INFO, PasswordComplexity), 'D'},
  501. {(PWSTR)TEXT("PasswordHistorySize"), offsetof(struct _SCE_PROFILE_INFO, PasswordHistorySize), 'D'},
  502. {(PWSTR)TEXT("LockoutBadCount"), offsetof(struct _SCE_PROFILE_INFO, LockoutBadCount), 'D'},
  503. {(PWSTR)TEXT("ResetLockoutCount"), offsetof(struct _SCE_PROFILE_INFO, ResetLockoutCount), 'D'},
  504. {(PWSTR)TEXT("LockoutDuration"), offsetof(struct _SCE_PROFILE_INFO, LockoutDuration), 'D'},
  505. {(PWSTR)TEXT("RequireLogonToChangePassword"), offsetof(struct _SCE_PROFILE_INFO, RequireLogonToChangePassword), 'D'},
  506. {(PWSTR)TEXT("ForceLogoffWhenHourExpire"), offsetof(struct _SCE_PROFILE_INFO, ForceLogoffWhenHourExpire), 'D'},
  507. {(PWSTR)TEXT("ClearTextPassword"), offsetof(struct _SCE_PROFILE_INFO, ClearTextPassword), 'D'},
  508. {(PWSTR)TEXT("LSAAnonymousNameLookup"), offsetof(struct _SCE_PROFILE_INFO, LSAAnonymousNameLookup), 'D'},
  509. {(PWSTR)TEXT("EnableAdminAccount"), offsetof(struct _SCE_PROFILE_INFO, EnableAdminAccount), 'D'},
  510. {(PWSTR)TEXT("EnableGuestAccount"), offsetof(struct _SCE_PROFILE_INFO, EnableGuestAccount), 'D'}
  511. };
  512. DWORD cAccess = sizeof(AccessLookup) / sizeof(SCE_KEY_LOOKUP);
  513. SCESTATUS rc;
  514. PSCESECTION hSectionSmp=NULL,
  515. hSectionSap=NULL;
  516. if ( hProfile == NULL || pInfo == NULL ) {
  517. return(SCESTATUS_INVALID_PARAMETER);
  518. }
  519. if ( dwMode & SCE_UPDATE_LOCAL_POLICY ) {
  520. //
  521. // update local policy table only
  522. //
  523. rc = ScepUpdateLocalSection(
  524. hProfile,
  525. pInfo,
  526. AccessLookup,
  527. cAccess,
  528. szSystemAccess,
  529. dwMode
  530. );
  531. if ( rc == SCESTATUS_SUCCESS ) {
  532. //
  533. // new admin name
  534. //
  535. rc = ScepUpdateLocalAccountName(
  536. hProfile,
  537. L"newadministratorname",
  538. pInfo->NewAdministratorName
  539. );
  540. if ( SCESTATUS_SUCCESS == rc ) {
  541. //
  542. // new guest name
  543. //
  544. rc = ScepUpdateLocalAccountName(
  545. hProfile,
  546. L"newguestname",
  547. pInfo->NewGuestName
  548. );
  549. }
  550. }
  551. } else {
  552. if ( pBufScep == NULL || pBufSap == NULL ) {
  553. return(SCESTATUS_INVALID_PARAMETER);
  554. }
  555. rc = ScepUpdateFixValueSection(
  556. hProfile,
  557. pInfo,
  558. pBufScep,
  559. pBufSap,
  560. AccessLookup,
  561. cAccess,
  562. szSystemAccess,
  563. &hSectionSmp,
  564. &hSectionSap
  565. );
  566. if ( rc == SCESTATUS_SUCCESS ) {
  567. //
  568. // new admin name
  569. //
  570. rc = ScepUpdateAccountName(
  571. hSectionSmp,
  572. hSectionSap,
  573. L"newadministratorname",
  574. pInfo->NewAdministratorName,
  575. pBufScep->NewAdministratorName,
  576. pBufSap->NewAdministratorName
  577. );
  578. if ( SCESTATUS_SUCCESS == rc ) {
  579. //
  580. // new guest name
  581. //
  582. rc = ScepUpdateAccountName(
  583. hSectionSmp,
  584. hSectionSap,
  585. L"newguestname",
  586. pInfo->NewGuestName,
  587. pBufScep->NewGuestName,
  588. pBufSap->NewGuestName
  589. );
  590. }
  591. SceJetCloseSection(&hSectionSap, TRUE);
  592. SceJetCloseSection(&hSectionSmp, TRUE);
  593. }
  594. }
  595. return(rc);
  596. }
  597. SCESTATUS
  598. ScepUpdateAccountName(
  599. IN PSCESECTION hSectionSmp,
  600. IN PSCESECTION hSectionSap,
  601. IN PCWSTR KeyName,
  602. IN PWSTR NewName OPTIONAL,
  603. IN PWSTR SmpName OPTIONAL,
  604. IN PWSTR SapName OPTIONAL
  605. )
  606. /*
  607. Routine Description:
  608. Update or delete Administrator and/or guest name
  609. Arguements:
  610. hSectionSmp - the SMP section context
  611. hSectionSap - the SAP section context
  612. KeyName - the key name where this account name is stored
  613. NewName - new name to change to, if NULL, the key is deleted
  614. SmpName - the old name in SMP buffer
  615. SapName - the analyzed name in SAP buffer
  616. Return Value:
  617. SCESTATUS
  618. */
  619. {
  620. DWORD LenNew=0, LenSmp=0, LenSap=0;
  621. SCESTATUS rc=SCESTATUS_SUCCESS;
  622. if ( !hSectionSmp || !hSectionSap || !KeyName ) {
  623. return(SCESTATUS_INVALID_PARAMETER);
  624. }
  625. if ( NewName )
  626. LenNew = wcslen(NewName);
  627. if ( SmpName )
  628. LenSmp = wcslen(SmpName);
  629. if ( SapName )
  630. LenSap = wcslen(SapName);
  631. if ( LenSap > 0 ) {
  632. //
  633. // old status is mismatch for this item
  634. //
  635. if ( LenNew > 0 && _wcsicmp(NewName, SapName) == 0 ) {
  636. //
  637. // now it is matched, delete the SAP entry
  638. //
  639. rc = SceJetDelete(
  640. hSectionSap,
  641. (PWSTR)KeyName,
  642. FALSE,
  643. SCEJET_DELETE_LINE
  644. );
  645. }
  646. //
  647. // update SMP entry
  648. //
  649. if ( !LenNew ) {
  650. //
  651. // delete the SMP entry
  652. //
  653. rc = SceJetDelete(
  654. hSectionSmp,
  655. (PWSTR)KeyName,
  656. FALSE,
  657. SCEJET_DELETE_LINE
  658. );
  659. } else {
  660. //
  661. // update it
  662. //
  663. rc = SceJetSetLine(
  664. hSectionSmp,
  665. (PWSTR)KeyName,
  666. TRUE,
  667. NewName,
  668. LenNew*sizeof(WCHAR),
  669. 0
  670. );
  671. }
  672. } else {
  673. //
  674. // old status is match
  675. //
  676. if ( LenNew != LenSmp ||
  677. ( LenNew > 0 && _wcsicmp(NewName, SmpName) != 0 ) ) {
  678. //
  679. // mismatch should be raised with pBufScep
  680. //
  681. rc = SceJetSetLine(
  682. hSectionSap,
  683. (PWSTR)KeyName,
  684. TRUE,
  685. SmpName,
  686. LenSmp*sizeof(WCHAR),
  687. 0
  688. );
  689. if ( !LenNew ) {
  690. //
  691. // delete SMP
  692. //
  693. rc = SceJetDelete(
  694. hSectionSmp,
  695. (PWSTR)KeyName,
  696. FALSE,
  697. SCEJET_DELETE_LINE
  698. );
  699. } else {
  700. //
  701. // update SMP
  702. //
  703. rc = SceJetSetLine(
  704. hSectionSmp,
  705. (PWSTR)KeyName,
  706. TRUE,
  707. NewName,
  708. LenNew*sizeof(WCHAR),
  709. 0
  710. );
  711. }
  712. }
  713. }
  714. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  715. rc = SCESTATUS_SUCCESS;
  716. }
  717. return(rc);
  718. }
  719. SCESTATUS
  720. ScepUpdateLocalAccountName(
  721. IN PSCECONTEXT hProfile,
  722. IN PCWSTR KeyName,
  723. IN PWSTR NewName OPTIONAL
  724. )
  725. /*
  726. Routine Description:
  727. Update or delete Administrator and/or guest name
  728. Arguements:
  729. KeyName - the key name where this account name is stored
  730. NewName - new name to change to, if NULL, the key is deleted
  731. Return Value:
  732. SCESTATUS
  733. */
  734. {
  735. DWORD LenNew=0;
  736. SCESTATUS rc=SCESTATUS_SUCCESS;
  737. if ( !KeyName ) {
  738. return(SCESTATUS_INVALID_PARAMETER);
  739. }
  740. if ( NewName )
  741. LenNew = wcslen(NewName);
  742. //
  743. // open local policy section
  744. //
  745. PSCESECTION hSectionSmp=NULL;
  746. rc = ScepOpenSectionForName(
  747. hProfile,
  748. SCE_ENGINE_SMP,
  749. szSystemAccess,
  750. &hSectionSmp
  751. );
  752. if ( rc != SCESTATUS_SUCCESS ) {
  753. return(rc);
  754. }
  755. if ( LenNew > 0 ) {
  756. //
  757. // there is a new name to set
  758. //
  759. rc = SceJetSetLine(
  760. hSectionSmp,
  761. (PWSTR)KeyName,
  762. TRUE,
  763. NewName,
  764. LenNew*sizeof(WCHAR),
  765. 0
  766. );
  767. } else {
  768. //
  769. // no name to set, delete it
  770. //
  771. rc = SceJetDelete(
  772. hSectionSmp,
  773. (PWSTR)KeyName,
  774. FALSE,
  775. SCEJET_DELETE_LINE
  776. );
  777. }
  778. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  779. rc = SCESTATUS_SUCCESS;
  780. }
  781. SceJetCloseSection(&hSectionSmp, TRUE);
  782. return(rc);
  783. }
  784. SCESTATUS
  785. ScepUpdateSystemAuditing(
  786. IN PSCECONTEXT hProfile,
  787. IN PSCE_PROFILE_INFO pInfo,
  788. IN PSCE_PROFILE_INFO pBufScep OPTIONAL,
  789. IN PSCE_PROFILE_INFO pBufSap OPTIONAL,
  790. IN DWORD dwMode
  791. )
  792. /*
  793. Routine Description:
  794. Update system auditing section
  795. Arguements:
  796. hProfile - the jet database handle
  797. pInfo - the changed info buffer
  798. pBufScep - the original SMP buffer
  799. pBufSap - the SAP buffer
  800. Return Value:
  801. SCESTATUS
  802. */
  803. {
  804. SCE_KEY_LOOKUP EventKeys[]={
  805. {(PWSTR)TEXT("AuditSystemEvents"), offsetof(struct _SCE_PROFILE_INFO, AuditSystemEvents), 'D'},
  806. {(PWSTR)TEXT("AuditLogonEvents"), offsetof(struct _SCE_PROFILE_INFO, AuditLogonEvents), 'D'},
  807. {(PWSTR)TEXT("AuditObjectAccess"), offsetof(struct _SCE_PROFILE_INFO, AuditObjectAccess), 'D'},
  808. {(PWSTR)TEXT("AuditPrivilegeUse"), offsetof(struct _SCE_PROFILE_INFO, AuditPrivilegeUse), 'D'},
  809. {(PWSTR)TEXT("AuditPolicyChange"), offsetof(struct _SCE_PROFILE_INFO, AuditPolicyChange), 'D'},
  810. {(PWSTR)TEXT("AuditAccountManage"), offsetof(struct _SCE_PROFILE_INFO, AuditAccountManage), 'D'},
  811. {(PWSTR)TEXT("AuditProcessTracking"),offsetof(struct _SCE_PROFILE_INFO, AuditProcessTracking),'D'},
  812. {(PWSTR)TEXT("AuditDSAccess"), offsetof(struct _SCE_PROFILE_INFO, AuditDSAccess), 'D'},
  813. {(PWSTR)TEXT("AuditAccountLogon"), offsetof(struct _SCE_PROFILE_INFO, AuditAccountLogon), 'D'}};
  814. DWORD cKeys = sizeof(EventKeys) / sizeof(SCE_KEY_LOOKUP);
  815. if ( hProfile == NULL || pInfo == NULL ) {
  816. return(SCESTATUS_INVALID_PARAMETER);
  817. }
  818. SCESTATUS rc;
  819. if ( dwMode & SCE_UPDATE_LOCAL_POLICY ) {
  820. //
  821. // update local policy table only
  822. //
  823. rc = ScepUpdateLocalSection(
  824. hProfile,
  825. pInfo,
  826. EventKeys,
  827. cKeys,
  828. szAuditEvent,
  829. dwMode
  830. );
  831. } else {
  832. if ( pBufScep == NULL || pBufSap == NULL ) {
  833. return(SCESTATUS_INVALID_PARAMETER);
  834. }
  835. rc = ScepUpdateFixValueSection(
  836. hProfile,
  837. pInfo,
  838. pBufScep,
  839. pBufSap,
  840. EventKeys,
  841. cKeys,
  842. szAuditEvent,
  843. NULL,
  844. NULL
  845. );
  846. }
  847. return rc;
  848. }
  849. SCESTATUS
  850. ScepUpdateLogs(
  851. IN PSCECONTEXT hProfile,
  852. IN PSCE_PROFILE_INFO pInfo,
  853. IN PSCE_PROFILE_INFO pBufScep OPTIONAL,
  854. IN PSCE_PROFILE_INFO pBufSap OPTIONAL,
  855. IN DWORD dwMode
  856. )
  857. /*
  858. Routine Description:
  859. Update event log sections
  860. Arguements:
  861. hProfile - the jet database handle
  862. pInfo - the changed info buffer
  863. pBufScep - the original SMP buffer
  864. pBufSap - the SAP buffer
  865. Return Value:
  866. SCESTATUS
  867. */
  868. {
  869. SCE_KEY_LOOKUP LogKeys[]={
  870. {(PWSTR)TEXT("MaximumLogSize"), offsetof(struct _SCE_PROFILE_INFO, MaximumLogSize), 'D'},
  871. {(PWSTR)TEXT("AuditLogRetentionPeriod"),offsetof(struct _SCE_PROFILE_INFO, AuditLogRetentionPeriod), 'D'},
  872. {(PWSTR)TEXT("RetentionDays"), offsetof(struct _SCE_PROFILE_INFO, RetentionDays), 'D'},
  873. {(PWSTR)TEXT("RestrictGuestAccess"), offsetof(struct _SCE_PROFILE_INFO, RestrictGuestAccess), 'D'}
  874. };
  875. DWORD cKeys = sizeof(LogKeys) / sizeof(SCE_KEY_LOOKUP);
  876. SCESTATUS rc;
  877. DWORD i, j;
  878. PCWSTR szAuditLog=NULL;
  879. if ( hProfile == NULL || pInfo == NULL ) {
  880. return(SCESTATUS_INVALID_PARAMETER);
  881. }
  882. if ( !(dwMode & SCE_UPDATE_LOCAL_POLICY) ) {
  883. if ( pBufScep == NULL || pBufSap == NULL ) {
  884. return(SCESTATUS_INVALID_PARAMETER);
  885. }
  886. }
  887. for ( i=0; i<3; i++) {
  888. //
  889. // Get Event Log setting for system log, security log and application log
  890. //
  891. switch (i) {
  892. case 0:
  893. szAuditLog = szAuditSystemLog;
  894. break;
  895. case 1:
  896. szAuditLog = szAuditSecurityLog;
  897. break;
  898. default:
  899. szAuditLog = szAuditApplicationLog;
  900. break;
  901. }
  902. if ( dwMode & SCE_UPDATE_LOCAL_POLICY ) {
  903. //
  904. // update local policy table only
  905. //
  906. rc = ScepUpdateLocalSection(
  907. hProfile,
  908. pInfo,
  909. LogKeys,
  910. 4,
  911. szAuditLog,
  912. dwMode
  913. );
  914. } else {
  915. //
  916. // get DWORD values for the section
  917. //
  918. rc = ScepUpdateFixValueSection(
  919. hProfile,
  920. pInfo,
  921. pBufScep,
  922. pBufSap,
  923. LogKeys,
  924. 4,
  925. szAuditLog,
  926. NULL,
  927. NULL
  928. );
  929. }
  930. if ( rc != SCESTATUS_SUCCESS )
  931. break;
  932. //
  933. // update the Offset for next section
  934. //
  935. for ( j=0; j<4; j++ )
  936. LogKeys[j].Offset += sizeof(DWORD);
  937. }
  938. return(rc);
  939. }
  940. SCESTATUS
  941. ScepUpdateKerberos(
  942. IN PSCECONTEXT hProfile,
  943. IN PSCE_KERBEROS_TICKET_INFO pInfo,
  944. IN PSCE_KERBEROS_TICKET_INFO pBufScep OPTIONAL,
  945. IN PSCE_KERBEROS_TICKET_INFO pBufSap OPTIONAL,
  946. IN DWORD dwMode
  947. )
  948. {
  949. SCESTATUS rc;
  950. SCE_KEY_LOOKUP KerberosKeys[]={
  951. {(PWSTR)TEXT("MaxTicketAge"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, MaxTicketAge), 'D'},
  952. {(PWSTR)TEXT("MaxRenewAge"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, MaxRenewAge), 'D'},
  953. {(PWSTR)TEXT("MaxServiceAge"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, MaxServiceAge), 'D'},
  954. {(PWSTR)TEXT("MaxClockSkew"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, MaxClockSkew), 'D'},
  955. {(PWSTR)TEXT("TicketValidateClient"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, TicketValidateClient), 'D'}
  956. };
  957. DWORD cKeys = sizeof(KerberosKeys) / sizeof(SCE_KEY_LOOKUP);
  958. SCE_KERBEROS_TICKET_INFO tmpBuf;
  959. if ( !pInfo ) {
  960. return(SCESTATUS_SUCCESS);
  961. }
  962. if ( dwMode & SCE_UPDATE_LOCAL_POLICY ) {
  963. rc = ScepUpdateLocalSection(
  964. hProfile,
  965. (PSCE_PROFILE_INFO)pInfo,
  966. KerberosKeys,
  967. cKeys,
  968. szKerberosPolicy,
  969. dwMode
  970. );
  971. } else {
  972. if ( !pBufScep || !pBufSap ) {
  973. //
  974. // if SMP or SAP buffer is NULL
  975. //
  976. tmpBuf.MaxTicketAge = SCE_NO_VALUE;
  977. tmpBuf.MaxRenewAge = SCE_NO_VALUE;
  978. tmpBuf.MaxServiceAge = SCE_NO_VALUE;
  979. tmpBuf.MaxClockSkew = SCE_NO_VALUE;
  980. tmpBuf.TicketValidateClient = SCE_NO_VALUE;
  981. }
  982. //
  983. // get DWORD values for the section
  984. //
  985. rc = ScepUpdateFixValueSection(
  986. hProfile,
  987. (PSCE_PROFILE_INFO)pInfo,
  988. pBufScep ? (PSCE_PROFILE_INFO)pBufScep : (PSCE_PROFILE_INFO)&tmpBuf,
  989. pBufSap ? (PSCE_PROFILE_INFO)pBufSap : (PSCE_PROFILE_INFO)&tmpBuf,
  990. KerberosKeys,
  991. cKeys,
  992. szKerberosPolicy,
  993. NULL,
  994. NULL
  995. );
  996. }
  997. return(rc);
  998. }
  999. SCESTATUS
  1000. ScepUpdateFixValueSection(
  1001. IN PSCECONTEXT hProfile,
  1002. IN PSCE_PROFILE_INFO pInfo,
  1003. IN PSCE_PROFILE_INFO pBufScep,
  1004. IN PSCE_PROFILE_INFO pBufSap,
  1005. IN SCE_KEY_LOOKUP *Keys,
  1006. IN DWORD cKeys,
  1007. IN PCWSTR SectionName,
  1008. OUT PSCESECTION *hSecScep OPTIONAL,
  1009. OUT PSCESECTION *hSecSap OPTIONAL
  1010. )
  1011. /*
  1012. Routine Description:
  1013. Update each key in the Keys array based on the editing rule. SMP entry is
  1014. updated with the new value. SAP entry is either deleted, or created, depending
  1015. on the new computed analysis status.
  1016. Arguements:
  1017. hProfile - the jet database handle
  1018. pInfo - the changed info buffer
  1019. pBufScep - the original SMP buffer
  1020. pBufSap - the SAP buffer
  1021. Keys - the lookup keys array
  1022. cKeys - the number of keys in the array
  1023. SecitonName - the section name to work on
  1024. hSecScep - the section context handle in SMP to output
  1025. hSecSap - the section context handle in SAP to output
  1026. Return Value:
  1027. SCESTATUS
  1028. */
  1029. {
  1030. SCESTATUS rc;
  1031. PSCESECTION hSectionSmp=NULL;
  1032. PSCESECTION hSectionSap=NULL;
  1033. DWORD i;
  1034. UINT Offset;
  1035. DWORD valScep, valSap, valNewScep;
  1036. //
  1037. // open smp section for system access
  1038. //
  1039. rc = ScepOpenSectionForName(
  1040. hProfile,
  1041. SCE_ENGINE_SMP,
  1042. SectionName,
  1043. &hSectionSmp
  1044. );
  1045. if ( rc == SCESTATUS_SUCCESS ) {
  1046. //
  1047. // open sap section for system access
  1048. //
  1049. rc = ScepOpenSectionForName(
  1050. hProfile,
  1051. SCE_ENGINE_SAP,
  1052. SectionName,
  1053. &hSectionSap
  1054. );
  1055. if ( rc == SCESTATUS_SUCCESS) {
  1056. for ( i=0; i<cKeys; i++) {
  1057. //
  1058. // get settings in AccessLookup table
  1059. //
  1060. Offset = Keys[i].Offset;
  1061. switch ( Keys[i].BufferType ) {
  1062. case 'B':
  1063. break;
  1064. case 'D': {
  1065. valScep = *((DWORD *)((CHAR *)pBufScep+Offset));
  1066. valSap = *((DWORD *)((CHAR *)pBufSap+Offset));
  1067. valNewScep = *((DWORD *)((CHAR *)pInfo+Offset));
  1068. switch ( valSap ) {
  1069. case SCE_NO_VALUE:
  1070. //
  1071. // old status is match
  1072. //
  1073. if ( valNewScep != valScep ) {
  1074. //
  1075. // mismatch should be raised with valScep
  1076. //
  1077. rc = ScepCompareAndSaveIntValue(
  1078. hSectionSap,
  1079. Keys[i].KeyString,
  1080. FALSE,
  1081. SCE_NO_VALUE,
  1082. (valScep != SCE_NO_VALUE ) ? valScep : SCE_NOT_ANALYZED_VALUE
  1083. );
  1084. }
  1085. break;
  1086. case SCE_ERROR_VALUE:
  1087. case SCE_NOT_ANALYZED_VALUE:
  1088. //
  1089. // old status is error when analyzing so we don't know the
  1090. // status of this one (yet), or
  1091. // this is an item that was added after analyzing
  1092. //
  1093. // do not change SAP table
  1094. //
  1095. break;
  1096. default:
  1097. //
  1098. // old status is mismatch for this item
  1099. //
  1100. if ( valNewScep == valSap ) {
  1101. //
  1102. // now it is matched, delete the SAP entry
  1103. //
  1104. rc = SceJetDelete(
  1105. hSectionSap,
  1106. Keys[i].KeyString,
  1107. FALSE,
  1108. SCEJET_DELETE_LINE_NO_CASE
  1109. );
  1110. }
  1111. break;
  1112. }
  1113. //
  1114. // update SMP entry
  1115. //
  1116. if ( valNewScep != valScep ) {
  1117. if ( valNewScep == SCE_NO_VALUE ) {
  1118. //
  1119. // delete Scep
  1120. //
  1121. rc = SceJetDelete(
  1122. hSectionSmp,
  1123. Keys[i].KeyString,
  1124. FALSE,
  1125. SCEJET_DELETE_LINE_NO_CASE
  1126. );
  1127. } else {
  1128. //
  1129. // update SMP
  1130. //
  1131. rc = ScepCompareAndSaveIntValue(
  1132. hSectionSmp,
  1133. Keys[i].KeyString,
  1134. FALSE,
  1135. SCE_NO_VALUE,
  1136. valNewScep
  1137. );
  1138. }
  1139. }
  1140. if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  1141. //
  1142. // if not find for delete, ignore the error
  1143. //
  1144. rc = SCESTATUS_SUCCESS;
  1145. }
  1146. break;
  1147. }
  1148. default:
  1149. break;
  1150. }
  1151. if ( rc != SCESTATUS_SUCCESS ) {
  1152. break;
  1153. }
  1154. }
  1155. //
  1156. // return the section handle if asked, else free it
  1157. //
  1158. if ( hSecSap != NULL )
  1159. *hSecSap = hSectionSap;
  1160. else
  1161. SceJetCloseSection(&hSectionSap, TRUE);
  1162. }
  1163. //
  1164. // return the section handle if asked, else free it
  1165. //
  1166. if ( hSecScep != NULL )
  1167. *hSecScep = hSectionSmp;
  1168. else
  1169. SceJetCloseSection(&hSectionSmp, TRUE);
  1170. }
  1171. return(rc);
  1172. }
  1173. SCESTATUS
  1174. ScepUpdateRegistryValues(
  1175. IN PSCECONTEXT hProfile,
  1176. IN PSCE_PROFILE_INFO pInfo,
  1177. IN PSCE_PROFILE_INFO pBufScep,
  1178. IN PSCE_PROFILE_INFO pBufSap
  1179. )
  1180. {
  1181. SCESTATUS rc;
  1182. PSCESECTION hSectionSmp=NULL;
  1183. PSCESECTION hSectionSap=NULL;
  1184. PWSTR valScep, valSap, valNewScep;
  1185. DWORD i,j,k,status;
  1186. if ( pInfo->RegValueCount == 0 ||
  1187. pInfo->aRegValues == NULL ) {
  1188. //
  1189. // impossible to have a empty buffer to update
  1190. // this buffer should contain all available registry values to configure/analyze
  1191. //
  1192. return(SCESTATUS_SUCCESS);
  1193. }
  1194. if ( (pBufScep->RegValueCount != 0 && pBufScep->aRegValues == NULL) ||
  1195. (pBufSap->RegValueCount != 0 && pBufSap->aRegValues == NULL) ) {
  1196. return(SCESTATUS_INVALID_PARAMETER);
  1197. }
  1198. //
  1199. // open smp section for system access
  1200. //
  1201. rc = ScepOpenSectionForName(
  1202. hProfile,
  1203. SCE_ENGINE_SMP,
  1204. szRegistryValues,
  1205. &hSectionSmp
  1206. );
  1207. if ( rc == SCESTATUS_SUCCESS ) {
  1208. //
  1209. // open sap section for system access
  1210. //
  1211. rc = ScepOpenSectionForName(
  1212. hProfile,
  1213. SCE_ENGINE_SAP,
  1214. szRegistryValues,
  1215. &hSectionSap
  1216. );
  1217. if ( rc == SCESTATUS_SUCCESS) {
  1218. for (i=0; i<pInfo->RegValueCount; i++ ) {
  1219. if ( !(pInfo->aRegValues[i].FullValueName) ) {
  1220. continue;
  1221. }
  1222. //
  1223. // find SMP match
  1224. //
  1225. for ( j=0; j<pBufScep->RegValueCount; j++ ) {
  1226. if ( pBufScep->aRegValues[j].FullValueName &&
  1227. _wcsicmp(pInfo->aRegValues[i].FullValueName,
  1228. pBufScep->aRegValues[j].FullValueName) == 0 ) {
  1229. break;
  1230. }
  1231. }
  1232. //
  1233. // find SAP match
  1234. //
  1235. for ( k=0; k<pBufSap->RegValueCount; k++ ) {
  1236. if ( pBufSap->aRegValues[k].FullValueName &&
  1237. _wcsicmp(pInfo->aRegValues[i].FullValueName,
  1238. pBufSap->aRegValues[k].FullValueName) == 0 ) {
  1239. break;
  1240. }
  1241. }
  1242. //
  1243. // find old configuration
  1244. //
  1245. if ( j < pBufScep->RegValueCount ) {
  1246. valScep = pBufScep->aRegValues[j].Value;
  1247. } else {
  1248. valScep = NULL;
  1249. }
  1250. //
  1251. // find analysis value and status
  1252. //
  1253. if ( k < pBufSap->RegValueCount ) {
  1254. valSap = pBufSap->aRegValues[k].Value;
  1255. status = pBufSap->aRegValues[k].Status;
  1256. } else {
  1257. valSap = NULL;
  1258. if ( valScep ) {
  1259. status = SCE_STATUS_GOOD;
  1260. } else {
  1261. status = SCE_STATUS_NOT_CONFIGURED;
  1262. }
  1263. }
  1264. valNewScep = pInfo->aRegValues[i].Value;
  1265. if ( status == SCE_STATUS_NOT_ANALYZED ||
  1266. status == SCE_STATUS_ERROR_NOT_AVAILABLE ) {
  1267. //
  1268. // do not change SAP
  1269. //
  1270. } else {
  1271. if ( valSap ) {
  1272. //
  1273. // mismatched
  1274. //
  1275. if ( valNewScep && _wcsicmp(valNewScep, valSap) == 0 ) {
  1276. //
  1277. // now it is matched, delete the SAP entry
  1278. //
  1279. rc = SceJetDelete(
  1280. hSectionSap,
  1281. pInfo->aRegValues[i].FullValueName,
  1282. FALSE,
  1283. SCEJET_DELETE_LINE_NO_CASE
  1284. );
  1285. }
  1286. } else {
  1287. if ( valScep ) {
  1288. //
  1289. // was a matched item
  1290. //
  1291. if (valNewScep && _wcsicmp(valNewScep, valScep) != 0 ) {
  1292. //
  1293. // mismatched
  1294. //
  1295. rc = ScepSaveRegValueEntry(
  1296. hSectionSap,
  1297. pInfo->aRegValues[i].FullValueName,
  1298. valScep,
  1299. pInfo->aRegValues[i].ValueType,
  1300. SCE_STATUS_MISMATCH
  1301. );
  1302. }
  1303. } else {
  1304. //
  1305. // was a not configure/not analyze item
  1306. //
  1307. rc = ScepSaveRegValueEntry(
  1308. hSectionSap,
  1309. pInfo->aRegValues[i].FullValueName,
  1310. NULL,
  1311. pInfo->aRegValues[i].ValueType,
  1312. SCE_STATUS_NOT_ANALYZED
  1313. );
  1314. }
  1315. }
  1316. }
  1317. if ( !valNewScep ) {
  1318. //
  1319. // delete Scep
  1320. //
  1321. rc = SceJetDelete(
  1322. hSectionSmp,
  1323. pInfo->aRegValues[i].FullValueName,
  1324. FALSE,
  1325. SCEJET_DELETE_LINE_NO_CASE
  1326. );
  1327. } else {
  1328. //
  1329. // update SMP
  1330. //
  1331. rc = ScepSaveRegValueEntry(
  1332. hSectionSmp,
  1333. pInfo->aRegValues[i].FullValueName,
  1334. valNewScep,
  1335. pInfo->aRegValues[i].ValueType,
  1336. 0
  1337. );
  1338. }
  1339. if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  1340. //
  1341. // if not find for delete, ignore the error
  1342. //
  1343. rc = SCESTATUS_SUCCESS;
  1344. }
  1345. if ( SCESTATUS_SUCCESS != rc ) {
  1346. break;
  1347. }
  1348. }
  1349. SceJetCloseSection(&hSectionSap, TRUE);
  1350. }
  1351. SceJetCloseSection(&hSectionSmp, TRUE);
  1352. }
  1353. return(rc);
  1354. }
  1355. SCESTATUS
  1356. ScepSaveRegValueEntry(
  1357. IN PSCESECTION hSection,
  1358. IN PWSTR Name,
  1359. IN PWSTR CurrentValue,
  1360. IN DWORD dType,
  1361. IN DWORD Status
  1362. )
  1363. /* ++
  1364. Routine Description:
  1365. Arguments:
  1366. hSection - The JET section context
  1367. Name - The entry name
  1368. CurrentValue - The current system setting (DWORD value)
  1369. dType - the registry value type
  1370. Return Value:
  1371. SCESTATUS_SUCCESS
  1372. SCESTATUS_INVALID_PARAMETER
  1373. SCESTATUS returned from SceJetSetLine
  1374. -- */
  1375. {
  1376. SCESTATUS rc;
  1377. PWSTR StrValue;
  1378. DWORD Len=0;
  1379. if ( Name == NULL )
  1380. return(SCESTATUS_INVALID_PARAMETER);
  1381. if ( CurrentValue == NULL && Status == 0 ) {
  1382. //
  1383. // delete this entry
  1384. //
  1385. rc = SceJetDelete( hSection,
  1386. Name,
  1387. FALSE,
  1388. SCEJET_DELETE_LINE_NO_CASE);
  1389. return (rc);
  1390. }
  1391. //
  1392. // update this entry
  1393. //
  1394. if ( CurrentValue ) {
  1395. Len = wcslen(CurrentValue);
  1396. }
  1397. StrValue = (PWSTR)ScepAlloc(0, (Len+4)*sizeof(WCHAR));
  1398. if ( StrValue ) {
  1399. *((CHAR *)StrValue) = (BYTE)(dType % 10) + '0';
  1400. *((CHAR *)StrValue+1) = (BYTE)Status + '0';
  1401. // swprintf(StrValue, L"%1d", dType);
  1402. StrValue[1] = L'\0';
  1403. if ( CurrentValue ) {
  1404. // there are binary data here
  1405. memcpy(StrValue+2, CurrentValue, Len*2);
  1406. }
  1407. StrValue[Len+2] = L'\0';
  1408. StrValue[Len+3] = L'\0';
  1409. if ( REG_MULTI_SZ == dType ) {
  1410. //
  1411. // convert the , to null
  1412. //
  1413. ScepConvertMultiSzToDelim(StrValue+2, Len+1, L',', L'\0');
  1414. }
  1415. rc = SceJetSetLine( hSection, Name, FALSE, StrValue, (Len+3)*2, 0);
  1416. ScepFree(StrValue);
  1417. } else {
  1418. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1419. }
  1420. return(rc);
  1421. }
  1422. SCESTATUS
  1423. ScepUpdatePrivileges(
  1424. IN PSCECONTEXT hProfile,
  1425. IN PSCE_PRIVILEGE_ASSIGNMENT pNewPriv,
  1426. IN PSCE_PRIVILEGE_ASSIGNMENT *pScepPriv
  1427. )
  1428. /*
  1429. Routine Description:
  1430. Update privileges
  1431. Arguements:
  1432. hProfile - the jet database handle
  1433. pNewPriv - the changed info buffer
  1434. pBufScep - the original SMP priv buffer
  1435. Return Value:
  1436. SCESTATUS
  1437. */
  1438. {
  1439. SCESTATUS rc;
  1440. PSCESECTION hSectionSmp=NULL;
  1441. PSCESECTION hSectionSap=NULL;
  1442. PSCE_PRIVILEGE_ASSIGNMENT pPriv, pNode, pParent;
  1443. DWORD NameLen;
  1444. if ( pScepPriv == NULL ) {
  1445. return(SCESTATUS_INVALID_PARAMETER);
  1446. }
  1447. if ( pNewPriv == NULL && *pScepPriv == NULL ) {
  1448. return(SCESTATUS_SUCCESS);
  1449. }
  1450. LSA_HANDLE LsaHandle=NULL;
  1451. rc = RtlNtStatusToDosError(
  1452. ScepOpenLsaPolicy(
  1453. MAXIMUM_ALLOWED,
  1454. &LsaHandle,
  1455. TRUE
  1456. ));
  1457. if ( ERROR_SUCCESS != rc ) {
  1458. return(ScepDosErrorToSceStatus(rc));
  1459. }
  1460. //
  1461. // open smp section for system access
  1462. //
  1463. rc = ScepOpenSectionForName(
  1464. hProfile,
  1465. SCE_ENGINE_SMP,
  1466. szPrivilegeRights,
  1467. &hSectionSmp
  1468. );
  1469. if ( rc == SCESTATUS_SUCCESS ) {
  1470. //
  1471. // open sap section for system access
  1472. //
  1473. rc = ScepOpenSectionForName(
  1474. hProfile,
  1475. SCE_ENGINE_SAP,
  1476. szPrivilegeRights,
  1477. &hSectionSap
  1478. );
  1479. if ( rc == SCESTATUS_SUCCESS ) {
  1480. //
  1481. // convert pNewPriv to Name/*SID format (from all name format)
  1482. //
  1483. PSCE_PRIVILEGE_ASSIGNMENT pConvertedPriv=NULL;
  1484. rc = ScepConvertPrivilegeList(LsaHandle,
  1485. pNewPriv,
  1486. 0,
  1487. SCE_ACCOUNT_SID_STRING,
  1488. &pConvertedPriv);
  1489. if ( ERROR_SUCCESS != rc ) {
  1490. //
  1491. // use the original list
  1492. //
  1493. pPriv = pNewPriv;
  1494. } else {
  1495. pPriv = pConvertedPriv;
  1496. }
  1497. for ( ; pPriv != NULL; pPriv = pPriv->Next ) {
  1498. //
  1499. // Process each privilege in the new list
  1500. //
  1501. if ( pPriv->Name == NULL ) {
  1502. continue;
  1503. }
  1504. NameLen = wcslen(pPriv->Name);
  1505. //
  1506. // look for the matched SMP
  1507. //
  1508. for ( pNode=*pScepPriv, pParent=NULL; pNode != NULL;
  1509. pParent = pNode, pNode = pNode->Next ) {
  1510. if ( pNode->Name == NULL ) {
  1511. continue;
  1512. }
  1513. if ( _wcsicmp(pPriv->Name, pNode->Name) == 0 ) {
  1514. break;
  1515. }
  1516. }
  1517. rc = ScepUpdateKeyNameList(
  1518. LsaHandle,
  1519. hSectionSmp,
  1520. hSectionSap,
  1521. NULL, // not a group
  1522. ( pNode == NULL ) ? FALSE : TRUE,
  1523. pPriv->Name,
  1524. NameLen,
  1525. pPriv->AssignedTo,
  1526. ( pNode == NULL ) ? NULL : pNode->AssignedTo,
  1527. SCE_FLAG_UPDATE_PRIV
  1528. );
  1529. if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  1530. rc = SCESTATUS_SUCCESS;
  1531. } else if ( rc != SCESTATUS_SUCCESS) {
  1532. break;
  1533. }
  1534. //
  1535. // remove the SMP node from pScepPriv
  1536. //
  1537. if ( pNode != NULL ) {
  1538. //
  1539. // link to the next
  1540. //
  1541. if ( pParent != NULL ) {
  1542. pParent->Next = pNode->Next;
  1543. } else {
  1544. *pScepPriv = pNode->Next;
  1545. }
  1546. //
  1547. // delete this node
  1548. //
  1549. ScepFreeNameList(pNode->AssignedTo);
  1550. ScepFree(pNode->Name);
  1551. ScepFree(pNode);
  1552. pNode = NULL;
  1553. }
  1554. }
  1555. if ( pConvertedPriv ) {
  1556. //
  1557. // free the new list
  1558. //
  1559. ScepFreePrivilege( pConvertedPriv );
  1560. pConvertedPriv = NULL;
  1561. }
  1562. //
  1563. // delete remaining SMP entries, do not care error code
  1564. //
  1565. if ( rc == SCESTATUS_SUCCESS ) {
  1566. for (pNode=*pScepPriv; pNode != NULL; pNode = pNode->Next ) {
  1567. //
  1568. // raise SAP entries first
  1569. //
  1570. if ( pNode->Name == NULL ) {
  1571. continue;
  1572. }
  1573. NameLen = wcslen(pNode->Name);
  1574. rc = SceJetSeek(
  1575. hSectionSap,
  1576. pNode->Name,
  1577. NameLen*sizeof(WCHAR),
  1578. SCEJET_SEEK_EQ_NO_CASE
  1579. );
  1580. if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  1581. //
  1582. // pNode->AssignedTo is already in name, *SID format
  1583. // no need to convert
  1584. //
  1585. rc = ScepWriteNameListValue(
  1586. LsaHandle,
  1587. hSectionSap,
  1588. pNode->Name,
  1589. pNode->AssignedTo,
  1590. SCE_WRITE_EMPTY_LIST,
  1591. 0
  1592. );
  1593. }
  1594. if ( rc == SCESTATUS_SUCCESS ) {
  1595. rc = SceJetDelete(
  1596. hSectionSmp,
  1597. pNode->Name,
  1598. FALSE,
  1599. SCEJET_DELETE_LINE_NO_CASE
  1600. );
  1601. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  1602. rc = SCESTATUS_SUCCESS;
  1603. }
  1604. }
  1605. if ( rc != SCESTATUS_SUCCESS ) {
  1606. break;
  1607. }
  1608. }
  1609. }
  1610. SceJetCloseSection(&hSectionSap, TRUE);
  1611. }
  1612. SceJetCloseSection(&hSectionSmp, TRUE);
  1613. }
  1614. if ( LsaHandle ) {
  1615. LsaClose(LsaHandle);
  1616. }
  1617. return(rc);
  1618. }
  1619. SCESTATUS
  1620. ScepGetKeyNameList(
  1621. IN LSA_HANDLE LsaPolicy,
  1622. IN PSCESECTION hSection,
  1623. IN PWSTR Key,
  1624. IN DWORD KeyLen,
  1625. IN DWORD dwAccountFormat,
  1626. OUT PSCE_NAME_LIST *pNameList
  1627. )
  1628. /* ++
  1629. Routine Description:
  1630. Read multi-sz format value for the key from the section into a name list
  1631. structure
  1632. Arguments:
  1633. hSection - the section handle
  1634. Key - the key name
  1635. KeyLen - the key length
  1636. pNameList - the name list of multi-sz value
  1637. Return Value:
  1638. SCE status
  1639. -- */
  1640. {
  1641. SCESTATUS rc;
  1642. PWSTR Value=NULL;
  1643. PSCE_NAME_STATUS_LIST pPrivilegeList=NULL;
  1644. DWORD ValueLen;
  1645. DWORD Len;
  1646. PWSTR pTemp;
  1647. if ( hSection == NULL || pNameList == NULL || Key == NULL ) {
  1648. return(SCESTATUS_INVALID_PARAMETER);
  1649. }
  1650. //
  1651. // goto the key
  1652. //
  1653. rc = SceJetGetValue(
  1654. hSection,
  1655. SCEJET_EXACT_MATCH_NO_CASE,
  1656. Key,
  1657. NULL,
  1658. 0,
  1659. NULL,
  1660. NULL,
  1661. 0,
  1662. &ValueLen
  1663. );
  1664. if ( rc != SCESTATUS_SUCCESS ) {
  1665. return(rc);
  1666. }
  1667. //
  1668. // allocate memory for the group name and value string
  1669. //
  1670. Value = (PWSTR)ScepAlloc( LMEM_ZEROINIT, ValueLen+2);
  1671. if ( Value == NULL )
  1672. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  1673. //
  1674. // Get the group and its value
  1675. //
  1676. rc = SceJetGetValue(
  1677. hSection,
  1678. SCEJET_CURRENT,
  1679. NULL,
  1680. NULL,
  1681. 0,
  1682. NULL,
  1683. Value,
  1684. ValueLen,
  1685. &ValueLen
  1686. );
  1687. if ( rc == SCESTATUS_SUCCESS ) {
  1688. //
  1689. // add the multi-sz value string to the node, depending on the value type
  1690. //
  1691. pTemp = Value;
  1692. while ( rc == SCESTATUS_SUCCESS && pTemp != NULL && pTemp[0]) {
  1693. Len = wcslen(pTemp);
  1694. if ( dwAccountFormat == 0 && pTemp[0] == L'*' ) {
  1695. //
  1696. // convert *SID to name
  1697. //
  1698. rc = ScepLookupSidStringAndAddToNameList(
  1699. LsaPolicy,
  1700. pNameList,
  1701. pTemp, // +1,
  1702. Len // -1
  1703. );
  1704. } else {
  1705. rc = ScepAddToNameList(pNameList, pTemp, Len );
  1706. }
  1707. pTemp += Len +1;
  1708. }
  1709. //
  1710. // Free the list if error
  1711. //
  1712. if ( rc != SCESTATUS_SUCCESS && *pNameList != NULL ) {
  1713. ScepFreeNameList(*pNameList);
  1714. *pNameList = NULL;
  1715. }
  1716. }
  1717. ScepFree(Value);
  1718. //
  1719. // close the find index range
  1720. //
  1721. SceJetGetValue(
  1722. hSection,
  1723. SCEJET_CLOSE_VALUE,
  1724. NULL,
  1725. NULL,
  1726. 0,
  1727. NULL,
  1728. NULL,
  1729. 0,
  1730. NULL
  1731. );
  1732. return(rc);
  1733. }
  1734. BYTE
  1735. ScepGetObjectAnalysisStatus(
  1736. IN PSCESECTION hSection,
  1737. IN PWSTR KeyName,
  1738. IN BOOL bLookForParent
  1739. )
  1740. /*
  1741. Routine Description:
  1742. Get analysis status for the KeyName specified. If bLookForParent is TRUE,
  1743. check for the closest parent status instead of this KeyName.
  1744. */
  1745. {
  1746. WCHAR StatusFlag=L'\0';
  1747. BYTE Status=(BYTE)-1;
  1748. DWORD Len;
  1749. SCESTATUS rc=SCESTATUS_SUCCESS;
  1750. PWSTR Buffer=NULL, pTemp;
  1751. pTemp = KeyName;
  1752. while ( TRUE ) {
  1753. if ( bLookForParent ) {
  1754. pTemp = wcschr(pTemp, L'\\');
  1755. if ( pTemp ) {
  1756. Len = (DWORD)(pTemp-KeyName);
  1757. Buffer = (PWSTR)ScepAlloc(0, (Len+1)*sizeof(WCHAR));
  1758. if ( Buffer ) {
  1759. memcpy(Buffer, KeyName, Len*sizeof(WCHAR));
  1760. Buffer[Len] = L'\0';
  1761. } else {
  1762. // no memory
  1763. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  1764. break;
  1765. }
  1766. } else {
  1767. Buffer = KeyName;
  1768. }
  1769. } else {
  1770. Buffer = KeyName;
  1771. }
  1772. rc = SceJetGetValue(
  1773. hSection,
  1774. SCEJET_EXACT_MATCH_NO_CASE,
  1775. Buffer,
  1776. NULL,
  1777. 0,
  1778. NULL,
  1779. (PWSTR)&StatusFlag,
  1780. 2,
  1781. &Len
  1782. );
  1783. if ( Buffer != KeyName ) {
  1784. ScepFree(Buffer);
  1785. Buffer = NULL;
  1786. }
  1787. if ( SCESTATUS_SUCCESS == rc ||
  1788. SCESTATUS_BUFFER_TOO_SMALL == rc ) {
  1789. //
  1790. // find the record
  1791. //
  1792. Status = *((BYTE *)&StatusFlag);
  1793. } else if ( rc != SCESTATUS_RECORD_NOT_FOUND ) {
  1794. break;
  1795. }
  1796. rc = SCESTATUS_SUCCESS;
  1797. if ( bLookForParent && pTemp ) {
  1798. pTemp++;
  1799. } else {
  1800. // the end
  1801. break;
  1802. }
  1803. }
  1804. if ( SCESTATUS_SUCCESS == rc ) {
  1805. return Status;
  1806. }
  1807. return (BYTE)-1;
  1808. }
  1809. DWORD
  1810. ScepQueryAnalysisStatus(
  1811. IN PSCESECTION hSection,
  1812. IN PWSTR KeyName,
  1813. IN DWORD NameLen
  1814. )
  1815. {
  1816. DWORD dwSapStatus = SCE_STATUS_GOOD;
  1817. SCESTATUS rc = SceJetSeek(
  1818. hSection,
  1819. KeyName,
  1820. NameLen*sizeof(WCHAR),
  1821. SCEJET_SEEK_EQ_NO_CASE
  1822. );
  1823. if ( rc == SCESTATUS_SUCCESS ) {
  1824. dwSapStatus = SCE_STATUS_MISMATCH;
  1825. //
  1826. // check if this is errored item, or not analyzed item
  1827. //
  1828. TCHAR szErrorValue[20];
  1829. DWORD ValueLen;
  1830. szErrorValue[0] = L'\0';
  1831. rc = SceJetGetValue(
  1832. hSection,
  1833. SCEJET_CURRENT,
  1834. NULL,
  1835. NULL,
  1836. 0,
  1837. NULL,
  1838. szErrorValue,
  1839. 20*sizeof(TCHAR),
  1840. &ValueLen
  1841. );
  1842. if ( SCESTATUS_SUCCESS == rc ||
  1843. SCESTATUS_BUFFER_TOO_SMALL == rc ) {
  1844. if ( szErrorValue[0] == L' ' ) {
  1845. dwSapStatus = SCE_STATUS_NOT_ANALYZED;
  1846. } else if ( _wcsicmp( SCE_ERROR_STRING, szErrorValue ) == 0 ) {
  1847. //
  1848. // this group is errored or not analyzed
  1849. //
  1850. dwSapStatus = SCE_STATUS_ERROR_NOT_AVAILABLE;
  1851. }
  1852. }
  1853. }
  1854. return dwSapStatus;
  1855. }
  1856. SCESTATUS
  1857. ScepUpdateKeyNameList(
  1858. IN LSA_HANDLE LsaPolicy,
  1859. IN PSCESECTION hSectionSmp,
  1860. IN PSCESECTION hSectionSap,
  1861. IN PWSTR GroupName OPTIONAL,
  1862. IN BOOL bScepExist,
  1863. IN PWSTR KeyName,
  1864. IN DWORD NameLen,
  1865. IN PSCE_NAME_LIST pNewList,
  1866. IN PSCE_NAME_LIST pScepList,
  1867. IN DWORD flag
  1868. )
  1869. /*
  1870. Routine Description:
  1871. Update multi-sz format value for a Key
  1872. Arguements:
  1873. hSectionSmp - the SMP section handle
  1874. hSectionSap - the SAP section handle
  1875. bScepExist - if th ekey exist in SMP
  1876. KeyName - the key name
  1877. NameLen - the name length
  1878. pNewList - the new value to update to
  1879. pScepList - the original value to update
  1880. Return Value:
  1881. SCESTATUS
  1882. */
  1883. {
  1884. SCESTATUS rc=SCESTATUS_SUCCESS;
  1885. PSCE_NAME_LIST pSapList=NULL;
  1886. if ( hSectionSmp == NULL || hSectionSap == NULL || KeyName == NULL ) {
  1887. return(SCESTATUS_INVALID_PARAMETER);
  1888. }
  1889. DWORD dwSapExist=ScepQueryAnalysisStatus(hSectionSap,
  1890. KeyName,
  1891. NameLen
  1892. );
  1893. if ( GroupName && (flag == SCE_FLAG_UPDATE_MEMBEROF) ) {
  1894. //
  1895. // this is for group membership (memberof) update
  1896. //
  1897. DWORD TmpLen = wcslen(GroupName)+wcslen(szMembers);
  1898. PWSTR TmpStr = (PWSTR)ScepAlloc(LPTR, (TmpLen+1)*sizeof(WCHAR));
  1899. if ( TmpStr ) {
  1900. swprintf(TmpStr, L"%s%s\0", GroupName, szMembers);
  1901. DWORD dwTmp = ScepQueryAnalysisStatus(hSectionSap,
  1902. TmpStr,
  1903. TmpLen
  1904. );
  1905. if ( dwTmp == SCE_STATUS_NOT_ANALYZED ||
  1906. dwTmp == SCE_STATUS_ERROR_NOT_AVAILABLE ) {
  1907. dwSapExist = dwTmp;
  1908. }
  1909. ScepFree(TmpStr);
  1910. } else {
  1911. // ignore this error
  1912. }
  1913. }
  1914. switch ( dwSapExist ) {
  1915. case SCE_STATUS_GOOD:
  1916. //
  1917. // SAP entry does not exist -- matched
  1918. //
  1919. if ( bScepExist ) {
  1920. //
  1921. // SMP entry exist
  1922. //
  1923. if ( !SceCompareNameList(pNewList, pScepList) ) {
  1924. //
  1925. // new SMP does not match SAP. SAP entry should be created with SMP
  1926. // for privileges, it's already in SID/name format, no need to convert
  1927. //
  1928. rc = ScepWriteNameListValue(
  1929. LsaPolicy,
  1930. hSectionSap,
  1931. KeyName,
  1932. pScepList,
  1933. GroupName ? (SCE_WRITE_EMPTY_LIST | SCE_WRITE_CONVERT) :
  1934. SCE_WRITE_EMPTY_LIST,
  1935. 0
  1936. );
  1937. }
  1938. } else {
  1939. //
  1940. // SMP entry does not exist. should not occur for privileges but
  1941. // it is possible for group membership (new added group)
  1942. // But if it occurs, create SAP entry with NULL
  1943. //
  1944. rc = SceJetSetLine(
  1945. hSectionSap,
  1946. KeyName,
  1947. FALSE,
  1948. L" ",
  1949. 2,
  1950. 0);
  1951. }
  1952. break;
  1953. case SCE_STATUS_ERROR_NOT_AVAILABLE:
  1954. case SCE_STATUS_NOT_ANALYZED:
  1955. //
  1956. // SAP entry errored or not analyzed
  1957. // do not change SAP entry
  1958. //
  1959. break;
  1960. default:
  1961. //
  1962. // SAP entry exists. -- mismatched or not configured
  1963. //
  1964. rc = ScepGetKeyNameList(
  1965. LsaPolicy,
  1966. hSectionSap,
  1967. KeyName,
  1968. NameLen,
  1969. GroupName ? 0 : SCE_ACCOUNT_SID_STRING,
  1970. &pSapList
  1971. );
  1972. if ( rc == SCESTATUS_SUCCESS ) {
  1973. //
  1974. // Get the SAP assigned to list and compare
  1975. //
  1976. if ( SceCompareNameList(pNewList, pSapList) ) {
  1977. //
  1978. // new SMP is the same as SAP, delete SAP entry
  1979. //
  1980. rc = SceJetDelete(
  1981. hSectionSap,
  1982. KeyName,
  1983. FALSE,
  1984. SCEJET_DELETE_LINE_NO_CASE
  1985. );
  1986. }
  1987. //
  1988. // free the Sap list
  1989. //
  1990. ScepFreeNameList(pSapList);
  1991. pSapList = NULL;
  1992. }
  1993. break;
  1994. }
  1995. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  1996. rc = SCESTATUS_SUCCESS;
  1997. }
  1998. if ( SCESTATUS_SUCCESS == rc ) {
  1999. //
  2000. // Update SMP with new value
  2001. //
  2002. rc = ScepWriteNameListValue(
  2003. LsaPolicy,
  2004. hSectionSmp,
  2005. KeyName,
  2006. pNewList,
  2007. GroupName ? (SCE_WRITE_EMPTY_LIST | SCE_WRITE_CONVERT) :
  2008. SCE_WRITE_EMPTY_LIST,
  2009. 0
  2010. );
  2011. }
  2012. return(rc);
  2013. }
  2014. SCESTATUS
  2015. ScepUpdateGroupMembership(
  2016. IN PSCECONTEXT hProfile,
  2017. IN PSCE_GROUP_MEMBERSHIP pNewGroup,
  2018. IN PSCE_GROUP_MEMBERSHIP *pScepGroup
  2019. )
  2020. /*
  2021. Routine Description:
  2022. Update group membership section
  2023. Arguements:
  2024. hProfile - the jet database handle
  2025. pNewGroup - the changed info buffer
  2026. pScepGroup - the original SMP buffer
  2027. Return Value:
  2028. SCESTATUS
  2029. */
  2030. {
  2031. SCESTATUS rc;
  2032. PSCESECTION hSectionSmp=NULL;
  2033. PSCESECTION hSectionSap=NULL;
  2034. PSCE_GROUP_MEMBERSHIP pGroup, pNode, pParent;
  2035. DWORD NameLen, MembersLen, MemberofLen;
  2036. PWSTR KeyName=NULL;
  2037. PWSTR SidString=NULL;
  2038. if ( pScepGroup == NULL ) {
  2039. return(SCESTATUS_INVALID_PARAMETER);
  2040. }
  2041. if ( pNewGroup == NULL && *pScepGroup == NULL ) {
  2042. return(SCESTATUS_SUCCESS);
  2043. }
  2044. LSA_HANDLE LsaHandle=NULL;
  2045. rc = RtlNtStatusToDosError(
  2046. ScepOpenLsaPolicy(
  2047. MAXIMUM_ALLOWED,
  2048. &LsaHandle,
  2049. TRUE
  2050. ));
  2051. if ( ERROR_SUCCESS != rc ) {
  2052. return(ScepDosErrorToSceStatus(rc));
  2053. }
  2054. //
  2055. // open smp section for system access
  2056. //
  2057. rc = ScepOpenSectionForName(
  2058. hProfile,
  2059. SCE_ENGINE_SMP,
  2060. szGroupMembership,
  2061. &hSectionSmp
  2062. );
  2063. if ( rc == SCESTATUS_SUCCESS ) {
  2064. //
  2065. // open sap section for system access
  2066. //
  2067. rc = ScepOpenSectionForName(
  2068. hProfile,
  2069. SCE_ENGINE_SAP,
  2070. szGroupMembership,
  2071. &hSectionSap
  2072. );
  2073. if ( rc == SCESTATUS_SUCCESS ) {
  2074. MemberofLen = wcslen(szMemberof);
  2075. MembersLen = wcslen(szMembers);
  2076. for ( pGroup=pNewGroup; pGroup != NULL; pGroup = pGroup->Next ) {
  2077. //
  2078. // Process each group members and memberof in the new list
  2079. //
  2080. if ( !(pGroup->GroupName) ) {
  2081. continue;
  2082. }
  2083. if ( (pGroup->Status & SCE_GROUP_STATUS_NC_MEMBERS) &&
  2084. (pGroup->Status & SCE_GROUP_STATUS_NC_MEMBEROF ) ) {
  2085. continue;
  2086. }
  2087. if ( wcschr(pGroup->GroupName, L'\\') ) {
  2088. //
  2089. // this is in account domain format, convert it to sid string
  2090. //
  2091. NameLen = 0;
  2092. ScepConvertNameToSidString(
  2093. LsaHandle,
  2094. pGroup->GroupName,
  2095. FALSE,
  2096. &SidString,
  2097. &NameLen
  2098. );
  2099. } else {
  2100. if ( ScepLookupNameTable( pGroup->GroupName, &SidString ) ) {
  2101. NameLen = wcslen(SidString);
  2102. } else {
  2103. SidString = NULL;
  2104. }
  2105. }
  2106. if ( SidString == NULL ) {
  2107. NameLen = wcslen(pGroup->GroupName);
  2108. }
  2109. KeyName = (PWSTR)ScepAlloc(LMEM_FIXED | LMEM_ZEROINIT,
  2110. (NameLen+MemberofLen+1)*sizeof(WCHAR));
  2111. if ( KeyName == NULL ) {
  2112. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  2113. } else {
  2114. //
  2115. // look for the matched SMP
  2116. //
  2117. for ( pNode=*pScepGroup, pParent=NULL; pNode != NULL;
  2118. pParent = pNode, pNode = pNode->Next ) {
  2119. if ( _wcsicmp(pGroup->GroupName, pNode->GroupName) == 0 ) {
  2120. break;
  2121. }
  2122. }
  2123. if ( !(pGroup->Status & SCE_GROUP_STATUS_NC_MEMBERS) ) {
  2124. //
  2125. // work for members first
  2126. //
  2127. if ( SidString ) {
  2128. swprintf(KeyName, L"%s%s\0", SidString, szMembers);
  2129. } else {
  2130. swprintf(KeyName, L"%s%s\0", pGroup->GroupName, szMembers);
  2131. }
  2132. KeyName = _wcslwr(KeyName);
  2133. rc = ScepUpdateKeyNameList(
  2134. LsaHandle,
  2135. hSectionSmp,
  2136. hSectionSap,
  2137. SidString ? SidString : pGroup->GroupName, // group name
  2138. ( pNode == NULL || (pNode->Status & SCE_GROUP_STATUS_NC_MEMBERS)) ? FALSE : TRUE,
  2139. KeyName,
  2140. NameLen+MembersLen,
  2141. pGroup->pMembers,
  2142. ( pNode == NULL ) ? NULL : pNode->pMembers,
  2143. SCE_FLAG_UPDATE_MEMBERS
  2144. );
  2145. }
  2146. if ( ( rc == SCESTATUS_SUCCESS ) &&
  2147. !(pGroup->Status & SCE_GROUP_STATUS_NC_MEMBERS) ) {
  2148. //
  2149. // work for memberof second
  2150. //
  2151. if ( SidString ) {
  2152. swprintf(KeyName, L"%s%s\0", SidString, szMemberof);
  2153. } else {
  2154. swprintf(KeyName, L"%s%s\0", pGroup->GroupName, szMemberof);
  2155. }
  2156. KeyName = _wcslwr(KeyName);
  2157. rc = ScepUpdateKeyNameList(
  2158. LsaHandle,
  2159. hSectionSmp,
  2160. hSectionSap,
  2161. SidString ? SidString : pGroup->GroupName,
  2162. ( pNode == NULL || (pNode->Status & SCE_GROUP_STATUS_NC_MEMBEROF) ) ? FALSE : TRUE,
  2163. KeyName,
  2164. NameLen+MemberofLen,
  2165. pGroup->pMemberOf,
  2166. ( pNode == NULL ) ? NULL : pNode->pMemberOf,
  2167. SCE_FLAG_UPDATE_MEMBEROF
  2168. );
  2169. }
  2170. ScepFree(KeyName);
  2171. KeyName = NULL;
  2172. }
  2173. if ( SidString ) {
  2174. LocalFree(SidString);
  2175. SidString = NULL;
  2176. }
  2177. if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  2178. rc = SCESTATUS_SUCCESS;
  2179. } else if ( rc != SCESTATUS_SUCCESS) {
  2180. break;
  2181. }
  2182. //
  2183. // remove the SMP node/or portion from pScepPriv
  2184. //
  2185. if ( pNode != NULL ) {
  2186. if ( !(pGroup->Status & SCE_GROUP_STATUS_NC_MEMBERS) &&
  2187. !(pGroup->Status & SCE_GROUP_STATUS_NC_MEMBEROF) ) {
  2188. //
  2189. // both of members and memberof are processed
  2190. // link to the next
  2191. //
  2192. if ( pParent != NULL ) {
  2193. pParent->Next = pNode->Next;
  2194. } else {
  2195. *pScepGroup = pNode->Next;
  2196. }
  2197. //
  2198. // delete this node
  2199. //
  2200. ScepFreeNameList(pNode->pMembers);
  2201. ScepFreeNameList(pNode->pMemberOf);
  2202. ScepFreeNameStatusList(pNode->pPrivilegesHeld);
  2203. ScepFree(pNode->GroupName);
  2204. ScepFree(pNode);
  2205. pNode = NULL;
  2206. } else {
  2207. if (!(pGroup->Status & SCE_GROUP_STATUS_NC_MEMBERS) ) {
  2208. pNode->Status |= SCE_GROUP_STATUS_NC_MEMBERS;
  2209. ScepFreeNameList(pNode->pMembers);
  2210. pNode->pMembers = NULL;
  2211. }
  2212. if ( !(pGroup->Status & SCE_GROUP_STATUS_NC_MEMBEROF) ) {
  2213. pNode->Status |= SCE_GROUP_STATUS_NC_MEMBEROF;
  2214. ScepFreeNameList(pNode->pMemberOf);
  2215. pNode->pMemberOf = NULL;
  2216. }
  2217. }
  2218. }
  2219. }
  2220. //
  2221. // delete remaining SMP entries, do not care error code
  2222. //
  2223. if ( rc == SCESTATUS_SUCCESS ) {
  2224. for (pNode=*pScepGroup; pNode != NULL; pNode = pNode->Next ) {
  2225. //
  2226. // raise SAP if it's not there
  2227. //
  2228. if ( pNode->GroupName == NULL ) {
  2229. continue;
  2230. }
  2231. if ( (pNode->Status & SCE_GROUP_STATUS_NC_MEMBERS) &&
  2232. (pNode->Status & SCE_GROUP_STATUS_NC_MEMBEROF) ) {
  2233. continue;
  2234. }
  2235. if ( wcschr(pNode->GroupName, L'\\') ) {
  2236. //
  2237. // this is in account domain format, convert it to sid string
  2238. //
  2239. NameLen = 0;
  2240. ScepConvertNameToSidString(
  2241. LsaHandle,
  2242. pNode->GroupName,
  2243. FALSE,
  2244. &SidString,
  2245. &NameLen
  2246. );
  2247. } else {
  2248. if ( ScepLookupNameTable( pNode->GroupName, &SidString ) ) {
  2249. NameLen = wcslen(SidString);
  2250. } else {
  2251. SidString = NULL;
  2252. }
  2253. }
  2254. if ( SidString == NULL ) {
  2255. NameLen = wcslen(pNode->GroupName);
  2256. }
  2257. KeyName = (PWSTR)ScepAlloc(LMEM_FIXED | LMEM_ZEROINIT,
  2258. (NameLen+MemberofLen+1)*sizeof(WCHAR));
  2259. if ( KeyName == NULL ) {
  2260. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  2261. } else {
  2262. BOOL bSapError=FALSE;
  2263. if ( SidString ) {
  2264. swprintf(KeyName, L"%s%s\0", SidString, szMembers);
  2265. } else {
  2266. swprintf(KeyName, L"%s%s\0", pNode->GroupName, szMembers);
  2267. }
  2268. if ( !(pNode->Status & SCE_GROUP_STATUS_NC_MEMBERS) ) {
  2269. //
  2270. // members configuration has to be deleted.
  2271. //
  2272. rc = SceJetDelete(
  2273. hSectionSmp,
  2274. KeyName,
  2275. FALSE,
  2276. SCEJET_DELETE_LINE_NO_CASE
  2277. );
  2278. }
  2279. if ( SCESTATUS_SUCCESS == rc ) {
  2280. rc = ScepQueryAnalysisStatus(hSectionSap,
  2281. KeyName,
  2282. NameLen+MembersLen
  2283. );
  2284. if ( rc == SCE_STATUS_NOT_ANALYZED ||
  2285. rc == SCE_STATUS_ERROR_NOT_AVAILABLE ) {
  2286. //
  2287. // the entire group is analyzed with error
  2288. // or the group is new added
  2289. //
  2290. if ( !(pNode->Status & SCE_GROUP_STATUS_NC_MEMBERS) &&
  2291. !(pNode->Status & SCE_GROUP_STATUS_NC_MEMBEROF) ) {
  2292. //
  2293. // the SAP should be removed because both members and
  2294. // memberof are deleted
  2295. //
  2296. rc = SceJetDelete(
  2297. hSectionSap,
  2298. SidString ? SidString : pNode->GroupName,
  2299. FALSE,
  2300. SCEJET_DELETE_PARTIAL_NO_CASE
  2301. );
  2302. } else {
  2303. // else leave the SAP stuff there.
  2304. rc = SCESTATUS_SUCCESS;
  2305. }
  2306. bSapError = TRUE;
  2307. } else {
  2308. if ( !(pNode->Status & SCE_GROUP_STATUS_NC_MEMBERS) ) {
  2309. if ( rc == SCE_STATUS_GOOD ) {
  2310. //
  2311. // SAP doesn't exist, this is a match group members
  2312. // remove SMP means this group becomes not configured
  2313. //
  2314. rc = ScepWriteNameListValue(
  2315. LsaHandle,
  2316. hSectionSap,
  2317. KeyName,
  2318. pNode->pMembers,
  2319. SCE_WRITE_EMPTY_LIST | SCE_WRITE_CONVERT,
  2320. 0
  2321. );
  2322. } else {
  2323. //
  2324. // it's already mismatched. do nothing to SAP table
  2325. //
  2326. rc = SCESTATUS_SUCCESS;
  2327. }
  2328. } else {
  2329. rc = SCESTATUS_SUCCESS;
  2330. }
  2331. }
  2332. }
  2333. if ( SCESTATUS_SUCCESS == rc ) {
  2334. //
  2335. // continue to process memberof
  2336. //
  2337. if ( !(pNode->Status & SCE_GROUP_STATUS_NC_MEMBEROF) ) {
  2338. if ( SidString ) {
  2339. swprintf(KeyName, L"%s%s\0", SidString, szMemberof);
  2340. } else {
  2341. swprintf(KeyName, L"%s%s\0", pNode->GroupName, szMemberof);
  2342. }
  2343. //
  2344. // delete configuration
  2345. //
  2346. rc = SceJetDelete(
  2347. hSectionSmp,
  2348. KeyName,
  2349. FALSE,
  2350. SCEJET_DELETE_LINE_NO_CASE
  2351. );
  2352. if ( (SCESTATUS_SUCCESS == rc) && !bSapError ) {
  2353. rc = SceJetSeek(
  2354. hSectionSap,
  2355. KeyName,
  2356. (NameLen+MemberofLen)*sizeof(WCHAR),
  2357. SCEJET_SEEK_EQ_NO_CASE
  2358. );
  2359. if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  2360. //
  2361. // SAP doesn't exist, this is a match group membership
  2362. // remove SMP means membership becomes "not configured"
  2363. //
  2364. rc = ScepWriteNameListValue(
  2365. LsaHandle,
  2366. hSectionSap,
  2367. KeyName,
  2368. pNode->pMemberOf,
  2369. SCE_WRITE_EMPTY_LIST | SCE_WRITE_CONVERT,
  2370. 0
  2371. );
  2372. } else {
  2373. //
  2374. // a mismatch item already
  2375. //
  2376. }
  2377. }
  2378. }
  2379. }
  2380. ScepFree(KeyName);
  2381. KeyName = NULL;
  2382. }
  2383. if ( SidString ) {
  2384. LocalFree(SidString);
  2385. SidString = NULL;
  2386. }
  2387. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  2388. rc = SCESTATUS_SUCCESS;
  2389. }
  2390. if ( rc != SCESTATUS_SUCCESS ) {
  2391. break;
  2392. }
  2393. }
  2394. }
  2395. SceJetCloseSection(&hSectionSap, TRUE);
  2396. }
  2397. SceJetCloseSection(&hSectionSmp, TRUE);
  2398. }
  2399. if ( LsaHandle ) {
  2400. LsaClose(LsaHandle);
  2401. }
  2402. return(rc);
  2403. }
  2404. SCESTATUS
  2405. ScepUpdateGeneralServices(
  2406. IN PSCECONTEXT hProfile,
  2407. IN PSCE_SERVICES pNewServices,
  2408. IN PSCE_SERVICES *pScepServices
  2409. )
  2410. /*
  2411. Routine Description:
  2412. Update general services section
  2413. Arguements:
  2414. hProfile - the jet database handle
  2415. pNewServices - the new server list
  2416. pScepServices - the original SMP service list
  2417. Return Value:
  2418. SCESTATUS
  2419. */
  2420. {
  2421. SCESTATUS rc;
  2422. PSCESECTION hSectionSmp=NULL;
  2423. PSCESECTION hSectionSap=NULL;
  2424. PSCE_SERVICES pService, pNode, pParent;
  2425. PSCE_SERVICES pSapService=NULL;
  2426. BOOL IsDifferent;
  2427. if ( pScepServices == NULL ) {
  2428. return(SCESTATUS_INVALID_PARAMETER);
  2429. }
  2430. if ( pNewServices == NULL && *pScepServices == NULL ) {
  2431. return(SCESTATUS_SUCCESS);
  2432. }
  2433. //
  2434. // open smp section for system access
  2435. //
  2436. rc = ScepOpenSectionForName(
  2437. hProfile,
  2438. SCE_ENGINE_SMP,
  2439. szServiceGeneral,
  2440. &hSectionSmp
  2441. );
  2442. if ( rc == SCESTATUS_SUCCESS ) {
  2443. //
  2444. // open sap section for system access
  2445. //
  2446. rc = ScepOpenSectionForName(
  2447. hProfile,
  2448. SCE_ENGINE_SAP,
  2449. szServiceGeneral,
  2450. &hSectionSap
  2451. );
  2452. if ( rc == SCESTATUS_SUCCESS ) {
  2453. for ( pService=pNewServices; pService != NULL; pService = pService->Next ) {
  2454. //
  2455. // look for the matched SMP
  2456. //
  2457. for ( pNode=*pScepServices, pParent=NULL; pNode != NULL;
  2458. pParent = pNode, pNode = pNode->Next ) {
  2459. if ( _wcsicmp(pService->ServiceName, pNode->ServiceName) == 0 ) {
  2460. break;
  2461. }
  2462. }
  2463. //
  2464. // get Sap
  2465. //
  2466. rc = ScepGetSingleServiceSetting(
  2467. hSectionSap,
  2468. pService->ServiceName,
  2469. &pSapService
  2470. );
  2471. if ( rc == SCESTATUS_SUCCESS ) {
  2472. //
  2473. // old status is mismatch, error, no not analyzed for this item
  2474. //
  2475. if ( pSapService &&
  2476. ( pSapService->Status == SCE_STATUS_NOT_ANALYZED ||
  2477. pSapService->Status == SCE_STATUS_ERROR_NOT_AVAILABLE ) ) {
  2478. // do not change SAP
  2479. } else {
  2480. rc = ScepCompareSingleServiceSetting(
  2481. pService,
  2482. pSapService,
  2483. &IsDifferent
  2484. );
  2485. if ( rc == SCESTATUS_SUCCESS ) {
  2486. if ( !IsDifferent ) {
  2487. //
  2488. // now it is matched, delete the SAP entry
  2489. //
  2490. SceJetDelete(
  2491. hSectionSap,
  2492. pService->ServiceName,
  2493. FALSE,
  2494. SCEJET_DELETE_LINE_NO_CASE
  2495. );
  2496. }
  2497. }
  2498. }
  2499. if ( SCESTATUS_SUCCESS == rc ) {
  2500. //
  2501. // update the SMP entry
  2502. //
  2503. rc = ScepSetSingleServiceSetting(
  2504. hSectionSmp,
  2505. pService
  2506. );
  2507. }
  2508. SceFreePSCE_SERVICES(pSapService);
  2509. pSapService = NULL;
  2510. } else if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  2511. //
  2512. // old status is matched or new added
  2513. //
  2514. if ( pNode == NULL ) {
  2515. //
  2516. // new added, add SMP first
  2517. //
  2518. rc = ScepSetSingleServiceSetting(
  2519. hSectionSmp,
  2520. pService
  2521. );
  2522. if ( rc == SCESTATUS_SUCCESS) {
  2523. pService->Status = SCE_STATUS_NOT_ANALYZED;
  2524. //
  2525. // raise SAP
  2526. //
  2527. rc = ScepSetSingleServiceSetting(
  2528. hSectionSap,
  2529. pService
  2530. );
  2531. }
  2532. } else {
  2533. rc = ScepCompareSingleServiceSetting(
  2534. pService,
  2535. pNode,
  2536. &IsDifferent
  2537. );
  2538. if ( rc == SCESTATUS_SUCCESS ) {
  2539. if ( IsDifferent ) {
  2540. //
  2541. // mismatch should be raised with valScep
  2542. //
  2543. pNode->Status = SCE_STATUS_MISMATCH;
  2544. rc = ScepSetSingleServiceSetting(
  2545. hSectionSap,
  2546. pNode
  2547. );
  2548. if ( rc == SCESTATUS_SUCCESS) {
  2549. //
  2550. // update SMP
  2551. //
  2552. rc = ScepSetSingleServiceSetting(
  2553. hSectionSmp,
  2554. pService
  2555. );
  2556. }
  2557. }
  2558. }
  2559. }
  2560. }
  2561. if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  2562. rc = SCESTATUS_SUCCESS;
  2563. } else if ( rc != SCESTATUS_SUCCESS) {
  2564. break;
  2565. }
  2566. //
  2567. // remove the SMP node from old configuration
  2568. //
  2569. if ( pNode != NULL ) {
  2570. //
  2571. // link to the next
  2572. //
  2573. if ( pParent != NULL ) {
  2574. pParent->Next = pNode->Next;
  2575. } else {
  2576. *pScepServices = pNode->Next;
  2577. }
  2578. //
  2579. // delete this node
  2580. //
  2581. ScepFree(pNode->ServiceName);
  2582. if (pNode->General.pSecurityDescriptor)
  2583. ScepFree(pNode->General.pSecurityDescriptor);
  2584. ScepFree(pNode);
  2585. pNode = NULL;
  2586. }
  2587. }
  2588. //
  2589. // delete remaining SMP entries, do not care error code
  2590. //
  2591. if ( rc == SCESTATUS_SUCCESS ) {
  2592. for (pNode=*pScepServices; pNode != NULL; pNode = pNode->Next ) {
  2593. //
  2594. // first change SAP entry
  2595. //
  2596. rc = SceJetSeek(
  2597. hSectionSap,
  2598. pNode->ServiceName,
  2599. wcslen(pNode->ServiceName)*sizeof(WCHAR),
  2600. SCEJET_SEEK_EQ_NO_CASE
  2601. );
  2602. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  2603. //
  2604. // was a match item
  2605. //
  2606. pNode->Status = SCE_STATUS_NOT_CONFIGURED;
  2607. rc = ScepSetSingleServiceSetting(
  2608. hSectionSap,
  2609. pNode
  2610. );
  2611. }
  2612. if ( rc == SCESTATUS_SUCCESS ||
  2613. rc == SCESTATUS_RECORD_NOT_FOUND ) {
  2614. //
  2615. // delete SMP - it's taken out of the service list
  2616. //
  2617. rc = SceJetDelete(
  2618. hSectionSmp,
  2619. pNode->ServiceName,
  2620. FALSE,
  2621. SCEJET_DELETE_LINE_NO_CASE
  2622. );
  2623. }
  2624. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  2625. rc = SCESTATUS_SUCCESS;
  2626. }
  2627. if ( rc != SCESTATUS_SUCCESS ) {
  2628. break;
  2629. }
  2630. }
  2631. }
  2632. SceJetCloseSection(&hSectionSap, TRUE);
  2633. }
  2634. SceJetCloseSection(&hSectionSmp, TRUE);
  2635. }
  2636. return(rc);
  2637. }
  2638. SCESTATUS
  2639. ScepUpdateObjectInfo(
  2640. IN PSCECONTEXT hProfile,
  2641. IN AREA_INFORMATION Area,
  2642. IN PWSTR ObjectName,
  2643. IN DWORD NameLen, // number of characters
  2644. IN BYTE ConfigStatus,
  2645. IN BOOL IsContainer,
  2646. IN PSECURITY_DESCRIPTOR pSD,
  2647. IN SECURITY_INFORMATION SeInfo,
  2648. OUT PBYTE pAnalysisStatus
  2649. )
  2650. /*
  2651. Routine Description:
  2652. Determine related changes to the object's parent(s), child(ren) in SMP and SAP
  2653. database then update the SMP entry for the object. Refer to objedit.doc for
  2654. the rule to update database.
  2655. Arguments:
  2656. hProfile - the database handle
  2657. Area - security area to update (file, registry, ds)
  2658. ObjectName - object name in full name
  2659. NameLen - the length of the object name
  2660. ConfigStatus - the flag changed to
  2661. IsContainer - if the object is a container type
  2662. pSD - the security descriptor for the object
  2663. SeInfo - the security information for the object
  2664. pAnalysisStatus - output status of analysis for the object
  2665. Return Value:
  2666. SCE status
  2667. */
  2668. {
  2669. SCESTATUS rc;
  2670. PCWSTR SectionName;
  2671. PSCESECTION hSectionSmp=NULL;
  2672. PSCESECTION hSectionSap=NULL;
  2673. SE_OBJECT_TYPE ObjectType;
  2674. HKEY hKey;
  2675. PWSTR JetName;
  2676. DWORD NewNameLen;
  2677. if ( hProfile == NULL || ObjectName == NULL ) {
  2678. return(SCESTATUS_INVALID_PARAMETER);
  2679. }
  2680. if ( (ConfigStatus > SCE_STATUS_NO_AUTO_INHERIT ||
  2681. ConfigStatus < SCE_STATUS_CHECK) &&
  2682. (BYTE)SCE_NO_VALUE != ConfigStatus &&
  2683. (DWORD)SCE_NO_VALUE != (DWORD)ConfigStatus ) {
  2684. return(SCESTATUS_INVALID_PARAMETER);
  2685. }
  2686. switch(Area) {
  2687. case AREA_REGISTRY_SECURITY:
  2688. SectionName = szRegistryKeys;
  2689. ObjectType = SE_REGISTRY_KEY;
  2690. rc = ScepOpenRegistryObject(
  2691. ObjectType,
  2692. ObjectName,
  2693. KEY_READ,
  2694. &hKey
  2695. );
  2696. if ( rc == ERROR_SUCCESS ) {
  2697. RegCloseKey(hKey);
  2698. } else {
  2699. //
  2700. // not find the key
  2701. //
  2702. return(SCESTATUS_INVALID_DATA);
  2703. }
  2704. JetName = ObjectName;
  2705. NewNameLen = NameLen;
  2706. break;
  2707. case AREA_FILE_SECURITY:
  2708. SectionName = szFileSecurity;
  2709. ObjectType = SE_FILE_OBJECT;
  2710. if ( ObjectName[0] == L'\\' ) { // UNC name format
  2711. return(SCESTATUS_INVALID_PARAMETER);
  2712. }
  2713. if ( 0xFFFFFFFF == GetFileAttributes(ObjectName) ) {
  2714. return(SCESTATUS_INVALID_DATA);
  2715. }
  2716. JetName = ObjectName;
  2717. NewNameLen = NameLen;
  2718. break;
  2719. #if 0
  2720. case AREA_DS_OBJECTS:
  2721. SectionName = szDSSecurity;
  2722. ObjectType = SE_DS_OBJECT;
  2723. rc = ScepLdapOpen(NULL);
  2724. if ( rc == SCESTATUS_SUCCESS ) {
  2725. //
  2726. // detect if the Ds object exist
  2727. //
  2728. rc = ScepDsObjectExist(ObjectName);
  2729. if ( rc == SCESTATUS_SUCCESS ) {
  2730. //
  2731. // convert LDAP name to Jet index name
  2732. //
  2733. rc = ScepConvertLdapToJetIndexName(
  2734. ObjectName,
  2735. &JetName
  2736. );
  2737. }
  2738. }
  2739. if ( rc != SCESTATUS_SUCCESS ) {
  2740. ScepLdapClose(NULL);
  2741. return(rc);
  2742. }
  2743. NewNameLen = wcslen(JetName);
  2744. break;
  2745. #endif
  2746. default:
  2747. return(SCESTATUS_INVALID_PARAMETER);
  2748. }
  2749. if ( pAnalysisStatus ) {
  2750. *pAnalysisStatus = (BYTE)SCE_NO_VALUE;
  2751. }
  2752. //
  2753. // open smp section for system access
  2754. //
  2755. rc = ScepOpenSectionForName(
  2756. hProfile,
  2757. SCE_ENGINE_SMP,
  2758. SectionName,
  2759. &hSectionSmp
  2760. );
  2761. if ( rc == SCESTATUS_SUCCESS ) {
  2762. //
  2763. // open sap section for system access
  2764. //
  2765. rc = ScepOpenSectionForName(
  2766. hProfile,
  2767. SCE_ENGINE_SAP,
  2768. SectionName,
  2769. &hSectionSap
  2770. );
  2771. if ( rc == SCESTATUS_SUCCESS) {
  2772. //
  2773. // Start a transaction so all updates related to this object is atomic
  2774. //
  2775. rc = SceJetStartTransaction( hProfile );
  2776. if ( rc == SCESTATUS_SUCCESS ) {
  2777. rc = SceJetSeek(
  2778. hSectionSmp,
  2779. JetName,
  2780. NewNameLen*sizeof(WCHAR),
  2781. SCEJET_SEEK_EQ_NO_CASE
  2782. );
  2783. if ( rc == SCESTATUS_SUCCESS ) {
  2784. //
  2785. // existing SMP object
  2786. //
  2787. if ( (BYTE)SCE_NO_VALUE == ConfigStatus ||
  2788. (DWORD)SCE_NO_VALUE == (DWORD)ConfigStatus ) {
  2789. //
  2790. // get the old configure flag
  2791. //
  2792. WCHAR StatusFlag;
  2793. BYTE ScepStatus=0;
  2794. DWORD Len;
  2795. rc = SceJetGetValue(
  2796. hSectionSmp,
  2797. SCEJET_CURRENT,
  2798. NULL,
  2799. NULL,
  2800. 0,
  2801. NULL,
  2802. (PWSTR)&StatusFlag,
  2803. 2,
  2804. &Len
  2805. );
  2806. if ( SCESTATUS_SUCCESS == rc ||
  2807. SCESTATUS_BUFFER_TOO_SMALL == rc ) {
  2808. //
  2809. // find the record
  2810. //
  2811. ScepStatus = *((BYTE *)&StatusFlag);
  2812. //
  2813. // update SAP entries.
  2814. //
  2815. rc = ScepObjectAdjustNode(
  2816. hSectionSmp,
  2817. hSectionSap,
  2818. JetName,
  2819. NewNameLen,
  2820. ObjectType,
  2821. ScepStatus,
  2822. IsContainer,
  2823. NULL,
  2824. 0,
  2825. FALSE, // remove the node
  2826. pAnalysisStatus
  2827. );
  2828. if ( SCESTATUS_SUCCESS == rc ) {
  2829. //
  2830. // delete the SMP entry
  2831. //
  2832. rc = SceJetDelete(
  2833. hSectionSmp,
  2834. JetName,
  2835. FALSE,
  2836. SCEJET_DELETE_LINE_NO_CASE
  2837. );
  2838. }
  2839. }
  2840. } else {
  2841. rc = ScepObjectUpdateExistingNode(
  2842. hSectionSmp,
  2843. hSectionSap,
  2844. JetName,
  2845. NewNameLen,
  2846. ObjectType,
  2847. ConfigStatus,
  2848. IsContainer,
  2849. pSD,
  2850. SeInfo,
  2851. pAnalysisStatus
  2852. );
  2853. if ( rc == SCESTATUS_SUCCESS ) {
  2854. //
  2855. // Update the SMP record
  2856. //
  2857. rc = ScepObjectSetKeySetting(
  2858. hSectionSmp,
  2859. JetName,
  2860. ConfigStatus,
  2861. IsContainer,
  2862. pSD,
  2863. SeInfo,
  2864. TRUE
  2865. );
  2866. }
  2867. }
  2868. } else if ( rc == SCESTATUS_RECORD_NOT_FOUND &&
  2869. (BYTE)SCE_NO_VALUE != ConfigStatus &&
  2870. (DWORD)SCE_NO_VALUE != (DWORD)ConfigStatus ) {
  2871. //
  2872. // new added object
  2873. //
  2874. rc = ScepObjectAdjustNode(
  2875. hSectionSmp,
  2876. hSectionSap,
  2877. JetName,
  2878. NewNameLen,
  2879. ObjectType,
  2880. ConfigStatus,
  2881. IsContainer,
  2882. pSD,
  2883. SeInfo,
  2884. TRUE, // add the node
  2885. pAnalysisStatus
  2886. );
  2887. }
  2888. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  2889. rc = SCESTATUS_SUCCESS;
  2890. }
  2891. //
  2892. // Commit or Rollback the changes
  2893. //
  2894. if ( rc == SCESTATUS_SUCCESS ) {
  2895. //
  2896. // needs return code for commiting the transaction
  2897. //
  2898. rc = SceJetCommitTransaction(hProfile, 0);
  2899. }
  2900. if ( rc != SCESTATUS_SUCCESS ) {
  2901. SceJetRollback(hProfile, 0);
  2902. }
  2903. }
  2904. SceJetCloseSection(&hSectionSap, TRUE);
  2905. } else if ( rc == SCESTATUS_BAD_FORMAT ) {
  2906. //
  2907. // SMP exist, but SAP does not exist
  2908. //
  2909. }
  2910. SceJetCloseSection(&hSectionSmp, TRUE);
  2911. } else if ( rc == SCESTATUS_BAD_FORMAT ) {
  2912. //
  2913. // SMP section does not exist
  2914. //
  2915. }
  2916. //
  2917. // free stuff used for DS
  2918. //
  2919. if ( Area == AREA_DS_OBJECTS ) {
  2920. ScepFree(JetName);
  2921. ScepLdapClose(NULL);
  2922. }
  2923. return(rc);
  2924. }
  2925. SCESTATUS
  2926. ScepObjectUpdateExistingNode(
  2927. IN PSCESECTION hSectionSmp,
  2928. IN PSCESECTION hSectionSap,
  2929. IN PWSTR ObjectName,
  2930. IN DWORD NameLen,
  2931. IN SE_OBJECT_TYPE ObjectType,
  2932. IN BYTE ConfigStatus,
  2933. IN BOOL IsContainer,
  2934. IN PSECURITY_DESCRIPTOR pSD,
  2935. IN SECURITY_INFORMATION SeInfo,
  2936. OUT PBYTE pAnalysisStatus
  2937. )
  2938. /*
  2939. Routine Description:
  2940. Update an existing object
  2941. Arguements:
  2942. see ScepUpdateObjectInfo
  2943. Return Value:
  2944. SCESTATUS
  2945. */
  2946. {
  2947. SCESTATUS rc;
  2948. BYTE ScepStatus, SapStatus;
  2949. PSECURITY_DESCRIPTOR pScepSD=NULL;
  2950. SECURITY_INFORMATION ScepSeInfo;
  2951. BYTE retStat = SCE_STATUS_NOT_ANALYZED;
  2952. rc = ScepObjectGetKeySetting(
  2953. hSectionSmp,
  2954. ObjectName,
  2955. &ScepStatus,
  2956. NULL,
  2957. &pScepSD,
  2958. &ScepSeInfo
  2959. );
  2960. if ( rc == SCESTATUS_SUCCESS ) {
  2961. //
  2962. // check for analysis status
  2963. //
  2964. SapStatus = ScepGetObjectAnalysisStatus(
  2965. hSectionSap,
  2966. ObjectName,
  2967. FALSE
  2968. );
  2969. if ( ScepStatus == SCE_STATUS_IGNORE ) {
  2970. //
  2971. // no change is needed if update from IGNORE to IGNORE
  2972. //
  2973. if ( ConfigStatus != SCE_STATUS_IGNORE ) {
  2974. //
  2975. // N.A. the object (changed from N.C)
  2976. //
  2977. rc = ScepObjectSetKeySetting(
  2978. hSectionSap,
  2979. ObjectName,
  2980. SCE_STATUS_NOT_ANALYZED,
  2981. TRUE,
  2982. NULL,
  2983. 0,
  2984. TRUE
  2985. );
  2986. } else {
  2987. if ( SapStatus == SCE_STATUS_NOT_CONFIGURED ) {
  2988. retStat = SapStatus;
  2989. }
  2990. }
  2991. } else if ( ConfigStatus == SCE_STATUS_IGNORE ) {
  2992. //
  2993. // changed to ignore. delete all children from SMP & SAP
  2994. //
  2995. rc = ScepObjectDeleteScepAndAllChildren(
  2996. hSectionSmp,
  2997. hSectionSap,
  2998. ObjectName,
  2999. IsContainer,
  3000. SCE_STATUS_NOT_CONFIGURED
  3001. );
  3002. retStat = SCE_STATUS_NOT_CONFIGURED;
  3003. } else if ( SapStatus == SCE_STATUS_NOT_ANALYZED ) {
  3004. //
  3005. // was already added/modified, no need to update SAP
  3006. // although children status may be mixed with C.C. or N.A.
  3007. //
  3008. if ( ConfigStatus == SCE_STATUS_OVERWRITE &&
  3009. ScepStatus != SCE_STATUS_OVERWRITE ) {
  3010. //
  3011. // change C.C children to N.A. children
  3012. //
  3013. rc = ScepObjectRaiseChildrenInBetween(
  3014. hSectionSmp,
  3015. hSectionSap,
  3016. ObjectName,
  3017. NameLen,
  3018. IsContainer,
  3019. SCE_STATUS_NOT_ANALYZED,
  3020. TRUE // change status only
  3021. );
  3022. } else if ( ConfigStatus != SCE_STATUS_OVERWRITE &&
  3023. ScepStatus == SCE_STATUS_OVERWRITE ) {
  3024. //
  3025. // change N.A. children to C.C. children
  3026. //
  3027. rc = ScepObjectRaiseChildrenInBetween(
  3028. hSectionSmp,
  3029. hSectionSap,
  3030. ObjectName,
  3031. NameLen,
  3032. IsContainer,
  3033. SCE_STATUS_CHILDREN_CONFIGURED,
  3034. TRUE // change status only
  3035. );
  3036. }
  3037. } else {
  3038. if ( ScepStatus == SCE_STATUS_OVERWRITE &&
  3039. ( ConfigStatus == SCE_STATUS_CHECK ||
  3040. ConfigStatus == SCE_STATUS_NO_AUTO_INHERIT ) ) {
  3041. //
  3042. // delete all mismatched status between this node
  3043. // and its children; N.A. all nodes in between
  3044. //
  3045. rc = ScepObjectRaiseChildrenInBetween(
  3046. hSectionSmp,
  3047. hSectionSap,
  3048. ObjectName,
  3049. NameLen,
  3050. IsContainer,
  3051. SCE_STATUS_NOT_ANALYZED,
  3052. FALSE
  3053. );
  3054. } else if ( ConfigStatus == SCE_STATUS_OVERWRITE &&
  3055. (ScepStatus == SCE_STATUS_CHECK ||
  3056. ScepStatus == SCE_STATUS_NO_AUTO_INHERIT) ) {
  3057. //
  3058. // change C.C children to N.A. children
  3059. //
  3060. rc = ScepObjectRaiseChildrenInBetween(
  3061. hSectionSmp,
  3062. hSectionSap,
  3063. ObjectName,
  3064. NameLen,
  3065. IsContainer,
  3066. SCE_STATUS_NOT_ANALYZED,
  3067. TRUE // change status only
  3068. );
  3069. }
  3070. //
  3071. // compare the current node status
  3072. //
  3073. if ( rc == SCESTATUS_SUCCESS ||
  3074. rc == SCESTATUS_RECORD_NOT_FOUND ) {
  3075. if ( SapStatus == SCE_STATUS_ERROR_NOT_AVAILABLE ) {
  3076. // if errored, don't touch it.
  3077. retStat = SapStatus;
  3078. rc = SCESTATUS_SUCCESS;
  3079. } else {
  3080. rc = ScepObjectCompareKeySetting(
  3081. hSectionSap,
  3082. ObjectName,
  3083. ObjectType,
  3084. TRUE,
  3085. pSD,
  3086. SeInfo,
  3087. pScepSD,
  3088. &retStat
  3089. );
  3090. }
  3091. }
  3092. }
  3093. if ( pScepSD ) {
  3094. ScepFree(pScepSD);
  3095. }
  3096. }
  3097. if ( pAnalysisStatus ) {
  3098. *pAnalysisStatus = retStat;
  3099. }
  3100. return(rc);
  3101. }
  3102. SCESTATUS
  3103. ScepObjectGetKeySetting(
  3104. IN PSCESECTION hSection,
  3105. IN PWSTR ObjectName,
  3106. OUT PBYTE Status,
  3107. OUT PBOOL IsContainer OPTIONAL,
  3108. OUT PSECURITY_DESCRIPTOR *pSecurityDescriptor OPTIONAL,
  3109. OUT PSECURITY_INFORMATION SeInfo OPTIONAL
  3110. )
  3111. /*
  3112. Routine Description:
  3113. Read settings for the object in the section
  3114. Arguements:
  3115. hSection - the section handle
  3116. others see ScepUpdateObjectInfo
  3117. Return Value:
  3118. SCESTATUS
  3119. */
  3120. {
  3121. SCESTATUS rc;
  3122. PWSTR Value=NULL;
  3123. DWORD ValueLen;
  3124. PSECURITY_DESCRIPTOR pTempSD=NULL;
  3125. SECURITY_INFORMATION tmpSeInfo;
  3126. DWORD SDsize, Win32Rc;
  3127. if ( hSection == NULL || ObjectName == NULL || Status == NULL ) {
  3128. return(SCESTATUS_INVALID_PARAMETER);
  3129. }
  3130. rc = SceJetGetValue(
  3131. hSection,
  3132. SCEJET_EXACT_MATCH_NO_CASE,
  3133. ObjectName,
  3134. NULL,
  3135. 0,
  3136. NULL,
  3137. NULL,
  3138. 0,
  3139. &ValueLen
  3140. );
  3141. if ( rc == SCESTATUS_SUCCESS ) {
  3142. //
  3143. // allocate memory for value string
  3144. //
  3145. Value = (PWSTR)ScepAlloc( LMEM_ZEROINIT, ValueLen+2);
  3146. if ( Value == NULL )
  3147. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  3148. //
  3149. // Get the value
  3150. //
  3151. rc = SceJetGetValue(
  3152. hSection,
  3153. SCEJET_CURRENT,
  3154. NULL,
  3155. NULL,
  3156. 0,
  3157. NULL,
  3158. Value,
  3159. ValueLen,
  3160. &ValueLen
  3161. );
  3162. if ( rc == SCESTATUS_SUCCESS ) {
  3163. if (pSecurityDescriptor != NULL ) {
  3164. //
  3165. // convert security descriptor
  3166. //
  3167. Win32Rc = ConvertTextSecurityDescriptor(
  3168. Value+1,
  3169. &pTempSD,
  3170. &SDsize,
  3171. &tmpSeInfo
  3172. );
  3173. if ( Win32Rc == NO_ERROR ) {
  3174. *pSecurityDescriptor = pTempSD;
  3175. if (tmpSeInfo )
  3176. *SeInfo = tmpSeInfo;
  3177. } else
  3178. rc = ScepDosErrorToSceStatus(Win32Rc);
  3179. }
  3180. if ( rc == SCESTATUS_SUCCESS ) {
  3181. *Status = *((BYTE *)Value);
  3182. if ( IsContainer != NULL )
  3183. *IsContainer = *((CHAR *)Value+1) != '0' ? TRUE : FALSE;
  3184. }
  3185. }
  3186. ScepFree(Value);
  3187. }
  3188. return(rc);
  3189. }
  3190. SCESTATUS
  3191. ScepObjectSetKeySetting(
  3192. IN PSCESECTION hSection,
  3193. IN PWSTR ObjectName,
  3194. IN BYTE Status,
  3195. IN BOOL IsContainer,
  3196. IN PSECURITY_DESCRIPTOR pSD,
  3197. IN SECURITY_INFORMATION SeInfo,
  3198. IN BOOL bOverwrite
  3199. )
  3200. /*
  3201. Routine Description:
  3202. Set settings for the object in the section
  3203. Arguements:
  3204. See ScepObjectGetKeySetting
  3205. bOverwrite - if the new setting should overwrite existing settings
  3206. Return Value:
  3207. SCESTATUS
  3208. */
  3209. {
  3210. SCESTATUS rc;
  3211. DWORD SDsize=0, Win32Rc=NO_ERROR;
  3212. PWSTR SDspec=NULL;
  3213. if ( hSection == NULL ||
  3214. ObjectName == NULL ) {
  3215. return(SCESTATUS_INVALID_PARAMETER);
  3216. }
  3217. if ( !bOverwrite ) {
  3218. rc = SceJetSeek(
  3219. hSection,
  3220. ObjectName,
  3221. wcslen(ObjectName)*sizeof(WCHAR),
  3222. SCEJET_SEEK_EQ_NO_CASE
  3223. );
  3224. if ( rc != SCESTATUS_RECORD_NOT_FOUND ) {
  3225. //
  3226. // if found it, do not overwrite, so just return
  3227. // if errored, also return
  3228. //
  3229. return(rc);
  3230. }
  3231. }
  3232. //
  3233. // convert security descriptor
  3234. //
  3235. if ( pSD ) {
  3236. Win32Rc = ConvertSecurityDescriptorToText (
  3237. pSD,
  3238. SeInfo,
  3239. &SDspec,
  3240. &SDsize
  3241. );
  3242. }
  3243. if ( Win32Rc == NO_ERROR ) {
  3244. rc = ScepSaveObjectString(
  3245. hSection,
  3246. ObjectName,
  3247. IsContainer,
  3248. Status,
  3249. SDspec,
  3250. SDsize
  3251. );
  3252. } else
  3253. rc = ScepDosErrorToSceStatus(Win32Rc);
  3254. if ( SDspec != NULL ) {
  3255. ScepFree(SDspec);
  3256. }
  3257. return(rc);
  3258. }
  3259. SCESTATUS
  3260. ScepObjectDeleteScepAndAllChildren(
  3261. IN PSCESECTION hSectionSmp,
  3262. IN PSCESECTION hSectionSap,
  3263. IN PWSTR ObjectName,
  3264. IN BOOL IsContainer,
  3265. IN BYTE StatusToRaise
  3266. )
  3267. /*
  3268. Routine Description:
  3269. Delete a object and all child objects from SMP and SAP
  3270. Arguements:
  3271. hSectionSmp - SMP section handle
  3272. hSectionSap - SAP section handle
  3273. ObjectName - the object's name
  3274. IsContainer - if the object is a container
  3275. Return Value:
  3276. SCESTATUS
  3277. */
  3278. {
  3279. SCESTATUS rc;
  3280. rc = SceJetDelete(
  3281. hSectionSmp,
  3282. ObjectName,
  3283. TRUE,
  3284. SCEJET_DELETE_PARTIAL_NO_CASE
  3285. );
  3286. if ( rc == SCESTATUS_SUCCESS ||
  3287. rc == SCESTATUS_RECORD_NOT_FOUND ) {
  3288. rc = SceJetDelete(
  3289. hSectionSap,
  3290. ObjectName,
  3291. TRUE,
  3292. SCEJET_DELETE_PARTIAL_NO_CASE
  3293. );
  3294. if ( rc == SCESTATUS_SUCCESS ||
  3295. rc == SCESTATUS_RECORD_NOT_FOUND ) {
  3296. //
  3297. // Raise a N.C. status for the object
  3298. //
  3299. rc = ScepObjectSetKeySetting(
  3300. hSectionSap,
  3301. ObjectName,
  3302. StatusToRaise, //SCE_STATUS_NOT_CONFIGURED,
  3303. IsContainer,
  3304. NULL,
  3305. 0,
  3306. TRUE
  3307. );
  3308. }
  3309. }
  3310. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  3311. rc = SCESTATUS_SUCCESS;
  3312. }
  3313. return(rc);
  3314. }
  3315. SCESTATUS
  3316. ScepObjectAdjustNode(
  3317. IN PSCESECTION hSectionSmp,
  3318. IN PSCESECTION hSectionSap,
  3319. IN PWSTR ObjectName,
  3320. IN DWORD NameLen,
  3321. IN SE_OBJECT_TYPE ObjectType,
  3322. IN BYTE ConfigStatus,
  3323. IN BOOL IsContainer,
  3324. IN PSECURITY_DESCRIPTOR pSD,
  3325. IN SECURITY_INFORMATION SeInfo,
  3326. IN BOOL bAdd,
  3327. OUT PBYTE pAnalysisStatus
  3328. )
  3329. /*
  3330. Routine Description:
  3331. Add a new object to SMP and SAP sections
  3332. Arguements:
  3333. hSectionSmp - the SMP section handle
  3334. hSectionSap - the SAP section handle
  3335. others see ScepUpdateObjectInfo
  3336. Return Value:
  3337. SCESTATUS
  3338. */
  3339. {
  3340. if ( hSectionSmp == NULL || hSectionSap == NULL ||
  3341. ObjectName == NULL || NameLen == 0 ) {
  3342. return(SCESTATUS_INVALID_PARAMETER);
  3343. }
  3344. SCESTATUS rc=SCESTATUS_SUCCESS;
  3345. WCHAR Delim;
  3346. switch ( ObjectType) {
  3347. case SE_REGISTRY_KEY:
  3348. case SE_FILE_OBJECT:
  3349. Delim = L'\\';
  3350. break;
  3351. /*
  3352. case SE_DS_OBJECT:
  3353. Delim = L',';
  3354. break;
  3355. */
  3356. default:
  3357. return(SCESTATUS_INVALID_PARAMETER);
  3358. }
  3359. INT i, Level=0, ParentLevel=0;
  3360. BYTE ParentStatus;
  3361. //
  3362. // get total number levels of the objectname
  3363. //
  3364. ScepObjectTotalLevel(ObjectName, Delim, &Level);
  3365. //
  3366. // allocate temp buffer
  3367. //
  3368. PWSTR ParentName = (PWSTR)ScepAlloc(0, (NameLen+1)*sizeof(WCHAR));
  3369. if ( ParentName == NULL ) {
  3370. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  3371. }
  3372. //
  3373. // loop through each parent of the object to turn of IGNORE status
  3374. //
  3375. ParentName[0] = L'\0';
  3376. rc = ScepObjectAdjustParentStatus(
  3377. hSectionSmp,
  3378. hSectionSap,
  3379. ObjectName,
  3380. NameLen,
  3381. Delim,
  3382. Level,
  3383. bAdd ? (BYTE)SCE_OBJECT_TURNOFF_IGNORE : 0, // if TRUE, turn off parent ignore status, otherwise, just get the parent
  3384. &ParentLevel,
  3385. &ParentStatus,
  3386. ParentName // ParentName
  3387. );
  3388. if ( rc != SCESTATUS_SUCCESS ) {
  3389. //
  3390. // error occurs when turning off IGNORE
  3391. //
  3392. ScepFree(ParentName);
  3393. return(rc);
  3394. }
  3395. BYTE retStat = SCE_STATUS_NOT_ANALYZED;
  3396. BOOL HasChild;
  3397. rc = ScepObjectHasAnyChild(
  3398. hSectionSmp,
  3399. ObjectName,
  3400. NameLen,
  3401. Delim,
  3402. &HasChild
  3403. );
  3404. if ( rc == SCESTATUS_SUCCESS ) {
  3405. if ( bAdd ) {
  3406. //
  3407. // ****when bAdd = TRUE, add the node.
  3408. // there are the following cases to consider regarding the SAP entries:
  3409. //
  3410. // 1. tree path is empty to the root (the first object added in this path)
  3411. // C.C. all parent nodes if they don't exist
  3412. // N.A. the object
  3413. // return status N.A.
  3414. // 2. have parent node but no child node (the new node is a leaf node)
  3415. // if the closest parent is in OVERWRITE status
  3416. // if the closet parent is new added (N.A. status)
  3417. // add the node, N.A. the object
  3418. // return status N.A.
  3419. // else
  3420. // if new node status is CHECK
  3421. // delete all SAP mismatches for children under the new node,
  3422. // determine MATCH/MISMATCH of the new node
  3423. // if new node status is OVERWRITE
  3424. // determine MATCH/MISMATCH of the new node, everthing else stays unchanged
  3425. // return status GOOD or MISMATCH
  3426. // if the closest parent is CHECK
  3427. // C.C. all nodes in the path to the parent,
  3428. // add the node, N.A. the object
  3429. // return status N.A.
  3430. // 3. have child node but no parent node
  3431. // new node's status (CHECK or OVERWRITE ) does not make difference
  3432. // if new status is IGNORE,
  3433. // delete all children in SMP and SAP,
  3434. // add the node and N.C. the object
  3435. // return status N.C.
  3436. // else
  3437. // delete all children in SAP,
  3438. // add the node,
  3439. // raise all SMP node and children as N.A.
  3440. // return status N.A
  3441. //
  3442. // 4. have both parent and child
  3443. // combine rules for 2 and 3 except:
  3444. // if parent's status is OVERWRITE and new node status is CHECK
  3445. // ONLY delete SAP mismatches for children between the new node and the child node
  3446. //
  3447. //
  3448. // decide child objects
  3449. //
  3450. if ( ConfigStatus == SCE_STATUS_IGNORE ) {
  3451. //
  3452. // delete all children objects from template and analysis database
  3453. //
  3454. rc = ScepObjectDeleteScepAndAllChildren(
  3455. hSectionSmp,
  3456. hSectionSap,
  3457. ObjectName,
  3458. IsContainer,
  3459. SCE_STATUS_NOT_ANALYZED
  3460. );
  3461. } else {
  3462. if ( ParentLevel > 0 && ParentStatus == SCE_STATUS_OVERWRITE ) {
  3463. //
  3464. // check if this parent was added (N.A. status)
  3465. //
  3466. BYTE oldStatus = ScepGetObjectAnalysisStatus(hSectionSap,
  3467. ParentName,
  3468. FALSE
  3469. );
  3470. if ( oldStatus == SCE_STATUS_NOT_ANALYZED ) {
  3471. //
  3472. // parent was also new added
  3473. // add the node, N.A. the object
  3474. //
  3475. rc = ScepObjectSetKeySetting(
  3476. hSectionSap,
  3477. ObjectName,
  3478. SCE_STATUS_NOT_ANALYZED,
  3479. TRUE,
  3480. NULL,
  3481. 0,
  3482. TRUE
  3483. );
  3484. } else {
  3485. //
  3486. // closest parent has OVERWRITE status
  3487. //
  3488. if ( ConfigStatus == SCE_STATUS_CHECK ||
  3489. ConfigStatus == SCE_STATUS_NO_AUTO_INHERIT ) {
  3490. //
  3491. // delete all SAP children except explicitly specified
  3492. //
  3493. if ( !HasChild ) {
  3494. //
  3495. // no child - delete everything under the SAP
  3496. //
  3497. rc = SceJetDelete(
  3498. hSectionSap,
  3499. ObjectName,
  3500. TRUE,
  3501. SCEJET_DELETE_PARTIAL_NO_CASE
  3502. );
  3503. } else {
  3504. //
  3505. // here is the problem: should only delete SAP entry between
  3506. // the new node and its child(ren)
  3507. // and raise C.C. for nodes in between
  3508. //
  3509. // p
  3510. // /
  3511. // .
  3512. // N
  3513. // / |
  3514. // . C
  3515. // / \
  3516. // . C
  3517. // /|
  3518. // C C
  3519. //
  3520. //
  3521. rc = ScepObjectRaiseChildrenInBetween(
  3522. hSectionSmp,
  3523. hSectionSap,
  3524. ObjectName,
  3525. NameLen,
  3526. IsContainer,
  3527. SCE_STATUS_CHILDREN_CONFIGURED,
  3528. FALSE
  3529. );
  3530. }
  3531. }
  3532. //
  3533. // determine the current node's status, MATCH or MISMATCH
  3534. //
  3535. if ( rc == SCESTATUS_SUCCESS ||
  3536. rc == SCESTATUS_RECORD_NOT_FOUND ) {
  3537. if ( oldStatus == SCE_STATUS_ERROR_NOT_AVAILABLE ) {
  3538. //
  3539. // Leave Error status alone
  3540. //
  3541. rc = ScepObjectSetKeySetting(
  3542. hSectionSap,
  3543. ObjectName,
  3544. oldStatus,
  3545. TRUE,
  3546. NULL,
  3547. 0,
  3548. TRUE
  3549. );
  3550. } else {
  3551. //
  3552. // should compare with SAP to decide mismatch status
  3553. //
  3554. rc = ScepObjectCompareKeySetting(
  3555. hSectionSap,
  3556. ObjectName,
  3557. ObjectType,
  3558. TRUE,
  3559. pSD,
  3560. SeInfo,
  3561. NULL,
  3562. &retStat
  3563. );
  3564. }
  3565. }
  3566. }
  3567. } else if ( !HasChild ) {
  3568. //
  3569. // there is no child but there may be a parent
  3570. // if there is a parent, parent's stauts is check
  3571. //
  3572. if ( ParentLevel > 0 ) {
  3573. // C.C. all nodes in the path to the parent,
  3574. // (if there is child, it's already CCed)
  3575. // add the node, N.A. the object
  3576. i = ParentLevel+1;
  3577. } else {
  3578. //
  3579. // no parent was found, no child - the first node
  3580. //
  3581. if ( ObjectType == SE_DS_OBJECT ) {
  3582. //
  3583. // Ds objects should start with the level for the local domain
  3584. //
  3585. PSCE_OBJECT_LIST pDsRoot=NULL;
  3586. rc = ScepEnumerateDsObjectRoots(NULL, &pDsRoot);
  3587. if ( rc == SCESTATUS_SUCCESS && pDsRoot != NULL ) {
  3588. ScepObjectTotalLevel(pDsRoot->Name, Delim, &ParentLevel);
  3589. ScepFreeObjectList(pDsRoot);
  3590. pDsRoot = NULL;
  3591. i = ParentLevel+1;
  3592. }
  3593. } else {
  3594. //
  3595. // other type starting with level 1
  3596. //
  3597. i = 1;
  3598. }
  3599. }
  3600. //
  3601. // process each node in between the new node and its closest parent
  3602. //
  3603. if ( rc == SCESTATUS_SUCCESS ) {
  3604. rc = ScepObjectRaiseNodesInPath(
  3605. hSectionSap,
  3606. ObjectName,
  3607. NameLen,
  3608. i,
  3609. Level,
  3610. Delim,
  3611. SCE_STATUS_CHILDREN_CONFIGURED
  3612. );
  3613. }
  3614. //
  3615. // N.A. the object
  3616. //
  3617. if ( rc == SCESTATUS_SUCCESS ) {
  3618. rc = ScepObjectSetKeySetting(
  3619. hSectionSap,
  3620. ObjectName,
  3621. SCE_STATUS_NOT_ANALYZED,
  3622. IsContainer,
  3623. NULL,
  3624. 0,
  3625. TRUE
  3626. );
  3627. }
  3628. } else {
  3629. //
  3630. // there is child
  3631. //
  3632. if ( ConfigStatus == SCE_STATUS_OVERWRITE ) {
  3633. //
  3634. // if there is a parent, it must be in CHECK status
  3635. // nodes between this node and its children
  3636. // should all be N.A.
  3637. //
  3638. rc = ScepObjectRaiseChildrenInBetween(
  3639. hSectionSmp,
  3640. hSectionSap,
  3641. ObjectName,
  3642. NameLen,
  3643. IsContainer,
  3644. SCE_STATUS_NOT_ANALYZED,
  3645. FALSE
  3646. );
  3647. }
  3648. //
  3649. // N.A. the object
  3650. //
  3651. if ( rc == SCESTATUS_SUCCESS ) {
  3652. rc = ScepObjectSetKeySetting(
  3653. hSectionSap,
  3654. ObjectName,
  3655. SCE_STATUS_NOT_ANALYZED,
  3656. IsContainer,
  3657. NULL,
  3658. 0,
  3659. TRUE
  3660. );
  3661. }
  3662. }
  3663. }
  3664. //
  3665. // add the SMP entry
  3666. //
  3667. if ( rc == SCESTATUS_SUCCESS ) {
  3668. rc = ScepObjectSetKeySetting(
  3669. hSectionSmp,
  3670. ObjectName,
  3671. ConfigStatus,
  3672. IsContainer,
  3673. pSD,
  3674. SeInfo,
  3675. TRUE
  3676. );
  3677. }
  3678. } else {
  3679. //
  3680. // when bAdd = FALSE, remove the node
  3681. // there are the following cases to consider regarding the SAP entries:
  3682. //
  3683. // 1. if there is no existing child under this node
  3684. // if no parent, or parent N.A., or parent not OVERWRITE
  3685. // find junction point with other siblings
  3686. // remove all SAP below junction point (if not exist, use root/parent)
  3687. // if no juction point and no parent
  3688. // N.C. the root
  3689. // return status N.C.
  3690. // else { parent in overwrite } if ( TNA/TI/TC) }
  3691. // delete all SAP below this object
  3692. // N.A. the object
  3693. // return status N.A.
  3694. // else ( parent in overwrite and TO )
  3695. // N.A. the object
  3696. // return status N.A.
  3697. // 2. have existing child(ren) - note multiple branches
  3698. // if no parent
  3699. // if object status was OVERWRITE
  3700. // delete SAP entries between this node and all children
  3701. // C.C. all branch nodes in between
  3702. // C.C. this object
  3703. // return status C.C.
  3704. // else { there is a parent }
  3705. // if (parent OVERWRITE, object N.A. OVERWRITE) or
  3706. // (parent not N.A., parent OVERWRITE, object not N.A., object OVERWRITE)
  3707. // N.A. object
  3708. // return N.A.
  3709. // else if parent CHECK, object OVERWRITE
  3710. // delete SAP entries between this node and all children
  3711. // C.C. all branch nodes in between
  3712. // C.C. object
  3713. // return C.C.
  3714. // else if (parent OVERWRITE, object CHECK) or
  3715. // (parent N.A., parent OVERWRITE, object not N.A., object OVERWRITE)
  3716. // delete SAP entries between this node and all children
  3717. // N.A. all branch nodes in between
  3718. // N.A. object
  3719. // return N.A.
  3720. // else { must be parent CHECK, object CHECK }
  3721. // C.C. object
  3722. // return C.C
  3723. //
  3724. //
  3725. // check if this parent was added (N.A. status)
  3726. //
  3727. BYTE oldParentFlag = ScepGetObjectAnalysisStatus(hSectionSap,
  3728. ParentName,
  3729. FALSE
  3730. );
  3731. BYTE oldObjectFlag = ScepGetObjectAnalysisStatus(hSectionSap,
  3732. ObjectName,
  3733. FALSE
  3734. );
  3735. if ( !HasChild ) {
  3736. if ( ParentLevel <= 0 ||
  3737. oldParentFlag == SCE_STATUS_NOT_ANALYZED ||
  3738. ParentStatus != SCE_STATUS_OVERWRITE ) {
  3739. //
  3740. // find junction point with other siblings
  3741. //
  3742. INT JuncLevel=0;
  3743. rc = ScepObjectAdjustParentStatus(
  3744. hSectionSmp,
  3745. hSectionSap,
  3746. ObjectName,
  3747. NameLen,
  3748. Delim,
  3749. Level,
  3750. SCE_OBJECT_SEARCH_JUNCTION,
  3751. &JuncLevel,
  3752. NULL,
  3753. NULL
  3754. );
  3755. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  3756. rc = SCESTATUS_SUCCESS;
  3757. }
  3758. if ( JuncLevel == 0 ) {
  3759. JuncLevel = ParentLevel;
  3760. }
  3761. if ( SCESTATUS_SUCCESS == rc ) {
  3762. //
  3763. // remove all SAP below junction point
  3764. // (if not exist, use root/parent)
  3765. //
  3766. rc = ScepObjectRaiseNodesInPath(
  3767. hSectionSap,
  3768. ObjectName,
  3769. NameLen,
  3770. (JuncLevel > 0) ? JuncLevel+1 : 1,
  3771. Level,
  3772. Delim,
  3773. (BYTE)SCE_NO_VALUE
  3774. );
  3775. if ( SCESTATUS_SUCCESS == rc ) {
  3776. //
  3777. // delete everything under this deleted node
  3778. //
  3779. rc = SceJetDelete(
  3780. hSectionSap,
  3781. ObjectName,
  3782. TRUE,
  3783. SCEJET_DELETE_PARTIAL_NO_CASE
  3784. );
  3785. }
  3786. }
  3787. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  3788. rc = SCESTATUS_SUCCESS;
  3789. }
  3790. if ( SCESTATUS_SUCCESS == rc ) {
  3791. if ( JuncLevel <= 0 ) {
  3792. //
  3793. // if no juction point and no parent, N.C. the root
  3794. // use the ParentName buffer
  3795. //
  3796. if ( ObjectType == SE_FILE_OBJECT ) {
  3797. if ( ParentName[0] == L'\0' ) {
  3798. //
  3799. // there is no parent
  3800. //
  3801. ParentName[0] = ObjectName[0];
  3802. ParentName[1] = ObjectName[1];
  3803. }
  3804. ParentName[2] = L'\\';
  3805. ParentName[3] = L'\0';
  3806. } else {
  3807. // reg keys
  3808. PWSTR pTemp = wcschr(ParentName, L'\\');
  3809. if ( pTemp ) {
  3810. ParentName[pTemp-ParentName] = L'\0';
  3811. } else if ( ParentName[0] == L'\0' ) {
  3812. pTemp = wcschr(ObjectName, L'\\');
  3813. if ( pTemp ) {
  3814. wcsncpy(ParentName, ObjectName, pTemp-ObjectName);
  3815. ParentName[pTemp-ObjectName] = L'\0';
  3816. } else {
  3817. wcscpy(ParentName, ObjectName);
  3818. }
  3819. }
  3820. }
  3821. rc = ScepObjectSetKeySetting(
  3822. hSectionSap,
  3823. ParentName,
  3824. SCE_STATUS_NOT_CONFIGURED,
  3825. TRUE,
  3826. NULL,
  3827. 0,
  3828. TRUE
  3829. );
  3830. }
  3831. }
  3832. retStat = SCE_STATUS_NOT_CONFIGURED;
  3833. } else {
  3834. if ( ConfigStatus != SCE_STATUS_OVERWRITE ) {
  3835. //
  3836. // delete all SAP below this object
  3837. //
  3838. rc = SceJetDelete(
  3839. hSectionSap,
  3840. ObjectName,
  3841. TRUE,
  3842. SCEJET_DELETE_PARTIAL_NO_CASE
  3843. );
  3844. }
  3845. if ( SCESTATUS_SUCCESS == rc ) {
  3846. //
  3847. // N.A. the object
  3848. //
  3849. rc = ScepObjectSetKeySetting(
  3850. hSectionSap,
  3851. ObjectName,
  3852. SCE_STATUS_NOT_ANALYZED,
  3853. IsContainer,
  3854. NULL,
  3855. 0,
  3856. TRUE
  3857. );
  3858. }
  3859. retStat = SCE_STATUS_NOT_ANALYZED;
  3860. }
  3861. } else if ( ParentLevel <= 0 ||
  3862. ( ParentStatus != SCE_STATUS_OVERWRITE &&
  3863. ConfigStatus == SCE_STATUS_OVERWRITE) ) {
  3864. // no parent, or parent check, object overwrite
  3865. if ( ConfigStatus == SCE_STATUS_OVERWRITE ) {
  3866. //
  3867. // delete SAP entries between this node and all children
  3868. // C.C. all branch nodes in between
  3869. //
  3870. rc = ScepObjectRaiseChildrenInBetween(
  3871. hSectionSmp,
  3872. hSectionSap,
  3873. ObjectName,
  3874. NameLen,
  3875. IsContainer,
  3876. SCE_STATUS_CHILDREN_CONFIGURED,
  3877. FALSE
  3878. );
  3879. }
  3880. if ( SCESTATUS_SUCCESS == rc ) {
  3881. // C.C. this object
  3882. rc = ScepObjectSetKeySetting(
  3883. hSectionSap,
  3884. ObjectName,
  3885. SCE_STATUS_CHILDREN_CONFIGURED,
  3886. IsContainer,
  3887. NULL,
  3888. 0,
  3889. TRUE
  3890. );
  3891. }
  3892. retStat = SCE_STATUS_CHILDREN_CONFIGURED;
  3893. } else {
  3894. //
  3895. // have both parent and children
  3896. //
  3897. if ( ParentStatus == SCE_STATUS_OVERWRITE &&
  3898. ConfigStatus == SCE_STATUS_OVERWRITE &&
  3899. ( oldObjectFlag == SCE_STATUS_NOT_ANALYZED ||
  3900. (oldParentFlag != SCE_STATUS_NOT_ANALYZED &&
  3901. oldObjectFlag != SCE_STATUS_NOT_ANALYZED )
  3902. ) ) {
  3903. //
  3904. // (parent OVERWRITE, object N.A. OVERWRITE) or
  3905. // (parent not N.A., parent OVERWRITE, object not N.A., object OVERWRITE)
  3906. // N.A. the object
  3907. //
  3908. retStat = SCE_STATUS_NOT_ANALYZED;
  3909. } else if ( ParentStatus == SCE_STATUS_OVERWRITE &&
  3910. ( ConfigStatus != SCE_STATUS_OVERWRITE ||
  3911. ( oldParentFlag == SCE_STATUS_NOT_ANALYZED &&
  3912. oldObjectFlag != SCE_STATUS_NOT_ANALYZED &&
  3913. ConfigStatus == SCE_STATUS_OVERWRITE ))
  3914. ) {
  3915. //
  3916. // (parent OVERWRITE, object CHECK) or
  3917. // (parent N.A., parent OVERWRITE, object not N.A., object OVERWRITE)
  3918. //
  3919. // delete SAP entries between this node and all children
  3920. // N.A. all branch nodes in between
  3921. //
  3922. rc = ScepObjectRaiseChildrenInBetween(
  3923. hSectionSmp,
  3924. hSectionSap,
  3925. ObjectName,
  3926. NameLen,
  3927. IsContainer,
  3928. SCE_STATUS_NOT_ANALYZED,
  3929. FALSE
  3930. );
  3931. // N.A. object
  3932. retStat = SCE_STATUS_NOT_ANALYZED;
  3933. } else {
  3934. //
  3935. // must be parent CHECK, object CHECK }
  3936. // C.C. object
  3937. //
  3938. retStat = SCE_STATUS_NOT_ANALYZED;
  3939. }
  3940. if ( SCESTATUS_SUCCESS == rc ) {
  3941. rc = ScepObjectSetKeySetting(
  3942. hSectionSap,
  3943. ObjectName,
  3944. retStat,
  3945. IsContainer,
  3946. NULL,
  3947. 0,
  3948. TRUE
  3949. );
  3950. }
  3951. }
  3952. //
  3953. // remove the SMP entry
  3954. //
  3955. if ( rc == SCESTATUS_SUCCESS ) {
  3956. rc = SceJetDelete(
  3957. hSectionSmp,
  3958. ObjectName,
  3959. FALSE,
  3960. SCEJET_DELETE_LINE_NO_CASE
  3961. );
  3962. }
  3963. }
  3964. }
  3965. ScepFree(ParentName);
  3966. if ( pAnalysisStatus ) {
  3967. *pAnalysisStatus = retStat;
  3968. }
  3969. return(rc);
  3970. }
  3971. SCESTATUS
  3972. ScepObjectRaiseNodesInPath(
  3973. IN PSCESECTION hSectionSap,
  3974. IN PWSTR ObjectName,
  3975. IN DWORD NameLen,
  3976. IN INT StartLevel,
  3977. IN INT EndLevel,
  3978. IN WCHAR Delim,
  3979. IN BYTE Status
  3980. )
  3981. {
  3982. BOOL LastOne=FALSE;
  3983. SCESTATUS rc = SCESTATUS_SUCCESS;
  3984. PWSTR NodeName=NULL;
  3985. //
  3986. // process each node in between the start level and end level
  3987. //
  3988. for ( INT i=StartLevel; rc==SCESTATUS_SUCCESS && i < EndLevel; i++ ) {
  3989. if ( NodeName == NULL ) {
  3990. NodeName = (PWSTR)ScepAlloc(0, (NameLen+1)*sizeof(WCHAR));
  3991. if ( NodeName == NULL ) {
  3992. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  3993. break;
  3994. }
  3995. }
  3996. //
  3997. // get level i full name
  3998. //
  3999. memset(NodeName, '\0', (NameLen+1)*sizeof(WCHAR));
  4000. rc = ScepGetFullNameInLevel(
  4001. ObjectName,
  4002. i,
  4003. Delim,
  4004. FALSE,
  4005. NodeName,
  4006. &LastOne
  4007. );
  4008. if ( rc == SCESTATUS_SUCCESS) {
  4009. if ( Status != (BYTE)SCE_NO_VALUE ) {
  4010. //
  4011. // raise the status
  4012. //
  4013. rc = ScepObjectSetKeySetting(
  4014. hSectionSap,
  4015. NodeName,
  4016. Status,
  4017. TRUE,
  4018. NULL,
  4019. 0,
  4020. TRUE
  4021. );
  4022. } else {
  4023. //
  4024. // remove the raise
  4025. //
  4026. rc = SceJetDelete(
  4027. hSectionSap,
  4028. NodeName,
  4029. FALSE,
  4030. SCEJET_DELETE_LINE_NO_CASE
  4031. );
  4032. }
  4033. }
  4034. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  4035. rc = SCESTATUS_SUCCESS;
  4036. }
  4037. if ( rc != SCESTATUS_SUCCESS ) {
  4038. break;
  4039. }
  4040. }
  4041. if ( NodeName ) {
  4042. ScepFree(NodeName);
  4043. }
  4044. return rc;
  4045. }
  4046. SCESTATUS
  4047. ScepObjectTotalLevel(
  4048. IN PWSTR ObjectName,
  4049. IN WCHAR Delim,
  4050. OUT PINT pLevel
  4051. )
  4052. /*
  4053. Routine Description:
  4054. Count total levels of the object name, for example, c:\winnt\system32
  4055. will return level of 3
  4056. Arguements:
  4057. ObjectName - the object's name in full path
  4058. Delim - the delimiter to look for
  4059. pLevel - the output level
  4060. Return Value:
  4061. SCESTATUS
  4062. */
  4063. {
  4064. PWSTR pStart;
  4065. if ( ObjectName == NULL || pLevel == NULL ) {
  4066. return(SCESTATUS_INVALID_PARAMETER);
  4067. }
  4068. pStart = ObjectName;
  4069. *pLevel = 0;
  4070. while (pStart) {
  4071. (*pLevel)++;
  4072. pStart = wcschr(pStart, Delim);
  4073. if ( pStart != NULL && *(pStart+1) != L'\0' )
  4074. pStart++;
  4075. else
  4076. break;
  4077. }
  4078. return(SCESTATUS_SUCCESS);
  4079. }
  4080. SCESTATUS
  4081. ScepObjectCompareKeySetting(
  4082. IN PSCESECTION hSectionSap,
  4083. IN PWSTR ObjectName,
  4084. IN SE_OBJECT_TYPE ObjectType,
  4085. IN BOOL IsContainer,
  4086. IN PSECURITY_DESCRIPTOR pSD,
  4087. IN SECURITY_INFORMATION SeInfo,
  4088. IN PSECURITY_DESCRIPTOR pScepSD,
  4089. OUT PBYTE pAnalysisStatus
  4090. )
  4091. /*
  4092. Routine Description:
  4093. Compare an object's setting with info in the section.
  4094. Arguements:
  4095. hSectionSap - the SAP section handle
  4096. others see ScepUpdateObjectInfo
  4097. Return Value:
  4098. SCESTATUS
  4099. */
  4100. {
  4101. SCESTATUS rc;
  4102. BYTE SapStatus;
  4103. PSECURITY_DESCRIPTOR pSapSD = NULL;
  4104. SECURITY_INFORMATION SapSeInfo;
  4105. DWORD Win32rc;
  4106. BYTE CompareStatus=0;
  4107. rc = ScepObjectGetKeySetting(
  4108. hSectionSap,
  4109. ObjectName,
  4110. &SapStatus,
  4111. NULL,
  4112. &pSapSD,
  4113. &SapSeInfo
  4114. );
  4115. if ( rc == SCESTATUS_SUCCESS ) {
  4116. //
  4117. // SAP record exists. was mismatched
  4118. //
  4119. Win32rc = ScepCompareObjectSecurity(
  4120. ObjectType,
  4121. IsContainer,
  4122. pSD,
  4123. pSapSD,
  4124. SeInfo,
  4125. &CompareStatus
  4126. );
  4127. if ( Win32rc != NO_ERROR ) {
  4128. rc = ScepDosErrorToSceStatus(Win32rc);
  4129. } else if ( !CompareStatus ) {
  4130. //
  4131. // new setting is same as the SAP setting - matched
  4132. // delete the SAP entry
  4133. //
  4134. rc = SceJetDelete(
  4135. hSectionSap,
  4136. ObjectName,
  4137. FALSE,
  4138. SCEJET_DELETE_LINE_NO_CASE
  4139. );
  4140. if ( pAnalysisStatus ) {
  4141. *pAnalysisStatus = SCE_STATUS_GOOD;
  4142. }
  4143. } else {
  4144. //
  4145. // still mismatched, just update the SMP entry (outside)
  4146. //
  4147. rc = ScepObjectSetKeySetting(
  4148. hSectionSap,
  4149. ObjectName,
  4150. CompareStatus, // SCE_STATUS_MISMATCH,
  4151. IsContainer,
  4152. pSapSD,
  4153. SapSeInfo,
  4154. TRUE
  4155. );
  4156. if ( pAnalysisStatus ) {
  4157. *pAnalysisStatus = CompareStatus; // SapStatus;
  4158. }
  4159. }
  4160. if ( pSapSD ) {
  4161. ScepFree(pSapSD);
  4162. }
  4163. } else if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  4164. rc = SCESTATUS_SUCCESS;
  4165. //
  4166. // no SAP record exist. was matched
  4167. //
  4168. Win32rc = ScepCompareObjectSecurity(
  4169. ObjectType,
  4170. IsContainer,
  4171. pSD,
  4172. pScepSD,
  4173. SeInfo,
  4174. &CompareStatus
  4175. );
  4176. if ( Win32rc != NO_ERROR ) {
  4177. rc = ScepDosErrorToSceStatus(Win32rc);
  4178. } else if ( CompareStatus ) {
  4179. //
  4180. // new setting is different from the SMP setting
  4181. // create SAP entry using the SMP setting
  4182. //
  4183. rc = ScepObjectSetKeySetting(
  4184. hSectionSap,
  4185. ObjectName,
  4186. CompareStatus, // SCE_STATUS_MISMATCH,
  4187. IsContainer,
  4188. pScepSD,
  4189. SeInfo,
  4190. TRUE
  4191. );
  4192. if ( pAnalysisStatus ) {
  4193. *pAnalysisStatus = CompareStatus; // SCE_STATUS_MISMATCH;
  4194. }
  4195. } else {
  4196. if ( pAnalysisStatus ) {
  4197. *pAnalysisStatus = SCE_STATUS_GOOD;
  4198. }
  4199. }
  4200. }
  4201. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  4202. rc = SCESTATUS_SUCCESS;
  4203. }
  4204. return(rc);
  4205. }
  4206. SCESTATUS
  4207. ScepObjectAdjustParentStatus(
  4208. IN PSCESECTION hSectionSmp,
  4209. IN PSCESECTION hSectionSap,
  4210. IN PWSTR ObjectName,
  4211. IN DWORD NameLen,
  4212. IN WCHAR Delim,
  4213. IN INT Level,
  4214. IN BYTE Flag,
  4215. OUT PINT ParentLevel,
  4216. OUT PBYTE ParentStatus OPTIONAL,
  4217. OUT PWSTR ParentName OPTIONAL
  4218. )
  4219. /*
  4220. Routine Description:
  4221. delete the ignored parent in the object's path (should only have one)
  4222. The following actions are taken when a IGNORE node is found:
  4223. (it should have N.C.ed in SAP but no children has N.C record)
  4224. delete all children in SMP and SAP
  4225. (force to have only no or one IGNORE in the path)
  4226. delete the SMP entry ( turn the IGNORE status to CHECK ?)
  4227. There should be no other nodes under a IGNORE node. But if there are,
  4228. delete them.
  4229. raise SAP status as "Not analyzed"
  4230. Arguments:
  4231. hSectionSmp - the SMP section handle
  4232. hSectionSap - the SAP section handle
  4233. ObjectName - the object's full name
  4234. NameLen - the length of the name
  4235. Delim - the delimiter to look for
  4236. Level - the total level of the object name
  4237. ParentLevel - output of its closest parent level
  4238. ParentStatus - output of its closest parent status
  4239. Return Value:
  4240. SCE status
  4241. */
  4242. {
  4243. SCESTATUS rc=SCESTATUS_SUCCESS;
  4244. INT i;
  4245. PWSTR Name=NULL;
  4246. BOOL LastOne;
  4247. DWORD ParentLen;
  4248. BYTE Status;
  4249. PSECURITY_DESCRIPTOR pScepSD=NULL;
  4250. SECURITY_INFORMATION SeInfo;
  4251. Name = (PWSTR)ScepAlloc(0, (NameLen+2)*sizeof(WCHAR));
  4252. if ( Name == NULL ) {
  4253. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  4254. }
  4255. *ParentLevel = 0;
  4256. for ( i=Level-1; i>=1; i-- ) {
  4257. //
  4258. // get level i full name
  4259. //
  4260. memset(Name, '\0', (NameLen+2)*sizeof(WCHAR));
  4261. rc = ScepGetFullNameInLevel(
  4262. ObjectName,
  4263. i,
  4264. Delim,
  4265. (Flag & SCE_OBJECT_SEARCH_JUNCTION) ? TRUE : FALSE,
  4266. Name,
  4267. &LastOne
  4268. );
  4269. if ( rc == SCESTATUS_SUCCESS ) {
  4270. //
  4271. // search and get information of this path
  4272. //
  4273. if ( Flag & SCE_OBJECT_SEARCH_JUNCTION ) {
  4274. DWORD Count=0;
  4275. rc = SceJetGetLineCount(
  4276. hSectionSmp,
  4277. Name,
  4278. FALSE,
  4279. &Count
  4280. );
  4281. if ( rc == SCESTATUS_SUCCESS &&
  4282. Count > 1 ) {
  4283. //
  4284. // there are other children under this node
  4285. // this is the junction point
  4286. //
  4287. *ParentLevel = i;
  4288. break;
  4289. }
  4290. //
  4291. // dont' care error
  4292. //
  4293. rc = SCESTATUS_SUCCESS;
  4294. } else {
  4295. ParentLen = wcslen(Name);
  4296. Status = (BYTE)-1;
  4297. rc = ScepObjectGetKeySetting(
  4298. hSectionSmp,
  4299. Name,
  4300. &Status,
  4301. NULL,
  4302. &pScepSD,
  4303. &SeInfo
  4304. );
  4305. if ( rc == SCESTATUS_SUCCESS ) {
  4306. //
  4307. // find a parent.
  4308. //
  4309. *ParentLevel = i;
  4310. if ( ParentStatus ) {
  4311. *ParentStatus = Status;
  4312. }
  4313. if ( ParentName ) {
  4314. wcscpy(ParentName, Name);
  4315. }
  4316. if ( (Flag & SCE_OBJECT_TURNOFF_IGNORE) &&
  4317. Status == SCE_STATUS_IGNORE ) {
  4318. //
  4319. // delete all SMP and SAP under this node
  4320. //
  4321. rc = ScepObjectDeleteScepAndAllChildren(
  4322. hSectionSmp,
  4323. hSectionSap,
  4324. Name,
  4325. TRUE,
  4326. SCE_STATUS_NOT_ANALYZED
  4327. );
  4328. /*
  4329. if ( rc == SCESTATUS_SUCCESS ) {
  4330. //
  4331. // change its status to CHECK,
  4332. //
  4333. rc = ScepObjectSetKeySetting(
  4334. hSectionSmp,
  4335. Name,
  4336. SCE_STATUS_CHECK,
  4337. TRUE,
  4338. pScepSD,
  4339. SeInfo,
  4340. TRUE
  4341. );
  4342. }
  4343. */
  4344. //
  4345. // all other nodes are deleted. should break out of the loop
  4346. //
  4347. }
  4348. if ( pScepSD ) {
  4349. ScepFree(pScepSD);
  4350. pScepSD = NULL;
  4351. }
  4352. if ( !(Flag & SCE_OBJECT_TURNOFF_IGNORE) ||
  4353. Status == SCE_STATUS_IGNORE ) {
  4354. if ( rc == SCESTATUS_RECORD_NOT_FOUND )
  4355. rc = SCESTATUS_SUCCESS;
  4356. break;
  4357. }
  4358. }
  4359. }
  4360. }
  4361. if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  4362. rc = SCESTATUS_SUCCESS;
  4363. }
  4364. //
  4365. // process next parent
  4366. //
  4367. if ( rc != SCESTATUS_SUCCESS )
  4368. break;
  4369. }
  4370. ScepFree(Name);
  4371. return(rc);
  4372. }
  4373. SCESTATUS
  4374. ScepObjectHasAnyChild(
  4375. IN PSCESECTION hSection,
  4376. IN PWSTR ObjectName,
  4377. IN DWORD NameLen,
  4378. IN WCHAR Delim,
  4379. OUT PBOOL bpHasChild
  4380. )
  4381. /*
  4382. Routine Description:
  4383. Detect if the object has child objects in the section
  4384. Arguements:
  4385. hSection - the section handle
  4386. ObjectName - the object name
  4387. NameLen - the name length
  4388. Delim - the delimeter to look for
  4389. bpHasChild - output TRUE if the object has a child in the section
  4390. Return Value:
  4391. SCESTATUS
  4392. */
  4393. {
  4394. SCESTATUS rc;
  4395. PWSTR pTemp=NULL;
  4396. if ( hSection == NULL || ObjectName == NULL ||
  4397. NameLen == 0 || Delim == L'\0' || bpHasChild == NULL ) {
  4398. return(SCESTATUS_INVALID_PARAMETER);
  4399. }
  4400. pTemp = (PWSTR)ScepAlloc(0, (NameLen+2)*sizeof(WCHAR));
  4401. if ( pTemp != NULL ) {
  4402. wcscpy(pTemp, ObjectName);
  4403. pTemp[NameLen] = Delim;
  4404. pTemp[NameLen+1] = L'\0';
  4405. rc = SceJetSeek(
  4406. hSection,
  4407. pTemp,
  4408. (NameLen+1)*sizeof(WCHAR),
  4409. SCEJET_SEEK_GE_NO_CASE
  4410. );
  4411. if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  4412. *bpHasChild = FALSE;
  4413. rc = SCESTATUS_SUCCESS;
  4414. } else if ( rc == SCESTATUS_SUCCESS ) {
  4415. *bpHasChild = TRUE;
  4416. }
  4417. ScepFree(pTemp);
  4418. } else
  4419. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  4420. return(rc);
  4421. }
  4422. SCESTATUS
  4423. ScepObjectRaiseChildrenInBetween(
  4424. IN PSCESECTION hSectionSmp,
  4425. IN PSCESECTION hSectionSap,
  4426. IN PWSTR ObjectName,
  4427. IN DWORD NameLen,
  4428. IN BOOL IsContainer,
  4429. IN BYTE Status,
  4430. IN BOOL bChangeStatusOnly
  4431. )
  4432. /*
  4433. Routine Description:
  4434. Delete any SAP entries for objects between Name and its children in SMP table
  4435. and raise SAP entries for bridge nodes to the Status specified.
  4436. For example, in the picture below, every SAP entry in the 1. level and 2. level
  4437. , except the C nodes, should be deleted from SAP. Then 1. and 2. nodes are
  4438. raised as Status.
  4439. p
  4440. /
  4441. .
  4442. N <----
  4443. / |
  4444. 1. C
  4445. / \
  4446. 2. C
  4447. /|
  4448. C C
  4449. Arguments:
  4450. hSectionSmp - the SMP section handle
  4451. hSection - the SAP section handle
  4452. Name - the object name
  4453. NameLen - the length of the name
  4454. Status - the object's status to raise
  4455. Return Value:
  4456. SCE status
  4457. */
  4458. {
  4459. SCESTATUS rc;
  4460. PWSTR *pSmpNames=NULL;
  4461. DWORD *pSmpNameLen=NULL;
  4462. DWORD cntNames=0;
  4463. BOOL bFirst=TRUE;
  4464. WCHAR Delim=L'\\';
  4465. DWORD DirLen = wcslen(ObjectName);
  4466. if ( ObjectName[DirLen-1] != Delim ) {
  4467. DirLen++;
  4468. }
  4469. PWSTR DirName = (PWSTR)ScepAlloc(0, (DirLen+1)*sizeof(WCHAR));
  4470. if ( DirName == NULL ) {
  4471. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  4472. }
  4473. wcscpy(DirName, ObjectName);
  4474. if ( DirName[DirLen-1] != Delim ) {
  4475. DirName[DirLen-1] = Delim;
  4476. }
  4477. //
  4478. // get all children of DirName in SMP
  4479. //
  4480. rc = SceJetGetLineCount(
  4481. hSectionSmp,
  4482. DirName,
  4483. FALSE,
  4484. &cntNames);
  4485. DWORD index=0;
  4486. if ( rc == SCESTATUS_SUCCESS ) {
  4487. pSmpNames = (PWSTR *)ScepAlloc(LPTR, cntNames*sizeof(PWSTR));
  4488. pSmpNameLen = (DWORD *)ScepAlloc(LPTR, cntNames*sizeof(DWORD));
  4489. if ( pSmpNames != NULL && pSmpNameLen != NULL ) {
  4490. //
  4491. // get each name loaded into this array
  4492. //
  4493. PWSTR Buffer=NULL;
  4494. DWORD KeyLen;
  4495. rc = SceJetGetValue(
  4496. hSectionSmp,
  4497. SCEJET_PREFIX_MATCH_NO_CASE,
  4498. DirName,
  4499. NULL,
  4500. 0,
  4501. &KeyLen,
  4502. NULL,
  4503. 0,
  4504. NULL
  4505. );
  4506. bFirst = TRUE;
  4507. while ( rc == SCESTATUS_SUCCESS ) {
  4508. Buffer = (PWSTR)ScepAlloc(LPTR, (KeyLen+1)*sizeof(WCHAR));
  4509. if ( Buffer == NULL ) {
  4510. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  4511. break;
  4512. }
  4513. rc = SceJetGetValue(
  4514. hSectionSmp,
  4515. SCEJET_CURRENT,
  4516. NULL,
  4517. Buffer,
  4518. KeyLen*sizeof(WCHAR),
  4519. NULL,
  4520. NULL,
  4521. 0,
  4522. NULL
  4523. );
  4524. if ( rc == SCESTATUS_SUCCESS ) {
  4525. if ( !bFirst ||
  4526. _wcsicmp(DirName, Buffer) != 0 ) {
  4527. //
  4528. // ignore the object itself
  4529. //
  4530. pSmpNames[index] = Buffer;
  4531. pSmpNameLen[index] = wcslen(Buffer);
  4532. Buffer = NULL;
  4533. index++;
  4534. }
  4535. bFirst = FALSE;
  4536. } else {
  4537. ScepFree(Buffer);
  4538. Buffer = NULL;
  4539. break;
  4540. }
  4541. //
  4542. // read next line
  4543. //
  4544. rc = SceJetGetValue(
  4545. hSectionSmp,
  4546. SCEJET_NEXT_LINE,
  4547. NULL,
  4548. NULL,
  4549. 0,
  4550. &KeyLen,
  4551. NULL,
  4552. 0,
  4553. NULL
  4554. );
  4555. }
  4556. } else {
  4557. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  4558. }
  4559. }
  4560. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  4561. rc = SCESTATUS_SUCCESS;
  4562. }
  4563. if ( SCESTATUS_SUCCESS == rc ) {
  4564. //
  4565. // should have one or more children but if it's 0
  4566. // delete everything in SAP
  4567. //
  4568. if ( cntNames == 0 || pSmpNames == NULL ||
  4569. pSmpNameLen == NULL ||
  4570. pSmpNameLen[0] == 0 || pSmpNames[0] == NULL ) {
  4571. rc = SceJetDelete(
  4572. hSectionSap,
  4573. DirName,
  4574. TRUE,
  4575. SCEJET_DELETE_PARTIAL_NO_CASE
  4576. );
  4577. } else if ( !bChangeStatusOnly ) {
  4578. //
  4579. // get each name loaded into this array
  4580. //
  4581. PWSTR Buffer=NULL;
  4582. DWORD KeyLen;
  4583. rc = SceJetGetValue(
  4584. hSectionSap,
  4585. SCEJET_PREFIX_MATCH_NO_CASE,
  4586. DirName,
  4587. NULL,
  4588. 0,
  4589. &KeyLen,
  4590. NULL,
  4591. 0,
  4592. NULL
  4593. );
  4594. bFirst = TRUE;
  4595. index = 0;
  4596. while ( rc == SCESTATUS_SUCCESS ) {
  4597. Buffer = (PWSTR)ScepAlloc(LPTR, (KeyLen+1)*sizeof(WCHAR));
  4598. if ( Buffer == NULL ) {
  4599. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  4600. break;
  4601. }
  4602. rc = SceJetGetValue(
  4603. hSectionSap,
  4604. SCEJET_CURRENT,
  4605. NULL,
  4606. Buffer,
  4607. KeyLen*sizeof(WCHAR),
  4608. NULL,
  4609. NULL,
  4610. 0,
  4611. NULL
  4612. );
  4613. if ( rc == SCESTATUS_SUCCESS &&
  4614. (!bFirst ||
  4615. _wcsicmp(DirName, Buffer) != 0) ) {
  4616. //
  4617. // ignore the object itself
  4618. // compare with the next child in SMP
  4619. // if it's before the next child, should delete it
  4620. //
  4621. int ci = _wcsnicmp(Buffer, pSmpNames[index], pSmpNameLen[index]);
  4622. while ( rc == SCESTATUS_SUCCESS &&
  4623. ci > 0 ) {
  4624. //
  4625. // this is the component or next one, move on to next one
  4626. //
  4627. index++;
  4628. if ( index >= cntNames || pSmpNames[index] == NULL ||
  4629. pSmpNameLen[index] == 0 ) {
  4630. //
  4631. // no more SMP child. We are done.
  4632. //
  4633. rc = SCESTATUS_RECORD_NOT_FOUND;
  4634. } else {
  4635. //
  4636. // already bigger than this child
  4637. //
  4638. ci = _wcsnicmp(Buffer, pSmpNames[index], pSmpNameLen[index]);
  4639. }
  4640. }
  4641. if ( ci < 0 ) {
  4642. SceJetDelete(
  4643. hSectionSap,
  4644. NULL, // delete the current line
  4645. FALSE,
  4646. SCEJET_DELETE_LINE
  4647. );
  4648. }
  4649. }
  4650. bFirst = FALSE;
  4651. ScepFree(Buffer);
  4652. Buffer = NULL;
  4653. if ( rc == SCESTATUS_SUCCESS ) {
  4654. //
  4655. // read next line
  4656. //
  4657. rc = SceJetGetValue(
  4658. hSectionSap,
  4659. SCEJET_NEXT_LINE,
  4660. NULL,
  4661. NULL,
  4662. 0,
  4663. &KeyLen,
  4664. NULL,
  4665. 0,
  4666. NULL
  4667. );
  4668. }
  4669. }
  4670. }
  4671. }
  4672. //
  4673. // raise SAP entries for branch nodes between ObjectName and
  4674. // SMP names as Status, then free smp names array
  4675. //
  4676. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  4677. rc = SCESTATUS_SUCCESS;
  4678. }
  4679. SCESTATUS rc2 = rc;
  4680. INT StartLevel=0, EndLevel=0;
  4681. if ( pSmpNames ) {
  4682. ScepObjectTotalLevel(ObjectName, Delim, &StartLevel);
  4683. StartLevel++;
  4684. for ( index=0; index<cntNames; index++) {
  4685. if ( pSmpNames[index] ) {
  4686. if ( SCESTATUS_SUCCESS == rc2 ) {
  4687. //
  4688. // get this object level
  4689. //
  4690. ScepObjectTotalLevel(pSmpNames[index], Delim, &EndLevel);
  4691. rc2 = ScepObjectRaiseNodesInPath(
  4692. hSectionSap,
  4693. pSmpNames[index],
  4694. pSmpNameLen[index],
  4695. StartLevel,
  4696. EndLevel,
  4697. Delim,
  4698. Status
  4699. );
  4700. if ( rc2 == SCESTATUS_RECORD_NOT_FOUND ) {
  4701. rc2 = SCESTATUS_SUCCESS;
  4702. }
  4703. if ( rc2 != SCESTATUS_SUCCESS ) {
  4704. rc = rc2;
  4705. }
  4706. }
  4707. ScepFree(pSmpNames[index]);
  4708. }
  4709. }
  4710. ScepFree(pSmpNames);
  4711. }
  4712. if ( pSmpNameLen ) {
  4713. ScepFree(pSmpNameLen);
  4714. }
  4715. ScepFree(DirName);
  4716. return rc;
  4717. }
  4718. SCESTATUS
  4719. ScepGetFullNameInLevel(
  4720. IN PCWSTR ObjectFullName,
  4721. IN DWORD Level,
  4722. IN WCHAR Delim,
  4723. IN BOOL bWithLastDelim,
  4724. OUT PWSTR Buffer,
  4725. OUT PBOOL LastOne
  4726. )
  4727. /* ++
  4728. Routine Description:
  4729. This routine parses a full path name and returns the component for the
  4730. level. For example, a object name "c:\winnt\system32" will return c: for
  4731. level 1, winnt for level 2, and system32 for level 3. This routine is
  4732. used when add a object to the security tree.
  4733. Arguments:
  4734. ObjectFullName - The full path name of the object
  4735. Level - the level of component to return
  4736. Delim - the deliminator to look for
  4737. Buffer - The address of buffer for the full path name to the level
  4738. LastOne - Flag to indicate if the component is the last one
  4739. Return value:
  4740. SCESTATUS
  4741. -- */
  4742. {
  4743. PWSTR pTemp, pStart;
  4744. DWORD i;
  4745. ULONG Len = 0;
  4746. if ( ObjectFullName == NULL )
  4747. return(SCESTATUS_INVALID_PARAMETER);
  4748. //
  4749. // loop through the object name to find the level
  4750. // if there is no such level, return INVALID_PARAMETER
  4751. //
  4752. pStart = (PWSTR)ObjectFullName;
  4753. for ( i=0; i<Level; i++) {
  4754. pTemp = wcschr(pStart, Delim);
  4755. if ( i == Level-1 ) {
  4756. //
  4757. // find the right level
  4758. //
  4759. if ( pTemp == NULL ) {
  4760. wcscpy(Buffer, ObjectFullName);
  4761. if ( bWithLastDelim ) {
  4762. Len = wcslen(ObjectFullName);
  4763. if (Buffer[Len - 1] != Delim)
  4764. Buffer[Len] = Delim;
  4765. }
  4766. *LastOne = TRUE;
  4767. } else {
  4768. Len = (DWORD)(pTemp - ObjectFullName);
  4769. if ( bWithLastDelim ) {
  4770. Len++;
  4771. }
  4772. wcsncpy(Buffer, ObjectFullName, Len);
  4773. if ( *(pTemp+1) == L'\0' )
  4774. *LastOne = TRUE;
  4775. else
  4776. *LastOne = FALSE;
  4777. }
  4778. } else {
  4779. if ( pTemp == NULL )
  4780. return(SCESTATUS_INVALID_PARAMETER);
  4781. else
  4782. pStart = pTemp + 1;
  4783. }
  4784. }
  4785. return(SCESTATUS_SUCCESS);
  4786. }
  4787. SCESTATUS
  4788. ScepUpdateLocalTable(
  4789. IN PSCECONTEXT hProfile,
  4790. IN AREA_INFORMATION Area,
  4791. IN PSCE_PROFILE_INFO pInfo,
  4792. IN DWORD dwMode
  4793. )
  4794. {
  4795. SCESTATUS rc=SCESTATUS_SUCCESS;
  4796. if ( Area & AREA_SECURITY_POLICY ) {
  4797. rc = ScepUpdateSystemAccess(hProfile,
  4798. pInfo,
  4799. NULL,
  4800. NULL,
  4801. dwMode
  4802. );
  4803. if ( rc == SCESTATUS_SUCCESS) {
  4804. //
  4805. // Update system auditing section
  4806. //
  4807. rc = ScepUpdateSystemAuditing(hProfile,
  4808. pInfo,
  4809. NULL,
  4810. NULL,
  4811. dwMode);
  4812. if ( rc == SCESTATUS_SUCCESS) {
  4813. //
  4814. // Update log sections
  4815. //
  4816. rc = ScepUpdateLogs(hProfile,
  4817. pInfo,
  4818. NULL,
  4819. NULL,
  4820. dwMode
  4821. );
  4822. if ( rc == SCESTATUS_SUCCESS && pInfo->pKerberosInfo ) {
  4823. //
  4824. // Update kerberos policy
  4825. //
  4826. rc = ScepUpdateKerberos(hProfile,
  4827. pInfo->pKerberosInfo,
  4828. NULL,
  4829. NULL,
  4830. dwMode
  4831. );
  4832. }
  4833. if ( rc == SCESTATUS_SUCCESS ) {
  4834. //
  4835. // update registry values
  4836. //
  4837. rc = ScepUpdateLocalRegValues(hProfile,
  4838. pInfo,
  4839. dwMode
  4840. );
  4841. }
  4842. //
  4843. // Note: policy attachment is not updated through this API
  4844. //
  4845. }
  4846. }
  4847. if ( rc != SCESTATUS_SUCCESS ) {
  4848. return(rc);
  4849. }
  4850. }
  4851. if ( Area & AREA_PRIVILEGES ) {
  4852. //
  4853. // update user rights
  4854. //
  4855. rc = ScepUpdateLocalPrivileges(
  4856. hProfile,
  4857. pInfo->OtherInfo.smp.pPrivilegeAssignedTo,
  4858. dwMode
  4859. );
  4860. }
  4861. return rc;
  4862. }
  4863. SCESTATUS
  4864. ScepUpdateLocalSection(
  4865. IN PSCECONTEXT hProfile,
  4866. IN PSCE_PROFILE_INFO pInfo,
  4867. IN SCE_KEY_LOOKUP *Keys,
  4868. IN DWORD cKeys,
  4869. IN PCWSTR SectionName,
  4870. IN DWORD dwMode
  4871. )
  4872. /*
  4873. Routine Description:
  4874. Update each key in the Keys array based on the editing rule. SMP entry is
  4875. updated with the new value. SAP entry is either deleted, or created, depending
  4876. on the new computed analysis status.
  4877. Arguements:
  4878. hProfile - the jet database handle
  4879. pInfo - the changed info buffer
  4880. Keys - the lookup keys array
  4881. cKeys - the number of keys in the array
  4882. SecitonName - the section name to work on
  4883. Return Value:
  4884. SCESTATUS
  4885. */
  4886. {
  4887. SCESTATUS rc;
  4888. PSCESECTION hSectionSmp=NULL;
  4889. DWORD i;
  4890. UINT Offset;
  4891. DWORD val;
  4892. //
  4893. // open smp section for system access
  4894. //
  4895. rc = ScepOpenSectionForName(
  4896. hProfile,
  4897. SCE_ENGINE_SMP,
  4898. SectionName,
  4899. &hSectionSmp
  4900. );
  4901. if ( rc == SCESTATUS_SUCCESS ) {
  4902. if ( !( dwMode & SCE_UPDATE_DIRTY_ONLY) ) {
  4903. SceJetDelete(hSectionSmp, NULL, FALSE, SCEJET_DELETE_SECTION);
  4904. }
  4905. for ( i=0; i<cKeys; i++) {
  4906. //
  4907. // get settings in AccessLookup table
  4908. //
  4909. Offset = Keys[i].Offset;
  4910. switch ( Keys[i].BufferType ) {
  4911. case 'B':
  4912. break;
  4913. case 'D':
  4914. val = *((DWORD *)((CHAR *)pInfo+Offset));
  4915. if ( val != SCE_NO_VALUE ) {
  4916. //
  4917. // something changed for this one
  4918. //
  4919. if ( ( dwMode & SCE_UPDATE_DIRTY_ONLY ) &&
  4920. ( val == SCE_DELETE_VALUE ) ) {
  4921. rc = SceJetDelete(
  4922. hSectionSmp,
  4923. Keys[i].KeyString,
  4924. FALSE,
  4925. SCEJET_DELETE_LINE_NO_CASE
  4926. );
  4927. } else {
  4928. //
  4929. // update the SMP entry
  4930. //
  4931. rc = ScepCompareAndSaveIntValue(
  4932. hSectionSmp,
  4933. Keys[i].KeyString,
  4934. FALSE,
  4935. SCE_NO_VALUE,
  4936. val
  4937. );
  4938. }
  4939. if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  4940. //
  4941. // if not find for delete, ignore the error
  4942. //
  4943. rc = SCESTATUS_SUCCESS;
  4944. }
  4945. }
  4946. break;
  4947. default:
  4948. break;
  4949. }
  4950. if ( rc != SCESTATUS_SUCCESS ) {
  4951. break;
  4952. }
  4953. }
  4954. SceJetCloseSection(&hSectionSmp, TRUE);
  4955. }
  4956. return(rc);
  4957. }
  4958. SCESTATUS
  4959. ScepUpdateLocalRegValues(
  4960. IN PSCECONTEXT hProfile,
  4961. IN PSCE_PROFILE_INFO pInfo,
  4962. IN DWORD dwMode
  4963. )
  4964. {
  4965. if ( hProfile == NULL || pInfo == NULL ) {
  4966. return(SCESTATUS_INVALID_PARAMETER);
  4967. }
  4968. if ( pInfo->RegValueCount == 0 ||
  4969. pInfo->aRegValues == NULL ) {
  4970. //
  4971. // impossible to have a empty buffer to update
  4972. // this buffer should contain all available registry values to configure/analyze
  4973. //
  4974. return(SCESTATUS_SUCCESS);
  4975. }
  4976. SCESTATUS rc;
  4977. PSCESECTION hSectionSmp=NULL;
  4978. DWORD i;
  4979. //
  4980. // open smp section for system access
  4981. //
  4982. rc = ScepOpenSectionForName(
  4983. hProfile,
  4984. SCE_ENGINE_SMP,
  4985. szRegistryValues,
  4986. &hSectionSmp
  4987. );
  4988. if ( rc == SCESTATUS_SUCCESS ) {
  4989. if ( !(dwMode & SCE_UPDATE_DIRTY_ONLY) ) {
  4990. SceJetDelete(hSectionSmp, NULL, FALSE, SCEJET_DELETE_SECTION);
  4991. }
  4992. for (i=0; i<pInfo->RegValueCount; i++ ) {
  4993. if ( !(pInfo->aRegValues[i].FullValueName) ) {
  4994. continue;
  4995. }
  4996. if ( ( dwMode & SCE_UPDATE_DIRTY_ONLY) &&
  4997. (pInfo->aRegValues[i].ValueType == SCE_DELETE_VALUE) ) {
  4998. rc = SceJetDelete(
  4999. hSectionSmp,
  5000. pInfo->aRegValues[i].FullValueName,
  5001. FALSE,
  5002. SCEJET_DELETE_LINE_NO_CASE
  5003. );
  5004. } else {
  5005. //
  5006. // update the SMP entry
  5007. //
  5008. rc = ScepSaveRegValueEntry(
  5009. hSectionSmp,
  5010. pInfo->aRegValues[i].FullValueName,
  5011. pInfo->aRegValues[i].Value,
  5012. pInfo->aRegValues[i].ValueType,
  5013. 0
  5014. );
  5015. }
  5016. if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  5017. //
  5018. // if not find for delete, ignore the error
  5019. //
  5020. rc = SCESTATUS_SUCCESS;
  5021. }
  5022. if ( SCESTATUS_SUCCESS != rc ) {
  5023. break;
  5024. }
  5025. }
  5026. SceJetCloseSection(&hSectionSmp, TRUE);
  5027. }
  5028. return(rc);
  5029. }
  5030. SCESTATUS
  5031. ScepUpdateLocalPrivileges(
  5032. IN PSCECONTEXT hProfile,
  5033. IN PSCE_PRIVILEGE_ASSIGNMENT pNewPriv,
  5034. IN DWORD dwMode
  5035. )
  5036. /*
  5037. Routine Description:
  5038. Update privileges
  5039. Arguements:
  5040. hProfile - the jet database handle
  5041. pNewPriv - the changed info buffer
  5042. pBufScep - the original SMP priv buffer
  5043. Return Value:
  5044. SCESTATUS
  5045. */
  5046. {
  5047. if ( hProfile == NULL ) {
  5048. return(SCESTATUS_INVALID_PARAMETER);
  5049. }
  5050. LSA_HANDLE LsaHandle=NULL;
  5051. SCESTATUS rc;
  5052. rc = RtlNtStatusToDosError(
  5053. ScepOpenLsaPolicy(
  5054. MAXIMUM_ALLOWED,
  5055. &LsaHandle,
  5056. TRUE
  5057. ));
  5058. if ( ERROR_SUCCESS != rc ) {
  5059. return(ScepDosErrorToSceStatus(rc));
  5060. }
  5061. PSCESECTION hSectionSmp=NULL;
  5062. //
  5063. // open smp section for system access
  5064. //
  5065. rc = ScepOpenSectionForName(
  5066. hProfile,
  5067. SCE_ENGINE_SMP,
  5068. szPrivilegeRights,
  5069. &hSectionSmp
  5070. );
  5071. if ( rc == SCESTATUS_SUCCESS ) {
  5072. if ( !(dwMode & SCE_UPDATE_DIRTY_ONLY) ) {
  5073. SceJetDelete(hSectionSmp, NULL, FALSE, SCEJET_DELETE_SECTION);
  5074. }
  5075. PSCE_PRIVILEGE_ASSIGNMENT pPriv;
  5076. for ( pPriv=pNewPriv; pPriv != NULL; pPriv = pPriv->Next ) {
  5077. //
  5078. // Process each privilege in the new list
  5079. //
  5080. if ( pPriv->Name == NULL ) {
  5081. continue;
  5082. }
  5083. if ( ( dwMode & SCE_UPDATE_DIRTY_ONLY) &&
  5084. ( pPriv->Status == SCE_DELETE_VALUE) ) {
  5085. rc = SceJetDelete(
  5086. hSectionSmp,
  5087. pPriv->Name,
  5088. FALSE,
  5089. SCEJET_DELETE_LINE_NO_CASE
  5090. );
  5091. } else {
  5092. rc = ScepWriteNameListValue(
  5093. LsaHandle,
  5094. hSectionSmp,
  5095. pPriv->Name,
  5096. pPriv->AssignedTo,
  5097. SCE_WRITE_EMPTY_LIST | SCE_WRITE_CONVERT | SCE_WRITE_LOCAL_TABLE,
  5098. 0
  5099. );
  5100. }
  5101. if ( rc == SCESTATUS_RECORD_NOT_FOUND )
  5102. rc = SCESTATUS_SUCCESS;
  5103. if ( rc != SCESTATUS_SUCCESS) {
  5104. break;
  5105. }
  5106. }
  5107. SceJetCloseSection(&hSectionSmp, TRUE);
  5108. }
  5109. if ( LsaHandle ) {
  5110. LsaClose(LsaHandle);
  5111. }
  5112. return(rc);
  5113. }
  5114. DWORD
  5115. ScepConvertNameListFormat(
  5116. IN LSA_HANDLE LsaHandle,
  5117. IN PSCE_NAME_LIST pInList,
  5118. IN DWORD FromFormat,
  5119. IN DWORD ToFormat,
  5120. OUT PSCE_NAME_LIST *ppOutList
  5121. )
  5122. {
  5123. if (LsaHandle == NULL || ppOutList == NULL ) {
  5124. return(ERROR_INVALID_PARAMETER);
  5125. }
  5126. *ppOutList = NULL;
  5127. PSCE_NAME_LIST pList;
  5128. DWORD rc = ERROR_SUCCESS;
  5129. PWSTR SidString=NULL;
  5130. for ( pList=pInList; pList != NULL; pList=pList->Next ) {
  5131. if ( pList->Name == NULL ) {
  5132. continue;
  5133. }
  5134. if ( wcschr(pList->Name, L'\\') ) {
  5135. rc = ScepLookupNameAndAddToSidStringList(
  5136. LsaHandle,
  5137. ppOutList,
  5138. pList->Name,
  5139. wcslen(pList->Name)
  5140. );
  5141. } else if ( ScepLookupNameTable( pList->Name, &SidString ) ) {
  5142. rc = ScepAddTwoNamesToNameList(
  5143. ppOutList,
  5144. FALSE,
  5145. NULL,
  5146. 0,
  5147. SidString,
  5148. wcslen(SidString)
  5149. );
  5150. } else {
  5151. rc = ScepAddToNameList(ppOutList, pList->Name, 0);
  5152. }
  5153. if ( rc != ERROR_SUCCESS ) {
  5154. break;
  5155. }
  5156. }
  5157. if ( rc != ERROR_SUCCESS &&
  5158. (*ppOutList ) ) {
  5159. ScepFreeNameList(*ppOutList);
  5160. *ppOutList = NULL;
  5161. }
  5162. return(rc);
  5163. }
  5164. DWORD
  5165. ScepConvertPrivilegeList(
  5166. IN LSA_HANDLE LsaHandle,
  5167. IN PSCE_PRIVILEGE_ASSIGNMENT pFromList,
  5168. IN DWORD FromFormat,
  5169. IN DWORD ToFormat,
  5170. OUT PSCE_PRIVILEGE_ASSIGNMENT *ppToList
  5171. )
  5172. {
  5173. if ( LsaHandle == NULL || pFromList == NULL || ppToList == NULL ) {
  5174. return(ERROR_INVALID_PARAMETER);
  5175. }
  5176. if ( FromFormat != 0 ||
  5177. ToFormat != SCE_ACCOUNT_SID_STRING ) {
  5178. return(ERROR_NOT_SUPPORTED);
  5179. }
  5180. //
  5181. // only support name->sid string convert, for now.
  5182. //
  5183. DWORD rc = ERROR_SUCCESS;
  5184. PSCE_PRIVILEGE_ASSIGNMENT pPriv, pPriv2;
  5185. PSCE_NAME_LIST pTempList=NULL;
  5186. for ( pPriv=pFromList; pPriv != NULL; pPriv=pPriv->Next ) {
  5187. if ( pPriv->Name == NULL ) {
  5188. continue;
  5189. }
  5190. rc = ScepConvertNameListFormat(LsaHandle,
  5191. pPriv->AssignedTo,
  5192. FromFormat,
  5193. ToFormat,
  5194. &pTempList
  5195. );
  5196. if ( rc != ERROR_SUCCESS ) {
  5197. break;
  5198. }
  5199. //
  5200. // a sce_privilege_assignment structure. allocate buffer
  5201. //
  5202. pPriv2 = (PSCE_PRIVILEGE_ASSIGNMENT)ScepAlloc( LMEM_ZEROINIT,
  5203. sizeof(SCE_PRIVILEGE_ASSIGNMENT) );
  5204. if ( pPriv2 == NULL ) {
  5205. rc = ERROR_NOT_ENOUGH_MEMORY;
  5206. break;
  5207. }
  5208. pPriv2->Name = (PWSTR)ScepAlloc( (UINT)0, (wcslen(pPriv->Name)+1)*sizeof(WCHAR));
  5209. if ( pPriv2->Name == NULL ) {
  5210. ScepFree(pPriv2);
  5211. rc = ERROR_NOT_ENOUGH_MEMORY;
  5212. break;
  5213. }
  5214. wcscpy(pPriv2->Name, pPriv->Name);
  5215. pPriv2->Value = pPriv->Value;
  5216. pPriv2->Status = pPriv->Status;
  5217. pPriv2->AssignedTo = pTempList;
  5218. pTempList = NULL;
  5219. pPriv2->Next = *ppToList;
  5220. *ppToList = pPriv2;
  5221. }
  5222. if ( pTempList ) {
  5223. ScepFreeNameList(pTempList);
  5224. }
  5225. if ( rc != ERROR_SUCCESS &&
  5226. (*ppToList) ) {
  5227. //
  5228. // free the output list
  5229. //
  5230. ScepFreePrivilege(*ppToList);
  5231. *ppToList = NULL;
  5232. }
  5233. return(rc);
  5234. }