Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

6430 lines
186 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 ( ScepLookupWellKnownName(
  2101. pGroup->GroupName,
  2102. LsaHandle,
  2103. &SidString ) ) {
  2104. NameLen = wcslen(SidString);
  2105. } else {
  2106. SidString = NULL;
  2107. }
  2108. }
  2109. if ( SidString == NULL ) {
  2110. NameLen = wcslen(pGroup->GroupName);
  2111. }
  2112. KeyName = (PWSTR)ScepAlloc(LMEM_FIXED | LMEM_ZEROINIT,
  2113. (NameLen+MemberofLen+1)*sizeof(WCHAR));
  2114. if ( KeyName == NULL ) {
  2115. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  2116. } else {
  2117. //
  2118. // look for the matched SMP
  2119. //
  2120. for ( pNode=*pScepGroup, pParent=NULL; pNode != NULL;
  2121. pParent = pNode, pNode = pNode->Next ) {
  2122. if ( _wcsicmp(pGroup->GroupName, pNode->GroupName) == 0 ) {
  2123. break;
  2124. }
  2125. }
  2126. if ( !(pGroup->Status & SCE_GROUP_STATUS_NC_MEMBERS) ) {
  2127. //
  2128. // work for members first
  2129. //
  2130. if ( SidString ) {
  2131. swprintf(KeyName, L"%s%s\0", SidString, szMembers);
  2132. } else {
  2133. swprintf(KeyName, L"%s%s\0", pGroup->GroupName, szMembers);
  2134. }
  2135. KeyName = _wcslwr(KeyName);
  2136. rc = ScepUpdateKeyNameList(
  2137. LsaHandle,
  2138. hSectionSmp,
  2139. hSectionSap,
  2140. SidString ? SidString : pGroup->GroupName, // group name
  2141. ( pNode == NULL || (pNode->Status & SCE_GROUP_STATUS_NC_MEMBERS)) ? FALSE : TRUE,
  2142. KeyName,
  2143. NameLen+MembersLen,
  2144. pGroup->pMembers,
  2145. ( pNode == NULL ) ? NULL : pNode->pMembers,
  2146. SCE_FLAG_UPDATE_MEMBERS
  2147. );
  2148. }
  2149. if ( ( rc == SCESTATUS_SUCCESS ) &&
  2150. !(pGroup->Status & SCE_GROUP_STATUS_NC_MEMBERS) ) {
  2151. //
  2152. // work for memberof second
  2153. //
  2154. if ( SidString ) {
  2155. swprintf(KeyName, L"%s%s\0", SidString, szMemberof);
  2156. } else {
  2157. swprintf(KeyName, L"%s%s\0", pGroup->GroupName, szMemberof);
  2158. }
  2159. KeyName = _wcslwr(KeyName);
  2160. rc = ScepUpdateKeyNameList(
  2161. LsaHandle,
  2162. hSectionSmp,
  2163. hSectionSap,
  2164. SidString ? SidString : pGroup->GroupName,
  2165. ( pNode == NULL || (pNode->Status & SCE_GROUP_STATUS_NC_MEMBEROF) ) ? FALSE : TRUE,
  2166. KeyName,
  2167. NameLen+MemberofLen,
  2168. pGroup->pMemberOf,
  2169. ( pNode == NULL ) ? NULL : pNode->pMemberOf,
  2170. SCE_FLAG_UPDATE_MEMBEROF
  2171. );
  2172. }
  2173. ScepFree(KeyName);
  2174. KeyName = NULL;
  2175. }
  2176. if ( SidString ) {
  2177. LocalFree(SidString);
  2178. SidString = NULL;
  2179. }
  2180. if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  2181. rc = SCESTATUS_SUCCESS;
  2182. } else if ( rc != SCESTATUS_SUCCESS) {
  2183. break;
  2184. }
  2185. //
  2186. // remove the SMP node/or portion from pScepPriv
  2187. //
  2188. if ( pNode != NULL ) {
  2189. if ( !(pGroup->Status & SCE_GROUP_STATUS_NC_MEMBERS) &&
  2190. !(pGroup->Status & SCE_GROUP_STATUS_NC_MEMBEROF) ) {
  2191. //
  2192. // both of members and memberof are processed
  2193. // link to the next
  2194. //
  2195. if ( pParent != NULL ) {
  2196. pParent->Next = pNode->Next;
  2197. } else {
  2198. *pScepGroup = pNode->Next;
  2199. }
  2200. //
  2201. // delete this node
  2202. //
  2203. ScepFreeNameList(pNode->pMembers);
  2204. ScepFreeNameList(pNode->pMemberOf);
  2205. ScepFreeNameStatusList(pNode->pPrivilegesHeld);
  2206. ScepFree(pNode->GroupName);
  2207. ScepFree(pNode);
  2208. pNode = NULL;
  2209. } else {
  2210. if (!(pGroup->Status & SCE_GROUP_STATUS_NC_MEMBERS) ) {
  2211. pNode->Status |= SCE_GROUP_STATUS_NC_MEMBERS;
  2212. ScepFreeNameList(pNode->pMembers);
  2213. pNode->pMembers = NULL;
  2214. }
  2215. if ( !(pGroup->Status & SCE_GROUP_STATUS_NC_MEMBEROF) ) {
  2216. pNode->Status |= SCE_GROUP_STATUS_NC_MEMBEROF;
  2217. ScepFreeNameList(pNode->pMemberOf);
  2218. pNode->pMemberOf = NULL;
  2219. }
  2220. }
  2221. }
  2222. }
  2223. //
  2224. // delete remaining SMP entries, do not care error code
  2225. //
  2226. if ( rc == SCESTATUS_SUCCESS ) {
  2227. for (pNode=*pScepGroup; pNode != NULL; pNode = pNode->Next ) {
  2228. //
  2229. // raise SAP if it's not there
  2230. //
  2231. if ( pNode->GroupName == NULL ) {
  2232. continue;
  2233. }
  2234. if ( (pNode->Status & SCE_GROUP_STATUS_NC_MEMBERS) &&
  2235. (pNode->Status & SCE_GROUP_STATUS_NC_MEMBEROF) ) {
  2236. continue;
  2237. }
  2238. if ( wcschr(pNode->GroupName, L'\\') ) {
  2239. //
  2240. // this is in account domain format, convert it to sid string
  2241. //
  2242. NameLen = 0;
  2243. ScepConvertNameToSidString(
  2244. LsaHandle,
  2245. pNode->GroupName,
  2246. FALSE,
  2247. &SidString,
  2248. &NameLen
  2249. );
  2250. } else {
  2251. if ( ScepLookupWellKnownName(
  2252. pNode->GroupName,
  2253. LsaHandle,
  2254. &SidString ) ) {
  2255. NameLen = wcslen(SidString);
  2256. } else {
  2257. SidString = NULL;
  2258. }
  2259. }
  2260. if ( SidString == NULL ) {
  2261. NameLen = wcslen(pNode->GroupName);
  2262. }
  2263. KeyName = (PWSTR)ScepAlloc(LMEM_FIXED | LMEM_ZEROINIT,
  2264. (NameLen+MemberofLen+1)*sizeof(WCHAR));
  2265. if ( KeyName == NULL ) {
  2266. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  2267. } else {
  2268. BOOL bSapError=FALSE;
  2269. if ( SidString ) {
  2270. swprintf(KeyName, L"%s%s\0", SidString, szMembers);
  2271. } else {
  2272. swprintf(KeyName, L"%s%s\0", pNode->GroupName, szMembers);
  2273. }
  2274. if ( !(pNode->Status & SCE_GROUP_STATUS_NC_MEMBERS) ) {
  2275. //
  2276. // members configuration has to be deleted.
  2277. //
  2278. rc = SceJetDelete(
  2279. hSectionSmp,
  2280. KeyName,
  2281. FALSE,
  2282. SCEJET_DELETE_LINE_NO_CASE
  2283. );
  2284. }
  2285. if ( SCESTATUS_SUCCESS == rc ) {
  2286. rc = ScepQueryAnalysisStatus(hSectionSap,
  2287. KeyName,
  2288. NameLen+MembersLen
  2289. );
  2290. if ( rc == SCE_STATUS_NOT_ANALYZED ||
  2291. rc == SCE_STATUS_ERROR_NOT_AVAILABLE ) {
  2292. //
  2293. // the entire group is analyzed with error
  2294. // or the group is new added
  2295. //
  2296. if ( !(pNode->Status & SCE_GROUP_STATUS_NC_MEMBERS) &&
  2297. !(pNode->Status & SCE_GROUP_STATUS_NC_MEMBEROF) ) {
  2298. //
  2299. // the SAP should be removed because both members and
  2300. // memberof are deleted
  2301. //
  2302. rc = SceJetDelete(
  2303. hSectionSap,
  2304. SidString ? SidString : pNode->GroupName,
  2305. FALSE,
  2306. SCEJET_DELETE_PARTIAL_NO_CASE
  2307. );
  2308. } else {
  2309. // else leave the SAP stuff there.
  2310. rc = SCESTATUS_SUCCESS;
  2311. }
  2312. bSapError = TRUE;
  2313. } else {
  2314. if ( !(pNode->Status & SCE_GROUP_STATUS_NC_MEMBERS) ) {
  2315. if ( rc == SCE_STATUS_GOOD ) {
  2316. //
  2317. // SAP doesn't exist, this is a match group members
  2318. // remove SMP means this group becomes not configured
  2319. //
  2320. rc = ScepWriteNameListValue(
  2321. LsaHandle,
  2322. hSectionSap,
  2323. KeyName,
  2324. pNode->pMembers,
  2325. SCE_WRITE_EMPTY_LIST | SCE_WRITE_CONVERT,
  2326. 0
  2327. );
  2328. } else {
  2329. //
  2330. // it's already mismatched. do nothing to SAP table
  2331. //
  2332. rc = SCESTATUS_SUCCESS;
  2333. }
  2334. } else {
  2335. rc = SCESTATUS_SUCCESS;
  2336. }
  2337. }
  2338. }
  2339. if ( SCESTATUS_SUCCESS == rc ) {
  2340. //
  2341. // continue to process memberof
  2342. //
  2343. if ( !(pNode->Status & SCE_GROUP_STATUS_NC_MEMBEROF) ) {
  2344. if ( SidString ) {
  2345. swprintf(KeyName, L"%s%s\0", SidString, szMemberof);
  2346. } else {
  2347. swprintf(KeyName, L"%s%s\0", pNode->GroupName, szMemberof);
  2348. }
  2349. //
  2350. // delete configuration
  2351. //
  2352. rc = SceJetDelete(
  2353. hSectionSmp,
  2354. KeyName,
  2355. FALSE,
  2356. SCEJET_DELETE_LINE_NO_CASE
  2357. );
  2358. if ( (SCESTATUS_SUCCESS == rc) && !bSapError ) {
  2359. rc = SceJetSeek(
  2360. hSectionSap,
  2361. KeyName,
  2362. (NameLen+MemberofLen)*sizeof(WCHAR),
  2363. SCEJET_SEEK_EQ_NO_CASE
  2364. );
  2365. if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  2366. //
  2367. // SAP doesn't exist, this is a match group membership
  2368. // remove SMP means membership becomes "not configured"
  2369. //
  2370. rc = ScepWriteNameListValue(
  2371. LsaHandle,
  2372. hSectionSap,
  2373. KeyName,
  2374. pNode->pMemberOf,
  2375. SCE_WRITE_EMPTY_LIST | SCE_WRITE_CONVERT,
  2376. 0
  2377. );
  2378. } else {
  2379. //
  2380. // a mismatch item already
  2381. //
  2382. }
  2383. }
  2384. }
  2385. }
  2386. ScepFree(KeyName);
  2387. KeyName = NULL;
  2388. }
  2389. if ( SidString ) {
  2390. LocalFree(SidString);
  2391. SidString = NULL;
  2392. }
  2393. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  2394. rc = SCESTATUS_SUCCESS;
  2395. }
  2396. if ( rc != SCESTATUS_SUCCESS ) {
  2397. break;
  2398. }
  2399. }
  2400. }
  2401. SceJetCloseSection(&hSectionSap, TRUE);
  2402. }
  2403. SceJetCloseSection(&hSectionSmp, TRUE);
  2404. }
  2405. if ( LsaHandle ) {
  2406. LsaClose(LsaHandle);
  2407. }
  2408. return(rc);
  2409. }
  2410. SCESTATUS
  2411. ScepUpdateGeneralServices(
  2412. IN PSCECONTEXT hProfile,
  2413. IN PSCE_SERVICES pNewServices,
  2414. IN PSCE_SERVICES *pScepServices
  2415. )
  2416. /*
  2417. Routine Description:
  2418. Update general services section
  2419. Arguements:
  2420. hProfile - the jet database handle
  2421. pNewServices - the new server list
  2422. pScepServices - the original SMP service list
  2423. Return Value:
  2424. SCESTATUS
  2425. */
  2426. {
  2427. SCESTATUS rc;
  2428. PSCESECTION hSectionSmp=NULL;
  2429. PSCESECTION hSectionSap=NULL;
  2430. PSCE_SERVICES pService, pNode, pParent;
  2431. PSCE_SERVICES pSapService=NULL;
  2432. BOOL IsDifferent;
  2433. if ( pScepServices == NULL ) {
  2434. return(SCESTATUS_INVALID_PARAMETER);
  2435. }
  2436. if ( pNewServices == NULL && *pScepServices == NULL ) {
  2437. return(SCESTATUS_SUCCESS);
  2438. }
  2439. //
  2440. // open smp section for system access
  2441. //
  2442. rc = ScepOpenSectionForName(
  2443. hProfile,
  2444. SCE_ENGINE_SMP,
  2445. szServiceGeneral,
  2446. &hSectionSmp
  2447. );
  2448. if ( rc == SCESTATUS_SUCCESS ) {
  2449. //
  2450. // open sap section for system access
  2451. //
  2452. rc = ScepOpenSectionForName(
  2453. hProfile,
  2454. SCE_ENGINE_SAP,
  2455. szServiceGeneral,
  2456. &hSectionSap
  2457. );
  2458. if ( rc == SCESTATUS_SUCCESS ) {
  2459. for ( pService=pNewServices; pService != NULL; pService = pService->Next ) {
  2460. //
  2461. // look for the matched SMP
  2462. //
  2463. for ( pNode=*pScepServices, pParent=NULL; pNode != NULL;
  2464. pParent = pNode, pNode = pNode->Next ) {
  2465. if ( _wcsicmp(pService->ServiceName, pNode->ServiceName) == 0 ) {
  2466. break;
  2467. }
  2468. }
  2469. //
  2470. // get Sap
  2471. //
  2472. rc = ScepGetSingleServiceSetting(
  2473. hSectionSap,
  2474. pService->ServiceName,
  2475. &pSapService
  2476. );
  2477. if ( rc == SCESTATUS_SUCCESS ) {
  2478. //
  2479. // old status is mismatch, error, no not analyzed for this item
  2480. //
  2481. if ( pSapService &&
  2482. ( pSapService->Status == SCE_STATUS_NOT_ANALYZED ||
  2483. pSapService->Status == SCE_STATUS_ERROR_NOT_AVAILABLE ) ) {
  2484. // do not change SAP
  2485. } else {
  2486. rc = ScepCompareSingleServiceSetting(
  2487. pService,
  2488. pSapService,
  2489. &IsDifferent
  2490. );
  2491. if ( rc == SCESTATUS_SUCCESS ) {
  2492. if ( !IsDifferent ) {
  2493. //
  2494. // now it is matched, delete the SAP entry
  2495. //
  2496. SceJetDelete(
  2497. hSectionSap,
  2498. pService->ServiceName,
  2499. FALSE,
  2500. SCEJET_DELETE_LINE_NO_CASE
  2501. );
  2502. }
  2503. }
  2504. }
  2505. if ( SCESTATUS_SUCCESS == rc ) {
  2506. //
  2507. // update the SMP entry
  2508. //
  2509. rc = ScepSetSingleServiceSetting(
  2510. hSectionSmp,
  2511. pService
  2512. );
  2513. }
  2514. SceFreePSCE_SERVICES(pSapService);
  2515. pSapService = NULL;
  2516. } else if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  2517. //
  2518. // old status is matched or new added
  2519. //
  2520. if ( pNode == NULL ) {
  2521. //
  2522. // new added, add SMP first
  2523. //
  2524. rc = ScepSetSingleServiceSetting(
  2525. hSectionSmp,
  2526. pService
  2527. );
  2528. if ( rc == SCESTATUS_SUCCESS) {
  2529. pService->Status = SCE_STATUS_NOT_ANALYZED;
  2530. //
  2531. // raise SAP
  2532. //
  2533. rc = ScepSetSingleServiceSetting(
  2534. hSectionSap,
  2535. pService
  2536. );
  2537. }
  2538. } else {
  2539. rc = ScepCompareSingleServiceSetting(
  2540. pService,
  2541. pNode,
  2542. &IsDifferent
  2543. );
  2544. if ( rc == SCESTATUS_SUCCESS ) {
  2545. if ( IsDifferent ) {
  2546. //
  2547. // mismatch should be raised with valScep
  2548. //
  2549. pNode->Status = SCE_STATUS_MISMATCH;
  2550. rc = ScepSetSingleServiceSetting(
  2551. hSectionSap,
  2552. pNode
  2553. );
  2554. if ( rc == SCESTATUS_SUCCESS) {
  2555. //
  2556. // update SMP
  2557. //
  2558. rc = ScepSetSingleServiceSetting(
  2559. hSectionSmp,
  2560. pService
  2561. );
  2562. }
  2563. }
  2564. }
  2565. }
  2566. }
  2567. if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  2568. rc = SCESTATUS_SUCCESS;
  2569. } else if ( rc != SCESTATUS_SUCCESS) {
  2570. break;
  2571. }
  2572. //
  2573. // remove the SMP node from old configuration
  2574. //
  2575. if ( pNode != NULL ) {
  2576. //
  2577. // link to the next
  2578. //
  2579. if ( pParent != NULL ) {
  2580. pParent->Next = pNode->Next;
  2581. } else {
  2582. *pScepServices = pNode->Next;
  2583. }
  2584. //
  2585. // delete this node
  2586. //
  2587. ScepFree(pNode->ServiceName);
  2588. if (pNode->General.pSecurityDescriptor)
  2589. ScepFree(pNode->General.pSecurityDescriptor);
  2590. ScepFree(pNode);
  2591. pNode = NULL;
  2592. }
  2593. }
  2594. //
  2595. // delete remaining SMP entries, do not care error code
  2596. //
  2597. if ( rc == SCESTATUS_SUCCESS ) {
  2598. for (pNode=*pScepServices; pNode != NULL; pNode = pNode->Next ) {
  2599. //
  2600. // first change SAP entry
  2601. //
  2602. rc = SceJetSeek(
  2603. hSectionSap,
  2604. pNode->ServiceName,
  2605. wcslen(pNode->ServiceName)*sizeof(WCHAR),
  2606. SCEJET_SEEK_EQ_NO_CASE
  2607. );
  2608. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  2609. //
  2610. // was a match item
  2611. //
  2612. pNode->Status = SCE_STATUS_NOT_CONFIGURED;
  2613. rc = ScepSetSingleServiceSetting(
  2614. hSectionSap,
  2615. pNode
  2616. );
  2617. }
  2618. if ( rc == SCESTATUS_SUCCESS ||
  2619. rc == SCESTATUS_RECORD_NOT_FOUND ) {
  2620. //
  2621. // delete SMP - it's taken out of the service list
  2622. //
  2623. rc = SceJetDelete(
  2624. hSectionSmp,
  2625. pNode->ServiceName,
  2626. FALSE,
  2627. SCEJET_DELETE_LINE_NO_CASE
  2628. );
  2629. }
  2630. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  2631. rc = SCESTATUS_SUCCESS;
  2632. }
  2633. if ( rc != SCESTATUS_SUCCESS ) {
  2634. break;
  2635. }
  2636. }
  2637. }
  2638. SceJetCloseSection(&hSectionSap, TRUE);
  2639. }
  2640. SceJetCloseSection(&hSectionSmp, TRUE);
  2641. }
  2642. return(rc);
  2643. }
  2644. SCESTATUS
  2645. ScepUpdateObjectInfo(
  2646. IN PSCECONTEXT hProfile,
  2647. IN AREA_INFORMATION Area,
  2648. IN PWSTR ObjectName,
  2649. IN DWORD NameLen, // number of characters
  2650. IN BYTE ConfigStatus,
  2651. IN BOOL IsContainer,
  2652. IN PSECURITY_DESCRIPTOR pSD,
  2653. IN SECURITY_INFORMATION SeInfo,
  2654. OUT PBYTE pAnalysisStatus
  2655. )
  2656. /*
  2657. Routine Description:
  2658. Determine related changes to the object's parent(s), child(ren) in SMP and SAP
  2659. database then update the SMP entry for the object. Refer to objedit.doc for
  2660. the rule to update database.
  2661. Arguments:
  2662. hProfile - the database handle
  2663. Area - security area to update (file, registry, ds)
  2664. ObjectName - object name in full name
  2665. NameLen - the length of the object name
  2666. ConfigStatus - the flag changed to
  2667. IsContainer - if the object is a container type
  2668. pSD - the security descriptor for the object
  2669. SeInfo - the security information for the object
  2670. pAnalysisStatus - output status of analysis for the object
  2671. Return Value:
  2672. SCE status
  2673. */
  2674. {
  2675. SCESTATUS rc;
  2676. PCWSTR SectionName;
  2677. PSCESECTION hSectionSmp=NULL;
  2678. PSCESECTION hSectionSap=NULL;
  2679. SE_OBJECT_TYPE ObjectType;
  2680. HKEY hKey;
  2681. PWSTR JetName;
  2682. DWORD NewNameLen;
  2683. if ( hProfile == NULL || ObjectName == NULL ) {
  2684. return(SCESTATUS_INVALID_PARAMETER);
  2685. }
  2686. if ( (ConfigStatus > SCE_STATUS_NO_AUTO_INHERIT ||
  2687. ConfigStatus < SCE_STATUS_CHECK) &&
  2688. (BYTE)SCE_NO_VALUE != ConfigStatus &&
  2689. (DWORD)SCE_NO_VALUE != (DWORD)ConfigStatus ) {
  2690. return(SCESTATUS_INVALID_PARAMETER);
  2691. }
  2692. switch(Area) {
  2693. case AREA_REGISTRY_SECURITY:
  2694. SectionName = szRegistryKeys;
  2695. ObjectType = SE_REGISTRY_KEY;
  2696. rc = ScepOpenRegistryObject(
  2697. ObjectType,
  2698. ObjectName,
  2699. KEY_READ,
  2700. &hKey
  2701. );
  2702. if ( rc == ERROR_SUCCESS ) {
  2703. RegCloseKey(hKey);
  2704. } else {
  2705. //
  2706. // not find the key
  2707. //
  2708. return(SCESTATUS_INVALID_DATA);
  2709. }
  2710. JetName = ObjectName;
  2711. NewNameLen = NameLen;
  2712. break;
  2713. case AREA_FILE_SECURITY:
  2714. SectionName = szFileSecurity;
  2715. ObjectType = SE_FILE_OBJECT;
  2716. if ( ObjectName[0] == L'\\' ) { // UNC name format
  2717. return(SCESTATUS_INVALID_PARAMETER);
  2718. }
  2719. if ( 0xFFFFFFFF == GetFileAttributes(ObjectName) ) {
  2720. return(SCESTATUS_INVALID_DATA);
  2721. }
  2722. JetName = ObjectName;
  2723. NewNameLen = NameLen;
  2724. break;
  2725. #if 0
  2726. case AREA_DS_OBJECTS:
  2727. SectionName = szDSSecurity;
  2728. ObjectType = SE_DS_OBJECT;
  2729. rc = ScepLdapOpen(NULL);
  2730. if ( rc == SCESTATUS_SUCCESS ) {
  2731. //
  2732. // detect if the Ds object exist
  2733. //
  2734. rc = ScepDsObjectExist(ObjectName);
  2735. if ( rc == SCESTATUS_SUCCESS ) {
  2736. //
  2737. // convert LDAP name to Jet index name
  2738. //
  2739. rc = ScepConvertLdapToJetIndexName(
  2740. ObjectName,
  2741. &JetName
  2742. );
  2743. }
  2744. }
  2745. if ( rc != SCESTATUS_SUCCESS ) {
  2746. ScepLdapClose(NULL);
  2747. return(rc);
  2748. }
  2749. NewNameLen = wcslen(JetName);
  2750. break;
  2751. #endif
  2752. default:
  2753. return(SCESTATUS_INVALID_PARAMETER);
  2754. }
  2755. if ( pAnalysisStatus ) {
  2756. *pAnalysisStatus = (BYTE)SCE_NO_VALUE;
  2757. }
  2758. //
  2759. // open smp section for system access
  2760. //
  2761. rc = ScepOpenSectionForName(
  2762. hProfile,
  2763. SCE_ENGINE_SMP,
  2764. SectionName,
  2765. &hSectionSmp
  2766. );
  2767. if ( rc == SCESTATUS_SUCCESS ) {
  2768. //
  2769. // open sap section for system access
  2770. //
  2771. rc = ScepOpenSectionForName(
  2772. hProfile,
  2773. SCE_ENGINE_SAP,
  2774. SectionName,
  2775. &hSectionSap
  2776. );
  2777. if ( rc == SCESTATUS_SUCCESS) {
  2778. //
  2779. // Start a transaction so all updates related to this object is atomic
  2780. //
  2781. rc = SceJetStartTransaction( hProfile );
  2782. if ( rc == SCESTATUS_SUCCESS ) {
  2783. rc = SceJetSeek(
  2784. hSectionSmp,
  2785. JetName,
  2786. NewNameLen*sizeof(WCHAR),
  2787. SCEJET_SEEK_EQ_NO_CASE
  2788. );
  2789. if ( rc == SCESTATUS_SUCCESS ) {
  2790. //
  2791. // existing SMP object
  2792. //
  2793. if ( (BYTE)SCE_NO_VALUE == ConfigStatus ||
  2794. (DWORD)SCE_NO_VALUE == (DWORD)ConfigStatus ) {
  2795. //
  2796. // get the old configure flag
  2797. //
  2798. WCHAR StatusFlag;
  2799. BYTE ScepStatus=0;
  2800. DWORD Len;
  2801. rc = SceJetGetValue(
  2802. hSectionSmp,
  2803. SCEJET_CURRENT,
  2804. NULL,
  2805. NULL,
  2806. 0,
  2807. NULL,
  2808. (PWSTR)&StatusFlag,
  2809. 2,
  2810. &Len
  2811. );
  2812. if ( SCESTATUS_SUCCESS == rc ||
  2813. SCESTATUS_BUFFER_TOO_SMALL == rc ) {
  2814. //
  2815. // find the record
  2816. //
  2817. ScepStatus = *((BYTE *)&StatusFlag);
  2818. //
  2819. // update SAP entries.
  2820. //
  2821. rc = ScepObjectAdjustNode(
  2822. hSectionSmp,
  2823. hSectionSap,
  2824. JetName,
  2825. NewNameLen,
  2826. ObjectType,
  2827. ScepStatus,
  2828. IsContainer,
  2829. NULL,
  2830. 0,
  2831. FALSE, // remove the node
  2832. pAnalysisStatus
  2833. );
  2834. if ( SCESTATUS_SUCCESS == rc ) {
  2835. //
  2836. // delete the SMP entry
  2837. //
  2838. rc = SceJetDelete(
  2839. hSectionSmp,
  2840. JetName,
  2841. FALSE,
  2842. SCEJET_DELETE_LINE_NO_CASE
  2843. );
  2844. }
  2845. }
  2846. } else {
  2847. rc = ScepObjectUpdateExistingNode(
  2848. hSectionSmp,
  2849. hSectionSap,
  2850. JetName,
  2851. NewNameLen,
  2852. ObjectType,
  2853. ConfigStatus,
  2854. IsContainer,
  2855. pSD,
  2856. SeInfo,
  2857. pAnalysisStatus
  2858. );
  2859. if ( rc == SCESTATUS_SUCCESS ) {
  2860. //
  2861. // Update the SMP record
  2862. //
  2863. rc = ScepObjectSetKeySetting(
  2864. hSectionSmp,
  2865. JetName,
  2866. ConfigStatus,
  2867. IsContainer,
  2868. pSD,
  2869. SeInfo,
  2870. TRUE
  2871. );
  2872. }
  2873. }
  2874. } else if ( rc == SCESTATUS_RECORD_NOT_FOUND &&
  2875. (BYTE)SCE_NO_VALUE != ConfigStatus &&
  2876. (DWORD)SCE_NO_VALUE != (DWORD)ConfigStatus ) {
  2877. //
  2878. // new added object
  2879. //
  2880. rc = ScepObjectAdjustNode(
  2881. hSectionSmp,
  2882. hSectionSap,
  2883. JetName,
  2884. NewNameLen,
  2885. ObjectType,
  2886. ConfigStatus,
  2887. IsContainer,
  2888. pSD,
  2889. SeInfo,
  2890. TRUE, // add the node
  2891. pAnalysisStatus
  2892. );
  2893. }
  2894. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  2895. rc = SCESTATUS_SUCCESS;
  2896. }
  2897. //
  2898. // Commit or Rollback the changes
  2899. //
  2900. if ( rc == SCESTATUS_SUCCESS ) {
  2901. //
  2902. // needs return code for commiting the transaction
  2903. //
  2904. rc = SceJetCommitTransaction(hProfile, 0);
  2905. }
  2906. if ( rc != SCESTATUS_SUCCESS ) {
  2907. SceJetRollback(hProfile, 0);
  2908. }
  2909. }
  2910. SceJetCloseSection(&hSectionSap, TRUE);
  2911. } else if ( rc == SCESTATUS_BAD_FORMAT ) {
  2912. //
  2913. // SMP exist, but SAP does not exist
  2914. //
  2915. }
  2916. SceJetCloseSection(&hSectionSmp, TRUE);
  2917. } else if ( rc == SCESTATUS_BAD_FORMAT ) {
  2918. //
  2919. // SMP section does not exist
  2920. //
  2921. }
  2922. //
  2923. // free stuff used for DS
  2924. //
  2925. if ( Area == AREA_DS_OBJECTS ) {
  2926. ScepFree(JetName);
  2927. ScepLdapClose(NULL);
  2928. }
  2929. return(rc);
  2930. }
  2931. SCESTATUS
  2932. ScepObjectUpdateExistingNode(
  2933. IN PSCESECTION hSectionSmp,
  2934. IN PSCESECTION hSectionSap,
  2935. IN PWSTR ObjectName,
  2936. IN DWORD NameLen,
  2937. IN SE_OBJECT_TYPE ObjectType,
  2938. IN BYTE ConfigStatus,
  2939. IN BOOL IsContainer,
  2940. IN PSECURITY_DESCRIPTOR pSD,
  2941. IN SECURITY_INFORMATION SeInfo,
  2942. OUT PBYTE pAnalysisStatus
  2943. )
  2944. /*
  2945. Routine Description:
  2946. Update an existing object
  2947. Arguements:
  2948. see ScepUpdateObjectInfo
  2949. Return Value:
  2950. SCESTATUS
  2951. */
  2952. {
  2953. SCESTATUS rc;
  2954. BYTE ScepStatus, SapStatus;
  2955. PSECURITY_DESCRIPTOR pScepSD=NULL;
  2956. SECURITY_INFORMATION ScepSeInfo;
  2957. BYTE retStat = SCE_STATUS_NOT_ANALYZED;
  2958. rc = ScepObjectGetKeySetting(
  2959. hSectionSmp,
  2960. ObjectName,
  2961. &ScepStatus,
  2962. NULL,
  2963. &pScepSD,
  2964. &ScepSeInfo
  2965. );
  2966. if ( rc == SCESTATUS_SUCCESS ) {
  2967. //
  2968. // check for analysis status
  2969. //
  2970. SapStatus = ScepGetObjectAnalysisStatus(
  2971. hSectionSap,
  2972. ObjectName,
  2973. FALSE
  2974. );
  2975. if ( ScepStatus == SCE_STATUS_IGNORE ) {
  2976. //
  2977. // no change is needed if update from IGNORE to IGNORE
  2978. //
  2979. if ( ConfigStatus != SCE_STATUS_IGNORE ) {
  2980. //
  2981. // N.A. the object (changed from N.C)
  2982. //
  2983. rc = ScepObjectSetKeySetting(
  2984. hSectionSap,
  2985. ObjectName,
  2986. SCE_STATUS_NOT_ANALYZED,
  2987. TRUE,
  2988. NULL,
  2989. 0,
  2990. TRUE
  2991. );
  2992. } else {
  2993. if ( SapStatus == SCE_STATUS_NOT_CONFIGURED ) {
  2994. retStat = SapStatus;
  2995. }
  2996. }
  2997. } else if ( ConfigStatus == SCE_STATUS_IGNORE ) {
  2998. //
  2999. // changed to ignore. delete all children from SMP & SAP
  3000. //
  3001. rc = ScepObjectDeleteScepAndAllChildren(
  3002. hSectionSmp,
  3003. hSectionSap,
  3004. ObjectName,
  3005. IsContainer,
  3006. SCE_STATUS_NOT_CONFIGURED
  3007. );
  3008. retStat = SCE_STATUS_NOT_CONFIGURED;
  3009. } else if ( SapStatus == SCE_STATUS_NOT_ANALYZED ) {
  3010. //
  3011. // was already added/modified, no need to update SAP
  3012. // although children status may be mixed with C.C. or N.A.
  3013. //
  3014. if ( ConfigStatus == SCE_STATUS_OVERWRITE &&
  3015. ScepStatus != SCE_STATUS_OVERWRITE ) {
  3016. //
  3017. // change C.C children to N.A. children
  3018. //
  3019. rc = ScepObjectRaiseChildrenInBetween(
  3020. hSectionSmp,
  3021. hSectionSap,
  3022. ObjectName,
  3023. NameLen,
  3024. IsContainer,
  3025. SCE_STATUS_NOT_ANALYZED,
  3026. TRUE // change status only
  3027. );
  3028. } else if ( ConfigStatus != SCE_STATUS_OVERWRITE &&
  3029. ScepStatus == SCE_STATUS_OVERWRITE ) {
  3030. //
  3031. // change N.A. children to C.C. children
  3032. //
  3033. rc = ScepObjectRaiseChildrenInBetween(
  3034. hSectionSmp,
  3035. hSectionSap,
  3036. ObjectName,
  3037. NameLen,
  3038. IsContainer,
  3039. SCE_STATUS_CHILDREN_CONFIGURED,
  3040. TRUE // change status only
  3041. );
  3042. }
  3043. } else {
  3044. if ( ScepStatus == SCE_STATUS_OVERWRITE &&
  3045. ( ConfigStatus == SCE_STATUS_CHECK ||
  3046. ConfigStatus == SCE_STATUS_NO_AUTO_INHERIT ) ) {
  3047. //
  3048. // delete all mismatched status between this node
  3049. // and its children; N.A. all nodes in between
  3050. //
  3051. rc = ScepObjectRaiseChildrenInBetween(
  3052. hSectionSmp,
  3053. hSectionSap,
  3054. ObjectName,
  3055. NameLen,
  3056. IsContainer,
  3057. SCE_STATUS_NOT_ANALYZED,
  3058. FALSE
  3059. );
  3060. } else if ( ConfigStatus == SCE_STATUS_OVERWRITE &&
  3061. (ScepStatus == SCE_STATUS_CHECK ||
  3062. ScepStatus == SCE_STATUS_NO_AUTO_INHERIT) ) {
  3063. //
  3064. // change C.C children to N.A. children
  3065. //
  3066. rc = ScepObjectRaiseChildrenInBetween(
  3067. hSectionSmp,
  3068. hSectionSap,
  3069. ObjectName,
  3070. NameLen,
  3071. IsContainer,
  3072. SCE_STATUS_NOT_ANALYZED,
  3073. TRUE // change status only
  3074. );
  3075. }
  3076. //
  3077. // compare the current node status
  3078. //
  3079. if ( rc == SCESTATUS_SUCCESS ||
  3080. rc == SCESTATUS_RECORD_NOT_FOUND ) {
  3081. if ( SapStatus == SCE_STATUS_ERROR_NOT_AVAILABLE ) {
  3082. // if errored, don't touch it.
  3083. retStat = SapStatus;
  3084. rc = SCESTATUS_SUCCESS;
  3085. } else {
  3086. rc = ScepObjectCompareKeySetting(
  3087. hSectionSap,
  3088. ObjectName,
  3089. ObjectType,
  3090. TRUE,
  3091. pSD,
  3092. SeInfo,
  3093. pScepSD,
  3094. &retStat
  3095. );
  3096. }
  3097. }
  3098. }
  3099. if ( pScepSD ) {
  3100. ScepFree(pScepSD);
  3101. }
  3102. }
  3103. if ( pAnalysisStatus ) {
  3104. *pAnalysisStatus = retStat;
  3105. }
  3106. return(rc);
  3107. }
  3108. SCESTATUS
  3109. ScepObjectGetKeySetting(
  3110. IN PSCESECTION hSection,
  3111. IN PWSTR ObjectName,
  3112. OUT PBYTE Status,
  3113. OUT PBOOL IsContainer OPTIONAL,
  3114. OUT PSECURITY_DESCRIPTOR *pSecurityDescriptor OPTIONAL,
  3115. OUT PSECURITY_INFORMATION SeInfo OPTIONAL
  3116. )
  3117. /*
  3118. Routine Description:
  3119. Read settings for the object in the section
  3120. Arguements:
  3121. hSection - the section handle
  3122. others see ScepUpdateObjectInfo
  3123. Return Value:
  3124. SCESTATUS
  3125. */
  3126. {
  3127. SCESTATUS rc;
  3128. PWSTR Value=NULL;
  3129. DWORD ValueLen;
  3130. PSECURITY_DESCRIPTOR pTempSD=NULL;
  3131. SECURITY_INFORMATION tmpSeInfo;
  3132. DWORD SDsize, Win32Rc;
  3133. if ( hSection == NULL || ObjectName == NULL || Status == NULL ) {
  3134. return(SCESTATUS_INVALID_PARAMETER);
  3135. }
  3136. rc = SceJetGetValue(
  3137. hSection,
  3138. SCEJET_EXACT_MATCH_NO_CASE,
  3139. ObjectName,
  3140. NULL,
  3141. 0,
  3142. NULL,
  3143. NULL,
  3144. 0,
  3145. &ValueLen
  3146. );
  3147. if ( rc == SCESTATUS_SUCCESS ) {
  3148. //
  3149. // allocate memory for value string
  3150. //
  3151. Value = (PWSTR)ScepAlloc( LMEM_ZEROINIT, ValueLen+2);
  3152. if ( Value == NULL )
  3153. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  3154. //
  3155. // Get the value
  3156. //
  3157. rc = SceJetGetValue(
  3158. hSection,
  3159. SCEJET_CURRENT,
  3160. NULL,
  3161. NULL,
  3162. 0,
  3163. NULL,
  3164. Value,
  3165. ValueLen,
  3166. &ValueLen
  3167. );
  3168. if ( rc == SCESTATUS_SUCCESS ) {
  3169. if (pSecurityDescriptor != NULL ) {
  3170. //
  3171. // convert security descriptor
  3172. //
  3173. Win32Rc = ConvertTextSecurityDescriptor(
  3174. Value+1,
  3175. &pTempSD,
  3176. &SDsize,
  3177. &tmpSeInfo
  3178. );
  3179. if ( Win32Rc == NO_ERROR ) {
  3180. *pSecurityDescriptor = pTempSD;
  3181. if (tmpSeInfo )
  3182. *SeInfo = tmpSeInfo;
  3183. } else
  3184. rc = ScepDosErrorToSceStatus(Win32Rc);
  3185. }
  3186. if ( rc == SCESTATUS_SUCCESS ) {
  3187. *Status = *((BYTE *)Value);
  3188. if ( IsContainer != NULL )
  3189. *IsContainer = *((CHAR *)Value+1) != '0' ? TRUE : FALSE;
  3190. }
  3191. }
  3192. ScepFree(Value);
  3193. }
  3194. return(rc);
  3195. }
  3196. SCESTATUS
  3197. ScepObjectSetKeySetting(
  3198. IN PSCESECTION hSection,
  3199. IN PWSTR ObjectName,
  3200. IN BYTE Status,
  3201. IN BOOL IsContainer,
  3202. IN PSECURITY_DESCRIPTOR pSD,
  3203. IN SECURITY_INFORMATION SeInfo,
  3204. IN BOOL bOverwrite
  3205. )
  3206. /*
  3207. Routine Description:
  3208. Set settings for the object in the section
  3209. Arguements:
  3210. See ScepObjectGetKeySetting
  3211. bOverwrite - if the new setting should overwrite existing settings
  3212. Return Value:
  3213. SCESTATUS
  3214. */
  3215. {
  3216. SCESTATUS rc;
  3217. DWORD SDsize=0, Win32Rc=NO_ERROR;
  3218. PWSTR SDspec=NULL;
  3219. if ( hSection == NULL ||
  3220. ObjectName == NULL ) {
  3221. return(SCESTATUS_INVALID_PARAMETER);
  3222. }
  3223. if ( !bOverwrite ) {
  3224. rc = SceJetSeek(
  3225. hSection,
  3226. ObjectName,
  3227. wcslen(ObjectName)*sizeof(WCHAR),
  3228. SCEJET_SEEK_EQ_NO_CASE
  3229. );
  3230. if ( rc != SCESTATUS_RECORD_NOT_FOUND ) {
  3231. //
  3232. // if found it, do not overwrite, so just return
  3233. // if errored, also return
  3234. //
  3235. return(rc);
  3236. }
  3237. }
  3238. //
  3239. // convert security descriptor
  3240. //
  3241. if ( pSD ) {
  3242. Win32Rc = ConvertSecurityDescriptorToText (
  3243. pSD,
  3244. SeInfo,
  3245. &SDspec,
  3246. &SDsize
  3247. );
  3248. }
  3249. if ( Win32Rc == NO_ERROR ) {
  3250. rc = ScepSaveObjectString(
  3251. hSection,
  3252. ObjectName,
  3253. IsContainer,
  3254. Status,
  3255. SDspec,
  3256. SDsize
  3257. );
  3258. } else
  3259. rc = ScepDosErrorToSceStatus(Win32Rc);
  3260. if ( SDspec != NULL ) {
  3261. ScepFree(SDspec);
  3262. }
  3263. return(rc);
  3264. }
  3265. SCESTATUS
  3266. ScepObjectDeleteScepAndAllChildren(
  3267. IN PSCESECTION hSectionSmp,
  3268. IN PSCESECTION hSectionSap,
  3269. IN PWSTR ObjectName,
  3270. IN BOOL IsContainer,
  3271. IN BYTE StatusToRaise
  3272. )
  3273. /*
  3274. Routine Description:
  3275. Delete a object and all child objects from SMP and SAP
  3276. Arguements:
  3277. hSectionSmp - SMP section handle
  3278. hSectionSap - SAP section handle
  3279. ObjectName - the object's name
  3280. IsContainer - if the object is a container
  3281. Return Value:
  3282. SCESTATUS
  3283. */
  3284. {
  3285. SCESTATUS rc;
  3286. rc = SceJetDelete(
  3287. hSectionSmp,
  3288. ObjectName,
  3289. TRUE,
  3290. SCEJET_DELETE_PARTIAL_NO_CASE
  3291. );
  3292. if ( rc == SCESTATUS_SUCCESS ||
  3293. rc == SCESTATUS_RECORD_NOT_FOUND ) {
  3294. rc = SceJetDelete(
  3295. hSectionSap,
  3296. ObjectName,
  3297. TRUE,
  3298. SCEJET_DELETE_PARTIAL_NO_CASE
  3299. );
  3300. if ( rc == SCESTATUS_SUCCESS ||
  3301. rc == SCESTATUS_RECORD_NOT_FOUND ) {
  3302. //
  3303. // Raise a N.C. status for the object
  3304. //
  3305. rc = ScepObjectSetKeySetting(
  3306. hSectionSap,
  3307. ObjectName,
  3308. StatusToRaise, //SCE_STATUS_NOT_CONFIGURED,
  3309. IsContainer,
  3310. NULL,
  3311. 0,
  3312. TRUE
  3313. );
  3314. }
  3315. }
  3316. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  3317. rc = SCESTATUS_SUCCESS;
  3318. }
  3319. return(rc);
  3320. }
  3321. SCESTATUS
  3322. ScepObjectAdjustNode(
  3323. IN PSCESECTION hSectionSmp,
  3324. IN PSCESECTION hSectionSap,
  3325. IN PWSTR ObjectName,
  3326. IN DWORD NameLen,
  3327. IN SE_OBJECT_TYPE ObjectType,
  3328. IN BYTE ConfigStatus,
  3329. IN BOOL IsContainer,
  3330. IN PSECURITY_DESCRIPTOR pSD,
  3331. IN SECURITY_INFORMATION SeInfo,
  3332. IN BOOL bAdd,
  3333. OUT PBYTE pAnalysisStatus
  3334. )
  3335. /*
  3336. Routine Description:
  3337. Add a new object to SMP and SAP sections
  3338. Arguements:
  3339. hSectionSmp - the SMP section handle
  3340. hSectionSap - the SAP section handle
  3341. others see ScepUpdateObjectInfo
  3342. Return Value:
  3343. SCESTATUS
  3344. */
  3345. {
  3346. if ( hSectionSmp == NULL || hSectionSap == NULL ||
  3347. ObjectName == NULL || NameLen == 0 ) {
  3348. return(SCESTATUS_INVALID_PARAMETER);
  3349. }
  3350. SCESTATUS rc=SCESTATUS_SUCCESS;
  3351. WCHAR Delim;
  3352. switch ( ObjectType) {
  3353. case SE_REGISTRY_KEY:
  3354. case SE_FILE_OBJECT:
  3355. Delim = L'\\';
  3356. break;
  3357. /*
  3358. case SE_DS_OBJECT:
  3359. Delim = L',';
  3360. break;
  3361. */
  3362. default:
  3363. return(SCESTATUS_INVALID_PARAMETER);
  3364. }
  3365. INT i, Level=0, ParentLevel=0;
  3366. BYTE ParentStatus;
  3367. //
  3368. // get total number levels of the objectname
  3369. //
  3370. ScepObjectTotalLevel(ObjectName, Delim, &Level);
  3371. //
  3372. // allocate temp buffer
  3373. //
  3374. PWSTR ParentName = (PWSTR)ScepAlloc(0, (NameLen+4)*sizeof(WCHAR));
  3375. if ( ParentName == NULL ) {
  3376. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  3377. }
  3378. //
  3379. // loop through each parent of the object to turn of IGNORE status
  3380. //
  3381. ParentName[0] = L'\0';
  3382. rc = ScepObjectAdjustParentStatus(
  3383. hSectionSmp,
  3384. hSectionSap,
  3385. ObjectName,
  3386. NameLen,
  3387. Delim,
  3388. Level,
  3389. bAdd ? (BYTE)SCE_OBJECT_TURNOFF_IGNORE : 0, // if TRUE, turn off parent ignore status, otherwise, just get the parent
  3390. &ParentLevel,
  3391. &ParentStatus,
  3392. ParentName // ParentName
  3393. );
  3394. if ( rc != SCESTATUS_SUCCESS ) {
  3395. //
  3396. // error occurs when turning off IGNORE
  3397. //
  3398. ScepFree(ParentName);
  3399. return(rc);
  3400. }
  3401. BYTE retStat = SCE_STATUS_NOT_ANALYZED;
  3402. BOOL HasChild;
  3403. rc = ScepObjectHasAnyChild(
  3404. hSectionSmp,
  3405. ObjectName,
  3406. NameLen,
  3407. Delim,
  3408. &HasChild
  3409. );
  3410. if ( rc == SCESTATUS_SUCCESS ) {
  3411. if ( bAdd ) {
  3412. //
  3413. // ****when bAdd = TRUE, add the node.
  3414. // there are the following cases to consider regarding the SAP entries:
  3415. //
  3416. // 1. tree path is empty to the root (the first object added in this path)
  3417. // C.C. all parent nodes if they don't exist
  3418. // N.A. the object
  3419. // return status N.A.
  3420. // 2. have parent node but no child node (the new node is a leaf node)
  3421. // if the closest parent is in OVERWRITE status
  3422. // if the closet parent is new added (N.A. status)
  3423. // add the node, N.A. the object
  3424. // return status N.A.
  3425. // else
  3426. // if new node status is CHECK
  3427. // delete all SAP mismatches for children under the new node,
  3428. // determine MATCH/MISMATCH of the new node
  3429. // if new node status is OVERWRITE
  3430. // determine MATCH/MISMATCH of the new node, everthing else stays unchanged
  3431. // return status GOOD or MISMATCH
  3432. // if the closest parent is CHECK
  3433. // C.C. all nodes in the path to the parent,
  3434. // add the node, N.A. the object
  3435. // return status N.A.
  3436. // 3. have child node but no parent node
  3437. // new node's status (CHECK or OVERWRITE ) does not make difference
  3438. // if new status is IGNORE,
  3439. // delete all children in SMP and SAP,
  3440. // add the node and N.C. the object
  3441. // return status N.C.
  3442. // else
  3443. // delete all children in SAP,
  3444. // add the node,
  3445. // raise all SMP node and children as N.A.
  3446. // return status N.A
  3447. //
  3448. // 4. have both parent and child
  3449. // combine rules for 2 and 3 except:
  3450. // if parent's status is OVERWRITE and new node status is CHECK
  3451. // ONLY delete SAP mismatches for children between the new node and the child node
  3452. //
  3453. //
  3454. // decide child objects
  3455. //
  3456. if ( ConfigStatus == SCE_STATUS_IGNORE ) {
  3457. //
  3458. // delete all children objects from template and analysis database
  3459. //
  3460. rc = ScepObjectDeleteScepAndAllChildren(
  3461. hSectionSmp,
  3462. hSectionSap,
  3463. ObjectName,
  3464. IsContainer,
  3465. SCE_STATUS_NOT_ANALYZED
  3466. );
  3467. } else {
  3468. if ( ParentLevel > 0 && ParentStatus == SCE_STATUS_OVERWRITE ) {
  3469. //
  3470. // check if this parent was added (N.A. status)
  3471. //
  3472. BYTE oldStatus = ScepGetObjectAnalysisStatus(hSectionSap,
  3473. ParentName,
  3474. FALSE
  3475. );
  3476. if ( oldStatus == SCE_STATUS_NOT_ANALYZED ) {
  3477. //
  3478. // parent was also new added
  3479. // add the node, N.A. the object
  3480. //
  3481. rc = ScepObjectSetKeySetting(
  3482. hSectionSap,
  3483. ObjectName,
  3484. SCE_STATUS_NOT_ANALYZED,
  3485. TRUE,
  3486. NULL,
  3487. 0,
  3488. TRUE
  3489. );
  3490. } else {
  3491. //
  3492. // closest parent has OVERWRITE status
  3493. //
  3494. if ( ConfigStatus == SCE_STATUS_CHECK ||
  3495. ConfigStatus == SCE_STATUS_NO_AUTO_INHERIT ) {
  3496. //
  3497. // delete all SAP children except explicitly specified
  3498. //
  3499. if ( !HasChild ) {
  3500. //
  3501. // no child - delete everything under the SAP
  3502. //
  3503. rc = SceJetDelete(
  3504. hSectionSap,
  3505. ObjectName,
  3506. TRUE,
  3507. SCEJET_DELETE_PARTIAL_NO_CASE
  3508. );
  3509. } else {
  3510. //
  3511. // here is the problem: should only delete SAP entry between
  3512. // the new node and its child(ren)
  3513. // and raise C.C. for nodes in between
  3514. //
  3515. // p
  3516. // /
  3517. // .
  3518. // N
  3519. // / |
  3520. // . C
  3521. // / \
  3522. // . C
  3523. // /|
  3524. // C C
  3525. //
  3526. //
  3527. rc = ScepObjectRaiseChildrenInBetween(
  3528. hSectionSmp,
  3529. hSectionSap,
  3530. ObjectName,
  3531. NameLen,
  3532. IsContainer,
  3533. SCE_STATUS_CHILDREN_CONFIGURED,
  3534. FALSE
  3535. );
  3536. }
  3537. }
  3538. //
  3539. // determine the current node's status, MATCH or MISMATCH
  3540. //
  3541. if ( rc == SCESTATUS_SUCCESS ||
  3542. rc == SCESTATUS_RECORD_NOT_FOUND ) {
  3543. if ( oldStatus == SCE_STATUS_ERROR_NOT_AVAILABLE ) {
  3544. //
  3545. // Leave Error status alone
  3546. //
  3547. rc = ScepObjectSetKeySetting(
  3548. hSectionSap,
  3549. ObjectName,
  3550. oldStatus,
  3551. TRUE,
  3552. NULL,
  3553. 0,
  3554. TRUE
  3555. );
  3556. } else {
  3557. //
  3558. // should compare with SAP to decide mismatch status
  3559. //
  3560. rc = ScepObjectCompareKeySetting(
  3561. hSectionSap,
  3562. ObjectName,
  3563. ObjectType,
  3564. TRUE,
  3565. pSD,
  3566. SeInfo,
  3567. NULL,
  3568. &retStat
  3569. );
  3570. }
  3571. }
  3572. }
  3573. } else if ( !HasChild ) {
  3574. //
  3575. // there is no child but there may be a parent
  3576. // if there is a parent, parent's stauts is check
  3577. //
  3578. if ( ParentLevel > 0 ) {
  3579. // C.C. all nodes in the path to the parent,
  3580. // (if there is child, it's already CCed)
  3581. // add the node, N.A. the object
  3582. i = ParentLevel+1;
  3583. } else {
  3584. //
  3585. // no parent was found, no child - the first node
  3586. //
  3587. if ( ObjectType == SE_DS_OBJECT ) {
  3588. //
  3589. // Ds objects should start with the level for the local domain
  3590. //
  3591. PSCE_OBJECT_LIST pDsRoot=NULL;
  3592. rc = ScepEnumerateDsObjectRoots(NULL, &pDsRoot);
  3593. if ( rc == SCESTATUS_SUCCESS && pDsRoot != NULL ) {
  3594. ScepObjectTotalLevel(pDsRoot->Name, Delim, &ParentLevel);
  3595. ScepFreeObjectList(pDsRoot);
  3596. pDsRoot = NULL;
  3597. i = ParentLevel+1;
  3598. }
  3599. } else {
  3600. //
  3601. // other type starting with level 1
  3602. //
  3603. i = 1;
  3604. }
  3605. }
  3606. //
  3607. // process each node in between the new node and its closest parent
  3608. //
  3609. if ( rc == SCESTATUS_SUCCESS ) {
  3610. rc = ScepObjectRaiseNodesInPath(
  3611. hSectionSap,
  3612. ObjectName,
  3613. NameLen,
  3614. i,
  3615. Level,
  3616. Delim,
  3617. SCE_STATUS_CHILDREN_CONFIGURED
  3618. );
  3619. }
  3620. //
  3621. // N.A. the object
  3622. //
  3623. if ( rc == SCESTATUS_SUCCESS ) {
  3624. rc = ScepObjectSetKeySetting(
  3625. hSectionSap,
  3626. ObjectName,
  3627. SCE_STATUS_NOT_ANALYZED,
  3628. IsContainer,
  3629. NULL,
  3630. 0,
  3631. TRUE
  3632. );
  3633. }
  3634. } else {
  3635. //
  3636. // there is child
  3637. //
  3638. if ( ConfigStatus == SCE_STATUS_OVERWRITE ) {
  3639. //
  3640. // if there is a parent, it must be in CHECK status
  3641. // nodes between this node and its children
  3642. // should all be N.A.
  3643. //
  3644. rc = ScepObjectRaiseChildrenInBetween(
  3645. hSectionSmp,
  3646. hSectionSap,
  3647. ObjectName,
  3648. NameLen,
  3649. IsContainer,
  3650. SCE_STATUS_NOT_ANALYZED,
  3651. FALSE
  3652. );
  3653. }
  3654. //
  3655. // N.A. the object
  3656. //
  3657. if ( rc == SCESTATUS_SUCCESS ) {
  3658. rc = ScepObjectSetKeySetting(
  3659. hSectionSap,
  3660. ObjectName,
  3661. SCE_STATUS_NOT_ANALYZED,
  3662. IsContainer,
  3663. NULL,
  3664. 0,
  3665. TRUE
  3666. );
  3667. }
  3668. }
  3669. }
  3670. //
  3671. // add the SMP entry
  3672. //
  3673. if ( rc == SCESTATUS_SUCCESS ) {
  3674. rc = ScepObjectSetKeySetting(
  3675. hSectionSmp,
  3676. ObjectName,
  3677. ConfigStatus,
  3678. IsContainer,
  3679. pSD,
  3680. SeInfo,
  3681. TRUE
  3682. );
  3683. }
  3684. } else {
  3685. //
  3686. // when bAdd = FALSE, remove the node
  3687. // there are the following cases to consider regarding the SAP entries:
  3688. //
  3689. // 1. if there is no existing child under this node
  3690. // if no parent, or parent N.A., or parent not OVERWRITE
  3691. // find junction point with other siblings
  3692. // remove all SAP below junction point (if not exist, use root/parent)
  3693. // if no juction point and no parent
  3694. // N.C. the root
  3695. // return status N.C.
  3696. // else { parent in overwrite } if ( TNA/TI/TC) }
  3697. // delete all SAP below this object
  3698. // N.A. the object
  3699. // return status N.A.
  3700. // else ( parent in overwrite and TO )
  3701. // N.A. the object
  3702. // return status N.A.
  3703. // 2. have existing child(ren) - note multiple branches
  3704. // if no parent
  3705. // if object status was OVERWRITE
  3706. // delete SAP entries between this node and all children
  3707. // C.C. all branch nodes in between
  3708. // C.C. this object
  3709. // return status C.C.
  3710. // else { there is a parent }
  3711. // if (parent OVERWRITE, object N.A. OVERWRITE) or
  3712. // (parent not N.A., parent OVERWRITE, object not N.A., object OVERWRITE)
  3713. // N.A. object
  3714. // return N.A.
  3715. // else if parent CHECK, object OVERWRITE
  3716. // delete SAP entries between this node and all children
  3717. // C.C. all branch nodes in between
  3718. // C.C. object
  3719. // return C.C.
  3720. // else if (parent OVERWRITE, object CHECK) or
  3721. // (parent N.A., parent OVERWRITE, object not N.A., object OVERWRITE)
  3722. // delete SAP entries between this node and all children
  3723. // N.A. all branch nodes in between
  3724. // N.A. object
  3725. // return N.A.
  3726. // else { must be parent CHECK, object CHECK }
  3727. // C.C. object
  3728. // return C.C
  3729. //
  3730. //
  3731. // check if this parent was added (N.A. status)
  3732. //
  3733. BYTE oldParentFlag = ScepGetObjectAnalysisStatus(hSectionSap,
  3734. ParentName,
  3735. FALSE
  3736. );
  3737. BYTE oldObjectFlag = ScepGetObjectAnalysisStatus(hSectionSap,
  3738. ObjectName,
  3739. FALSE
  3740. );
  3741. if ( !HasChild ) {
  3742. if ( ParentLevel <= 0 ||
  3743. oldParentFlag == SCE_STATUS_NOT_ANALYZED ||
  3744. ParentStatus != SCE_STATUS_OVERWRITE ) {
  3745. //
  3746. // find junction point with other siblings
  3747. //
  3748. INT JuncLevel=0;
  3749. rc = ScepObjectAdjustParentStatus(
  3750. hSectionSmp,
  3751. hSectionSap,
  3752. ObjectName,
  3753. NameLen,
  3754. Delim,
  3755. Level,
  3756. SCE_OBJECT_SEARCH_JUNCTION,
  3757. &JuncLevel,
  3758. NULL,
  3759. NULL
  3760. );
  3761. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  3762. rc = SCESTATUS_SUCCESS;
  3763. }
  3764. if ( JuncLevel == 0 ) {
  3765. JuncLevel = ParentLevel;
  3766. }
  3767. if ( SCESTATUS_SUCCESS == rc ) {
  3768. //
  3769. // remove all SAP below junction point
  3770. // (if not exist, use root/parent)
  3771. //
  3772. rc = ScepObjectRaiseNodesInPath(
  3773. hSectionSap,
  3774. ObjectName,
  3775. NameLen,
  3776. (JuncLevel > 0) ? JuncLevel+1 : 1,
  3777. Level,
  3778. Delim,
  3779. (BYTE)SCE_NO_VALUE
  3780. );
  3781. if ( SCESTATUS_SUCCESS == rc ) {
  3782. //
  3783. // delete everything under this deleted node
  3784. //
  3785. rc = SceJetDelete(
  3786. hSectionSap,
  3787. ObjectName,
  3788. TRUE,
  3789. SCEJET_DELETE_PARTIAL_NO_CASE
  3790. );
  3791. }
  3792. }
  3793. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  3794. rc = SCESTATUS_SUCCESS;
  3795. }
  3796. if ( SCESTATUS_SUCCESS == rc ) {
  3797. if ( JuncLevel <= 0 ) {
  3798. //
  3799. // if no juction point and no parent, N.C. the root
  3800. // use the ParentName buffer
  3801. //
  3802. if ( ObjectType == SE_FILE_OBJECT ) {
  3803. if ( ParentName[0] == L'\0' ) {
  3804. //
  3805. // there is no parent
  3806. //
  3807. ParentName[0] = ObjectName[0];
  3808. ParentName[1] = ObjectName[1];
  3809. }
  3810. ParentName[2] = L'\\';
  3811. ParentName[3] = L'\0';
  3812. } else {
  3813. // reg keys
  3814. PWSTR pTemp = wcschr(ParentName, L'\\');
  3815. if ( pTemp ) {
  3816. ParentName[pTemp-ParentName] = L'\0';
  3817. } else if ( ParentName[0] == L'\0' ) {
  3818. pTemp = wcschr(ObjectName, L'\\');
  3819. if ( pTemp ) {
  3820. wcsncpy(ParentName, ObjectName, pTemp-ObjectName);
  3821. ParentName[pTemp-ObjectName] = L'\0';
  3822. } else {
  3823. wcscpy(ParentName, ObjectName);
  3824. }
  3825. }
  3826. }
  3827. rc = ScepObjectSetKeySetting(
  3828. hSectionSap,
  3829. ParentName,
  3830. SCE_STATUS_NOT_CONFIGURED,
  3831. TRUE,
  3832. NULL,
  3833. 0,
  3834. TRUE
  3835. );
  3836. }
  3837. }
  3838. retStat = SCE_STATUS_NOT_CONFIGURED;
  3839. } else {
  3840. if ( ConfigStatus != SCE_STATUS_OVERWRITE ) {
  3841. //
  3842. // delete all SAP below this object
  3843. //
  3844. rc = SceJetDelete(
  3845. hSectionSap,
  3846. ObjectName,
  3847. TRUE,
  3848. SCEJET_DELETE_PARTIAL_NO_CASE
  3849. );
  3850. }
  3851. if ( SCESTATUS_SUCCESS == rc ) {
  3852. //
  3853. // N.A. the object
  3854. //
  3855. rc = ScepObjectSetKeySetting(
  3856. hSectionSap,
  3857. ObjectName,
  3858. SCE_STATUS_NOT_ANALYZED,
  3859. IsContainer,
  3860. NULL,
  3861. 0,
  3862. TRUE
  3863. );
  3864. }
  3865. retStat = SCE_STATUS_NOT_ANALYZED;
  3866. }
  3867. } else if ( ParentLevel <= 0 ||
  3868. ( ParentStatus != SCE_STATUS_OVERWRITE &&
  3869. ConfigStatus == SCE_STATUS_OVERWRITE) ) {
  3870. // no parent, or parent check, object overwrite
  3871. if ( ConfigStatus == SCE_STATUS_OVERWRITE ) {
  3872. //
  3873. // delete SAP entries between this node and all children
  3874. // C.C. all branch nodes in between
  3875. //
  3876. rc = ScepObjectRaiseChildrenInBetween(
  3877. hSectionSmp,
  3878. hSectionSap,
  3879. ObjectName,
  3880. NameLen,
  3881. IsContainer,
  3882. SCE_STATUS_CHILDREN_CONFIGURED,
  3883. FALSE
  3884. );
  3885. }
  3886. if ( SCESTATUS_SUCCESS == rc ) {
  3887. // C.C. this object
  3888. rc = ScepObjectSetKeySetting(
  3889. hSectionSap,
  3890. ObjectName,
  3891. SCE_STATUS_CHILDREN_CONFIGURED,
  3892. IsContainer,
  3893. NULL,
  3894. 0,
  3895. TRUE
  3896. );
  3897. }
  3898. retStat = SCE_STATUS_CHILDREN_CONFIGURED;
  3899. } else {
  3900. //
  3901. // have both parent and children
  3902. //
  3903. if ( ParentStatus == SCE_STATUS_OVERWRITE &&
  3904. ConfigStatus == SCE_STATUS_OVERWRITE &&
  3905. ( oldObjectFlag == SCE_STATUS_NOT_ANALYZED ||
  3906. (oldParentFlag != SCE_STATUS_NOT_ANALYZED &&
  3907. oldObjectFlag != SCE_STATUS_NOT_ANALYZED )
  3908. ) ) {
  3909. //
  3910. // (parent OVERWRITE, object N.A. OVERWRITE) or
  3911. // (parent not N.A., parent OVERWRITE, object not N.A., object OVERWRITE)
  3912. // N.A. the object
  3913. //
  3914. retStat = SCE_STATUS_NOT_ANALYZED;
  3915. } else if ( ParentStatus == SCE_STATUS_OVERWRITE &&
  3916. ( ConfigStatus != SCE_STATUS_OVERWRITE ||
  3917. ( oldParentFlag == SCE_STATUS_NOT_ANALYZED &&
  3918. oldObjectFlag != SCE_STATUS_NOT_ANALYZED &&
  3919. ConfigStatus == SCE_STATUS_OVERWRITE ))
  3920. ) {
  3921. //
  3922. // (parent OVERWRITE, object CHECK) or
  3923. // (parent N.A., parent OVERWRITE, object not N.A., object OVERWRITE)
  3924. //
  3925. // delete SAP entries between this node and all children
  3926. // N.A. all branch nodes in between
  3927. //
  3928. rc = ScepObjectRaiseChildrenInBetween(
  3929. hSectionSmp,
  3930. hSectionSap,
  3931. ObjectName,
  3932. NameLen,
  3933. IsContainer,
  3934. SCE_STATUS_NOT_ANALYZED,
  3935. FALSE
  3936. );
  3937. // N.A. object
  3938. retStat = SCE_STATUS_NOT_ANALYZED;
  3939. } else {
  3940. //
  3941. // must be parent CHECK, object CHECK }
  3942. // C.C. object
  3943. //
  3944. retStat = SCE_STATUS_NOT_ANALYZED;
  3945. }
  3946. if ( SCESTATUS_SUCCESS == rc ) {
  3947. rc = ScepObjectSetKeySetting(
  3948. hSectionSap,
  3949. ObjectName,
  3950. retStat,
  3951. IsContainer,
  3952. NULL,
  3953. 0,
  3954. TRUE
  3955. );
  3956. }
  3957. }
  3958. //
  3959. // remove the SMP entry
  3960. //
  3961. if ( rc == SCESTATUS_SUCCESS ) {
  3962. rc = SceJetDelete(
  3963. hSectionSmp,
  3964. ObjectName,
  3965. FALSE,
  3966. SCEJET_DELETE_LINE_NO_CASE
  3967. );
  3968. }
  3969. }
  3970. }
  3971. ScepFree(ParentName);
  3972. if ( pAnalysisStatus ) {
  3973. *pAnalysisStatus = retStat;
  3974. }
  3975. return(rc);
  3976. }
  3977. SCESTATUS
  3978. ScepObjectRaiseNodesInPath(
  3979. IN PSCESECTION hSectionSap,
  3980. IN PWSTR ObjectName,
  3981. IN DWORD NameLen,
  3982. IN INT StartLevel,
  3983. IN INT EndLevel,
  3984. IN WCHAR Delim,
  3985. IN BYTE Status
  3986. )
  3987. {
  3988. BOOL LastOne=FALSE;
  3989. SCESTATUS rc = SCESTATUS_SUCCESS;
  3990. PWSTR NodeName=NULL;
  3991. //
  3992. // process each node in between the start level and end level
  3993. //
  3994. for ( INT i=StartLevel; rc==SCESTATUS_SUCCESS && i < EndLevel; i++ ) {
  3995. if ( NodeName == NULL ) {
  3996. NodeName = (PWSTR)ScepAlloc(0, (NameLen+1)*sizeof(WCHAR));
  3997. if ( NodeName == NULL ) {
  3998. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  3999. break;
  4000. }
  4001. }
  4002. //
  4003. // get level i full name
  4004. //
  4005. memset(NodeName, '\0', (NameLen+1)*sizeof(WCHAR));
  4006. rc = ScepGetFullNameInLevel(
  4007. ObjectName,
  4008. i,
  4009. Delim,
  4010. FALSE,
  4011. NodeName,
  4012. &LastOne
  4013. );
  4014. if ( rc == SCESTATUS_SUCCESS) {
  4015. if ( Status != (BYTE)SCE_NO_VALUE ) {
  4016. //
  4017. // raise the status
  4018. //
  4019. rc = ScepObjectSetKeySetting(
  4020. hSectionSap,
  4021. NodeName,
  4022. Status,
  4023. TRUE,
  4024. NULL,
  4025. 0,
  4026. TRUE
  4027. );
  4028. } else {
  4029. //
  4030. // remove the raise
  4031. //
  4032. rc = SceJetDelete(
  4033. hSectionSap,
  4034. NodeName,
  4035. FALSE,
  4036. SCEJET_DELETE_LINE_NO_CASE
  4037. );
  4038. }
  4039. }
  4040. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  4041. rc = SCESTATUS_SUCCESS;
  4042. }
  4043. if ( rc != SCESTATUS_SUCCESS ) {
  4044. break;
  4045. }
  4046. }
  4047. if ( NodeName ) {
  4048. ScepFree(NodeName);
  4049. }
  4050. return rc;
  4051. }
  4052. SCESTATUS
  4053. ScepObjectTotalLevel(
  4054. IN PWSTR ObjectName,
  4055. IN WCHAR Delim,
  4056. OUT PINT pLevel
  4057. )
  4058. /*
  4059. Routine Description:
  4060. Count total levels of the object name, for example, c:\winnt\system32
  4061. will return level of 3
  4062. Arguements:
  4063. ObjectName - the object's name in full path
  4064. Delim - the delimiter to look for
  4065. pLevel - the output level
  4066. Return Value:
  4067. SCESTATUS
  4068. */
  4069. {
  4070. PWSTR pStart;
  4071. if ( ObjectName == NULL || pLevel == NULL ) {
  4072. return(SCESTATUS_INVALID_PARAMETER);
  4073. }
  4074. pStart = ObjectName;
  4075. *pLevel = 0;
  4076. while (pStart) {
  4077. (*pLevel)++;
  4078. pStart = wcschr(pStart, Delim);
  4079. if ( pStart != NULL && *(pStart+1) != L'\0' )
  4080. pStart++;
  4081. else
  4082. break;
  4083. }
  4084. return(SCESTATUS_SUCCESS);
  4085. }
  4086. SCESTATUS
  4087. ScepObjectCompareKeySetting(
  4088. IN PSCESECTION hSectionSap,
  4089. IN PWSTR ObjectName,
  4090. IN SE_OBJECT_TYPE ObjectType,
  4091. IN BOOL IsContainer,
  4092. IN PSECURITY_DESCRIPTOR pSD,
  4093. IN SECURITY_INFORMATION SeInfo,
  4094. IN PSECURITY_DESCRIPTOR pScepSD,
  4095. OUT PBYTE pAnalysisStatus
  4096. )
  4097. /*
  4098. Routine Description:
  4099. Compare an object's setting with info in the section.
  4100. Arguements:
  4101. hSectionSap - the SAP section handle
  4102. others see ScepUpdateObjectInfo
  4103. Return Value:
  4104. SCESTATUS
  4105. */
  4106. {
  4107. SCESTATUS rc;
  4108. BYTE SapStatus;
  4109. PSECURITY_DESCRIPTOR pSapSD = NULL;
  4110. SECURITY_INFORMATION SapSeInfo;
  4111. DWORD Win32rc;
  4112. BYTE CompareStatus=0;
  4113. rc = ScepObjectGetKeySetting(
  4114. hSectionSap,
  4115. ObjectName,
  4116. &SapStatus,
  4117. NULL,
  4118. &pSapSD,
  4119. &SapSeInfo
  4120. );
  4121. if ( rc == SCESTATUS_SUCCESS ) {
  4122. //
  4123. // SAP record exists. was mismatched
  4124. //
  4125. Win32rc = ScepCompareObjectSecurity(
  4126. ObjectType,
  4127. IsContainer,
  4128. pSD,
  4129. pSapSD,
  4130. SeInfo,
  4131. &CompareStatus
  4132. );
  4133. if ( Win32rc != NO_ERROR ) {
  4134. rc = ScepDosErrorToSceStatus(Win32rc);
  4135. } else if ( !CompareStatus ) {
  4136. //
  4137. // new setting is same as the SAP setting - matched
  4138. // delete the SAP entry
  4139. //
  4140. rc = SceJetDelete(
  4141. hSectionSap,
  4142. ObjectName,
  4143. FALSE,
  4144. SCEJET_DELETE_LINE_NO_CASE
  4145. );
  4146. if ( pAnalysisStatus ) {
  4147. *pAnalysisStatus = SCE_STATUS_GOOD;
  4148. }
  4149. } else {
  4150. //
  4151. // still mismatched, just update the SMP entry (outside)
  4152. //
  4153. rc = ScepObjectSetKeySetting(
  4154. hSectionSap,
  4155. ObjectName,
  4156. CompareStatus, // SCE_STATUS_MISMATCH,
  4157. IsContainer,
  4158. pSapSD,
  4159. SapSeInfo,
  4160. TRUE
  4161. );
  4162. if ( pAnalysisStatus ) {
  4163. *pAnalysisStatus = CompareStatus; // SapStatus;
  4164. }
  4165. }
  4166. if ( pSapSD ) {
  4167. ScepFree(pSapSD);
  4168. }
  4169. } else if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  4170. rc = SCESTATUS_SUCCESS;
  4171. //
  4172. // no SAP record exist. was matched
  4173. //
  4174. Win32rc = ScepCompareObjectSecurity(
  4175. ObjectType,
  4176. IsContainer,
  4177. pSD,
  4178. pScepSD,
  4179. SeInfo,
  4180. &CompareStatus
  4181. );
  4182. if ( Win32rc != NO_ERROR ) {
  4183. rc = ScepDosErrorToSceStatus(Win32rc);
  4184. } else if ( CompareStatus ) {
  4185. //
  4186. // new setting is different from the SMP setting
  4187. // create SAP entry using the SMP setting
  4188. //
  4189. rc = ScepObjectSetKeySetting(
  4190. hSectionSap,
  4191. ObjectName,
  4192. CompareStatus, // SCE_STATUS_MISMATCH,
  4193. IsContainer,
  4194. pScepSD,
  4195. SeInfo,
  4196. TRUE
  4197. );
  4198. if ( pAnalysisStatus ) {
  4199. *pAnalysisStatus = CompareStatus; // SCE_STATUS_MISMATCH;
  4200. }
  4201. } else {
  4202. if ( pAnalysisStatus ) {
  4203. *pAnalysisStatus = SCE_STATUS_GOOD;
  4204. }
  4205. }
  4206. }
  4207. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  4208. rc = SCESTATUS_SUCCESS;
  4209. }
  4210. return(rc);
  4211. }
  4212. SCESTATUS
  4213. ScepObjectAdjustParentStatus(
  4214. IN PSCESECTION hSectionSmp,
  4215. IN PSCESECTION hSectionSap,
  4216. IN PWSTR ObjectName,
  4217. IN DWORD NameLen,
  4218. IN WCHAR Delim,
  4219. IN INT Level,
  4220. IN BYTE Flag,
  4221. OUT PINT ParentLevel,
  4222. OUT PBYTE ParentStatus OPTIONAL,
  4223. OUT PWSTR ParentName OPTIONAL
  4224. )
  4225. /*
  4226. Routine Description:
  4227. delete the ignored parent in the object's path (should only have one)
  4228. The following actions are taken when a IGNORE node is found:
  4229. (it should have N.C.ed in SAP but no children has N.C record)
  4230. delete all children in SMP and SAP
  4231. (force to have only no or one IGNORE in the path)
  4232. delete the SMP entry ( turn the IGNORE status to CHECK ?)
  4233. There should be no other nodes under a IGNORE node. But if there are,
  4234. delete them.
  4235. raise SAP status as "Not analyzed"
  4236. Arguments:
  4237. hSectionSmp - the SMP section handle
  4238. hSectionSap - the SAP section handle
  4239. ObjectName - the object's full name
  4240. NameLen - the length of the name
  4241. Delim - the delimiter to look for
  4242. Level - the total level of the object name
  4243. ParentLevel - output of its closest parent level
  4244. ParentStatus - output of its closest parent status
  4245. Return Value:
  4246. SCE status
  4247. */
  4248. {
  4249. SCESTATUS rc=SCESTATUS_SUCCESS;
  4250. INT i;
  4251. PWSTR Name=NULL;
  4252. BOOL LastOne;
  4253. DWORD ParentLen;
  4254. BYTE Status;
  4255. PSECURITY_DESCRIPTOR pScepSD=NULL;
  4256. SECURITY_INFORMATION SeInfo;
  4257. Name = (PWSTR)ScepAlloc(0, (NameLen+2)*sizeof(WCHAR));
  4258. if ( Name == NULL ) {
  4259. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  4260. }
  4261. *ParentLevel = 0;
  4262. for ( i=Level-1; i>=1; i-- ) {
  4263. //
  4264. // get level i full name
  4265. //
  4266. memset(Name, '\0', (NameLen+2)*sizeof(WCHAR));
  4267. rc = ScepGetFullNameInLevel(
  4268. ObjectName,
  4269. i,
  4270. Delim,
  4271. (Flag & SCE_OBJECT_SEARCH_JUNCTION) ? TRUE : FALSE,
  4272. Name,
  4273. &LastOne
  4274. );
  4275. if ( rc == SCESTATUS_SUCCESS ) {
  4276. //
  4277. // search and get information of this path
  4278. //
  4279. if ( Flag & SCE_OBJECT_SEARCH_JUNCTION ) {
  4280. DWORD Count=0;
  4281. rc = SceJetGetLineCount(
  4282. hSectionSmp,
  4283. Name,
  4284. FALSE,
  4285. &Count
  4286. );
  4287. if ( rc == SCESTATUS_SUCCESS &&
  4288. Count > 1 ) {
  4289. //
  4290. // there are other children under this node
  4291. // this is the junction point
  4292. //
  4293. *ParentLevel = i;
  4294. break;
  4295. }
  4296. //
  4297. // dont' care error
  4298. //
  4299. rc = SCESTATUS_SUCCESS;
  4300. } else {
  4301. ParentLen = wcslen(Name);
  4302. Status = (BYTE)-1;
  4303. rc = ScepObjectGetKeySetting(
  4304. hSectionSmp,
  4305. Name,
  4306. &Status,
  4307. NULL,
  4308. &pScepSD,
  4309. &SeInfo
  4310. );
  4311. if ( rc == SCESTATUS_SUCCESS ) {
  4312. //
  4313. // find a parent.
  4314. //
  4315. *ParentLevel = i;
  4316. if ( ParentStatus ) {
  4317. *ParentStatus = Status;
  4318. }
  4319. if ( ParentName ) {
  4320. wcscpy(ParentName, Name);
  4321. }
  4322. if ( (Flag & SCE_OBJECT_TURNOFF_IGNORE) &&
  4323. Status == SCE_STATUS_IGNORE ) {
  4324. //
  4325. // delete all SMP and SAP under this node
  4326. //
  4327. rc = ScepObjectDeleteScepAndAllChildren(
  4328. hSectionSmp,
  4329. hSectionSap,
  4330. Name,
  4331. TRUE,
  4332. SCE_STATUS_NOT_ANALYZED
  4333. );
  4334. /*
  4335. if ( rc == SCESTATUS_SUCCESS ) {
  4336. //
  4337. // change its status to CHECK,
  4338. //
  4339. rc = ScepObjectSetKeySetting(
  4340. hSectionSmp,
  4341. Name,
  4342. SCE_STATUS_CHECK,
  4343. TRUE,
  4344. pScepSD,
  4345. SeInfo,
  4346. TRUE
  4347. );
  4348. }
  4349. */
  4350. //
  4351. // all other nodes are deleted. should break out of the loop
  4352. //
  4353. }
  4354. if ( pScepSD ) {
  4355. ScepFree(pScepSD);
  4356. pScepSD = NULL;
  4357. }
  4358. if ( !(Flag & SCE_OBJECT_TURNOFF_IGNORE) ||
  4359. Status == SCE_STATUS_IGNORE ) {
  4360. if ( rc == SCESTATUS_RECORD_NOT_FOUND )
  4361. rc = SCESTATUS_SUCCESS;
  4362. break;
  4363. }
  4364. }
  4365. }
  4366. }
  4367. if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  4368. rc = SCESTATUS_SUCCESS;
  4369. }
  4370. //
  4371. // process next parent
  4372. //
  4373. if ( rc != SCESTATUS_SUCCESS )
  4374. break;
  4375. }
  4376. ScepFree(Name);
  4377. return(rc);
  4378. }
  4379. SCESTATUS
  4380. ScepObjectHasAnyChild(
  4381. IN PSCESECTION hSection,
  4382. IN PWSTR ObjectName,
  4383. IN DWORD NameLen,
  4384. IN WCHAR Delim,
  4385. OUT PBOOL bpHasChild
  4386. )
  4387. /*
  4388. Routine Description:
  4389. Detect if the object has child objects in the section
  4390. Arguements:
  4391. hSection - the section handle
  4392. ObjectName - the object name
  4393. NameLen - the name length
  4394. Delim - the delimeter to look for
  4395. bpHasChild - output TRUE if the object has a child in the section
  4396. Return Value:
  4397. SCESTATUS
  4398. */
  4399. {
  4400. SCESTATUS rc;
  4401. PWSTR pTemp=NULL;
  4402. if ( hSection == NULL || ObjectName == NULL ||
  4403. NameLen == 0 || Delim == L'\0' || bpHasChild == NULL ) {
  4404. return(SCESTATUS_INVALID_PARAMETER);
  4405. }
  4406. pTemp = (PWSTR)ScepAlloc(0, (NameLen+2)*sizeof(WCHAR));
  4407. if ( pTemp != NULL ) {
  4408. wcscpy(pTemp, ObjectName);
  4409. pTemp[NameLen] = Delim;
  4410. pTemp[NameLen+1] = L'\0';
  4411. rc = SceJetSeek(
  4412. hSection,
  4413. pTemp,
  4414. (NameLen+1)*sizeof(WCHAR),
  4415. SCEJET_SEEK_GE_NO_CASE
  4416. );
  4417. if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  4418. *bpHasChild = FALSE;
  4419. rc = SCESTATUS_SUCCESS;
  4420. } else if ( rc == SCESTATUS_SUCCESS ) {
  4421. *bpHasChild = TRUE;
  4422. }
  4423. ScepFree(pTemp);
  4424. } else
  4425. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  4426. return(rc);
  4427. }
  4428. SCESTATUS
  4429. ScepObjectRaiseChildrenInBetween(
  4430. IN PSCESECTION hSectionSmp,
  4431. IN PSCESECTION hSectionSap,
  4432. IN PWSTR ObjectName,
  4433. IN DWORD NameLen,
  4434. IN BOOL IsContainer,
  4435. IN BYTE Status,
  4436. IN BOOL bChangeStatusOnly
  4437. )
  4438. /*
  4439. Routine Description:
  4440. Delete any SAP entries for objects between Name and its children in SMP table
  4441. and raise SAP entries for bridge nodes to the Status specified.
  4442. For example, in the picture below, every SAP entry in the 1. level and 2. level
  4443. , except the C nodes, should be deleted from SAP. Then 1. and 2. nodes are
  4444. raised as Status.
  4445. p
  4446. /
  4447. .
  4448. N <----
  4449. / |
  4450. 1. C
  4451. / \
  4452. 2. C
  4453. /|
  4454. C C
  4455. Arguments:
  4456. hSectionSmp - the SMP section handle
  4457. hSection - the SAP section handle
  4458. Name - the object name
  4459. NameLen - the length of the name
  4460. Status - the object's status to raise
  4461. Return Value:
  4462. SCE status
  4463. */
  4464. {
  4465. SCESTATUS rc;
  4466. PWSTR *pSmpNames=NULL;
  4467. DWORD *pSmpNameLen=NULL;
  4468. DWORD cntNames=0;
  4469. BOOL bFirst=TRUE;
  4470. WCHAR Delim=L'\\';
  4471. DWORD DirLen = wcslen(ObjectName);
  4472. if ( ObjectName[DirLen-1] != Delim ) {
  4473. DirLen++;
  4474. }
  4475. PWSTR DirName = (PWSTR)ScepAlloc(0, (DirLen+1)*sizeof(WCHAR));
  4476. if ( DirName == NULL ) {
  4477. return(SCESTATUS_NOT_ENOUGH_RESOURCE);
  4478. }
  4479. wcscpy(DirName, ObjectName);
  4480. if ( DirName[DirLen-1] != Delim ) {
  4481. DirName[DirLen-1] = Delim;
  4482. }
  4483. //
  4484. // get all children of DirName in SMP
  4485. //
  4486. rc = SceJetGetLineCount(
  4487. hSectionSmp,
  4488. DirName,
  4489. FALSE,
  4490. &cntNames);
  4491. DWORD index=0;
  4492. if ( rc == SCESTATUS_SUCCESS ) {
  4493. pSmpNames = (PWSTR *)ScepAlloc(LPTR, cntNames*sizeof(PWSTR));
  4494. pSmpNameLen = (DWORD *)ScepAlloc(LPTR, cntNames*sizeof(DWORD));
  4495. if ( pSmpNames != NULL && pSmpNameLen != NULL ) {
  4496. //
  4497. // get each name loaded into this array
  4498. //
  4499. PWSTR Buffer=NULL;
  4500. DWORD KeyLen;
  4501. rc = SceJetGetValue(
  4502. hSectionSmp,
  4503. SCEJET_PREFIX_MATCH_NO_CASE,
  4504. DirName,
  4505. NULL,
  4506. 0,
  4507. &KeyLen,
  4508. NULL,
  4509. 0,
  4510. NULL
  4511. );
  4512. bFirst = TRUE;
  4513. while ( rc == SCESTATUS_SUCCESS ) {
  4514. Buffer = (PWSTR)ScepAlloc(LPTR, (KeyLen+1)*sizeof(WCHAR));
  4515. if ( Buffer == NULL ) {
  4516. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  4517. break;
  4518. }
  4519. rc = SceJetGetValue(
  4520. hSectionSmp,
  4521. SCEJET_CURRENT,
  4522. NULL,
  4523. Buffer,
  4524. KeyLen*sizeof(WCHAR),
  4525. NULL,
  4526. NULL,
  4527. 0,
  4528. NULL
  4529. );
  4530. if ( rc == SCESTATUS_SUCCESS ) {
  4531. if ( !bFirst ||
  4532. _wcsicmp(DirName, Buffer) != 0 ) {
  4533. //
  4534. // ignore the object itself
  4535. //
  4536. pSmpNames[index] = Buffer;
  4537. pSmpNameLen[index] = wcslen(Buffer);
  4538. Buffer = NULL;
  4539. index++;
  4540. }
  4541. bFirst = FALSE;
  4542. } else {
  4543. ScepFree(Buffer);
  4544. Buffer = NULL;
  4545. break;
  4546. }
  4547. //
  4548. // read next line
  4549. //
  4550. rc = SceJetGetValue(
  4551. hSectionSmp,
  4552. SCEJET_NEXT_LINE,
  4553. NULL,
  4554. NULL,
  4555. 0,
  4556. &KeyLen,
  4557. NULL,
  4558. 0,
  4559. NULL
  4560. );
  4561. }
  4562. } else {
  4563. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  4564. }
  4565. }
  4566. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  4567. rc = SCESTATUS_SUCCESS;
  4568. }
  4569. if ( SCESTATUS_SUCCESS == rc ) {
  4570. //
  4571. // should have one or more children but if it's 0
  4572. // delete everything in SAP
  4573. //
  4574. if ( cntNames == 0 || pSmpNames == NULL ||
  4575. pSmpNameLen == NULL ||
  4576. pSmpNameLen[0] == 0 || pSmpNames[0] == NULL ) {
  4577. rc = SceJetDelete(
  4578. hSectionSap,
  4579. DirName,
  4580. TRUE,
  4581. SCEJET_DELETE_PARTIAL_NO_CASE
  4582. );
  4583. } else if ( !bChangeStatusOnly ) {
  4584. //
  4585. // get each name loaded into this array
  4586. //
  4587. PWSTR Buffer=NULL;
  4588. DWORD KeyLen;
  4589. rc = SceJetGetValue(
  4590. hSectionSap,
  4591. SCEJET_PREFIX_MATCH_NO_CASE,
  4592. DirName,
  4593. NULL,
  4594. 0,
  4595. &KeyLen,
  4596. NULL,
  4597. 0,
  4598. NULL
  4599. );
  4600. bFirst = TRUE;
  4601. index = 0;
  4602. while ( rc == SCESTATUS_SUCCESS ) {
  4603. Buffer = (PWSTR)ScepAlloc(LPTR, (KeyLen+1)*sizeof(WCHAR));
  4604. if ( Buffer == NULL ) {
  4605. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  4606. break;
  4607. }
  4608. rc = SceJetGetValue(
  4609. hSectionSap,
  4610. SCEJET_CURRENT,
  4611. NULL,
  4612. Buffer,
  4613. KeyLen*sizeof(WCHAR),
  4614. NULL,
  4615. NULL,
  4616. 0,
  4617. NULL
  4618. );
  4619. if ( rc == SCESTATUS_SUCCESS &&
  4620. (!bFirst ||
  4621. _wcsicmp(DirName, Buffer) != 0) ) {
  4622. //
  4623. // ignore the object itself
  4624. // compare with the next child in SMP
  4625. // if it's before the next child, should delete it
  4626. //
  4627. int ci = _wcsnicmp(Buffer, pSmpNames[index], pSmpNameLen[index]);
  4628. while ( rc == SCESTATUS_SUCCESS &&
  4629. ci > 0 ) {
  4630. //
  4631. // this is the component or next one, move on to next one
  4632. //
  4633. index++;
  4634. if ( index >= cntNames || pSmpNames[index] == NULL ||
  4635. pSmpNameLen[index] == 0 ) {
  4636. //
  4637. // no more SMP child. We are done.
  4638. //
  4639. rc = SCESTATUS_RECORD_NOT_FOUND;
  4640. } else {
  4641. //
  4642. // already bigger than this child
  4643. //
  4644. ci = _wcsnicmp(Buffer, pSmpNames[index], pSmpNameLen[index]);
  4645. }
  4646. }
  4647. if ( ci < 0 ) {
  4648. SceJetDelete(
  4649. hSectionSap,
  4650. NULL, // delete the current line
  4651. FALSE,
  4652. SCEJET_DELETE_LINE
  4653. );
  4654. }
  4655. }
  4656. bFirst = FALSE;
  4657. ScepFree(Buffer);
  4658. Buffer = NULL;
  4659. if ( rc == SCESTATUS_SUCCESS ) {
  4660. //
  4661. // read next line
  4662. //
  4663. rc = SceJetGetValue(
  4664. hSectionSap,
  4665. SCEJET_NEXT_LINE,
  4666. NULL,
  4667. NULL,
  4668. 0,
  4669. &KeyLen,
  4670. NULL,
  4671. 0,
  4672. NULL
  4673. );
  4674. }
  4675. }
  4676. }
  4677. }
  4678. //
  4679. // raise SAP entries for branch nodes between ObjectName and
  4680. // SMP names as Status, then free smp names array
  4681. //
  4682. if ( SCESTATUS_RECORD_NOT_FOUND == rc ) {
  4683. rc = SCESTATUS_SUCCESS;
  4684. }
  4685. SCESTATUS rc2 = rc;
  4686. INT StartLevel=0, EndLevel=0;
  4687. if ( pSmpNames ) {
  4688. ScepObjectTotalLevel(ObjectName, Delim, &StartLevel);
  4689. StartLevel++;
  4690. for ( index=0; index<cntNames; index++) {
  4691. if ( pSmpNames[index] ) {
  4692. if ( SCESTATUS_SUCCESS == rc2 ) {
  4693. //
  4694. // get this object level
  4695. //
  4696. ScepObjectTotalLevel(pSmpNames[index], Delim, &EndLevel);
  4697. rc2 = ScepObjectRaiseNodesInPath(
  4698. hSectionSap,
  4699. pSmpNames[index],
  4700. pSmpNameLen[index],
  4701. StartLevel,
  4702. EndLevel,
  4703. Delim,
  4704. Status
  4705. );
  4706. if ( rc2 == SCESTATUS_RECORD_NOT_FOUND ) {
  4707. rc2 = SCESTATUS_SUCCESS;
  4708. }
  4709. if ( rc2 != SCESTATUS_SUCCESS ) {
  4710. rc = rc2;
  4711. }
  4712. }
  4713. ScepFree(pSmpNames[index]);
  4714. }
  4715. }
  4716. ScepFree(pSmpNames);
  4717. }
  4718. if ( pSmpNameLen ) {
  4719. ScepFree(pSmpNameLen);
  4720. }
  4721. ScepFree(DirName);
  4722. return rc;
  4723. }
  4724. SCESTATUS
  4725. ScepGetFullNameInLevel(
  4726. IN PCWSTR ObjectFullName,
  4727. IN DWORD Level,
  4728. IN WCHAR Delim,
  4729. IN BOOL bWithLastDelim,
  4730. OUT PWSTR Buffer,
  4731. OUT PBOOL LastOne
  4732. )
  4733. /* ++
  4734. Routine Description:
  4735. This routine parses a full path name and returns the component for the
  4736. level. For example, a object name "c:\winnt\system32" will return c: for
  4737. level 1, winnt for level 2, and system32 for level 3. This routine is
  4738. used when add a object to the security tree.
  4739. Arguments:
  4740. ObjectFullName - The full path name of the object
  4741. Level - the level of component to return
  4742. Delim - the deliminator to look for
  4743. Buffer - The address of buffer for the full path name to the level
  4744. LastOne - Flag to indicate if the component is the last one
  4745. Return value:
  4746. SCESTATUS
  4747. -- */
  4748. {
  4749. PWSTR pTemp, pStart;
  4750. DWORD i;
  4751. ULONG Len = 0;
  4752. if ( ObjectFullName == NULL )
  4753. return(SCESTATUS_INVALID_PARAMETER);
  4754. //
  4755. // loop through the object name to find the level
  4756. // if there is no such level, return INVALID_PARAMETER
  4757. //
  4758. pStart = (PWSTR)ObjectFullName;
  4759. for ( i=0; i<Level; i++) {
  4760. pTemp = wcschr(pStart, Delim);
  4761. if ( i == Level-1 ) {
  4762. //
  4763. // find the right level
  4764. //
  4765. if ( pTemp == NULL ) {
  4766. wcscpy(Buffer, ObjectFullName);
  4767. if ( bWithLastDelim ) {
  4768. Len = wcslen(ObjectFullName);
  4769. if (Buffer[Len - 1] != Delim)
  4770. Buffer[Len] = Delim;
  4771. }
  4772. *LastOne = TRUE;
  4773. } else {
  4774. Len = (DWORD)(pTemp - ObjectFullName);
  4775. if ( bWithLastDelim ) {
  4776. Len++;
  4777. }
  4778. wcsncpy(Buffer, ObjectFullName, Len);
  4779. if ( *(pTemp+1) == L'\0' )
  4780. *LastOne = TRUE;
  4781. else
  4782. *LastOne = FALSE;
  4783. }
  4784. } else {
  4785. if ( pTemp == NULL )
  4786. return(SCESTATUS_INVALID_PARAMETER);
  4787. else
  4788. pStart = pTemp + 1;
  4789. }
  4790. }
  4791. return(SCESTATUS_SUCCESS);
  4792. }
  4793. SCESTATUS
  4794. ScepUpdateLocalTable(
  4795. IN PSCECONTEXT hProfile,
  4796. IN AREA_INFORMATION Area,
  4797. IN PSCE_PROFILE_INFO pInfo,
  4798. IN DWORD dwMode
  4799. )
  4800. {
  4801. SCESTATUS rc=SCESTATUS_SUCCESS;
  4802. if ( Area & AREA_SECURITY_POLICY ) {
  4803. rc = ScepUpdateSystemAccess(hProfile,
  4804. pInfo,
  4805. NULL,
  4806. NULL,
  4807. dwMode
  4808. );
  4809. if ( rc == SCESTATUS_SUCCESS) {
  4810. //
  4811. // Update system auditing section
  4812. //
  4813. rc = ScepUpdateSystemAuditing(hProfile,
  4814. pInfo,
  4815. NULL,
  4816. NULL,
  4817. dwMode);
  4818. if ( rc == SCESTATUS_SUCCESS) {
  4819. //
  4820. // Update log sections
  4821. //
  4822. rc = ScepUpdateLogs(hProfile,
  4823. pInfo,
  4824. NULL,
  4825. NULL,
  4826. dwMode
  4827. );
  4828. if ( rc == SCESTATUS_SUCCESS && pInfo->pKerberosInfo ) {
  4829. //
  4830. // Update kerberos policy
  4831. //
  4832. rc = ScepUpdateKerberos(hProfile,
  4833. pInfo->pKerberosInfo,
  4834. NULL,
  4835. NULL,
  4836. dwMode
  4837. );
  4838. }
  4839. if ( rc == SCESTATUS_SUCCESS ) {
  4840. //
  4841. // update registry values
  4842. //
  4843. rc = ScepUpdateLocalRegValues(hProfile,
  4844. pInfo,
  4845. dwMode
  4846. );
  4847. }
  4848. //
  4849. // Note: policy attachment is not updated through this API
  4850. //
  4851. }
  4852. }
  4853. if ( rc != SCESTATUS_SUCCESS ) {
  4854. return(rc);
  4855. }
  4856. }
  4857. if ( Area & AREA_PRIVILEGES ) {
  4858. //
  4859. // update user rights
  4860. //
  4861. rc = ScepUpdateLocalPrivileges(
  4862. hProfile,
  4863. pInfo->OtherInfo.smp.pPrivilegeAssignedTo,
  4864. dwMode
  4865. );
  4866. }
  4867. return rc;
  4868. }
  4869. SCESTATUS
  4870. ScepUpdateLocalSection(
  4871. IN PSCECONTEXT hProfile,
  4872. IN PSCE_PROFILE_INFO pInfo,
  4873. IN SCE_KEY_LOOKUP *Keys,
  4874. IN DWORD cKeys,
  4875. IN PCWSTR SectionName,
  4876. IN DWORD dwMode
  4877. )
  4878. /*
  4879. Routine Description:
  4880. Update each key in the Keys array based on the editing rule. SMP entry is
  4881. updated with the new value. SAP entry is either deleted, or created, depending
  4882. on the new computed analysis status.
  4883. Arguements:
  4884. hProfile - the jet database handle
  4885. pInfo - the changed info buffer
  4886. Keys - the lookup keys array
  4887. cKeys - the number of keys in the array
  4888. SecitonName - the section name to work on
  4889. Return Value:
  4890. SCESTATUS
  4891. */
  4892. {
  4893. SCESTATUS rc;
  4894. PSCESECTION hSectionSmp=NULL;
  4895. DWORD i;
  4896. UINT Offset;
  4897. DWORD val;
  4898. //
  4899. // open smp section for system access
  4900. //
  4901. rc = ScepOpenSectionForName(
  4902. hProfile,
  4903. SCE_ENGINE_SMP,
  4904. SectionName,
  4905. &hSectionSmp
  4906. );
  4907. if ( rc == SCESTATUS_SUCCESS ) {
  4908. if ( !( dwMode & SCE_UPDATE_DIRTY_ONLY) ) {
  4909. SceJetDelete(hSectionSmp, NULL, FALSE, SCEJET_DELETE_SECTION);
  4910. }
  4911. for ( i=0; i<cKeys; i++) {
  4912. //
  4913. // get settings in AccessLookup table
  4914. //
  4915. Offset = Keys[i].Offset;
  4916. switch ( Keys[i].BufferType ) {
  4917. case 'B':
  4918. break;
  4919. case 'D':
  4920. val = *((DWORD *)((CHAR *)pInfo+Offset));
  4921. if ( val != SCE_NO_VALUE ) {
  4922. //
  4923. // something changed for this one
  4924. //
  4925. if ( ( dwMode & SCE_UPDATE_DIRTY_ONLY ) &&
  4926. ( val == SCE_DELETE_VALUE ) ) {
  4927. rc = SceJetDelete(
  4928. hSectionSmp,
  4929. Keys[i].KeyString,
  4930. FALSE,
  4931. SCEJET_DELETE_LINE_NO_CASE
  4932. );
  4933. } else {
  4934. //
  4935. // update the SMP entry
  4936. //
  4937. rc = ScepCompareAndSaveIntValue(
  4938. hSectionSmp,
  4939. Keys[i].KeyString,
  4940. FALSE,
  4941. SCE_NO_VALUE,
  4942. val
  4943. );
  4944. }
  4945. if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  4946. //
  4947. // if not find for delete, ignore the error
  4948. //
  4949. rc = SCESTATUS_SUCCESS;
  4950. }
  4951. }
  4952. break;
  4953. default:
  4954. break;
  4955. }
  4956. if ( rc != SCESTATUS_SUCCESS ) {
  4957. break;
  4958. }
  4959. }
  4960. SceJetCloseSection(&hSectionSmp, TRUE);
  4961. }
  4962. return(rc);
  4963. }
  4964. SCESTATUS
  4965. ScepUpdateLocalRegValues(
  4966. IN PSCECONTEXT hProfile,
  4967. IN PSCE_PROFILE_INFO pInfo,
  4968. IN DWORD dwMode
  4969. )
  4970. {
  4971. if ( hProfile == NULL || pInfo == NULL ) {
  4972. return(SCESTATUS_INVALID_PARAMETER);
  4973. }
  4974. if ( pInfo->RegValueCount == 0 ||
  4975. pInfo->aRegValues == NULL ) {
  4976. //
  4977. // impossible to have a empty buffer to update
  4978. // this buffer should contain all available registry values to configure/analyze
  4979. //
  4980. return(SCESTATUS_SUCCESS);
  4981. }
  4982. SCESTATUS rc;
  4983. PSCESECTION hSectionSmp=NULL;
  4984. DWORD i;
  4985. //
  4986. // open smp section for system access
  4987. //
  4988. rc = ScepOpenSectionForName(
  4989. hProfile,
  4990. SCE_ENGINE_SMP,
  4991. szRegistryValues,
  4992. &hSectionSmp
  4993. );
  4994. if ( rc == SCESTATUS_SUCCESS ) {
  4995. if ( !(dwMode & SCE_UPDATE_DIRTY_ONLY) ) {
  4996. SceJetDelete(hSectionSmp, NULL, FALSE, SCEJET_DELETE_SECTION);
  4997. }
  4998. for (i=0; i<pInfo->RegValueCount; i++ ) {
  4999. if ( !(pInfo->aRegValues[i].FullValueName) ) {
  5000. continue;
  5001. }
  5002. if ( ( dwMode & SCE_UPDATE_DIRTY_ONLY) &&
  5003. (pInfo->aRegValues[i].ValueType == SCE_DELETE_VALUE) ) {
  5004. rc = SceJetDelete(
  5005. hSectionSmp,
  5006. pInfo->aRegValues[i].FullValueName,
  5007. FALSE,
  5008. SCEJET_DELETE_LINE_NO_CASE
  5009. );
  5010. } else {
  5011. //
  5012. // update the SMP entry
  5013. //
  5014. rc = ScepSaveRegValueEntry(
  5015. hSectionSmp,
  5016. pInfo->aRegValues[i].FullValueName,
  5017. pInfo->aRegValues[i].Value,
  5018. pInfo->aRegValues[i].ValueType,
  5019. 0
  5020. );
  5021. }
  5022. if ( rc == SCESTATUS_RECORD_NOT_FOUND ) {
  5023. //
  5024. // if not find for delete, ignore the error
  5025. //
  5026. rc = SCESTATUS_SUCCESS;
  5027. }
  5028. if ( SCESTATUS_SUCCESS != rc ) {
  5029. break;
  5030. }
  5031. }
  5032. SceJetCloseSection(&hSectionSmp, TRUE);
  5033. }
  5034. return(rc);
  5035. }
  5036. SCESTATUS
  5037. ScepUpdateLocalPrivileges(
  5038. IN PSCECONTEXT hProfile,
  5039. IN PSCE_PRIVILEGE_ASSIGNMENT pNewPriv,
  5040. IN DWORD dwMode
  5041. )
  5042. /*
  5043. Routine Description:
  5044. Update privileges
  5045. Arguements:
  5046. hProfile - the jet database handle
  5047. pNewPriv - the changed info buffer
  5048. pBufScep - the original SMP priv buffer
  5049. Return Value:
  5050. SCESTATUS
  5051. */
  5052. {
  5053. if ( hProfile == NULL ) {
  5054. return(SCESTATUS_INVALID_PARAMETER);
  5055. }
  5056. LSA_HANDLE LsaHandle=NULL;
  5057. SCESTATUS rc;
  5058. rc = RtlNtStatusToDosError(
  5059. ScepOpenLsaPolicy(
  5060. MAXIMUM_ALLOWED,
  5061. &LsaHandle,
  5062. TRUE
  5063. ));
  5064. if ( ERROR_SUCCESS != rc ) {
  5065. return(ScepDosErrorToSceStatus(rc));
  5066. }
  5067. PSCESECTION hSectionSmp=NULL;
  5068. //
  5069. // open smp section for system access
  5070. //
  5071. rc = ScepOpenSectionForName(
  5072. hProfile,
  5073. SCE_ENGINE_SMP,
  5074. szPrivilegeRights,
  5075. &hSectionSmp
  5076. );
  5077. if ( rc == SCESTATUS_SUCCESS ) {
  5078. if ( !(dwMode & SCE_UPDATE_DIRTY_ONLY) ) {
  5079. SceJetDelete(hSectionSmp, NULL, FALSE, SCEJET_DELETE_SECTION);
  5080. }
  5081. PSCE_PRIVILEGE_ASSIGNMENT pPriv;
  5082. for ( pPriv=pNewPriv; pPriv != NULL; pPriv = pPriv->Next ) {
  5083. //
  5084. // Process each privilege in the new list
  5085. //
  5086. if ( pPriv->Name == NULL ) {
  5087. continue;
  5088. }
  5089. if ( ( dwMode & SCE_UPDATE_DIRTY_ONLY) &&
  5090. ( pPriv->Status == SCE_DELETE_VALUE) ) {
  5091. rc = SceJetDelete(
  5092. hSectionSmp,
  5093. pPriv->Name,
  5094. FALSE,
  5095. SCEJET_DELETE_LINE_NO_CASE
  5096. );
  5097. } else {
  5098. rc = ScepWriteNameListValue(
  5099. LsaHandle,
  5100. hSectionSmp,
  5101. pPriv->Name,
  5102. pPriv->AssignedTo,
  5103. SCE_WRITE_EMPTY_LIST | SCE_WRITE_CONVERT | SCE_WRITE_LOCAL_TABLE,
  5104. 0
  5105. );
  5106. }
  5107. if ( rc == SCESTATUS_RECORD_NOT_FOUND )
  5108. rc = SCESTATUS_SUCCESS;
  5109. if ( rc != SCESTATUS_SUCCESS) {
  5110. break;
  5111. }
  5112. }
  5113. SceJetCloseSection(&hSectionSmp, TRUE);
  5114. }
  5115. if ( LsaHandle ) {
  5116. LsaClose(LsaHandle);
  5117. }
  5118. return(rc);
  5119. }
  5120. DWORD
  5121. ScepConvertNameListFormat(
  5122. IN LSA_HANDLE LsaHandle,
  5123. IN PSCE_NAME_LIST pInList,
  5124. IN DWORD FromFormat,
  5125. IN DWORD ToFormat,
  5126. OUT PSCE_NAME_LIST *ppOutList
  5127. )
  5128. {
  5129. if (LsaHandle == NULL || ppOutList == NULL ) {
  5130. return(ERROR_INVALID_PARAMETER);
  5131. }
  5132. *ppOutList = NULL;
  5133. PSCE_NAME_LIST pList;
  5134. DWORD rc = ERROR_SUCCESS;
  5135. PWSTR SidString=NULL;
  5136. for ( pList=pInList; pList != NULL; pList=pList->Next ) {
  5137. if ( pList->Name == NULL ) {
  5138. continue;
  5139. }
  5140. if ( wcschr(pList->Name, L'\\') ) {
  5141. rc = ScepLookupNameAndAddToSidStringList(
  5142. LsaHandle,
  5143. ppOutList,
  5144. pList->Name,
  5145. wcslen(pList->Name)
  5146. );
  5147. } else if ( ScepLookupWellKnownName(
  5148. pList->Name,
  5149. LsaHandle,
  5150. &SidString ) ) {
  5151. rc = ScepAddTwoNamesToNameList(
  5152. ppOutList,
  5153. FALSE,
  5154. NULL,
  5155. 0,
  5156. SidString,
  5157. wcslen(SidString)
  5158. );
  5159. } else {
  5160. rc = ScepAddToNameList(ppOutList, pList->Name, 0);
  5161. }
  5162. if ( rc != ERROR_SUCCESS ) {
  5163. break;
  5164. }
  5165. }
  5166. if ( rc != ERROR_SUCCESS &&
  5167. (*ppOutList ) ) {
  5168. ScepFreeNameList(*ppOutList);
  5169. *ppOutList = NULL;
  5170. }
  5171. return(rc);
  5172. }
  5173. DWORD
  5174. ScepConvertPrivilegeList(
  5175. IN LSA_HANDLE LsaHandle,
  5176. IN PSCE_PRIVILEGE_ASSIGNMENT pFromList,
  5177. IN DWORD FromFormat,
  5178. IN DWORD ToFormat,
  5179. OUT PSCE_PRIVILEGE_ASSIGNMENT *ppToList
  5180. )
  5181. {
  5182. if ( LsaHandle == NULL || pFromList == NULL || ppToList == NULL ) {
  5183. return(ERROR_INVALID_PARAMETER);
  5184. }
  5185. if ( FromFormat != 0 ||
  5186. ToFormat != SCE_ACCOUNT_SID_STRING ) {
  5187. return(ERROR_NOT_SUPPORTED);
  5188. }
  5189. //
  5190. // only support name->sid string convert, for now.
  5191. //
  5192. DWORD rc = ERROR_SUCCESS;
  5193. PSCE_PRIVILEGE_ASSIGNMENT pPriv, pPriv2;
  5194. PSCE_NAME_LIST pTempList=NULL;
  5195. for ( pPriv=pFromList; pPriv != NULL; pPriv=pPriv->Next ) {
  5196. if ( pPriv->Name == NULL ) {
  5197. continue;
  5198. }
  5199. rc = ScepConvertNameListFormat(LsaHandle,
  5200. pPriv->AssignedTo,
  5201. FromFormat,
  5202. ToFormat,
  5203. &pTempList
  5204. );
  5205. if ( rc != ERROR_SUCCESS ) {
  5206. break;
  5207. }
  5208. //
  5209. // a sce_privilege_assignment structure. allocate buffer
  5210. //
  5211. pPriv2 = (PSCE_PRIVILEGE_ASSIGNMENT)ScepAlloc( LMEM_ZEROINIT,
  5212. sizeof(SCE_PRIVILEGE_ASSIGNMENT) );
  5213. if ( pPriv2 == NULL ) {
  5214. rc = ERROR_NOT_ENOUGH_MEMORY;
  5215. break;
  5216. }
  5217. pPriv2->Name = (PWSTR)ScepAlloc( (UINT)0, (wcslen(pPriv->Name)+1)*sizeof(WCHAR));
  5218. if ( pPriv2->Name == NULL ) {
  5219. ScepFree(pPriv2);
  5220. rc = ERROR_NOT_ENOUGH_MEMORY;
  5221. break;
  5222. }
  5223. wcscpy(pPriv2->Name, pPriv->Name);
  5224. pPriv2->Value = pPriv->Value;
  5225. pPriv2->Status = pPriv->Status;
  5226. pPriv2->AssignedTo = pTempList;
  5227. pTempList = NULL;
  5228. pPriv2->Next = *ppToList;
  5229. *ppToList = pPriv2;
  5230. }
  5231. if ( pTempList ) {
  5232. ScepFreeNameList(pTempList);
  5233. }
  5234. if ( rc != ERROR_SUCCESS &&
  5235. (*ppToList) ) {
  5236. //
  5237. // free the output list
  5238. //
  5239. ScepFreePrivilege(*ppToList);
  5240. *ppToList = NULL;
  5241. }
  5242. return(rc);
  5243. }