/lsass/server/store/samdb/samdbsecurity.c

https://github.com/BeyondTrust/pbis-open · C · 1448 lines · 1104 code · 250 blank · 94 comment · 77 complexity · 9bf507d794141c42b1bfd5ed7de83bff MD5 · raw file

  1. /* Editor Settings: expandtabs and use 4 spaces for indentation
  2. * ex: set softtabstop=4 tabstop=8 expandtab shiftwidth=4: *
  3. */
  4. /*
  5. * Copyright © BeyondTrust Software 2004 - 2019
  6. * All rights reserved.
  7. *
  8. * Licensed under the Apache License, Version 2.0 (the "License");
  9. * you may not use this file except in compliance with the License.
  10. * You may obtain a copy of the License at
  11. *
  12. * http://www.apache.org/licenses/LICENSE-2.0
  13. *
  14. * Unless required by applicable law or agreed to in writing, software
  15. * distributed under the License is distributed on an "AS IS" BASIS,
  16. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. * See the License for the specific language governing permissions and
  18. * limitations under the License.
  19. *
  20. * BEYONDTRUST MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING TERMS AS
  21. * WELL. IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT WITH
  22. * BEYONDTRUST, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE TERMS OF THAT
  23. * SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE APACHE LICENSE,
  24. * NOTWITHSTANDING THE ABOVE NOTICE. IF YOU HAVE QUESTIONS, OR WISH TO REQUEST
  25. * A COPY OF THE ALTERNATE LICENSING TERMS OFFERED BY BEYONDTRUST, PLEASE CONTACT
  26. * BEYONDTRUST AT beyondtrust.com/contact
  27. */
  28. /*
  29. * Copyright (C) BeyondTrust Software. All rights reserved.
  30. *
  31. * Module Name:
  32. *
  33. * samdbsecurity.c
  34. *
  35. * Abstract:
  36. *
  37. *
  38. * BeyondTrust SAM Database Provider
  39. *
  40. * Security Descriptor handling routines
  41. *
  42. * Authors: Rafal Szczesniak (rafal@likewise.com)
  43. *
  44. */
  45. #include "includes.h"
  46. typedef struct _ACCESS_LIST
  47. {
  48. PSID *ppSid;
  49. ACCESS_MASK AccessMask;
  50. ULONG ulAccessType;
  51. } ACCESS_LIST, *PACCESS_LIST;
  52. static
  53. DWORD
  54. SamDbCreateLocalDomainDacl(
  55. PSID pSid,
  56. PACL *ppDacl
  57. );
  58. static
  59. DWORD
  60. SamDbCreateBuiltinDomainDacl(
  61. PSID pSid,
  62. PACL *ppDacl
  63. );
  64. static
  65. DWORD
  66. SamDbCreateLocalUserDacl(
  67. PSID pSid,
  68. PACL *ppDacl
  69. );
  70. static
  71. DWORD
  72. SamDbCreateLocalGroupDacl(
  73. PSID pSid,
  74. PACL *ppDacl
  75. );
  76. static
  77. DWORD
  78. SamDbCreateBuiltinGroupDacl(
  79. PSID pSid,
  80. PACL *ppDacl
  81. );
  82. static
  83. DWORD
  84. SamDbCreateNewLocalAccountDacl(
  85. PSID pSid,
  86. PACL *ppDacl
  87. );
  88. static
  89. DWORD
  90. SamDbCreateDacl(
  91. PACL *ppDacl,
  92. PACCESS_LIST pList
  93. );
  94. DWORD
  95. SamDbCreateLocalDomainSecDesc(
  96. PSID pSid,
  97. PSECURITY_DESCRIPTOR_RELATIVE *ppSecDescRel,
  98. PULONG pulSecDescLen
  99. )
  100. {
  101. DWORD dwError = ERROR_SUCCESS;
  102. NTSTATUS ntStatus = STATUS_SUCCESS;
  103. PSID pOwnerSid = NULL;
  104. PSID pGroupSid = NULL;
  105. PSECURITY_DESCRIPTOR_ABSOLUTE pSecDesc = NULL;
  106. PSECURITY_DESCRIPTOR_RELATIVE pSecDescRel = NULL;
  107. PSECURITY_DESCRIPTOR_RELATIVE pNewSecDescRel = NULL;
  108. ULONG ulSecDescLen = 1024;
  109. PACL pDacl = NULL;
  110. dwError = LwAllocateMemory(SECURITY_DESCRIPTOR_ABSOLUTE_MIN_SIZE,
  111. OUT_PPVOID(&pSecDesc));
  112. BAIL_ON_SAMDB_ERROR(dwError);
  113. ntStatus = RtlCreateSecurityDescriptorAbsolute(
  114. pSecDesc,
  115. SECURITY_DESCRIPTOR_REVISION);
  116. BAIL_ON_NT_STATUS(ntStatus);
  117. /*
  118. * Set owner to SYSTEM
  119. */
  120. dwError = LwAllocateWellKnownSid(WinLocalSystemSid,
  121. NULL,
  122. &pOwnerSid,
  123. NULL);
  124. BAIL_ON_SAMDB_ERROR(dwError);
  125. ntStatus = RtlSetOwnerSecurityDescriptor(
  126. pSecDesc,
  127. pOwnerSid,
  128. FALSE);
  129. BAIL_ON_NT_STATUS(ntStatus);
  130. /*
  131. * Set group to BUILTIN\Administrators
  132. */
  133. dwError = LwAllocateWellKnownSid(WinBuiltinAdministratorsSid,
  134. NULL,
  135. &pGroupSid,
  136. NULL);
  137. BAIL_ON_SAMDB_ERROR(dwError);
  138. ntStatus = RtlSetGroupSecurityDescriptor(
  139. pSecDesc,
  140. pGroupSid,
  141. FALSE);
  142. BAIL_ON_NT_STATUS(ntStatus);
  143. /* Create default DACL */
  144. dwError = SamDbCreateLocalDomainDacl(pSid,
  145. &pDacl);
  146. BAIL_ON_SAMDB_ERROR(dwError);
  147. ntStatus = RtlSetDaclSecurityDescriptor(
  148. pSecDesc,
  149. TRUE,
  150. pDacl,
  151. FALSE);
  152. BAIL_ON_NT_STATUS(ntStatus);
  153. do
  154. {
  155. dwError = LwReallocMemory(pSecDescRel,
  156. OUT_PPVOID(&pNewSecDescRel),
  157. ulSecDescLen);
  158. BAIL_ON_SAMDB_ERROR(dwError);
  159. pSecDescRel = pNewSecDescRel;
  160. pNewSecDescRel = NULL;
  161. ntStatus = RtlAbsoluteToSelfRelativeSD(
  162. pSecDesc,
  163. pSecDescRel,
  164. &ulSecDescLen);
  165. if (ntStatus == STATUS_BUFFER_TOO_SMALL)
  166. {
  167. ulSecDescLen *= 2;
  168. }
  169. } while (ntStatus != STATUS_SUCCESS &&
  170. ulSecDescLen <= SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE);
  171. *ppSecDescRel = pSecDescRel;
  172. *pulSecDescLen = ulSecDescLen;
  173. cleanup:
  174. if (dwError == ERROR_SUCCESS &&
  175. ntStatus != STATUS_SUCCESS)
  176. {
  177. dwError = LwNtStatusToWin32Error(ntStatus);
  178. }
  179. return dwError;
  180. error:
  181. LW_SAFE_FREE_MEMORY(pSecDescRel);
  182. *ppSecDescRel = NULL;
  183. *pulSecDescLen = 0;
  184. goto cleanup;
  185. }
  186. DWORD
  187. SamDbCreateBuiltinDomainSecDesc(
  188. PSID pSid,
  189. PSECURITY_DESCRIPTOR_RELATIVE *ppSecDescRel,
  190. PULONG pulSecDescLen
  191. )
  192. {
  193. DWORD dwError = ERROR_SUCCESS;
  194. NTSTATUS ntStatus = STATUS_SUCCESS;
  195. PSID pOwnerSid = NULL;
  196. PSID pGroupSid = NULL;
  197. PSECURITY_DESCRIPTOR_ABSOLUTE pSecDesc = NULL;
  198. PSECURITY_DESCRIPTOR_RELATIVE pSecDescRel = NULL;
  199. PSECURITY_DESCRIPTOR_RELATIVE pNewSecDescRel = NULL;
  200. ULONG ulSecDescLen = 1024;
  201. PACL pDacl = NULL;
  202. dwError = LwAllocateMemory(SECURITY_DESCRIPTOR_ABSOLUTE_MIN_SIZE,
  203. OUT_PPVOID(&pSecDesc));
  204. BAIL_ON_SAMDB_ERROR(dwError);
  205. ntStatus = RtlCreateSecurityDescriptorAbsolute(
  206. pSecDesc,
  207. SECURITY_DESCRIPTOR_REVISION);
  208. BAIL_ON_NT_STATUS(ntStatus);
  209. /*
  210. * Set owner to LOCAL_SYSTEM
  211. */
  212. dwError = LwAllocateWellKnownSid(WinLocalSystemSid,
  213. NULL,
  214. &pOwnerSid,
  215. NULL);
  216. BAIL_ON_SAMDB_ERROR(dwError);
  217. ntStatus = RtlSetOwnerSecurityDescriptor(
  218. pSecDesc,
  219. pOwnerSid,
  220. FALSE);
  221. BAIL_ON_NT_STATUS(ntStatus);
  222. /*
  223. * Set group to BUILTIN\Administrators
  224. */
  225. dwError = LwAllocateWellKnownSid(WinBuiltinAdministratorsSid,
  226. NULL,
  227. &pGroupSid,
  228. NULL);
  229. BAIL_ON_SAMDB_ERROR(dwError);
  230. ntStatus = RtlSetGroupSecurityDescriptor(
  231. pSecDesc,
  232. pGroupSid,
  233. FALSE);
  234. BAIL_ON_NT_STATUS(ntStatus);
  235. /* Create default DACL */
  236. dwError = SamDbCreateBuiltinDomainDacl(pSid,
  237. &pDacl);
  238. BAIL_ON_SAMDB_ERROR(dwError);
  239. ntStatus = RtlSetDaclSecurityDescriptor(
  240. pSecDesc,
  241. TRUE,
  242. pDacl,
  243. FALSE);
  244. BAIL_ON_NT_STATUS(ntStatus);
  245. do
  246. {
  247. dwError = LwReallocMemory(pSecDescRel,
  248. OUT_PPVOID(&pNewSecDescRel),
  249. ulSecDescLen);
  250. BAIL_ON_SAMDB_ERROR(dwError);
  251. pSecDescRel = pNewSecDescRel;
  252. pNewSecDescRel = NULL;
  253. ntStatus = RtlAbsoluteToSelfRelativeSD(
  254. pSecDesc,
  255. pSecDescRel,
  256. &ulSecDescLen);
  257. if (ntStatus == STATUS_BUFFER_TOO_SMALL)
  258. {
  259. ulSecDescLen *= 2;
  260. }
  261. } while (ntStatus != STATUS_SUCCESS &&
  262. ulSecDescLen <= SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE);
  263. *ppSecDescRel = pSecDescRel;
  264. *pulSecDescLen = ulSecDescLen;
  265. cleanup:
  266. if (dwError == ERROR_SUCCESS &&
  267. ntStatus != STATUS_SUCCESS)
  268. {
  269. dwError = LwNtStatusToWin32Error(ntStatus);
  270. }
  271. return dwError;
  272. error:
  273. LW_SAFE_FREE_MEMORY(pSecDescRel);
  274. *ppSecDescRel = NULL;
  275. *pulSecDescLen = 0;
  276. goto cleanup;
  277. }
  278. DWORD
  279. SamDbCreateLocalUserSecDesc(
  280. PSID pUserSid,
  281. PSECURITY_DESCRIPTOR_RELATIVE *ppSecDescRel,
  282. PULONG pulSecDescLen
  283. )
  284. {
  285. DWORD dwError = ERROR_SUCCESS;
  286. NTSTATUS ntStatus = STATUS_SUCCESS;
  287. PSID pOwnerSid = NULL;
  288. PSID pGroupSid = NULL;
  289. PSECURITY_DESCRIPTOR_ABSOLUTE pSecDesc = NULL;
  290. PSECURITY_DESCRIPTOR_RELATIVE pSecDescRel = NULL;
  291. PSECURITY_DESCRIPTOR_RELATIVE pNewSecDescRel = NULL;
  292. ULONG ulSecDescLen = 1024;
  293. PACL pDacl = NULL;
  294. dwError = LwAllocateMemory(SECURITY_DESCRIPTOR_ABSOLUTE_MIN_SIZE,
  295. OUT_PPVOID(&pSecDesc));
  296. BAIL_ON_SAMDB_ERROR(dwError);
  297. ntStatus = RtlCreateSecurityDescriptorAbsolute(
  298. pSecDesc,
  299. SECURITY_DESCRIPTOR_REVISION);
  300. BAIL_ON_NT_STATUS(ntStatus);
  301. /*
  302. * Set owner (BUITLIN\Administrators)
  303. */
  304. dwError = LwAllocateWellKnownSid(WinBuiltinAdministratorsSid,
  305. NULL,
  306. &pOwnerSid,
  307. NULL);
  308. BAIL_ON_SAMDB_ERROR(dwError);
  309. ntStatus = RtlSetOwnerSecurityDescriptor(pSecDesc,
  310. pOwnerSid,
  311. FALSE);
  312. BAIL_ON_NT_STATUS(ntStatus);
  313. /*
  314. * Set group (BUILTIN\Administrators)
  315. */
  316. dwError = LwAllocateWellKnownSid(WinBuiltinAdministratorsSid,
  317. NULL,
  318. &pGroupSid,
  319. NULL);
  320. BAIL_ON_SAMDB_ERROR(dwError);
  321. ntStatus = RtlSetGroupSecurityDescriptor(pSecDesc,
  322. pGroupSid,
  323. FALSE);
  324. BAIL_ON_NT_STATUS(ntStatus);
  325. /* create default DACL */
  326. dwError = SamDbCreateLocalUserDacl(pUserSid,
  327. &pDacl);
  328. BAIL_ON_SAMDB_ERROR(dwError);
  329. ntStatus = RtlSetDaclSecurityDescriptor(
  330. pSecDesc,
  331. TRUE,
  332. pDacl,
  333. FALSE);
  334. BAIL_ON_NT_STATUS(ntStatus);
  335. do
  336. {
  337. dwError = LwReallocMemory(pSecDescRel,
  338. OUT_PPVOID(&pNewSecDescRel),
  339. ulSecDescLen);
  340. BAIL_ON_SAMDB_ERROR(dwError);
  341. pSecDescRel = pNewSecDescRel;
  342. pNewSecDescRel = NULL;
  343. ntStatus = RtlAbsoluteToSelfRelativeSD(
  344. pSecDesc,
  345. pSecDescRel,
  346. &ulSecDescLen);
  347. if (ntStatus == STATUS_BUFFER_TOO_SMALL)
  348. {
  349. ulSecDescLen *= 2;
  350. }
  351. } while (ntStatus != STATUS_SUCCESS &&
  352. ulSecDescLen <= SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE);
  353. *ppSecDescRel = pSecDescRel;
  354. *pulSecDescLen = ulSecDescLen;
  355. cleanup:
  356. if (dwError == ERROR_SUCCESS &&
  357. ntStatus != STATUS_SUCCESS)
  358. {
  359. dwError = LwNtStatusToWin32Error(ntStatus);
  360. }
  361. return dwError;
  362. error:
  363. LW_SAFE_FREE_MEMORY(pSecDescRel);
  364. *ppSecDescRel = NULL;
  365. *pulSecDescLen = 0;
  366. goto cleanup;
  367. }
  368. DWORD
  369. SamDbCreateLocalGroupSecDesc(
  370. PSID pSid,
  371. PSECURITY_DESCRIPTOR_RELATIVE *ppSecDescRel,
  372. PULONG pulSecDescLen
  373. )
  374. {
  375. DWORD dwError = ERROR_SUCCESS;
  376. NTSTATUS ntStatus = STATUS_SUCCESS;
  377. PSID pOwnerSid = NULL;
  378. PSID pGroupSid = NULL;
  379. PSECURITY_DESCRIPTOR_ABSOLUTE pSecDesc = NULL;
  380. PSECURITY_DESCRIPTOR_RELATIVE pSecDescRel = NULL;
  381. PSECURITY_DESCRIPTOR_RELATIVE pNewSecDescRel = NULL;
  382. ULONG ulSecDescLen = 1024;
  383. PACL pDacl = NULL;
  384. dwError = LwAllocateMemory(SECURITY_DESCRIPTOR_ABSOLUTE_MIN_SIZE,
  385. OUT_PPVOID(&pSecDesc));
  386. BAIL_ON_SAMDB_ERROR(dwError);
  387. ntStatus = RtlCreateSecurityDescriptorAbsolute(
  388. pSecDesc,
  389. SECURITY_DESCRIPTOR_REVISION);
  390. BAIL_ON_NT_STATUS(ntStatus);
  391. /*
  392. * Set owner (BUILTIN\Administrators)
  393. */
  394. dwError = LwAllocateWellKnownSid(WinBuiltinAdministratorsSid,
  395. NULL,
  396. &pOwnerSid,
  397. NULL);
  398. BAIL_ON_SAMDB_ERROR(dwError);
  399. ntStatus = RtlSetOwnerSecurityDescriptor(pSecDesc,
  400. pOwnerSid,
  401. FALSE);
  402. BAIL_ON_NT_STATUS(ntStatus);
  403. /*
  404. * Set group (BUILTIN\Administrators)
  405. */
  406. dwError = LwAllocateWellKnownSid(WinBuiltinAdministratorsSid,
  407. NULL,
  408. &pGroupSid,
  409. NULL);
  410. BAIL_ON_SAMDB_ERROR(dwError);
  411. ntStatus = RtlSetGroupSecurityDescriptor(pSecDesc,
  412. pGroupSid,
  413. FALSE);
  414. BAIL_ON_NT_STATUS(ntStatus);
  415. /* create default DACL */
  416. dwError = SamDbCreateLocalGroupDacl(pSid,
  417. &pDacl);
  418. BAIL_ON_SAMDB_ERROR(dwError);
  419. ntStatus = RtlSetDaclSecurityDescriptor(
  420. pSecDesc,
  421. TRUE,
  422. pDacl,
  423. FALSE);
  424. BAIL_ON_NT_STATUS(ntStatus);
  425. do
  426. {
  427. dwError = LwReallocMemory(pSecDescRel,
  428. OUT_PPVOID(&pNewSecDescRel),
  429. ulSecDescLen);
  430. BAIL_ON_SAMDB_ERROR(dwError);
  431. pSecDescRel = pNewSecDescRel;
  432. pNewSecDescRel = NULL;
  433. ntStatus = RtlAbsoluteToSelfRelativeSD(
  434. pSecDesc,
  435. pSecDescRel,
  436. &ulSecDescLen);
  437. if (ntStatus == STATUS_BUFFER_TOO_SMALL)
  438. {
  439. ulSecDescLen *= 2;
  440. }
  441. } while (ntStatus != STATUS_SUCCESS &&
  442. ulSecDescLen <= SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE);
  443. *ppSecDescRel = pSecDescRel;
  444. *pulSecDescLen = ulSecDescLen;
  445. cleanup:
  446. if (dwError == ERROR_SUCCESS &&
  447. ntStatus != STATUS_SUCCESS)
  448. {
  449. dwError = LwNtStatusToWin32Error(ntStatus);
  450. }
  451. return dwError;
  452. error:
  453. LW_SAFE_FREE_MEMORY(pSecDescRel);
  454. *ppSecDescRel = NULL;
  455. *pulSecDescLen = 0;
  456. goto cleanup;
  457. }
  458. DWORD
  459. SamDbCreateBuiltinGroupSecDesc(
  460. PSID pSid,
  461. PSECURITY_DESCRIPTOR_RELATIVE *ppSecDescRel,
  462. PULONG pulSecDescLen
  463. )
  464. {
  465. DWORD dwError = ERROR_SUCCESS;
  466. NTSTATUS ntStatus = STATUS_SUCCESS;
  467. PSID pOwnerSid = NULL;
  468. PSID pGroupSid = NULL;
  469. PSECURITY_DESCRIPTOR_ABSOLUTE pSecDesc = NULL;
  470. PSECURITY_DESCRIPTOR_RELATIVE pSecDescRel = NULL;
  471. PSECURITY_DESCRIPTOR_RELATIVE pNewSecDescRel = NULL;
  472. ULONG ulSecDescLen = 1024;
  473. PACL pDacl = NULL;
  474. dwError = LwAllocateMemory(SECURITY_DESCRIPTOR_ABSOLUTE_MIN_SIZE,
  475. OUT_PPVOID(&pSecDesc));
  476. BAIL_ON_SAMDB_ERROR(dwError);
  477. ntStatus = RtlCreateSecurityDescriptorAbsolute(
  478. pSecDesc,
  479. SECURITY_DESCRIPTOR_REVISION);
  480. BAIL_ON_NT_STATUS(ntStatus);
  481. /*
  482. * Set owner (BUILTIN\Administrators)
  483. */
  484. dwError = LwAllocateWellKnownSid(WinBuiltinAdministratorsSid,
  485. NULL,
  486. &pOwnerSid,
  487. NULL);
  488. BAIL_ON_SAMDB_ERROR(dwError);
  489. ntStatus = RtlSetOwnerSecurityDescriptor(pSecDesc,
  490. pOwnerSid,
  491. FALSE);
  492. BAIL_ON_NT_STATUS(ntStatus);
  493. /*
  494. * Set group (BUILTIN\Administrators)
  495. */
  496. dwError = LwAllocateWellKnownSid(WinBuiltinAdministratorsSid,
  497. NULL,
  498. &pGroupSid,
  499. NULL);
  500. BAIL_ON_SAMDB_ERROR(dwError);
  501. ntStatus = RtlSetGroupSecurityDescriptor(pSecDesc,
  502. pGroupSid,
  503. FALSE);
  504. BAIL_ON_NT_STATUS(ntStatus);
  505. /* create default DACL */
  506. dwError = SamDbCreateBuiltinGroupDacl(pSid,
  507. &pDacl);
  508. BAIL_ON_SAMDB_ERROR(dwError);
  509. ntStatus = RtlSetDaclSecurityDescriptor(
  510. pSecDesc,
  511. TRUE,
  512. pDacl,
  513. FALSE);
  514. BAIL_ON_NT_STATUS(ntStatus);
  515. do
  516. {
  517. dwError = LwReallocMemory(pSecDescRel,
  518. OUT_PPVOID(&pNewSecDescRel),
  519. ulSecDescLen);
  520. BAIL_ON_SAMDB_ERROR(dwError);
  521. pSecDescRel = pNewSecDescRel;
  522. pNewSecDescRel = NULL;
  523. ntStatus = RtlAbsoluteToSelfRelativeSD(
  524. pSecDesc,
  525. pSecDescRel,
  526. &ulSecDescLen);
  527. if (ntStatus == STATUS_BUFFER_TOO_SMALL)
  528. {
  529. ulSecDescLen *= 2;
  530. }
  531. } while (ntStatus != STATUS_SUCCESS &&
  532. ulSecDescLen <= SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE);
  533. *ppSecDescRel = pSecDescRel;
  534. *pulSecDescLen = ulSecDescLen;
  535. cleanup:
  536. if (dwError == ERROR_SUCCESS &&
  537. ntStatus != STATUS_SUCCESS)
  538. {
  539. dwError = LwNtStatusToWin32Error(ntStatus);
  540. }
  541. return dwError;
  542. error:
  543. LW_SAFE_FREE_MEMORY(pSecDescRel);
  544. *ppSecDescRel = NULL;
  545. *pulSecDescLen = 0;
  546. goto cleanup;
  547. }
  548. DWORD
  549. SamDbCreateNewLocalAccountSecDesc(
  550. PSID pSid,
  551. PSECURITY_DESCRIPTOR_RELATIVE *ppSecDescRel,
  552. PULONG pulSecDescLen
  553. )
  554. {
  555. DWORD dwError = ERROR_SUCCESS;
  556. NTSTATUS ntStatus = STATUS_SUCCESS;
  557. PSID pOwnerSid = NULL;
  558. PSID pGroupSid = NULL;
  559. PSECURITY_DESCRIPTOR_ABSOLUTE pSecDesc = NULL;
  560. PSECURITY_DESCRIPTOR_RELATIVE pSecDescRel = NULL;
  561. PSECURITY_DESCRIPTOR_RELATIVE pNewSecDescRel = NULL;
  562. ULONG ulSecDescLen = 1024;
  563. PACL pDacl = NULL;
  564. dwError = LwAllocateMemory(SECURITY_DESCRIPTOR_ABSOLUTE_MIN_SIZE,
  565. OUT_PPVOID(&pSecDesc));
  566. BAIL_ON_SAMDB_ERROR(dwError);
  567. ntStatus = RtlCreateSecurityDescriptorAbsolute(
  568. pSecDesc,
  569. SECURITY_DESCRIPTOR_REVISION);
  570. BAIL_ON_NT_STATUS(ntStatus);
  571. /*
  572. * Set owner (BUILTIN\Administrators)
  573. */
  574. dwError = LwAllocateWellKnownSid(WinBuiltinAdministratorsSid,
  575. NULL,
  576. &pOwnerSid,
  577. NULL);
  578. BAIL_ON_SAMDB_ERROR(dwError);
  579. ntStatus = RtlSetOwnerSecurityDescriptor(pSecDesc,
  580. pOwnerSid,
  581. FALSE);
  582. BAIL_ON_NT_STATUS(ntStatus);
  583. /*
  584. * Set group (BUILTIN\Administrators)
  585. */
  586. dwError = LwAllocateWellKnownSid(WinBuiltinAdministratorsSid,
  587. NULL,
  588. &pGroupSid,
  589. NULL);
  590. BAIL_ON_SAMDB_ERROR(dwError);
  591. ntStatus = RtlSetGroupSecurityDescriptor(pSecDesc,
  592. pGroupSid,
  593. FALSE);
  594. BAIL_ON_NT_STATUS(ntStatus);
  595. /* create default DACL */
  596. dwError = SamDbCreateNewLocalAccountDacl(pSid,
  597. &pDacl);
  598. BAIL_ON_SAMDB_ERROR(dwError);
  599. ntStatus = RtlSetDaclSecurityDescriptor(
  600. pSecDesc,
  601. TRUE,
  602. pDacl,
  603. FALSE);
  604. BAIL_ON_NT_STATUS(ntStatus);
  605. do
  606. {
  607. dwError = LwReallocMemory(pSecDescRel,
  608. OUT_PPVOID(&pNewSecDescRel),
  609. ulSecDescLen);
  610. BAIL_ON_SAMDB_ERROR(dwError);
  611. pSecDescRel = pNewSecDescRel;
  612. pNewSecDescRel = NULL;
  613. ntStatus = RtlAbsoluteToSelfRelativeSD(
  614. pSecDesc,
  615. pSecDescRel,
  616. &ulSecDescLen);
  617. if (ntStatus == STATUS_BUFFER_TOO_SMALL)
  618. {
  619. ulSecDescLen *= 2;
  620. }
  621. } while (ntStatus != STATUS_SUCCESS &&
  622. ulSecDescLen <= SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE);
  623. *ppSecDescRel = pSecDescRel;
  624. *pulSecDescLen = ulSecDescLen;
  625. cleanup:
  626. LW_SAFE_FREE_MEMORY(pSecDesc);
  627. LW_SAFE_FREE_MEMORY(pDacl);
  628. LW_SAFE_FREE_MEMORY(pOwnerSid);
  629. LW_SAFE_FREE_MEMORY(pGroupSid);
  630. if (dwError == ERROR_SUCCESS &&
  631. ntStatus != STATUS_SUCCESS)
  632. {
  633. dwError = LwNtStatusToWin32Error(ntStatus);
  634. }
  635. return dwError;
  636. error:
  637. LW_SAFE_FREE_MEMORY(pSecDescRel);
  638. *ppSecDescRel = NULL;
  639. *pulSecDescLen = 0;
  640. goto cleanup;
  641. }
  642. static
  643. DWORD
  644. SamDbCreateLocalDomainDacl(
  645. PSID pSid,
  646. PACL *ppDacl
  647. )
  648. {
  649. ACCESS_MASK AdminAccessMask = STANDARD_RIGHTS_REQUIRED |
  650. DOMAIN_ACCESS_LOOKUP_INFO_1 |
  651. DOMAIN_ACCESS_SET_INFO_1 |
  652. DOMAIN_ACCESS_LOOKUP_INFO_2 |
  653. DOMAIN_ACCESS_SET_INFO_2 |
  654. DOMAIN_ACCESS_CREATE_USER |
  655. DOMAIN_ACCESS_CREATE_GROUP |
  656. DOMAIN_ACCESS_CREATE_ALIAS |
  657. DOMAIN_ACCESS_LOOKUP_ALIAS |
  658. DOMAIN_ACCESS_ENUM_ACCOUNTS |
  659. DOMAIN_ACCESS_OPEN_ACCOUNT |
  660. DOMAIN_ACCESS_SET_INFO_3;
  661. ACCESS_MASK AllAccessMask = STANDARD_RIGHTS_READ |
  662. DOMAIN_ACCESS_LOOKUP_INFO_1 |
  663. DOMAIN_ACCESS_LOOKUP_INFO_2 |
  664. DOMAIN_ACCESS_LOOKUP_ALIAS |
  665. DOMAIN_ACCESS_ENUM_ACCOUNTS |
  666. DOMAIN_ACCESS_OPEN_ACCOUNT;
  667. DWORD dwError = ERROR_SUCCESS;
  668. NTSTATUS ntStatus = STATUS_SUCCESS;
  669. PACL pDacl = NULL;
  670. ULONG ulLocalAdminSidLen = 0;
  671. PSID pLocalAdminSid = NULL;
  672. PSID pBuiltinAdminsSid = NULL;
  673. PSID pWorldSid = NULL;
  674. ACCESS_LIST AccessList[] = {
  675. {
  676. .ppSid = &pLocalAdminSid,
  677. .AccessMask = AdminAccessMask,
  678. .ulAccessType = ACCESS_ALLOWED_ACE_TYPE
  679. },
  680. {
  681. .ppSid = &pBuiltinAdminsSid,
  682. .AccessMask = AdminAccessMask,
  683. .ulAccessType = ACCESS_ALLOWED_ACE_TYPE
  684. },
  685. {
  686. .ppSid = &pWorldSid,
  687. .AccessMask = AllAccessMask,
  688. .ulAccessType = ACCESS_ALLOWED_ACE_TYPE
  689. },
  690. {
  691. .ppSid = NULL,
  692. .AccessMask = 0,
  693. .ulAccessType = 0
  694. }
  695. };
  696. ulLocalAdminSidLen = RtlLengthRequiredSid(pSid->SubAuthorityCount + 1);
  697. dwError = LwAllocateMemory(ulLocalAdminSidLen,
  698. OUT_PPVOID(&pLocalAdminSid));
  699. BAIL_ON_SAMDB_ERROR(dwError);
  700. ntStatus = RtlCopySid(ulLocalAdminSidLen,
  701. pLocalAdminSid,
  702. pSid);
  703. BAIL_ON_NT_STATUS(ntStatus);
  704. ntStatus = RtlAppendRidSid(ulLocalAdminSidLen,
  705. pLocalAdminSid,
  706. DOMAIN_USER_RID_ADMIN);
  707. dwError = LwAllocateWellKnownSid(WinBuiltinAdministratorsSid,
  708. NULL,
  709. &pBuiltinAdminsSid,
  710. NULL);
  711. BAIL_ON_SAMDB_ERROR(dwError);
  712. dwError = LwAllocateWellKnownSid(WinWorldSid,
  713. NULL,
  714. &pWorldSid,
  715. NULL);
  716. BAIL_ON_SAMDB_ERROR(dwError);
  717. dwError = SamDbCreateDacl(&pDacl, AccessList);
  718. BAIL_ON_LSA_ERROR(dwError);
  719. *ppDacl = pDacl;
  720. cleanup:
  721. LW_SAFE_FREE_MEMORY(pBuiltinAdminsSid);
  722. LW_SAFE_FREE_MEMORY(pWorldSid);
  723. LW_SAFE_FREE_MEMORY(pLocalAdminSid);
  724. if (dwError == ERROR_SUCCESS &&
  725. ntStatus != STATUS_SUCCESS)
  726. {
  727. dwError = LwNtStatusToWin32Error(ntStatus);
  728. }
  729. return dwError;
  730. error:
  731. LW_SAFE_FREE_MEMORY(pDacl);
  732. *ppDacl = NULL;
  733. goto cleanup;
  734. }
  735. static
  736. DWORD
  737. SamDbCreateBuiltinDomainDacl(
  738. PSID pSid,
  739. PACL *ppDacl
  740. )
  741. {
  742. ACCESS_MASK AdminAccessMask = STANDARD_RIGHTS_READ |
  743. DOMAIN_ACCESS_LOOKUP_INFO_1 |
  744. DOMAIN_ACCESS_SET_INFO_1 |
  745. DOMAIN_ACCESS_LOOKUP_INFO_2 |
  746. DOMAIN_ACCESS_SET_INFO_2 |
  747. DOMAIN_ACCESS_CREATE_USER |
  748. DOMAIN_ACCESS_CREATE_GROUP |
  749. DOMAIN_ACCESS_CREATE_ALIAS |
  750. DOMAIN_ACCESS_LOOKUP_ALIAS |
  751. DOMAIN_ACCESS_ENUM_ACCOUNTS |
  752. DOMAIN_ACCESS_OPEN_ACCOUNT |
  753. DOMAIN_ACCESS_SET_INFO_3;
  754. ACCESS_MASK AllAccessMask = STANDARD_RIGHTS_READ |
  755. DOMAIN_ACCESS_LOOKUP_INFO_1 |
  756. DOMAIN_ACCESS_LOOKUP_INFO_2 |
  757. DOMAIN_ACCESS_LOOKUP_ALIAS |
  758. DOMAIN_ACCESS_ENUM_ACCOUNTS |
  759. DOMAIN_ACCESS_OPEN_ACCOUNT;
  760. DWORD dwError = ERROR_SUCCESS;
  761. NTSTATUS ntStatus = STATUS_SUCCESS;
  762. PACL pDacl = NULL;
  763. PSID pBuiltinAdminsSid = NULL;
  764. PSID pWorldSid = NULL;
  765. ACCESS_LIST AccessList[] = {
  766. {
  767. .ppSid = &pBuiltinAdminsSid,
  768. .AccessMask = AdminAccessMask,
  769. .ulAccessType = ACCESS_ALLOWED_ACE_TYPE
  770. },
  771. {
  772. .ppSid = &pWorldSid,
  773. .AccessMask = AllAccessMask,
  774. .ulAccessType = ACCESS_ALLOWED_ACE_TYPE
  775. },
  776. {
  777. .ppSid = NULL,
  778. .AccessMask = 0,
  779. .ulAccessType = 0
  780. }
  781. };
  782. dwError = LwAllocateWellKnownSid(WinBuiltinAdministratorsSid,
  783. NULL,
  784. &pBuiltinAdminsSid,
  785. NULL);
  786. BAIL_ON_SAMDB_ERROR(dwError);
  787. dwError = LwAllocateWellKnownSid(WinWorldSid,
  788. NULL,
  789. &pWorldSid,
  790. NULL);
  791. BAIL_ON_SAMDB_ERROR(dwError);
  792. dwError = SamDbCreateDacl(&pDacl, AccessList);
  793. BAIL_ON_LSA_ERROR(dwError);
  794. *ppDacl = pDacl;
  795. cleanup:
  796. LW_SAFE_FREE_MEMORY(pBuiltinAdminsSid);
  797. LW_SAFE_FREE_MEMORY(pWorldSid);
  798. if (dwError == ERROR_SUCCESS &&
  799. ntStatus != STATUS_SUCCESS)
  800. {
  801. dwError = LwNtStatusToWin32Error(ntStatus);
  802. }
  803. return dwError;
  804. error:
  805. LW_SAFE_FREE_MEMORY(pDacl);
  806. *ppDacl = NULL;
  807. goto cleanup;
  808. }
  809. static
  810. DWORD
  811. SamDbCreateLocalUserDacl(
  812. PSID pAccountSid,
  813. PACL *ppDacl
  814. )
  815. {
  816. ACCESS_MASK AdminsAccessMask = STANDARD_RIGHTS_READ |
  817. WRITE_DAC |
  818. WRITE_OWNER |
  819. DELETE |
  820. USER_ACCESS_GET_NAME_ETC |
  821. USER_ACCESS_GET_LOCALE |
  822. USER_ACCESS_SET_LOC_COM |
  823. USER_ACCESS_GET_LOGONINFO |
  824. USER_ACCESS_GET_ATTRIBUTES |
  825. USER_ACCESS_SET_ATTRIBUTES |
  826. USER_ACCESS_CHANGE_PASSWORD |
  827. USER_ACCESS_SET_PASSWORD |
  828. USER_ACCESS_GET_GROUPS |
  829. USER_ACCESS_GET_GROUP_MEMBERSHIP |
  830. USER_ACCESS_CHANGE_GROUP_MEMBERSHIP;
  831. ACCESS_MASK AccountAccessMask = STANDARD_RIGHTS_READ |
  832. USER_ACCESS_SET_LOC_COM |
  833. USER_ACCESS_CHANGE_PASSWORD;
  834. ACCESS_MASK AllAccessMask = STANDARD_RIGHTS_READ |
  835. USER_ACCESS_GET_NAME_ETC |
  836. USER_ACCESS_GET_LOCALE |
  837. USER_ACCESS_GET_LOGONINFO |
  838. USER_ACCESS_GET_ATTRIBUTES |
  839. USER_ACCESS_CHANGE_PASSWORD |
  840. USER_ACCESS_GET_GROUPS |
  841. USER_ACCESS_GET_GROUP_MEMBERSHIP;
  842. DWORD dwError = ERROR_SUCCESS;
  843. NTSTATUS ntStatus = STATUS_SUCCESS;
  844. PACL pDacl = NULL;
  845. PSID pBuiltinAdminsSid = NULL;
  846. PSID pWorldSid = NULL;
  847. ACCESS_LIST AccessList[] = {
  848. {
  849. .ppSid = &pWorldSid,
  850. .AccessMask = AllAccessMask,
  851. .ulAccessType = ACCESS_ALLOWED_ACE_TYPE
  852. },
  853. {
  854. .ppSid = &pBuiltinAdminsSid,
  855. .AccessMask = AdminsAccessMask,
  856. .ulAccessType = ACCESS_ALLOWED_ACE_TYPE
  857. },
  858. {
  859. .ppSid = &pAccountSid,
  860. .AccessMask = AccountAccessMask,
  861. .ulAccessType = ACCESS_ALLOWED_ACE_TYPE
  862. },
  863. {
  864. .ppSid = NULL,
  865. .AccessMask = 0,
  866. .ulAccessType = 0
  867. }
  868. };
  869. dwError = LwAllocateWellKnownSid(WinBuiltinAdministratorsSid,
  870. NULL,
  871. &pBuiltinAdminsSid,
  872. NULL);
  873. BAIL_ON_SAMDB_ERROR(dwError);
  874. dwError = LwAllocateWellKnownSid(WinWorldSid,
  875. NULL,
  876. &pWorldSid,
  877. NULL);
  878. BAIL_ON_SAMDB_ERROR(dwError);
  879. dwError = SamDbCreateDacl(&pDacl, &AccessList[0]);
  880. BAIL_ON_LSA_ERROR(dwError);
  881. *ppDacl = pDacl;
  882. cleanup:
  883. LW_SAFE_FREE_MEMORY(pBuiltinAdminsSid);
  884. LW_SAFE_FREE_MEMORY(pWorldSid);
  885. if (dwError == ERROR_SUCCESS &&
  886. ntStatus != STATUS_SUCCESS)
  887. {
  888. dwError = LwNtStatusToWin32Error(ntStatus);
  889. }
  890. return dwError;
  891. error:
  892. LW_SAFE_FREE_MEMORY(pDacl);
  893. *ppDacl = NULL;
  894. goto cleanup;
  895. }
  896. static
  897. DWORD
  898. SamDbCreateLocalGroupDacl(
  899. PSID pSid,
  900. PACL *ppDacl
  901. )
  902. {
  903. ACCESS_MASK AdminAccessMask = STANDARD_RIGHTS_REQUIRED |
  904. ALIAS_ACCESS_ADD_MEMBER |
  905. ALIAS_ACCESS_REMOVE_MEMBER |
  906. ALIAS_ACCESS_GET_MEMBERS |
  907. ALIAS_ACCESS_LOOKUP_INFO |
  908. ALIAS_ACCESS_SET_INFO;
  909. ACCESS_MASK AllAccessMask = STANDARD_RIGHTS_READ |
  910. ALIAS_ACCESS_GET_MEMBERS |
  911. ALIAS_ACCESS_LOOKUP_INFO;
  912. DWORD dwError = ERROR_SUCCESS;
  913. NTSTATUS ntStatus = STATUS_SUCCESS;
  914. PACL pDacl = NULL;
  915. ULONG ulLocalAdminSidLen = 0;
  916. PSID pLocalAdminSid = NULL;
  917. PSID pBuiltinAdminsSid = NULL;
  918. PSID pWorldSid = NULL;
  919. ACCESS_LIST AccessList[] = {
  920. {
  921. .ppSid = &pLocalAdminSid,
  922. .AccessMask = AdminAccessMask,
  923. .ulAccessType = ACCESS_ALLOWED_ACE_TYPE
  924. },
  925. {
  926. .ppSid = &pBuiltinAdminsSid,
  927. .AccessMask = AdminAccessMask,
  928. .ulAccessType = ACCESS_ALLOWED_ACE_TYPE
  929. },
  930. {
  931. .ppSid = &pWorldSid,
  932. .AccessMask = AllAccessMask,
  933. .ulAccessType = ACCESS_ALLOWED_ACE_TYPE
  934. },
  935. {
  936. .ppSid = NULL,
  937. .AccessMask = 0,
  938. .ulAccessType = 0
  939. }
  940. };
  941. ulLocalAdminSidLen = RtlLengthRequiredSid(pSid->SubAuthorityCount + 1);
  942. dwError = LwAllocateMemory(ulLocalAdminSidLen,
  943. OUT_PPVOID(&pLocalAdminSid));
  944. BAIL_ON_SAMDB_ERROR(dwError);
  945. ntStatus = RtlCopySid(ulLocalAdminSidLen,
  946. pLocalAdminSid,
  947. pSid);
  948. BAIL_ON_NT_STATUS(ntStatus);
  949. ntStatus = RtlAppendRidSid(ulLocalAdminSidLen,
  950. pLocalAdminSid,
  951. DOMAIN_USER_RID_ADMIN);
  952. dwError = LwAllocateWellKnownSid(WinBuiltinAdministratorsSid,
  953. NULL,
  954. &pBuiltinAdminsSid,
  955. NULL);
  956. BAIL_ON_SAMDB_ERROR(dwError);
  957. dwError = LwAllocateWellKnownSid(WinWorldSid,
  958. NULL,
  959. &pWorldSid,
  960. NULL);
  961. BAIL_ON_SAMDB_ERROR(dwError);
  962. dwError = SamDbCreateDacl(&pDacl, AccessList);
  963. BAIL_ON_LSA_ERROR(dwError);
  964. *ppDacl = pDacl;
  965. cleanup:
  966. LW_SAFE_FREE_MEMORY(pBuiltinAdminsSid);
  967. LW_SAFE_FREE_MEMORY(pWorldSid);
  968. LW_SAFE_FREE_MEMORY(pLocalAdminSid);
  969. if (dwError == ERROR_SUCCESS &&
  970. ntStatus != STATUS_SUCCESS)
  971. {
  972. dwError = LwNtStatusToWin32Error(ntStatus);
  973. }
  974. return dwError;
  975. error:
  976. LW_SAFE_FREE_MEMORY(pDacl);
  977. *ppDacl = NULL;
  978. goto cleanup;
  979. }
  980. static
  981. DWORD
  982. SamDbCreateBuiltinGroupDacl(
  983. PSID pSid,
  984. PACL *ppDacl
  985. )
  986. {
  987. ACCESS_MASK AdminAccessMask = STANDARD_RIGHTS_REQUIRED |
  988. ALIAS_ACCESS_ADD_MEMBER |
  989. ALIAS_ACCESS_REMOVE_MEMBER |
  990. ALIAS_ACCESS_GET_MEMBERS |
  991. ALIAS_ACCESS_LOOKUP_INFO |
  992. ALIAS_ACCESS_SET_INFO;
  993. ACCESS_MASK AllAccessMask = STANDARD_RIGHTS_READ |
  994. ALIAS_ACCESS_GET_MEMBERS |
  995. ALIAS_ACCESS_LOOKUP_INFO;
  996. DWORD dwError = ERROR_SUCCESS;
  997. NTSTATUS ntStatus = STATUS_SUCCESS;
  998. PACL pDacl = NULL;
  999. PSID pBuiltinAdminsSid = NULL;
  1000. PSID pWorldSid = NULL;
  1001. ACCESS_LIST AccessList[] = {
  1002. {
  1003. .ppSid = &pBuiltinAdminsSid,
  1004. .AccessMask = AdminAccessMask,
  1005. .ulAccessType = ACCESS_ALLOWED_ACE_TYPE
  1006. },
  1007. {
  1008. .ppSid = &pWorldSid,
  1009. .AccessMask = AllAccessMask,
  1010. .ulAccessType = ACCESS_ALLOWED_ACE_TYPE
  1011. },
  1012. {
  1013. .ppSid = NULL,
  1014. .AccessMask = 0,
  1015. .ulAccessType = 0
  1016. }
  1017. };
  1018. dwError = LwAllocateWellKnownSid(WinBuiltinAdministratorsSid,
  1019. NULL,
  1020. &pBuiltinAdminsSid,
  1021. NULL);
  1022. BAIL_ON_SAMDB_ERROR(dwError);
  1023. dwError = LwAllocateWellKnownSid(WinWorldSid,
  1024. NULL,
  1025. &pWorldSid,
  1026. NULL);
  1027. BAIL_ON_SAMDB_ERROR(dwError);
  1028. dwError = SamDbCreateDacl(&pDacl, AccessList);
  1029. BAIL_ON_LSA_ERROR(dwError);
  1030. *ppDacl = pDacl;
  1031. cleanup:
  1032. LW_SAFE_FREE_MEMORY(pBuiltinAdminsSid);
  1033. LW_SAFE_FREE_MEMORY(pWorldSid);
  1034. if (dwError == ERROR_SUCCESS &&
  1035. ntStatus != STATUS_SUCCESS)
  1036. {
  1037. dwError = LwNtStatusToWin32Error(ntStatus);
  1038. }
  1039. return dwError;
  1040. error:
  1041. LW_SAFE_FREE_MEMORY(pDacl);
  1042. *ppDacl = NULL;
  1043. goto cleanup;
  1044. }
  1045. static
  1046. DWORD
  1047. SamDbCreateNewLocalAccountDacl(
  1048. PSID pSid,
  1049. PACL *ppDacl
  1050. )
  1051. {
  1052. ACCESS_MASK AdminAccessMask = STANDARD_RIGHTS_REQUIRED |
  1053. USER_ACCESS_GET_NAME_ETC |
  1054. USER_ACCESS_GET_LOCALE |
  1055. USER_ACCESS_SET_LOC_COM |
  1056. USER_ACCESS_GET_LOGONINFO |
  1057. USER_ACCESS_GET_ATTRIBUTES |
  1058. USER_ACCESS_SET_ATTRIBUTES |
  1059. USER_ACCESS_CHANGE_PASSWORD |
  1060. USER_ACCESS_SET_PASSWORD |
  1061. USER_ACCESS_GET_GROUPS |
  1062. USER_ACCESS_GET_GROUP_MEMBERSHIP |
  1063. USER_ACCESS_CHANGE_GROUP_MEMBERSHIP |
  1064. ALIAS_ACCESS_ADD_MEMBER |
  1065. ALIAS_ACCESS_REMOVE_MEMBER |
  1066. ALIAS_ACCESS_GET_MEMBERS |
  1067. ALIAS_ACCESS_LOOKUP_INFO |
  1068. ALIAS_ACCESS_SET_INFO;
  1069. ACCESS_MASK AllAccessMask = STANDARD_RIGHTS_READ |
  1070. USER_ACCESS_GET_NAME_ETC |
  1071. USER_ACCESS_GET_LOCALE |
  1072. USER_ACCESS_GET_LOGONINFO |
  1073. USER_ACCESS_GET_ATTRIBUTES |
  1074. USER_ACCESS_GET_GROUPS |
  1075. USER_ACCESS_GET_GROUP_MEMBERSHIP |
  1076. ALIAS_ACCESS_GET_MEMBERS |
  1077. ALIAS_ACCESS_LOOKUP_INFO;
  1078. DWORD dwError = ERROR_SUCCESS;
  1079. NTSTATUS ntStatus = STATUS_SUCCESS;
  1080. PACL pDacl = NULL;
  1081. PSID pBuiltinAdminsSid = NULL;
  1082. PSID pWorldSid = NULL;
  1083. ACCESS_LIST AccessList[] = {
  1084. {
  1085. .ppSid = &pBuiltinAdminsSid,
  1086. .AccessMask = AdminAccessMask,
  1087. .ulAccessType = ACCESS_ALLOWED_ACE_TYPE
  1088. },
  1089. {
  1090. .ppSid = &pWorldSid,
  1091. .AccessMask = AllAccessMask,
  1092. .ulAccessType = ACCESS_ALLOWED_ACE_TYPE
  1093. },
  1094. {
  1095. .ppSid = NULL,
  1096. .AccessMask = 0,
  1097. .ulAccessType = 0
  1098. }
  1099. };
  1100. dwError = LwAllocateWellKnownSid(WinBuiltinAdministratorsSid,
  1101. NULL,
  1102. &pBuiltinAdminsSid,
  1103. NULL);
  1104. BAIL_ON_SAMDB_ERROR(dwError);
  1105. dwError = LwAllocateWellKnownSid(WinWorldSid,
  1106. NULL,
  1107. &pWorldSid,
  1108. NULL);
  1109. BAIL_ON_SAMDB_ERROR(dwError);
  1110. dwError = SamDbCreateDacl(&pDacl, AccessList);
  1111. BAIL_ON_LSA_ERROR(dwError);
  1112. *ppDacl = pDacl;
  1113. cleanup:
  1114. LW_SAFE_FREE_MEMORY(pBuiltinAdminsSid);
  1115. LW_SAFE_FREE_MEMORY(pWorldSid);
  1116. if (dwError == ERROR_SUCCESS &&
  1117. ntStatus != STATUS_SUCCESS)
  1118. {
  1119. dwError = LwNtStatusToWin32Error(ntStatus);
  1120. }
  1121. return dwError;
  1122. error:
  1123. LW_SAFE_FREE_MEMORY(pDacl);
  1124. *ppDacl = NULL;
  1125. goto cleanup;
  1126. }
  1127. static
  1128. DWORD
  1129. SamDbCreateDacl(
  1130. PACL *ppDacl,
  1131. PACCESS_LIST pList
  1132. )
  1133. {
  1134. DWORD dwError = ERROR_SUCCESS;
  1135. NTSTATUS ntStatus = STATUS_SUCCESS;
  1136. DWORD dwDaclSize = 0;
  1137. PACL pDacl = NULL;
  1138. DWORD i = 0;
  1139. ULONG ulSidSize = 0;
  1140. dwDaclSize += ACL_HEADER_SIZE;
  1141. for (i = 0; pList[i].ppSid && (*pList[i].ppSid); i++)
  1142. {
  1143. ulSidSize = RtlLengthSid(*(pList[i].ppSid));
  1144. if (pList[i].ulAccessType == ACCESS_ALLOWED_ACE_TYPE)
  1145. {
  1146. dwDaclSize += ulSidSize + sizeof(ACCESS_ALLOWED_ACE);
  1147. }
  1148. else if (pList[i].ulAccessType == ACCESS_DENIED_ACE_TYPE)
  1149. {
  1150. dwDaclSize += ulSidSize + sizeof(ACCESS_DENIED_ACE);
  1151. }
  1152. }
  1153. dwError = LwAllocateMemory(dwDaclSize,
  1154. OUT_PPVOID(&pDacl));
  1155. BAIL_ON_LSA_ERROR(dwError);
  1156. ntStatus = RtlCreateAcl(pDacl, dwDaclSize, ACL_REVISION);
  1157. BAIL_ON_NT_STATUS(ntStatus);
  1158. for (i = 0; pList[i].ppSid && (*pList[i].ppSid); i++)
  1159. {
  1160. if (pList[i].ulAccessType == ACCESS_ALLOWED_ACE_TYPE)
  1161. {
  1162. ntStatus = RtlAddAccessAllowedAceEx(pDacl,
  1163. ACL_REVISION,
  1164. 0,
  1165. pList[i].AccessMask,
  1166. *(pList[i].ppSid));
  1167. }
  1168. else if (pList[i].ulAccessType == ACCESS_DENIED_ACE_TYPE)
  1169. {
  1170. ntStatus = RtlAddAccessDeniedAceEx(pDacl,
  1171. ACL_REVISION,
  1172. 0,
  1173. pList[i].AccessMask,
  1174. *(pList[i].ppSid));
  1175. }
  1176. BAIL_ON_NT_STATUS(ntStatus);
  1177. }
  1178. *ppDacl = pDacl;
  1179. cleanup:
  1180. if (dwError == ERROR_SUCCESS &&
  1181. ntStatus != STATUS_SUCCESS)
  1182. {
  1183. dwError = LwNtStatusToWin32Error(ntStatus);
  1184. }
  1185. return dwError;
  1186. error:
  1187. LW_SAFE_FREE_MEMORY(pDacl);
  1188. *ppDacl = NULL;
  1189. goto cleanup;
  1190. }
  1191. /*
  1192. local variables:
  1193. mode: c
  1194. c-basic-offset: 4
  1195. indent-tabs-mode: nil
  1196. tab-width: 4
  1197. end:
  1198. */