2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: Security manager
5 * FILE: ntoskrnl/ob/security.c
8 * 26/07/98: Added stubs for security functions
11 /* INCLUDES *****************************************************************/
14 #include <internal/debug.h>
16 /* FUNCTIONS ***************************************************************/
22 ObAssignSecurity(IN PACCESS_STATE AccessState
,
23 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
27 PSECURITY_DESCRIPTOR NewDescriptor
;
30 /* Build the new security descriptor */
31 Status
= SeAssignSecurity(SecurityDescriptor
,
32 AccessState
->SecurityDescriptor
,
34 (Type
== ObDirectoryType
),
35 &AccessState
->SubjectSecurityContext
,
38 if (!NT_SUCCESS(Status
))
41 if (Type
->Security
!= NULL
)
43 /* Call the security method */
44 Status
= Type
->Security(Object
,
45 AssignSecurityDescriptor
,
52 /* Assign the security descriptor to the object header */
53 Status
= ObpAddSecurityDescriptor(NewDescriptor
,
54 &(BODY_TO_HEADER(Object
)->SecurityDescriptor
));
57 /* Release the new security descriptor */
58 SeDeassignSecurity(&NewDescriptor
);
68 ObGetObjectSecurity(IN PVOID Object
,
69 OUT PSECURITY_DESCRIPTOR
*SecurityDescriptor
,
70 OUT PBOOLEAN MemoryAllocated
)
72 POBJECT_HEADER Header
;
76 Header
= BODY_TO_HEADER(Object
);
77 if (Header
->ObjectType
== NULL
)
78 return STATUS_UNSUCCESSFUL
;
80 if (Header
->ObjectType
->Security
== NULL
)
82 ObpReferenceCachedSecurityDescriptor(Header
->SecurityDescriptor
);
83 *SecurityDescriptor
= Header
->SecurityDescriptor
;
84 *MemoryAllocated
= FALSE
;
85 return STATUS_SUCCESS
;
88 /* Get the security descriptor size */
90 Status
= Header
->ObjectType
->Security(Object
,
91 QuerySecurityDescriptor
,
92 OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
|
93 DACL_SECURITY_INFORMATION
| SACL_SECURITY_INFORMATION
,
96 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
99 /* Allocate security descriptor */
100 *SecurityDescriptor
= ExAllocatePool(NonPagedPool
,
102 if (*SecurityDescriptor
== NULL
)
103 return STATUS_INSUFFICIENT_RESOURCES
;
105 /* Query security descriptor */
106 Status
= Header
->ObjectType
->Security(Object
,
107 QuerySecurityDescriptor
,
108 OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
|
109 DACL_SECURITY_INFORMATION
| SACL_SECURITY_INFORMATION
,
112 if (!NT_SUCCESS(Status
))
114 ExFreePool(*SecurityDescriptor
);
118 *MemoryAllocated
= TRUE
;
120 return STATUS_SUCCESS
;
128 ObReleaseObjectSecurity(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
129 IN BOOLEAN MemoryAllocated
)
131 if (SecurityDescriptor
== NULL
)
136 ExFreePool(SecurityDescriptor
);
140 ObpDereferenceCachedSecurityDescriptor(SecurityDescriptor
);
149 NtQuerySecurityObject(IN HANDLE Handle
,
150 IN SECURITY_INFORMATION SecurityInformation
,
151 OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
153 OUT PULONG ResultLength
)
155 POBJECT_HEADER Header
;
157 PSECURITY_DESCRIPTOR ObjectSd
;
162 ULONG OwnerLength
= 0;
163 ULONG GroupLength
= 0;
164 ULONG DaclLength
= 0;
165 ULONG SaclLength
= 0;
170 Status
= ObReferenceObjectByHandle(Handle
,
171 (SecurityInformation
& SACL_SECURITY_INFORMATION
) ? ACCESS_SYSTEM_SECURITY
: 0,
176 if (!NT_SUCCESS(Status
))
181 Header
= BODY_TO_HEADER(Object
);
182 if (Header
->ObjectType
== NULL
)
184 ObDereferenceObject(Object
);
185 return STATUS_UNSUCCESSFUL
;
188 if (Header
->ObjectType
->Security
!= NULL
)
190 Status
= Header
->ObjectType
->Security(Object
,
191 QuerySecurityDescriptor
,
195 *ResultLength
= Length
;
199 ObjectSd
= Header
->SecurityDescriptor
;
201 if (ObjectSd
!= NULL
)
203 Control
= SE_SELF_RELATIVE
;
204 if ((SecurityInformation
& OWNER_SECURITY_INFORMATION
) &&
205 (ObjectSd
->Owner
!= NULL
))
207 Owner
= (PSID
)((ULONG_PTR
)ObjectSd
->Owner
+ (ULONG_PTR
)ObjectSd
);
208 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
209 Control
|= (ObjectSd
->Control
& SE_OWNER_DEFAULTED
);
212 if ((SecurityInformation
& GROUP_SECURITY_INFORMATION
) &&
213 (ObjectSd
->Group
!= NULL
))
215 Group
= (PSID
)((ULONG_PTR
)ObjectSd
->Group
+ (ULONG_PTR
)ObjectSd
);
216 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
217 Control
|= (ObjectSd
->Control
& SE_GROUP_DEFAULTED
);
220 if ((SecurityInformation
& DACL_SECURITY_INFORMATION
) &&
221 (ObjectSd
->Control
& SE_DACL_PRESENT
))
223 if (ObjectSd
->Dacl
!= NULL
)
225 Dacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Dacl
+ (ULONG_PTR
)ObjectSd
);
226 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
228 Control
|= (ObjectSd
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
231 if ((SecurityInformation
& SACL_SECURITY_INFORMATION
) &&
232 (ObjectSd
->Control
& SE_SACL_PRESENT
))
234 if (ObjectSd
->Sacl
!= NULL
)
236 Sacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Sacl
+ (ULONG_PTR
)ObjectSd
);
237 SaclLength
= ROUND_UP(Sacl
->AclSize
, 4);
239 Control
|= (ObjectSd
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
242 *ResultLength
= OwnerLength
+ GroupLength
+
243 DaclLength
+ SaclLength
+ sizeof(SECURITY_DESCRIPTOR
);
244 if (Length
>= *ResultLength
)
246 RtlCreateSecurityDescriptor(SecurityDescriptor
,
247 SECURITY_DESCRIPTOR_REVISION1
);
248 SecurityDescriptor
->Control
= Control
;
250 Current
= (ULONG_PTR
)SecurityDescriptor
+ sizeof(SECURITY_DESCRIPTOR
);
252 if (OwnerLength
!= 0)
254 RtlCopyMemory((PVOID
)Current
,
257 SecurityDescriptor
->Owner
= (PSID
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
258 Current
+= OwnerLength
;
261 if (GroupLength
!= 0)
263 RtlCopyMemory((PVOID
)Current
,
266 SecurityDescriptor
->Group
= (PSID
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
267 Current
+= GroupLength
;
272 RtlCopyMemory((PVOID
)Current
,
275 SecurityDescriptor
->Dacl
= (PACL
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
276 Current
+= DaclLength
;
281 RtlCopyMemory((PVOID
)Current
,
284 SecurityDescriptor
->Sacl
= (PACL
)(Current
- (ULONG_PTR
)SecurityDescriptor
);
285 Current
+= SaclLength
;
288 Status
= STATUS_SUCCESS
;
292 Status
= STATUS_BUFFER_TOO_SMALL
;
298 Status
= STATUS_UNSUCCESSFUL
;
302 ObDereferenceObject(Object
);
312 NtSetSecurityObject(IN HANDLE Handle
,
313 IN SECURITY_INFORMATION SecurityInformation
,
314 IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
316 PSECURITY_DESCRIPTOR ObjectSd
;
317 PSECURITY_DESCRIPTOR NewSd
;
318 POBJECT_HEADER Header
;
324 ULONG OwnerLength
= 0;
325 ULONG GroupLength
= 0;
326 ULONG DaclLength
= 0;
327 ULONG SaclLength
= 0;
332 Status
= ObReferenceObjectByHandle(Handle
,
333 (SecurityInformation
& SACL_SECURITY_INFORMATION
) ? ACCESS_SYSTEM_SECURITY
: 0,
338 if (!NT_SUCCESS(Status
))
343 Header
= BODY_TO_HEADER(Object
);
344 if (Header
->ObjectType
!= NULL
)
346 ObDereferenceObject(Object
);
347 return STATUS_UNSUCCESSFUL
;
350 if (Header
->ObjectType
->Security
!= NULL
)
352 Status
= Header
->ObjectType
->Security(Object
,
353 SetSecurityDescriptor
,
360 ObjectSd
= Header
->SecurityDescriptor
;
362 /* Get owner and owner size */
363 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
365 if (SecurityDescriptor
->Owner
!= NULL
)
367 Owner
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Owner
+ (ULONG_PTR
)SecurityDescriptor
);
368 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
370 Control
|= (SecurityDescriptor
->Control
& SE_OWNER_DEFAULTED
);
374 if (ObjectSd
->Owner
!= NULL
)
376 Owner
= (PSID
)((ULONG_PTR
)ObjectSd
->Owner
+ (ULONG_PTR
)ObjectSd
);
377 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
379 Control
|= (ObjectSd
->Control
& SE_OWNER_DEFAULTED
);
382 /* Get group and group size */
383 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
385 if (SecurityDescriptor
->Group
!= NULL
)
387 Group
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Group
+ (ULONG_PTR
)SecurityDescriptor
);
388 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
390 Control
|= (SecurityDescriptor
->Control
& SE_GROUP_DEFAULTED
);
394 if (ObjectSd
->Group
!= NULL
)
396 Group
= (PSID
)((ULONG_PTR
)ObjectSd
->Group
+ (ULONG_PTR
)ObjectSd
);
397 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
399 Control
|= (ObjectSd
->Control
& SE_GROUP_DEFAULTED
);
402 /* Get DACL and DACL size */
403 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
405 if ((SecurityDescriptor
->Control
& SE_DACL_PRESENT
) &&
406 (SecurityDescriptor
->Dacl
!= NULL
))
408 Dacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Dacl
+ (ULONG_PTR
)SecurityDescriptor
);
409 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
411 Control
|= (SecurityDescriptor
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
415 if ((ObjectSd
->Control
& SE_DACL_PRESENT
) &&
416 (ObjectSd
->Dacl
!= NULL
))
418 Dacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Dacl
+ (ULONG_PTR
)ObjectSd
);
419 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
421 Control
|= (ObjectSd
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
424 /* Get SACL and SACL size */
425 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
427 if ((SecurityDescriptor
->Control
& SE_SACL_PRESENT
) &&
428 (SecurityDescriptor
->Sacl
!= NULL
))
430 Sacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Sacl
+ (ULONG_PTR
)SecurityDescriptor
);
431 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
433 Control
|= (SecurityDescriptor
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
437 if ((ObjectSd
->Control
& SE_SACL_PRESENT
) &&
438 (ObjectSd
->Sacl
!= NULL
))
440 Sacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Sacl
+ (ULONG_PTR
)ObjectSd
);
441 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
443 Control
|= (ObjectSd
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
446 NewSd
= ExAllocatePool(NonPagedPool
,
447 sizeof(SECURITY_DESCRIPTOR
) + OwnerLength
+ GroupLength
+
448 DaclLength
+ SaclLength
);
451 ObDereferenceObject(Object
);
452 return STATUS_INSUFFICIENT_RESOURCES
;
455 RtlCreateSecurityDescriptor(NewSd
,
456 SECURITY_DESCRIPTOR_REVISION1
);
457 NewSd
->Control
= Control
;
459 Current
= (ULONG_PTR
)NewSd
+ sizeof(SECURITY_DESCRIPTOR
);
461 if (OwnerLength
!= 0)
463 RtlCopyMemory((PVOID
)Current
,
466 NewSd
->Owner
= (PSID
)(Current
- (ULONG_PTR
)NewSd
);
467 Current
+= OwnerLength
;
470 if (GroupLength
!= 0)
472 RtlCopyMemory((PVOID
)Current
,
475 NewSd
->Group
= (PSID
)(Current
- (ULONG_PTR
)NewSd
);
476 Current
+= GroupLength
;
481 RtlCopyMemory((PVOID
)Current
,
484 NewSd
->Dacl
= (PACL
)(Current
- (ULONG_PTR
)NewSd
);
485 Current
+= DaclLength
;
490 RtlCopyMemory((PVOID
)Current
,
493 NewSd
->Sacl
= (PACL
)(Current
- (ULONG_PTR
)NewSd
);
494 Current
+= SaclLength
;
498 Status
= ObpAddSecurityDescriptor(NewSd
,
499 &Header
->SecurityDescriptor
);
500 if (NT_SUCCESS(Status
))
502 /* Remove the old security descriptor */
503 ObpRemoveSecurityDescriptor(ObjectSd
);
507 /* Restore the old security descriptor */
508 Header
->SecurityDescriptor
= ObjectSd
;
514 ObDereferenceObject(Object
);