3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ob/security.c
6 * PURPOSE: Security manager
8 * PROGRAMERS: No programmer listed.
11 /* INCLUDES *****************************************************************/
15 #include <internal/debug.h>
17 /* FUNCTIONS ***************************************************************/
23 ObAssignSecurity(IN PACCESS_STATE AccessState
,
24 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
28 PSECURITY_DESCRIPTOR NewDescriptor
;
33 /* Build the new security descriptor */
34 Status
= SeAssignSecurity(SecurityDescriptor
,
35 AccessState
->SecurityDescriptor
,
37 (Type
== ObDirectoryType
),
38 &AccessState
->SubjectSecurityContext
,
39 &Type
->TypeInfo
.GenericMapping
,
41 if (!NT_SUCCESS(Status
))
44 if (Type
->TypeInfo
.SecurityProcedure
!= NULL
)
46 /* Call the security method */
47 Status
= Type
->TypeInfo
.SecurityProcedure(Object
,
48 AssignSecurityDescriptor
,
55 /* Assign the security descriptor to the object header */
56 Status
= ObpAddSecurityDescriptor(NewDescriptor
,
57 &(BODY_TO_HEADER(Object
)->SecurityDescriptor
));
60 /* Release the new security descriptor */
61 SeDeassignSecurity(&NewDescriptor
);
71 ObGetObjectSecurity(IN PVOID Object
,
72 OUT PSECURITY_DESCRIPTOR
*SecurityDescriptor
,
73 OUT PBOOLEAN MemoryAllocated
)
75 POBJECT_HEADER Header
;
81 Header
= BODY_TO_HEADER(Object
);
82 if (Header
->ObjectType
== NULL
)
83 return STATUS_UNSUCCESSFUL
;
85 if (Header
->ObjectType
->TypeInfo
.SecurityProcedure
== NULL
)
87 ObpReferenceCachedSecurityDescriptor(Header
->SecurityDescriptor
);
88 *SecurityDescriptor
= Header
->SecurityDescriptor
;
89 *MemoryAllocated
= FALSE
;
90 return STATUS_SUCCESS
;
93 /* Get the security descriptor size */
95 Status
= Header
->ObjectType
->TypeInfo
.SecurityProcedure(Object
,
96 QuerySecurityDescriptor
,
97 OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
|
98 DACL_SECURITY_INFORMATION
| SACL_SECURITY_INFORMATION
,
101 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
104 /* Allocate security descriptor */
105 *SecurityDescriptor
= ExAllocatePool(NonPagedPool
,
107 if (*SecurityDescriptor
== NULL
)
108 return STATUS_INSUFFICIENT_RESOURCES
;
110 /* Query security descriptor */
111 Status
= Header
->ObjectType
->TypeInfo
.SecurityProcedure(Object
,
112 QuerySecurityDescriptor
,
113 OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
|
114 DACL_SECURITY_INFORMATION
| SACL_SECURITY_INFORMATION
,
117 if (!NT_SUCCESS(Status
))
119 ExFreePool(*SecurityDescriptor
);
123 *MemoryAllocated
= TRUE
;
125 return STATUS_SUCCESS
;
133 ObReleaseObjectSecurity(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
134 IN BOOLEAN MemoryAllocated
)
138 if (SecurityDescriptor
== NULL
)
143 ExFreePool(SecurityDescriptor
);
147 ObpDereferenceCachedSecurityDescriptor(SecurityDescriptor
);
156 NtQuerySecurityObject(IN HANDLE Handle
,
157 IN SECURITY_INFORMATION SecurityInformation
,
158 OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
160 OUT PULONG ResultLength
)
162 POBJECT_HEADER Header
;
168 DPRINT("NtQuerySecurityObject() called\n");
170 Status
= ObReferenceObjectByHandle(Handle
,
171 (SecurityInformation
& SACL_SECURITY_INFORMATION
) ? ACCESS_SYSTEM_SECURITY
: 0,
176 if (!NT_SUCCESS(Status
))
178 DPRINT1("ObReferenceObjectByHandle() failed (Status %lx)\n", Status
);
182 Header
= BODY_TO_HEADER(Object
);
183 if (Header
->ObjectType
== NULL
)
185 DPRINT1("Invalid object type\n");
186 ObDereferenceObject(Object
);
187 return STATUS_UNSUCCESSFUL
;
190 if (Header
->ObjectType
->TypeInfo
.SecurityProcedure
!= NULL
)
192 *ResultLength
= Length
;
193 Status
= Header
->ObjectType
->TypeInfo
.SecurityProcedure(Object
,
194 QuerySecurityDescriptor
,
201 *ResultLength
= Length
;
202 Status
= SeQuerySecurityDescriptorInfo(&SecurityInformation
,
205 &Header
->SecurityDescriptor
);
208 ObDereferenceObject(Object
);
218 NtSetSecurityObject(IN HANDLE Handle
,
219 IN SECURITY_INFORMATION SecurityInformation
,
220 IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
222 PSECURITY_DESCRIPTOR ObjectSd
;
223 PSECURITY_DESCRIPTOR NewSd
;
224 POBJECT_HEADER Header
;
230 ULONG OwnerLength
= 0;
231 ULONG GroupLength
= 0;
232 ULONG DaclLength
= 0;
233 ULONG SaclLength
= 0;
240 DPRINT("NtSetSecurityObject() called\n");
242 Status
= ObReferenceObjectByHandle(Handle
,
243 (SecurityInformation
& SACL_SECURITY_INFORMATION
) ? ACCESS_SYSTEM_SECURITY
: 0,
248 if (!NT_SUCCESS(Status
))
250 DPRINT1("ObReferenceObjectByHandle() failed (Status %lx)\n", Status
);
254 Header
= BODY_TO_HEADER(Object
);
255 if (Header
->ObjectType
== NULL
)
257 DPRINT1("Invalid object type\n");
258 ObDereferenceObject(Object
);
259 return STATUS_UNSUCCESSFUL
;
262 if (Header
->ObjectType
->TypeInfo
.SecurityProcedure
!= NULL
)
264 Status
= Header
->ObjectType
->TypeInfo
.SecurityProcedure(Object
,
265 SetSecurityDescriptor
,
272 ObjectSd
= Header
->SecurityDescriptor
;
274 /* Get owner and owner size */
275 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
277 if (SecurityDescriptor
->Owner
!= NULL
)
279 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
280 Owner
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Owner
+
281 (ULONG_PTR
)SecurityDescriptor
);
283 Owner
= (PSID
)SecurityDescriptor
->Owner
;
284 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
286 Control
|= (SecurityDescriptor
->Control
& SE_OWNER_DEFAULTED
);
290 if (ObjectSd
->Owner
!= NULL
)
292 Owner
= (PSID
)((ULONG_PTR
)ObjectSd
->Owner
+ (ULONG_PTR
)ObjectSd
);
293 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
295 Control
|= (ObjectSd
->Control
& SE_OWNER_DEFAULTED
);
298 /* Get group and group size */
299 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
301 if (SecurityDescriptor
->Group
!= NULL
)
303 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
304 Group
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Group
+
305 (ULONG_PTR
)SecurityDescriptor
);
307 Group
= (PSID
)SecurityDescriptor
->Group
;
308 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
310 Control
|= (SecurityDescriptor
->Control
& SE_GROUP_DEFAULTED
);
314 if (ObjectSd
->Group
!= NULL
)
316 Group
= (PSID
)((ULONG_PTR
)ObjectSd
->Group
+ (ULONG_PTR
)ObjectSd
);
317 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
319 Control
|= (ObjectSd
->Control
& SE_GROUP_DEFAULTED
);
322 /* Get DACL and DACL size */
323 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
325 if ((SecurityDescriptor
->Control
& SE_DACL_PRESENT
) &&
326 (SecurityDescriptor
->Dacl
!= NULL
))
328 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
329 Dacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Dacl
+
330 (ULONG_PTR
)SecurityDescriptor
);
332 Dacl
= (PACL
)SecurityDescriptor
->Dacl
;
334 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
336 Control
|= (SecurityDescriptor
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
340 if ((ObjectSd
->Control
& SE_DACL_PRESENT
) &&
341 (ObjectSd
->Dacl
!= NULL
))
343 Dacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Dacl
+ (ULONG_PTR
)ObjectSd
);
344 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
346 Control
|= (ObjectSd
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
349 /* Get SACL and SACL size */
350 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
352 if ((SecurityDescriptor
->Control
& SE_SACL_PRESENT
) &&
353 (SecurityDescriptor
->Sacl
!= NULL
))
355 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
356 Sacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Sacl
+
357 (ULONG_PTR
)SecurityDescriptor
);
359 Sacl
= (PACL
)SecurityDescriptor
->Sacl
;
360 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
362 Control
|= (SecurityDescriptor
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
366 if ((ObjectSd
->Control
& SE_SACL_PRESENT
) &&
367 (ObjectSd
->Sacl
!= NULL
))
369 Sacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Sacl
+ (ULONG_PTR
)ObjectSd
);
370 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
372 Control
|= (ObjectSd
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
375 NewSd
= ExAllocatePool(NonPagedPool
,
376 sizeof(SECURITY_DESCRIPTOR
) + OwnerLength
+ GroupLength
+
377 DaclLength
+ SaclLength
);
380 ObDereferenceObject(Object
);
381 return STATUS_INSUFFICIENT_RESOURCES
;
384 RtlCreateSecurityDescriptor(NewSd
,
385 SECURITY_DESCRIPTOR_REVISION1
);
386 /* We always build a self-relative descriptor */
387 NewSd
->Control
= Control
| SE_SELF_RELATIVE
;
389 Current
= (ULONG_PTR
)NewSd
+ sizeof(SECURITY_DESCRIPTOR
);
391 if (OwnerLength
!= 0)
393 RtlCopyMemory((PVOID
)Current
,
396 NewSd
->Owner
= (PSID
)(Current
- (ULONG_PTR
)NewSd
);
397 Current
+= OwnerLength
;
400 if (GroupLength
!= 0)
402 RtlCopyMemory((PVOID
)Current
,
405 NewSd
->Group
= (PSID
)(Current
- (ULONG_PTR
)NewSd
);
406 Current
+= GroupLength
;
411 RtlCopyMemory((PVOID
)Current
,
414 NewSd
->Dacl
= (PACL
)(Current
- (ULONG_PTR
)NewSd
);
415 Current
+= DaclLength
;
420 RtlCopyMemory((PVOID
)Current
,
423 NewSd
->Sacl
= (PACL
)(Current
- (ULONG_PTR
)NewSd
);
424 Current
+= SaclLength
;
428 Status
= ObpAddSecurityDescriptor(NewSd
,
429 &Header
->SecurityDescriptor
);
430 if (NT_SUCCESS(Status
))
432 /* Remove the old security descriptor */
433 ObpRemoveSecurityDescriptor(ObjectSd
);
437 /* Restore the old security descriptor */
438 Header
->SecurityDescriptor
= ObjectSd
;
444 ObDereferenceObject(Object
);