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.

950 lines
29 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. Semethod.c
  5. Abstract:
  6. This Module implements the SeDefaultObjectMethod procedure. This
  7. procedure and SeAssignSecurity are the only two procedures that will
  8. place a security descriptor on an object. Therefore they must understand
  9. and agree on how a descriptor is allocated from pool so that they can
  10. deallocate and reallocate pool as necessary. Any security descriptor
  11. that is attached to an object by these procedures has the following
  12. pool allocation plan.
  13. 1. if the objects security descriptor is null then there is no pool
  14. allocated
  15. 2. otherwise there is at least one pool allocation for the security
  16. descriptor header. if its ACL fields are null then there are no
  17. other pool allocations (this should never happen).
  18. 3. There is a separate pool allocation for each ACL in the descriptor.
  19. So a maximum of three pool allocations can occur for each attached
  20. security descriptor.
  21. 4 Everytime an acl is replace in a descriptor we see if we can use
  22. the old ACL and if so then we try and keep the ACL size as large
  23. as possible.
  24. Note that this is different from the algorithm used to capture
  25. a security descriptor (which puts everything in one pool allocation).
  26. Also note that this can be easily optimized at a later time (if necessary)
  27. to use only one allocation.
  28. Author:
  29. Gary Kimura (GaryKi) 9-Nov-1989
  30. Jim Kelly (JimK) 10-May-1990
  31. Environment:
  32. Kernel Mode
  33. Revision History:
  34. --*/
  35. #include "pch.h"
  36. #pragma hdrstop
  37. NTSTATUS
  38. SepDefaultDeleteMethod (
  39. IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor
  40. );
  41. #ifdef ALLOC_PRAGMA
  42. #pragma alloc_text(PAGE,SeSetSecurityAccessMask)
  43. #pragma alloc_text(PAGE,SeQuerySecurityAccessMask)
  44. #pragma alloc_text(PAGE,SeDefaultObjectMethod)
  45. #pragma alloc_text(PAGE,SeSetSecurityDescriptorInfo)
  46. #pragma alloc_text(PAGE,SeSetSecurityDescriptorInfoEx)
  47. #pragma alloc_text(PAGE,SeQuerySecurityDescriptorInfo)
  48. #pragma alloc_text(PAGE,SepDefaultDeleteMethod)
  49. #endif
  50. VOID
  51. SeSetSecurityAccessMask(
  52. IN SECURITY_INFORMATION SecurityInformation,
  53. OUT PACCESS_MASK DesiredAccess
  54. )
  55. /*++
  56. Routine Description:
  57. This routine builds an access mask representing the accesses necessary
  58. to set the object security information specified in the SecurityInformation
  59. parameter. While it is not difficult to determine this information,
  60. the use of a single routine to generate it will ensure minimal impact
  61. when the security information associated with an object is extended in
  62. the future (to include mandatory access control information).
  63. Arguments:
  64. SecurityInformation - Identifies the object's security information to be
  65. modified.
  66. DesiredAccess - Points to an access mask to be set to represent the
  67. accesses necessary to modify the information specified in the
  68. SecurityInformation parameter.
  69. Return Value:
  70. None.
  71. --*/
  72. {
  73. PAGED_CODE();
  74. //
  75. // Figure out accesses needed to perform the indicated operation(s).
  76. //
  77. (*DesiredAccess) = 0;
  78. if ((SecurityInformation & OWNER_SECURITY_INFORMATION) ||
  79. (SecurityInformation & GROUP_SECURITY_INFORMATION) ) {
  80. (*DesiredAccess) |= WRITE_OWNER;
  81. }
  82. if (SecurityInformation & DACL_SECURITY_INFORMATION) {
  83. (*DesiredAccess) |= WRITE_DAC;
  84. }
  85. if (SecurityInformation & SACL_SECURITY_INFORMATION) {
  86. (*DesiredAccess) |= ACCESS_SYSTEM_SECURITY;
  87. }
  88. return;
  89. }
  90. VOID
  91. SeQuerySecurityAccessMask(
  92. IN SECURITY_INFORMATION SecurityInformation,
  93. OUT PACCESS_MASK DesiredAccess
  94. )
  95. /*++
  96. Routine Description:
  97. This routine builds an access mask representing the accesses necessary
  98. to query the object security information specified in the
  99. SecurityInformation parameter. While it is not difficult to determine
  100. this information, the use of a single routine to generate it will ensure
  101. minimal impact when the security information associated with an object is
  102. extended in the future (to include mandatory access control information).
  103. Arguments:
  104. SecurityInformation - Identifies the object's security information to be
  105. queried.
  106. DesiredAccess - Points to an access mask to be set to represent the
  107. accesses necessary to query the information specified in the
  108. SecurityInformation parameter.
  109. Return Value:
  110. None.
  111. --*/
  112. {
  113. PAGED_CODE();
  114. //
  115. // Figure out accesses needed to perform the indicated operation(s).
  116. //
  117. (*DesiredAccess) = 0;
  118. if ((SecurityInformation & OWNER_SECURITY_INFORMATION) ||
  119. (SecurityInformation & GROUP_SECURITY_INFORMATION) ||
  120. (SecurityInformation & DACL_SECURITY_INFORMATION)) {
  121. (*DesiredAccess) |= READ_CONTROL;
  122. }
  123. if ((SecurityInformation & SACL_SECURITY_INFORMATION)) {
  124. (*DesiredAccess) |= ACCESS_SYSTEM_SECURITY;
  125. }
  126. return;
  127. }
  128. NTSTATUS
  129. SeDefaultObjectMethod (
  130. IN PVOID Object,
  131. IN SECURITY_OPERATION_CODE OperationCode,
  132. IN PSECURITY_INFORMATION SecurityInformation,
  133. IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
  134. IN OUT PULONG CapturedLength,
  135. IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
  136. IN POOL_TYPE PoolType,
  137. IN PGENERIC_MAPPING GenericMapping
  138. )
  139. /*++
  140. Routine Description:
  141. This is the default security method for objects. It is responsible
  142. for either retrieving, setting, and deleting the security descriptor of
  143. an object. It is not used to assign the original security descriptor
  144. to an object (use SeAssignSecurity for that purpose).
  145. IT IS ASSUMED THAT THE OBJECT MANAGER HAS ALREADY DONE THE ACCESS
  146. VALIDATIONS NECESSARY TO ALLOW THE REQUESTED OPERATIONS TO BE PERFORMED.
  147. Arguments:
  148. Object - Supplies a pointer to the object being used.
  149. OperationCode - Indicates if the operation is for setting, querying, or
  150. deleting the object's security descriptor.
  151. SecurityInformation - Indicates which security information is being
  152. queried or set. This argument is ignored for the delete operation.
  153. SecurityDescriptor - The meaning of this parameter depends on the
  154. OperationCode:
  155. QuerySecurityDescriptor - For the query operation this supplies the
  156. buffer to copy the descriptor into. The security descriptor is
  157. assumed to have been probed up to the size passed in in Length.
  158. Since it still points into user space, it must always be
  159. accessed in a try clause in case it should suddenly disappear.
  160. SetSecurityDescriptor - For a set operation this supplies the
  161. security descriptor to copy into the object. The security
  162. descriptor must be captured before this routine is called.
  163. DeleteSecurityDescriptor - It is ignored when deleting a security
  164. descriptor.
  165. AssignSecurityDescriptor - For assign operations this is the
  166. security descriptor that will be assigned to the object.
  167. It is assumed to be in kernel space, and is therefore not
  168. probed or captured.
  169. CapturedLength - For the query operation this specifies the length, in
  170. bytes, of the security descriptor buffer, and upon return contains
  171. the number of bytes needed to store the descriptor. If the length
  172. needed is greater than the length supplied the operation will fail.
  173. It is ignored in the set and delete operation.
  174. This parameter is assumed to be captured and probed as appropriate.
  175. ObjectsSecurityDescriptor - For the Set operation this supplies the address
  176. of a pointer to the object's current security descriptor. This routine
  177. will either modify the security descriptor in place or allocate a new
  178. security descriptor and use this variable to indicate its new location.
  179. For the query operation it simply supplies the security descriptor
  180. being queried. The caller is responsible for freeing the old security
  181. descriptor.
  182. PoolType - For the set operation this specifies the pool type to use if
  183. a new security descriptor needs to be allocated. It is ignored
  184. in the query and delete operation.
  185. the mapping of generic to specific/standard access types for the object
  186. being accessed. This mapping structure is expected to be safe to
  187. access (i.e., captured if necessary) prior to be passed to this routine.
  188. Return Value:
  189. NTSTATUS - STATUS_SUCCESS if the operation is successful and an
  190. appropriate error status otherwise.
  191. --*/
  192. {
  193. PAGED_CODE();
  194. //
  195. // If the object's security descriptor is null, then object is not
  196. // one that has security information associated with it. Return
  197. // an error.
  198. //
  199. //
  200. // Make sure the common parts of our input are proper
  201. //
  202. ASSERT( (OperationCode == SetSecurityDescriptor) ||
  203. (OperationCode == QuerySecurityDescriptor) ||
  204. (OperationCode == AssignSecurityDescriptor) ||
  205. (OperationCode == DeleteSecurityDescriptor) );
  206. //
  207. // This routine simply cases off of the operation code to decide
  208. // which support routine to call
  209. //
  210. switch (OperationCode) {
  211. case SetSecurityDescriptor:
  212. ASSERT( (PoolType == PagedPool) || (PoolType == NonPagedPool) );
  213. return ObSetSecurityDescriptorInfo( Object,
  214. SecurityInformation,
  215. SecurityDescriptor,
  216. ObjectsSecurityDescriptor,
  217. PoolType,
  218. GenericMapping
  219. );
  220. case QuerySecurityDescriptor:
  221. //
  222. // check the rest of our input and call the default query security
  223. // method
  224. //
  225. ASSERT( CapturedLength != NULL );
  226. return ObQuerySecurityDescriptorInfo( Object,
  227. SecurityInformation,
  228. SecurityDescriptor,
  229. CapturedLength,
  230. ObjectsSecurityDescriptor );
  231. case DeleteSecurityDescriptor:
  232. //
  233. // call the default delete security method
  234. //
  235. return SepDefaultDeleteMethod( ObjectsSecurityDescriptor );
  236. case AssignSecurityDescriptor:
  237. ObAssignObjectSecurityDescriptor( Object, SecurityDescriptor, PoolType );
  238. return( STATUS_SUCCESS );
  239. default:
  240. //
  241. // Bugcheck on any other operation code, We won't get here if
  242. // the earlier asserts are still checked.
  243. //
  244. KeBugCheckEx( SECURITY_SYSTEM, 0, STATUS_INVALID_PARAMETER, 0, 0 );
  245. }
  246. }
  247. NTSTATUS
  248. SeSetSecurityDescriptorInfo (
  249. IN PVOID Object OPTIONAL,
  250. IN PSECURITY_INFORMATION SecurityInformation,
  251. IN PSECURITY_DESCRIPTOR ModificationDescriptor,
  252. IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
  253. IN POOL_TYPE PoolType,
  254. IN PGENERIC_MAPPING GenericMapping
  255. )
  256. /*++
  257. Routine Description:
  258. This routine will set an object's security descriptor. The input
  259. security descriptor must be previously captured.
  260. Arguments:
  261. Object - Optionally supplies the object whose security is
  262. being adjusted. This is used to update security quota
  263. information.
  264. SecurityInformation - Indicates which security information is
  265. to be applied to the object. The value(s) to be assigned are
  266. passed in the SecurityDescriptor parameter.
  267. ModificationDescriptor - Supplies the input security descriptor to be
  268. applied to the object. The caller of this routine is expected
  269. to probe and capture the passed security descriptor before calling
  270. and release it after calling.
  271. ObjectsSecurityDescriptor - Supplies the address of a pointer to
  272. the objects security descriptor that is going to be altered by
  273. this procedure. This structure must be deallocated by the caller.
  274. PoolType - Specifies the type of pool to allocate for the objects
  275. security descriptor.
  276. GenericMapping - This argument provides the mapping of generic to
  277. specific/standard access types for the object being accessed.
  278. This mapping structure is expected to be safe to access
  279. (i.e., captured if necessary) prior to be passed to this routine.
  280. Return Value:
  281. NTSTATUS - STATUS_SUCCESS if successful and an appropriate error
  282. value otherwise.
  283. --*/
  284. {
  285. //
  286. // Make sure the object already has a security descriptor.
  287. // Objects that 'may' have security descriptors 'must' have security
  288. // descriptors. If this one doesn't already have one, then we can't
  289. // assign one to it.
  290. //
  291. if ((*ObjectsSecurityDescriptor) == NULL) {
  292. return(STATUS_NO_SECURITY_ON_OBJECT);
  293. }
  294. //
  295. // Pass this call to the common Rtlp routine.
  296. //
  297. return RtlpSetSecurityObject (
  298. Object,
  299. *SecurityInformation,
  300. ModificationDescriptor,
  301. ObjectsSecurityDescriptor,
  302. 0, // No Auto Inheritance
  303. PoolType,
  304. GenericMapping,
  305. NULL ); // No Token
  306. }
  307. NTSTATUS
  308. SeSetSecurityDescriptorInfoEx (
  309. IN PVOID Object OPTIONAL,
  310. IN PSECURITY_INFORMATION SecurityInformation,
  311. IN PSECURITY_DESCRIPTOR ModificationDescriptor,
  312. IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
  313. IN ULONG AutoInheritFlags,
  314. IN POOL_TYPE PoolType,
  315. IN PGENERIC_MAPPING GenericMapping
  316. )
  317. /*++
  318. Routine Description:
  319. This routine will set an object's security descriptor. The input
  320. security descriptor must be previously captured.
  321. Arguments:
  322. Object - Optionally supplies the object whose security is
  323. being adjusted. This is used to update security quota
  324. information.
  325. SecurityInformation - Indicates which security information is
  326. to be applied to the object. The value(s) to be assigned are
  327. passed in the SecurityDescriptor parameter.
  328. ModificationDescriptor - Supplies the input security descriptor to be
  329. applied to the object. The caller of this routine is expected
  330. to probe and capture the passed security descriptor before calling
  331. and release it after calling.
  332. ObjectsSecurityDescriptor - Supplies the address of a pointer to
  333. the objects security descriptor that is going to be altered by
  334. this procedure. This structure must be deallocated by the caller.
  335. AutoInheritFlags - Controls automatic inheritance of ACES.
  336. Valid values are a bits mask of the logical OR of
  337. one or more of the following bits:
  338. SEF_DACL_AUTO_INHERIT - If set, inherited ACEs from the
  339. DACL in the ObjectsSecurityDescriptor are preserved and inherited ACEs from
  340. the ModificationDescriptor are ignored. Inherited ACEs are not supposed
  341. to be modified; so preserving them across this call is appropriate.
  342. If a protected server does not itself implement auto inheritance, it should
  343. not set this bit. The caller of the protected server may implement
  344. auto inheritance and my indeed be modifying inherited ACEs.
  345. SEF_SACL_AUTO_INHERIT - If set, inherited ACEs from the
  346. SACL in the ObjectsSecurityDescriptor are preserved and inherited ACEs from
  347. the ModificationDescriptor are ignored. Inherited ACEs are not supposed
  348. to be modified; so preserving them across this call is appropriate.
  349. If a protected server does not itself implement auto inheritance, it should
  350. not set this bit. The caller of the protected server may implement
  351. auto inheritance and my indeed be modifying inherited ACEs.
  352. PoolType - Specifies the type of pool to allocate for the objects
  353. security descriptor.
  354. GenericMapping - This argument provides the mapping of generic to
  355. specific/standard access types for the object being accessed.
  356. This mapping structure is expected to be safe to access
  357. (i.e., captured if necessary) prior to be passed to this routine.
  358. Return Value:
  359. NTSTATUS - STATUS_SUCCESS if successful and an appropriate error
  360. value otherwise.
  361. --*/
  362. {
  363. PAGED_CODE();
  364. //
  365. // Make sure the object already has a security descriptor.
  366. // Objects that 'may' have security descriptors 'must' have security
  367. // descriptors. If this one doesn't already have one, then we can't
  368. // assign one to it.
  369. //
  370. if ((*ObjectsSecurityDescriptor) == NULL) {
  371. return(STATUS_NO_SECURITY_ON_OBJECT);
  372. }
  373. //
  374. // Pass this call to the common Rtlp routine.
  375. //
  376. return RtlpSetSecurityObject (
  377. Object,
  378. *SecurityInformation,
  379. ModificationDescriptor,
  380. ObjectsSecurityDescriptor,
  381. AutoInheritFlags,
  382. PoolType,
  383. GenericMapping,
  384. NULL ); // No Token
  385. }
  386. NTSTATUS
  387. SeQuerySecurityDescriptorInfo (
  388. IN PSECURITY_INFORMATION SecurityInformation,
  389. OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
  390. IN OUT PULONG Length,
  391. IN PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor
  392. )
  393. /*++
  394. Routine Description:
  395. This routine will extract the desired information from the
  396. passed security descriptor and return the information in
  397. the passed buffer as a security descriptor in self-relative
  398. format.
  399. Arguments:
  400. SecurityInformation - Specifies what information is being queried.
  401. SecurityDescriptor - Supplies the buffer to output the requested
  402. information into.
  403. This buffer has been probed only to the size indicated by
  404. the Length parameter. Since it still points into user space,
  405. it must always be accessed in a try clause.
  406. Length - Supplies the address of a variable containing the length of
  407. the security descriptor buffer. Upon return this variable will
  408. contain the length needed to store the requested information.
  409. ObjectsSecurityDescriptor - Supplies the address of a pointer to
  410. the objects security descriptor. The passed security descriptor
  411. must be in self-relative format.
  412. Return Value:
  413. NTSTATUS - STATUS_SUCCESS if successful and an appropriate error value
  414. otherwise
  415. --*/
  416. {
  417. ULONG BufferLength;
  418. ULONG Size;
  419. ULONG OwnerLength=0;
  420. ULONG GroupLength=0;
  421. ULONG DaclLength=0;
  422. ULONG SaclLength=0;
  423. PUCHAR NextFree;
  424. SECURITY_DESCRIPTOR IObjectSecurity;
  425. //
  426. // Note that IObjectSecurity is not a pointer to a pointer
  427. // like ObjectsSecurityDescriptor is.
  428. //
  429. SECURITY_DESCRIPTOR_RELATIVE *ISecurityDescriptor = SecurityDescriptor;
  430. PAGED_CODE();
  431. //
  432. // We will be accessing user memory throughout this routine,
  433. // therefore do everything in a try-except clause.
  434. //
  435. try {
  436. BufferLength = *Length;
  437. //
  438. // Check if the object's descriptor is null, and if it is then
  439. // we only need to return a blank security descriptor record
  440. //
  441. if (*ObjectsSecurityDescriptor == NULL) {
  442. *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
  443. //
  444. // Now make sure it's large enough for the security descriptor
  445. // record
  446. //
  447. if (BufferLength < sizeof(SECURITY_DESCRIPTOR_RELATIVE)) {
  448. return STATUS_BUFFER_TOO_SMALL;
  449. }
  450. //
  451. // It's large enough to make a blank security descriptor record
  452. //
  453. // Note that this parameter has been probed for write by the
  454. // object manager, however, we still have to be careful when
  455. // writing to it.
  456. //
  457. //
  458. // We do not have to probe this here, because the object
  459. // manager has probed it for length=BufferLength, which we
  460. // know at this point is at least as large as a security
  461. // descriptor.
  462. //
  463. RtlCreateSecurityDescriptorRelative( SecurityDescriptor,
  464. SECURITY_DESCRIPTOR_REVISION );
  465. //
  466. // Mark it as self-relative
  467. //
  468. RtlpSetControlBits( ISecurityDescriptor, SE_SELF_RELATIVE );
  469. //
  470. // And return to our caller
  471. //
  472. return STATUS_SUCCESS;
  473. }
  474. //
  475. // Create an absolute format SD on the stack pointing into
  476. // user space to simplify the following code
  477. //
  478. RtlCopyMemory( (&IObjectSecurity),
  479. *ObjectsSecurityDescriptor,
  480. sizeof(SECURITY_DESCRIPTOR_RELATIVE) );
  481. IObjectSecurity.Owner = RtlpOwnerAddrSecurityDescriptor(
  482. (SECURITY_DESCRIPTOR *) *ObjectsSecurityDescriptor );
  483. IObjectSecurity.Group = RtlpGroupAddrSecurityDescriptor(
  484. (SECURITY_DESCRIPTOR *) *ObjectsSecurityDescriptor );
  485. IObjectSecurity.Dacl = RtlpDaclAddrSecurityDescriptor(
  486. (SECURITY_DESCRIPTOR *) *ObjectsSecurityDescriptor );
  487. IObjectSecurity.Sacl = RtlpSaclAddrSecurityDescriptor(
  488. (SECURITY_DESCRIPTOR *) *ObjectsSecurityDescriptor );
  489. IObjectSecurity.Control &= ~SE_SELF_RELATIVE;
  490. //
  491. // This is not a blank descriptor so we need to determine the size
  492. // needed to store the requested information. It is the size of the
  493. // descriptor record plus the size of each requested component.
  494. //
  495. Size = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
  496. if ( (((*SecurityInformation) & OWNER_SECURITY_INFORMATION)) &&
  497. (IObjectSecurity.Owner != NULL) ) {
  498. OwnerLength = SeLengthSid( IObjectSecurity.Owner );
  499. Size += (ULONG)LongAlignSize(OwnerLength);
  500. }
  501. if ( (((*SecurityInformation) & GROUP_SECURITY_INFORMATION)) &&
  502. (IObjectSecurity.Group != NULL) ) {
  503. GroupLength = SeLengthSid( IObjectSecurity.Group );
  504. Size += (ULONG)LongAlignSize(GroupLength);
  505. }
  506. if ( (((*SecurityInformation) & DACL_SECURITY_INFORMATION)) &&
  507. (IObjectSecurity.Control & SE_DACL_PRESENT) &&
  508. (IObjectSecurity.Dacl != NULL) ) {
  509. DaclLength = (ULONG)LongAlignSize((IObjectSecurity.Dacl)->AclSize);
  510. Size += DaclLength;
  511. }
  512. if ( (((*SecurityInformation) & SACL_SECURITY_INFORMATION)) &&
  513. (IObjectSecurity.Control & SE_SACL_PRESENT) &&
  514. (IObjectSecurity.Sacl != NULL) ) {
  515. SaclLength = (ULONG)LongAlignSize((IObjectSecurity.Sacl)->AclSize);
  516. Size += SaclLength;
  517. }
  518. //
  519. // Tell the caller how much space this will require
  520. // (whether we actually fit or not)
  521. //
  522. *Length = Size;
  523. //
  524. // Now make sure the size is less than or equal to the length
  525. // we were passed
  526. //
  527. if (Size > BufferLength) {
  528. return STATUS_BUFFER_TOO_SMALL;
  529. }
  530. //
  531. // The length is fine.
  532. //
  533. // Fill in the length and flags part of the security descriptor.
  534. // The real addresses of each acl will be filled in later when we
  535. // copy the ACLs over.
  536. //
  537. // Note that we only set a flag in the descriptor if the information
  538. // was requested, which is a simple copy of the requested information
  539. // input variable
  540. //
  541. // The output buffer has already been probed to the passed size,
  542. // so we can just write to it.
  543. //
  544. RtlCreateSecurityDescriptorRelative( SecurityDescriptor,
  545. SECURITY_DESCRIPTOR_REVISION );
  546. //
  547. // Mark the returned Security Descriptor as being in
  548. // self-relative format
  549. //
  550. RtlpSetControlBits( ISecurityDescriptor, SE_SELF_RELATIVE );
  551. //
  552. // NextFree is used to point to the next free spot in the
  553. // returned security descriptor.
  554. //
  555. NextFree = LongAlignPtr((PUCHAR)SecurityDescriptor +
  556. sizeof(SECURITY_DESCRIPTOR_RELATIVE));
  557. //
  558. // Copy the Owner SID if necessary and update the NextFree pointer,
  559. // keeping it longword aligned.
  560. //
  561. if ( ((*SecurityInformation) & OWNER_SECURITY_INFORMATION) &&
  562. ((IObjectSecurity.Owner) != NULL) ) {
  563. RtlMoveMemory( NextFree,
  564. IObjectSecurity.Owner,
  565. OwnerLength );
  566. ISecurityDescriptor->Owner = (ULONG)((PUCHAR)NextFree - (PUCHAR)SecurityDescriptor);
  567. RtlpPropagateControlBits(
  568. ISecurityDescriptor,
  569. &IObjectSecurity,
  570. SE_OWNER_DEFAULTED
  571. );
  572. NextFree += (ULONG)LongAlignSize(OwnerLength);
  573. }
  574. //
  575. // Copy the Group SID if necessary and update the NextFree pointer,
  576. // keeping it longword aligned.
  577. //
  578. if ( ((*SecurityInformation) & GROUP_SECURITY_INFORMATION) &&
  579. (IObjectSecurity.Group != NULL) ) {
  580. RtlMoveMemory( NextFree,
  581. IObjectSecurity.Group,
  582. GroupLength );
  583. ISecurityDescriptor->Group = (ULONG)((PUCHAR)NextFree - (PUCHAR)SecurityDescriptor);
  584. RtlpPropagateControlBits(
  585. ISecurityDescriptor,
  586. &IObjectSecurity,
  587. SE_GROUP_DEFAULTED
  588. );
  589. NextFree += (ULONG)LongAlignSize(GroupLength);
  590. }
  591. //
  592. // Set discretionary acl information if requested.
  593. // If not set in object's security,
  594. // then everything is already set properly.
  595. //
  596. if ( (*SecurityInformation) & DACL_SECURITY_INFORMATION) {
  597. RtlpPropagateControlBits(
  598. ISecurityDescriptor,
  599. &IObjectSecurity,
  600. SE_DACL_PRESENT | SE_DACL_DEFAULTED | SE_DACL_PROTECTED | SE_DACL_AUTO_INHERITED
  601. );
  602. //
  603. // Copy the acl if non-null and update the NextFree pointer,
  604. // keeping it longword aligned.
  605. //
  606. if ( (IObjectSecurity.Control & SE_DACL_PRESENT) != 0 &&
  607. IObjectSecurity.Dacl != NULL) {
  608. RtlMoveMemory( NextFree,
  609. IObjectSecurity.Dacl,
  610. (IObjectSecurity.Dacl)->AclSize );
  611. ISecurityDescriptor->Dacl = (ULONG)((PUCHAR)NextFree - (PUCHAR)SecurityDescriptor);
  612. NextFree += DaclLength;
  613. }
  614. }
  615. //
  616. // Set system acl information if requested.
  617. // If not set in object's security,
  618. // then everything is already set properly.
  619. //
  620. if ( (*SecurityInformation) & SACL_SECURITY_INFORMATION) {
  621. RtlpPropagateControlBits(
  622. ISecurityDescriptor,
  623. &IObjectSecurity,
  624. SE_SACL_PRESENT | SE_SACL_DEFAULTED | SE_SACL_PROTECTED | SE_SACL_AUTO_INHERITED
  625. );
  626. //
  627. // Copy the acl if non-null and update the NextFree pointer,
  628. // keeping it longword aligned.
  629. //
  630. if ( (IObjectSecurity.Control & SE_SACL_PRESENT) != 0 &&
  631. IObjectSecurity.Sacl != NULL) {
  632. RtlMoveMemory( NextFree,
  633. IObjectSecurity.Sacl,
  634. (IObjectSecurity.Sacl)->AclSize );
  635. ISecurityDescriptor->Sacl = (ULONG)((PUCHAR)NextFree - (PUCHAR)SecurityDescriptor);
  636. }
  637. }
  638. } except(EXCEPTION_EXECUTE_HANDLER) {
  639. return(GetExceptionCode());
  640. }
  641. return STATUS_SUCCESS;
  642. }
  643. NTSTATUS
  644. SepDefaultDeleteMethod (
  645. IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor
  646. )
  647. /*++
  648. Routine Description:
  649. This is a private procedure to delete the security descriptor for
  650. an object. It cleans up any pool allocations that have occured
  651. as part of the descriptor.
  652. Arguments:
  653. ObjectsSecurityDescriptor - Supplies the address of a pointer
  654. to the security descriptor being deleted.
  655. Return Value:
  656. NTSTATUS - STATUS_SUCCESS
  657. --*/
  658. {
  659. PAGED_CODE();
  660. return (ObDeassignSecurity ( ObjectsSecurityDescriptor ));
  661. }