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 *****************************************************************/
15 #include <internal/debug.h>
17 /* FUNCTIONS ***************************************************************/
23 ObAssignSecurity(IN PACCESS_STATE AccessState
,
24 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
28 PSECURITY_DESCRIPTOR NewDescriptor
;
31 /* Build the new security descriptor */
32 Status
= SeAssignSecurity(SecurityDescriptor
,
33 AccessState
->SecurityDescriptor
,
35 (Type
== ObDirectoryType
),
36 &AccessState
->SubjectSecurityContext
,
39 if (!NT_SUCCESS(Status
))
42 if (Type
->Security
!= NULL
)
44 /* Call the security method */
45 Status
= Type
->Security(Object
,
46 AssignSecurityDescriptor
,
53 /* Assign the security descriptor to the object header */
54 Status
= ObpAddSecurityDescriptor(NewDescriptor
,
55 &(BODY_TO_HEADER(Object
)->SecurityDescriptor
));
58 /* Release the new security descriptor */
59 SeDeassignSecurity(&NewDescriptor
);
69 ObGetObjectSecurity(IN PVOID Object
,
70 OUT PSECURITY_DESCRIPTOR
*SecurityDescriptor
,
71 OUT PBOOLEAN MemoryAllocated
)
73 POBJECT_HEADER Header
;
77 Header
= BODY_TO_HEADER(Object
);
78 if (Header
->ObjectType
== NULL
)
79 return STATUS_UNSUCCESSFUL
;
81 if (Header
->ObjectType
->Security
== NULL
)
83 ObpReferenceCachedSecurityDescriptor(Header
->SecurityDescriptor
);
84 *SecurityDescriptor
= Header
->SecurityDescriptor
;
85 *MemoryAllocated
= FALSE
;
86 return STATUS_SUCCESS
;
89 /* Get the security descriptor size */
91 Status
= Header
->ObjectType
->Security(Object
,
92 QuerySecurityDescriptor
,
93 OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
|
94 DACL_SECURITY_INFORMATION
| SACL_SECURITY_INFORMATION
,
97 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
100 /* Allocate security descriptor */
101 *SecurityDescriptor
= ExAllocatePool(NonPagedPool
,
103 if (*SecurityDescriptor
== NULL
)
104 return STATUS_INSUFFICIENT_RESOURCES
;
106 /* Query security descriptor */
107 Status
= Header
->ObjectType
->Security(Object
,
108 QuerySecurityDescriptor
,
109 OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
|
110 DACL_SECURITY_INFORMATION
| SACL_SECURITY_INFORMATION
,
113 if (!NT_SUCCESS(Status
))
115 ExFreePool(*SecurityDescriptor
);
119 *MemoryAllocated
= TRUE
;
121 return STATUS_SUCCESS
;
129 ObReleaseObjectSecurity(IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
130 IN BOOLEAN MemoryAllocated
)
132 if (SecurityDescriptor
== NULL
)
137 ExFreePool(SecurityDescriptor
);
141 ObpDereferenceCachedSecurityDescriptor(SecurityDescriptor
);
150 NtQuerySecurityObject(IN HANDLE Handle
,
151 IN SECURITY_INFORMATION SecurityInformation
,
152 OUT PSECURITY_DESCRIPTOR SecurityDescriptor
,
154 OUT PULONG ResultLength
)
156 POBJECT_HEADER Header
;
160 DPRINT("NtQuerySecurityObject() called\n");
162 Status
= ObReferenceObjectByHandle(Handle
,
163 (SecurityInformation
& SACL_SECURITY_INFORMATION
) ? ACCESS_SYSTEM_SECURITY
: 0,
168 if (!NT_SUCCESS(Status
))
170 DPRINT1("ObReferenceObjectByHandle() failed (Status %lx)\n", Status
);
174 Header
= BODY_TO_HEADER(Object
);
175 if (Header
->ObjectType
== NULL
)
177 DPRINT1("Invalid object type\n");
178 ObDereferenceObject(Object
);
179 return STATUS_UNSUCCESSFUL
;
182 if (Header
->ObjectType
->Security
!= NULL
)
184 *ResultLength
= Length
;
185 Status
= Header
->ObjectType
->Security(Object
,
186 QuerySecurityDescriptor
,
193 *ResultLength
= Length
;
194 Status
= SeQuerySecurityDescriptorInfo(&SecurityInformation
,
197 &Header
->SecurityDescriptor
);
200 ObDereferenceObject(Object
);
210 NtSetSecurityObject(IN HANDLE Handle
,
211 IN SECURITY_INFORMATION SecurityInformation
,
212 IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
214 PSECURITY_DESCRIPTOR ObjectSd
;
215 PSECURITY_DESCRIPTOR NewSd
;
216 POBJECT_HEADER Header
;
222 ULONG OwnerLength
= 0;
223 ULONG GroupLength
= 0;
224 ULONG DaclLength
= 0;
225 ULONG SaclLength
= 0;
230 DPRINT("NtSetSecurityObject() called\n");
232 Status
= ObReferenceObjectByHandle(Handle
,
233 (SecurityInformation
& SACL_SECURITY_INFORMATION
) ? ACCESS_SYSTEM_SECURITY
: 0,
238 if (!NT_SUCCESS(Status
))
240 DPRINT1("ObReferenceObjectByHandle() failed (Status %lx)\n", Status
);
244 Header
= BODY_TO_HEADER(Object
);
245 if (Header
->ObjectType
== NULL
)
247 DPRINT1("Invalid object type\n");
248 ObDereferenceObject(Object
);
249 return STATUS_UNSUCCESSFUL
;
252 if (Header
->ObjectType
->Security
!= NULL
)
254 Status
= Header
->ObjectType
->Security(Object
,
255 SetSecurityDescriptor
,
262 ObjectSd
= Header
->SecurityDescriptor
;
264 /* Get owner and owner size */
265 if (SecurityInformation
& OWNER_SECURITY_INFORMATION
)
267 if (SecurityDescriptor
->Owner
!= NULL
)
269 Owner
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Owner
+ (ULONG_PTR
)SecurityDescriptor
);
270 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
272 Control
|= (SecurityDescriptor
->Control
& SE_OWNER_DEFAULTED
);
276 if (ObjectSd
->Owner
!= NULL
)
278 Owner
= (PSID
)((ULONG_PTR
)ObjectSd
->Owner
+ (ULONG_PTR
)ObjectSd
);
279 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
281 Control
|= (ObjectSd
->Control
& SE_OWNER_DEFAULTED
);
284 /* Get group and group size */
285 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
287 if (SecurityDescriptor
->Group
!= NULL
)
289 Group
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Group
+ (ULONG_PTR
)SecurityDescriptor
);
290 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
292 Control
|= (SecurityDescriptor
->Control
& SE_GROUP_DEFAULTED
);
296 if (ObjectSd
->Group
!= NULL
)
298 Group
= (PSID
)((ULONG_PTR
)ObjectSd
->Group
+ (ULONG_PTR
)ObjectSd
);
299 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
301 Control
|= (ObjectSd
->Control
& SE_GROUP_DEFAULTED
);
304 /* Get DACL and DACL size */
305 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
307 if ((SecurityDescriptor
->Control
& SE_DACL_PRESENT
) &&
308 (SecurityDescriptor
->Dacl
!= NULL
))
310 Dacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Dacl
+ (ULONG_PTR
)SecurityDescriptor
);
311 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
313 Control
|= (SecurityDescriptor
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
317 if ((ObjectSd
->Control
& SE_DACL_PRESENT
) &&
318 (ObjectSd
->Dacl
!= NULL
))
320 Dacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Dacl
+ (ULONG_PTR
)ObjectSd
);
321 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
323 Control
|= (ObjectSd
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
326 /* Get SACL and SACL size */
327 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
329 if ((SecurityDescriptor
->Control
& SE_SACL_PRESENT
) &&
330 (SecurityDescriptor
->Sacl
!= NULL
))
332 Sacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Sacl
+ (ULONG_PTR
)SecurityDescriptor
);
333 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
335 Control
|= (SecurityDescriptor
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
339 if ((ObjectSd
->Control
& SE_SACL_PRESENT
) &&
340 (ObjectSd
->Sacl
!= NULL
))
342 Sacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Sacl
+ (ULONG_PTR
)ObjectSd
);
343 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
345 Control
|= (ObjectSd
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
348 NewSd
= ExAllocatePool(NonPagedPool
,
349 sizeof(SECURITY_DESCRIPTOR
) + OwnerLength
+ GroupLength
+
350 DaclLength
+ SaclLength
);
353 ObDereferenceObject(Object
);
354 return STATUS_INSUFFICIENT_RESOURCES
;
357 RtlCreateSecurityDescriptor(NewSd
,
358 SECURITY_DESCRIPTOR_REVISION1
);
359 NewSd
->Control
= Control
;
361 Current
= (ULONG_PTR
)NewSd
+ sizeof(SECURITY_DESCRIPTOR
);
363 if (OwnerLength
!= 0)
365 RtlCopyMemory((PVOID
)Current
,
368 NewSd
->Owner
= (PSID
)(Current
- (ULONG_PTR
)NewSd
);
369 Current
+= OwnerLength
;
372 if (GroupLength
!= 0)
374 RtlCopyMemory((PVOID
)Current
,
377 NewSd
->Group
= (PSID
)(Current
- (ULONG_PTR
)NewSd
);
378 Current
+= GroupLength
;
383 RtlCopyMemory((PVOID
)Current
,
386 NewSd
->Dacl
= (PACL
)(Current
- (ULONG_PTR
)NewSd
);
387 Current
+= DaclLength
;
392 RtlCopyMemory((PVOID
)Current
,
395 NewSd
->Sacl
= (PACL
)(Current
- (ULONG_PTR
)NewSd
);
396 Current
+= SaclLength
;
400 Status
= ObpAddSecurityDescriptor(NewSd
,
401 &Header
->SecurityDescriptor
);
402 if (NT_SUCCESS(Status
))
404 /* Remove the old security descriptor */
405 ObpRemoveSecurityDescriptor(ObjectSd
);
409 /* Restore the old security descriptor */
410 Header
->SecurityDescriptor
= ObjectSd
;
416 ObDereferenceObject(Object
);