Implement ObGetObjectSecurity() and ObReleaseObjectSecurity().
[reactos.git] / reactos / ntoskrnl / ob / security.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: Security manager
5 * FILE: ntoskrnl/ob/security.c
6 * PROGRAMER: ?
7 * REVISION HISTORY:
8 * 26/07/98: Added stubs for security functions
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ddk/ntddk.h>
14 #include <internal/ob.h>
15
16 #include <internal/debug.h>
17
18 /* FUNCTIONS ***************************************************************/
19
20 /*
21 * @implemented
22 */
23 NTSTATUS STDCALL
24 ObAssignSecurity(IN PACCESS_STATE AccessState,
25 IN PSECURITY_DESCRIPTOR SecurityDescriptor,
26 IN PVOID Object,
27 IN POBJECT_TYPE Type)
28 {
29 PSECURITY_DESCRIPTOR NewDescriptor;
30 NTSTATUS Status;
31
32 /* Build the new security descriptor */
33 Status = SeAssignSecurity(SecurityDescriptor,
34 AccessState->SecurityDescriptor,
35 &NewDescriptor,
36 (Type == ObDirectoryType),
37 &AccessState->SubjectSecurityContext,
38 Type->Mapping,
39 PagedPool);
40 if (!NT_SUCCESS(Status))
41 return Status;
42
43 if (Type->Security != NULL)
44 {
45 /* Call the security method */
46 Status = Type->Security(Object,
47 AssignSecurityDescriptor,
48 0,
49 NewDescriptor,
50 NULL);
51 }
52 else
53 {
54 /* Assign the security descriptor to the object header */
55 Status = ObpAddSecurityDescriptor(NewDescriptor,
56 &(BODY_TO_HEADER(Object)->SecurityDescriptor));
57 }
58
59 /* Release the new security descriptor */
60 SeDeassignSecurity(&NewDescriptor);
61
62 return Status;
63 }
64
65
66 /*
67 * @implemented
68 */
69 NTSTATUS STDCALL
70 ObGetObjectSecurity(IN PVOID Object,
71 OUT PSECURITY_DESCRIPTOR *SecurityDescriptor,
72 OUT PBOOLEAN MemoryAllocated)
73 {
74 POBJECT_HEADER Header;
75 ULONG Length;
76 NTSTATUS Status;
77
78 Header = BODY_TO_HEADER(Object);
79 if (Header->ObjectType == NULL)
80 return STATUS_UNSUCCESSFUL;
81
82 if (Header->ObjectType->Security == NULL)
83 {
84 ObpReferenceCachedSecurityDescriptor(Header->SecurityDescriptor);
85 *SecurityDescriptor = Header->SecurityDescriptor;
86 *MemoryAllocated = FALSE;
87 return STATUS_SUCCESS;
88 }
89
90 /* Get the security descriptor size */
91 Length = 0;
92 Status = Header->ObjectType->Security(Object,
93 QuerySecurityDescriptor,
94 OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
95 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
96 NULL,
97 &Length);
98 if (Status != STATUS_BUFFER_TOO_SMALL)
99 return Status;
100
101 /* Allocate security descriptor */
102 *SecurityDescriptor = ExAllocatePool(NonPagedPool,
103 Length);
104 if (*SecurityDescriptor == NULL)
105 return STATUS_INSUFFICIENT_RESOURCES;
106
107 /* Query security descriptor */
108 Status = Header->ObjectType->Security(Object,
109 QuerySecurityDescriptor,
110 OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
111 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
112 *SecurityDescriptor,
113 &Length);
114 if (!NT_SUCCESS(Status))
115 {
116 ExFreePool(*SecurityDescriptor);
117 return Status;
118 }
119
120 *MemoryAllocated = TRUE;
121
122 return STATUS_SUCCESS;
123 }
124
125
126 /*
127 * @implemented
128 */
129 VOID STDCALL
130 ObReleaseObjectSecurity(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
131 IN BOOLEAN MemoryAllocated)
132 {
133 if (SecurityDescriptor == NULL)
134 return;
135
136 if (MemoryAllocated)
137 {
138 ExFreePool(SecurityDescriptor);
139 }
140 else
141 {
142 ObpDereferenceCachedSecurityDescriptor(SecurityDescriptor);
143 }
144 }
145
146
147 /*
148 * @implemented
149 */
150 NTSTATUS STDCALL
151 NtQuerySecurityObject(IN HANDLE Handle,
152 IN SECURITY_INFORMATION SecurityInformation,
153 OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
154 IN ULONG Length,
155 OUT PULONG ResultLength)
156 {
157 POBJECT_HEADER Header;
158 PVOID Object;
159 NTSTATUS Status;
160
161 Status = ObReferenceObjectByHandle(Handle,
162 0,
163 NULL,
164 KeGetPreviousMode(),
165 &Object,
166 NULL);
167 if (!NT_SUCCESS(Status))
168 {
169 return Status;
170 }
171
172 Header = BODY_TO_HEADER(Object);
173 if (Header->ObjectType == NULL)
174 return STATUS_UNSUCCESSFUL;
175
176 if (Header->ObjectType->Security != NULL)
177 {
178 Status = Header->ObjectType->Security(Object,
179 QuerySecurityDescriptor,
180 SecurityInformation,
181 SecurityDescriptor,
182 &Length);
183 *ResultLength = Length;
184 }
185 else
186 {
187 if (Header->SecurityDescriptor != NULL)
188 {
189 /* FIXME: Use SecurityInformation */
190 *ResultLength = RtlLengthSecurityDescriptor(Header->SecurityDescriptor);
191 if (Length >= *ResultLength)
192 {
193 RtlCopyMemory(SecurityDescriptor,
194 Header->SecurityDescriptor,
195 *ResultLength);
196
197 Status = STATUS_SUCCESS;
198 }
199 else
200 {
201 Status = STATUS_BUFFER_TOO_SMALL;
202 }
203 }
204 else
205 {
206 *ResultLength = 0;
207 Status = STATUS_UNSUCCESSFUL;
208 }
209 }
210
211 ObDereferenceObject(Object);
212
213 return Status;
214 }
215
216
217 /*
218 * @unimplemented
219 */
220 NTSTATUS STDCALL
221 NtSetSecurityObject(IN HANDLE Handle,
222 IN SECURITY_INFORMATION SecurityInformation,
223 IN PSECURITY_DESCRIPTOR SecurityDescriptor)
224 {
225 POBJECT_HEADER Header;
226 PVOID Object;
227 NTSTATUS Status;
228
229 Status = ObReferenceObjectByHandle(Handle,
230 0,
231 NULL,
232 KeGetPreviousMode(),
233 &Object,
234 NULL);
235 if (!NT_SUCCESS(Status))
236 {
237 return(Status);
238 }
239
240 Header = BODY_TO_HEADER(Object);
241 if (Header->ObjectType != NULL &&
242 Header->ObjectType->Security != NULL)
243 {
244 Status = Header->ObjectType->Security(Object,
245 SetSecurityDescriptor,
246 SecurityInformation,
247 SecurityDescriptor,
248 NULL);
249 }
250 else
251 {
252 Status = STATUS_NOT_IMPLEMENTED;
253 }
254
255 ObDereferenceObject(Object);
256
257 return(Status);
258 }
259
260 /* EOF */