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
;
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 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
270 Owner
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Owner
+
271 (ULONG_PTR
)SecurityDescriptor
);
273 Owner
= (PSID
)SecurityDescriptor
->Owner
;
274 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
276 Control
|= (SecurityDescriptor
->Control
& SE_OWNER_DEFAULTED
);
280 if (ObjectSd
->Owner
!= NULL
)
282 Owner
= (PSID
)((ULONG_PTR
)ObjectSd
->Owner
+ (ULONG_PTR
)ObjectSd
);
283 OwnerLength
= ROUND_UP(RtlLengthSid(Owner
), 4);
285 Control
|= (ObjectSd
->Control
& SE_OWNER_DEFAULTED
);
288 /* Get group and group size */
289 if (SecurityInformation
& GROUP_SECURITY_INFORMATION
)
291 if (SecurityDescriptor
->Group
!= NULL
)
293 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
294 Group
= (PSID
)((ULONG_PTR
)SecurityDescriptor
->Group
+
295 (ULONG_PTR
)SecurityDescriptor
);
297 Group
= (PSID
)SecurityDescriptor
->Group
;
298 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
300 Control
|= (SecurityDescriptor
->Control
& SE_GROUP_DEFAULTED
);
304 if (ObjectSd
->Group
!= NULL
)
306 Group
= (PSID
)((ULONG_PTR
)ObjectSd
->Group
+ (ULONG_PTR
)ObjectSd
);
307 GroupLength
= ROUND_UP(RtlLengthSid(Group
), 4);
309 Control
|= (ObjectSd
->Control
& SE_GROUP_DEFAULTED
);
312 /* Get DACL and DACL size */
313 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
315 if ((SecurityDescriptor
->Control
& SE_DACL_PRESENT
) &&
316 (SecurityDescriptor
->Dacl
!= NULL
))
318 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
319 Dacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Dacl
+
320 (ULONG_PTR
)SecurityDescriptor
);
322 Dacl
= (PACL
)SecurityDescriptor
->Dacl
;
324 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
326 Control
|= (SecurityDescriptor
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
330 if ((ObjectSd
->Control
& SE_DACL_PRESENT
) &&
331 (ObjectSd
->Dacl
!= NULL
))
333 Dacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Dacl
+ (ULONG_PTR
)ObjectSd
);
334 DaclLength
= ROUND_UP((ULONG
)Dacl
->AclSize
, 4);
336 Control
|= (ObjectSd
->Control
& (SE_DACL_DEFAULTED
| SE_DACL_PRESENT
));
339 /* Get SACL and SACL size */
340 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
342 if ((SecurityDescriptor
->Control
& SE_SACL_PRESENT
) &&
343 (SecurityDescriptor
->Sacl
!= NULL
))
345 if( SecurityDescriptor
->Control
& SE_SELF_RELATIVE
)
346 Sacl
= (PACL
)((ULONG_PTR
)SecurityDescriptor
->Sacl
+
347 (ULONG_PTR
)SecurityDescriptor
);
349 Sacl
= (PACL
)SecurityDescriptor
->Sacl
;
350 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
352 Control
|= (SecurityDescriptor
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
356 if ((ObjectSd
->Control
& SE_SACL_PRESENT
) &&
357 (ObjectSd
->Sacl
!= NULL
))
359 Sacl
= (PACL
)((ULONG_PTR
)ObjectSd
->Sacl
+ (ULONG_PTR
)ObjectSd
);
360 SaclLength
= ROUND_UP((ULONG
)Sacl
->AclSize
, 4);
362 Control
|= (ObjectSd
->Control
& (SE_SACL_DEFAULTED
| SE_SACL_PRESENT
));
365 NewSd
= ExAllocatePool(NonPagedPool
,
366 sizeof(SECURITY_DESCRIPTOR
) + OwnerLength
+ GroupLength
+
367 DaclLength
+ SaclLength
);
370 ObDereferenceObject(Object
);
371 return STATUS_INSUFFICIENT_RESOURCES
;
374 RtlCreateSecurityDescriptor(NewSd
,
375 SECURITY_DESCRIPTOR_REVISION1
);
376 /* We always build a self-relative descriptor */
377 NewSd
->Control
= Control
| SE_SELF_RELATIVE
;
379 Current
= (ULONG_PTR
)NewSd
+ sizeof(SECURITY_DESCRIPTOR
);
381 if (OwnerLength
!= 0)
383 RtlCopyMemory((PVOID
)Current
,
386 NewSd
->Owner
= (PSID
)(Current
- (ULONG_PTR
)NewSd
);
387 Current
+= OwnerLength
;
390 if (GroupLength
!= 0)
392 RtlCopyMemory((PVOID
)Current
,
395 NewSd
->Group
= (PSID
)(Current
- (ULONG_PTR
)NewSd
);
396 Current
+= GroupLength
;
401 RtlCopyMemory((PVOID
)Current
,
404 NewSd
->Dacl
= (PACL
)(Current
- (ULONG_PTR
)NewSd
);
405 Current
+= DaclLength
;
410 RtlCopyMemory((PVOID
)Current
,
413 NewSd
->Sacl
= (PACL
)(Current
- (ULONG_PTR
)NewSd
);
414 Current
+= SaclLength
;
418 Status
= ObpAddSecurityDescriptor(NewSd
,
419 &Header
->SecurityDescriptor
);
420 if (NT_SUCCESS(Status
))
422 /* Remove the old security descriptor */
423 ObpRemoveSecurityDescriptor(ObjectSd
);
427 /* Restore the old security descriptor */
428 Header
->SecurityDescriptor
= ObjectSd
;
434 ObDereferenceObject(Object
);