Abandoning silverblade-audio branch.
[reactos.git] / reactos / lib / rtl / security.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/rtl/security.c
5 * PURPOSE: Security related functions and Security Objects
6 * PROGRAMMER: Eric Kohl
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #include <rtl.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16 /* FUNCTIONS ***************************************************************/
17
18 /*
19 * @implemented
20 */
21 NTSTATUS NTAPI
22 RtlImpersonateSelf(IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
23 {
24 HANDLE ProcessToken;
25 HANDLE ImpersonationToken;
26 NTSTATUS Status;
27 OBJECT_ATTRIBUTES ObjAttr;
28 SECURITY_QUALITY_OF_SERVICE Sqos;
29
30 PAGED_CODE_RTL();
31
32 Status = ZwOpenProcessToken(NtCurrentProcess(),
33 TOKEN_DUPLICATE,
34 &ProcessToken);
35 if (!NT_SUCCESS(Status))
36 {
37 DPRINT1("NtOpenProcessToken() failed (Status %lx)\n", Status);
38 return(Status);
39 }
40
41 Sqos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
42 Sqos.ImpersonationLevel = ImpersonationLevel;
43 Sqos.ContextTrackingMode = 0;
44 Sqos.EffectiveOnly = FALSE;
45
46 InitializeObjectAttributes(
47 &ObjAttr,
48 NULL,
49 0,
50 NULL,
51 NULL
52 );
53
54 ObjAttr.SecurityQualityOfService = &Sqos;
55
56 Status = ZwDuplicateToken(ProcessToken,
57 TOKEN_IMPERSONATE,
58 &ObjAttr,
59 Sqos.EffectiveOnly, /* why both here _and_ in Sqos? */
60 TokenImpersonation,
61 &ImpersonationToken);
62 if (!NT_SUCCESS(Status))
63 {
64 DPRINT1("NtDuplicateToken() failed (Status %lx)\n", Status);
65 NtClose(ProcessToken);
66 return(Status);
67 }
68
69 Status = ZwSetInformationThread(NtCurrentThread(),
70 ThreadImpersonationToken,
71 &ImpersonationToken,
72 sizeof(HANDLE));
73 if (!NT_SUCCESS(Status))
74 {
75 DPRINT1("NtSetInformationThread() failed (Status %lx)\n", Status);
76 }
77
78 ZwClose(ImpersonationToken);
79 ZwClose(ProcessToken);
80
81 return(Status);
82 }
83
84 /*
85 * @unimplemented
86 */
87 NTSTATUS
88 NTAPI
89 RtlAcquirePrivilege(IN PULONG Privilege,
90 IN ULONG NumPriv,
91 IN ULONG Flags,
92 OUT PVOID *ReturnedState)
93 {
94 UNIMPLEMENTED;
95 return STATUS_NOT_IMPLEMENTED;
96 }
97
98 /*
99 * @unimplemented
100 */
101 VOID
102 NTAPI
103 RtlReleasePrivilege(IN PVOID ReturnedState)
104 {
105 UNIMPLEMENTED;
106 }
107
108 /*
109 * @implemented
110 */
111 NTSTATUS NTAPI
112 RtlAdjustPrivilege(IN ULONG Privilege,
113 IN BOOLEAN Enable,
114 IN BOOLEAN CurrentThread,
115 OUT PBOOLEAN Enabled)
116 {
117 TOKEN_PRIVILEGES NewState;
118 TOKEN_PRIVILEGES OldState;
119 ULONG ReturnLength;
120 HANDLE TokenHandle;
121 NTSTATUS Status;
122
123 PAGED_CODE_RTL();
124
125 DPRINT ("RtlAdjustPrivilege() called\n");
126
127 if (CurrentThread)
128 {
129 Status = ZwOpenThreadToken (NtCurrentThread (),
130 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
131 FALSE,
132 &TokenHandle);
133 }
134 else
135 {
136 Status = ZwOpenProcessToken (NtCurrentProcess (),
137 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
138 &TokenHandle);
139 }
140
141 if (!NT_SUCCESS (Status))
142 {
143 DPRINT1 ("Retrieving token handle failed (Status %lx)\n", Status);
144 return Status;
145 }
146
147 OldState.PrivilegeCount = 1;
148
149 NewState.PrivilegeCount = 1;
150 NewState.Privileges[0].Luid.LowPart = Privilege;
151 NewState.Privileges[0].Luid.HighPart = 0;
152 NewState.Privileges[0].Attributes = (Enable) ? SE_PRIVILEGE_ENABLED : 0;
153
154 Status = ZwAdjustPrivilegesToken (TokenHandle,
155 FALSE,
156 &NewState,
157 sizeof(TOKEN_PRIVILEGES),
158 &OldState,
159 &ReturnLength);
160 ZwClose (TokenHandle);
161 if (Status == STATUS_NOT_ALL_ASSIGNED)
162 {
163 DPRINT1 ("Failed to assign all privileges\n");
164 return STATUS_PRIVILEGE_NOT_HELD;
165 }
166 if (!NT_SUCCESS(Status))
167 {
168 DPRINT1 ("NtAdjustPrivilegesToken() failed (Status %lx)\n", Status);
169 return Status;
170 }
171
172 if (OldState.PrivilegeCount == 0)
173 {
174 *Enabled = Enable;
175 }
176 else
177 {
178 *Enabled = (OldState.Privileges[0].Attributes & SE_PRIVILEGE_ENABLED);
179 }
180
181 DPRINT ("RtlAdjustPrivilege() done\n");
182
183 return STATUS_SUCCESS;
184 }
185
186 /*
187 * @implemented
188 */
189 NTSTATUS
190 NTAPI
191 RtlDeleteSecurityObject(IN PSECURITY_DESCRIPTOR *ObjectDescriptor)
192 {
193 DPRINT("RtlDeleteSecurityObject(%p)\n", ObjectDescriptor);
194
195 RtlFreeHeap(RtlGetProcessHeap(),
196 0,
197 *ObjectDescriptor);
198
199 return STATUS_SUCCESS;
200 }
201
202
203 /*
204 * @unimplemented
205 */
206 NTSTATUS
207 NTAPI
208 RtlNewSecurityObject(IN PSECURITY_DESCRIPTOR ParentDescriptor,
209 IN PSECURITY_DESCRIPTOR CreatorDescriptor,
210 OUT PSECURITY_DESCRIPTOR *NewDescriptor,
211 IN BOOLEAN IsDirectoryObject,
212 IN HANDLE Token,
213 IN PGENERIC_MAPPING GenericMapping)
214 {
215 UNIMPLEMENTED;
216 return STATUS_NOT_IMPLEMENTED;
217 }
218
219
220 /*
221 * @unimplemented
222 */
223 NTSTATUS
224 NTAPI
225 RtlQuerySecurityObject(IN PSECURITY_DESCRIPTOR ObjectDescriptor,
226 IN SECURITY_INFORMATION SecurityInformation,
227 OUT PSECURITY_DESCRIPTOR ResultantDescriptor,
228 IN ULONG DescriptorLength,
229 OUT PULONG ReturnLength)
230 {
231 NTSTATUS Status;
232 SECURITY_DESCRIPTOR desc;
233 BOOLEAN defaulted, present;
234 PACL pacl;
235 PSID psid;
236
237 Status = RtlCreateSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION);
238 if (!NT_SUCCESS(Status)) return Status;
239
240 if (SecurityInformation & OWNER_SECURITY_INFORMATION)
241 {
242 Status = RtlGetOwnerSecurityDescriptor(ObjectDescriptor, &psid, &defaulted);
243 if (!NT_SUCCESS(Status)) return Status;
244 Status = RtlSetOwnerSecurityDescriptor(&desc, psid, defaulted);
245 if (!NT_SUCCESS(Status)) return Status;
246 }
247
248 if (SecurityInformation & GROUP_SECURITY_INFORMATION)
249 {
250 Status = RtlGetGroupSecurityDescriptor(ObjectDescriptor, &psid, &defaulted);
251 if (!NT_SUCCESS(Status)) return Status;
252 Status = RtlSetGroupSecurityDescriptor(&desc, psid, defaulted);
253 if (!NT_SUCCESS(Status)) return Status;
254 }
255
256 if (SecurityInformation & DACL_SECURITY_INFORMATION)
257 {
258 Status = RtlGetDaclSecurityDescriptor(ObjectDescriptor, &present, &pacl, &defaulted);
259 if (!NT_SUCCESS(Status)) return Status;
260 Status = RtlSetDaclSecurityDescriptor(&desc, present, pacl, defaulted);
261 if (!NT_SUCCESS(Status)) return Status;
262 }
263
264 if (SecurityInformation & SACL_SECURITY_INFORMATION)
265 {
266 Status = RtlGetSaclSecurityDescriptor(ObjectDescriptor, &present, &pacl, &defaulted);
267 if (!NT_SUCCESS(Status)) return Status;
268 Status = RtlSetSaclSecurityDescriptor(&desc, present, pacl, defaulted);
269 if (!NT_SUCCESS(Status)) return Status;
270 }
271
272 *ReturnLength = DescriptorLength;
273 return RtlAbsoluteToSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
274 }
275
276
277 /*
278 * @unimplemented
279 */
280 NTSTATUS
281 NTAPI
282 RtlSetSecurityObject(IN SECURITY_INFORMATION SecurityInformation,
283 IN PSECURITY_DESCRIPTOR ModificationDescriptor,
284 OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
285 IN PGENERIC_MAPPING GenericMapping,
286 IN HANDLE Token)
287 {
288 UNIMPLEMENTED;
289 return STATUS_NOT_IMPLEMENTED;
290 }
291
292 /*
293 * @unimplemented
294 */
295 NTSTATUS
296 NTAPI
297 RtlRegisterSecureMemoryCacheCallback(IN PRTL_SECURE_MEMORY_CACHE_CALLBACK Callback)
298 {
299 UNIMPLEMENTED;
300 return STATUS_NOT_IMPLEMENTED;
301 }
302
303 /*
304 * @unimplemented
305 */
306 BOOLEAN
307 NTAPI
308 RtlFlushSecureMemoryCache(IN PVOID MemoryCache,
309 IN OPTIONAL SIZE_T MemoryLength)
310 {
311 UNIMPLEMENTED;
312 return FALSE;
313 }