Fix NtAccessCheck() prototype.
[reactos.git] / reactos / ntoskrnl / se / semgr.c
1 /* $Id: semgr.c,v 1.31 2004/07/12 12:04:17 ekohl Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Security manager
6 * FILE: kernel/se/semgr.c
7 * PROGRAMER: ?
8 * REVISION HISTORY:
9 * 26/07/98: Added stubs for security functions
10 */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <internal/ps.h>
16 #include <internal/se.h>
17
18 #include <internal/debug.h>
19
20 #define TAG_SXPT TAG('S', 'X', 'P', 'T')
21
22
23 /* GLOBALS ******************************************************************/
24
25 PSE_EXPORTS EXPORTED SeExports = NULL;
26
27
28 /* PROTOTYPES ***************************************************************/
29
30 static BOOLEAN SepInitExports(VOID);
31
32 /* FUNCTIONS ****************************************************************/
33
34
35 BOOLEAN INIT_FUNCTION
36 SeInit1(VOID)
37 {
38 SepInitLuid();
39
40 if (!SepInitSecurityIDs())
41 return FALSE;
42
43 if (!SepInitDACLs())
44 return FALSE;
45
46 if (!SepInitSDs())
47 return FALSE;
48
49 SepInitPrivileges();
50
51 if (!SepInitExports())
52 return FALSE;
53
54 return TRUE;
55 }
56
57
58 BOOLEAN INIT_FUNCTION
59 SeInit2(VOID)
60 {
61 SepInitializeTokenImplementation();
62
63 return TRUE;
64 }
65
66
67 BOOLEAN
68 SeInitSRM(VOID)
69 {
70 OBJECT_ATTRIBUTES ObjectAttributes;
71 UNICODE_STRING Name;
72 HANDLE DirectoryHandle;
73 HANDLE EventHandle;
74 NTSTATUS Status;
75
76 /* Create '\Security' directory */
77 RtlInitUnicodeString(&Name,
78 L"\\Security");
79 InitializeObjectAttributes(&ObjectAttributes,
80 &Name,
81 OBJ_PERMANENT,
82 0,
83 NULL);
84 Status = NtCreateDirectoryObject(&DirectoryHandle,
85 DIRECTORY_ALL_ACCESS,
86 &ObjectAttributes);
87 if (!NT_SUCCESS(Status))
88 {
89 DPRINT1("Failed to create 'Security' directory!\n");
90 return FALSE;
91 }
92
93 /* Create 'LSA_AUTHENTICATION_INITALIZED' event */
94 RtlInitUnicodeString(&Name,
95 L"\\LSA_AUTHENTICATION_INITALIZED");
96 InitializeObjectAttributes(&ObjectAttributes,
97 &Name,
98 OBJ_PERMANENT,
99 DirectoryHandle,
100 SePublicDefaultSd);
101 Status = NtCreateEvent(&EventHandle,
102 EVENT_ALL_ACCESS,
103 &ObjectAttributes,
104 FALSE,
105 FALSE);
106 if (!NT_SUCCESS(Status))
107 {
108 DPRINT1("Failed to create 'LSA_AUTHENTICATION_INITALIZED' event!\n");
109 NtClose(DirectoryHandle);
110 return FALSE;
111 }
112
113 NtClose(EventHandle);
114 NtClose(DirectoryHandle);
115
116 /* FIXME: Create SRM port and listener thread */
117
118 return TRUE;
119 }
120
121
122 static BOOLEAN INIT_FUNCTION
123 SepInitExports(VOID)
124 {
125 SeExports = ExAllocatePoolWithTag(NonPagedPool,
126 sizeof(SE_EXPORTS),
127 TAG_SXPT);
128 if (SeExports == NULL)
129 return FALSE;
130
131 SeExports->SeCreateTokenPrivilege = SeCreateTokenPrivilege;
132 SeExports->SeAssignPrimaryTokenPrivilege = SeAssignPrimaryTokenPrivilege;
133 SeExports->SeLockMemoryPrivilege = SeLockMemoryPrivilege;
134 SeExports->SeIncreaseQuotaPrivilege = SeIncreaseQuotaPrivilege;
135 SeExports->SeUnsolicitedInputPrivilege = SeUnsolicitedInputPrivilege;
136 SeExports->SeTcbPrivilege = SeTcbPrivilege;
137 SeExports->SeSecurityPrivilege = SeSecurityPrivilege;
138 SeExports->SeTakeOwnershipPrivilege = SeTakeOwnershipPrivilege;
139 SeExports->SeLoadDriverPrivilege = SeLoadDriverPrivilege;
140 SeExports->SeCreatePagefilePrivilege = SeCreatePagefilePrivilege;
141 SeExports->SeIncreaseBasePriorityPrivilege = SeIncreaseBasePriorityPrivilege;
142 SeExports->SeSystemProfilePrivilege = SeSystemProfilePrivilege;
143 SeExports->SeSystemtimePrivilege = SeSystemtimePrivilege;
144 SeExports->SeProfileSingleProcessPrivilege = SeProfileSingleProcessPrivilege;
145 SeExports->SeCreatePermanentPrivilege = SeCreatePermanentPrivilege;
146 SeExports->SeBackupPrivilege = SeBackupPrivilege;
147 SeExports->SeRestorePrivilege = SeRestorePrivilege;
148 SeExports->SeShutdownPrivilege = SeShutdownPrivilege;
149 SeExports->SeDebugPrivilege = SeDebugPrivilege;
150 SeExports->SeAuditPrivilege = SeAuditPrivilege;
151 SeExports->SeSystemEnvironmentPrivilege = SeSystemEnvironmentPrivilege;
152 SeExports->SeChangeNotifyPrivilege = SeChangeNotifyPrivilege;
153 SeExports->SeRemoteShutdownPrivilege = SeRemoteShutdownPrivilege;
154
155 SeExports->SeNullSid = SeNullSid;
156 SeExports->SeWorldSid = SeWorldSid;
157 SeExports->SeLocalSid = SeLocalSid;
158 SeExports->SeCreatorOwnerSid = SeCreatorOwnerSid;
159 SeExports->SeCreatorGroupSid = SeCreatorGroupSid;
160 SeExports->SeNtAuthoritySid = SeNtAuthoritySid;
161 SeExports->SeDialupSid = SeDialupSid;
162 SeExports->SeNetworkSid = SeNetworkSid;
163 SeExports->SeBatchSid = SeBatchSid;
164 SeExports->SeInteractiveSid = SeInteractiveSid;
165 SeExports->SeLocalSystemSid = SeLocalSystemSid;
166 SeExports->SeAliasAdminsSid = SeAliasAdminsSid;
167 SeExports->SeAliasUsersSid = SeAliasUsersSid;
168 SeExports->SeAliasGuestsSid = SeAliasGuestsSid;
169 SeExports->SeAliasPowerUsersSid = SeAliasPowerUsersSid;
170 SeExports->SeAliasAccountOpsSid = SeAliasAccountOpsSid;
171 SeExports->SeAliasSystemOpsSid = SeAliasSystemOpsSid;
172 SeExports->SeAliasPrintOpsSid = SeAliasPrintOpsSid;
173 SeExports->SeAliasBackupOpsSid = SeAliasBackupOpsSid;
174
175 return TRUE;
176 }
177
178
179 VOID SepReferenceLogonSession(PLUID AuthenticationId)
180 {
181 UNIMPLEMENTED;
182 }
183
184 VOID SepDeReferenceLogonSession(PLUID AuthenticationId)
185 {
186 UNIMPLEMENTED;
187 }
188
189
190
191 /*
192 * @unimplemented
193 */
194 NTSTATUS STDCALL
195 NtAllocateUuids(PULARGE_INTEGER Time,
196 PULONG Range,
197 PULONG Sequence)
198 {
199 UNIMPLEMENTED;
200 return(STATUS_NOT_IMPLEMENTED);
201 }
202
203
204 NTSTATUS STDCALL
205 NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
206 IN HANDLE ClientToken,
207 IN ACCESS_MASK DesiredAccess,
208 IN PGENERIC_MAPPING GenericMapping,
209 OUT PPRIVILEGE_SET PrivilegeSet,
210 OUT PULONG ReturnLength,
211 OUT PACCESS_MASK GrantedAccess,
212 OUT PNTSTATUS AccessStatus)
213 {
214 UNIMPLEMENTED;
215 return(STATUS_NOT_IMPLEMENTED);
216 }
217
218
219 /*
220 * @implemented
221 */
222 VOID STDCALL
223 SeCaptureSubjectContext(OUT PSECURITY_SUBJECT_CONTEXT SubjectContext)
224 {
225 PEPROCESS Process;
226 BOOLEAN CopyOnOpen;
227 BOOLEAN EffectiveOnly;
228
229 Process = PsGetCurrentThread ()->ThreadsProcess;
230
231 SubjectContext->ProcessAuditId = Process;
232 SubjectContext->ClientToken =
233 PsReferenceImpersonationToken (PsGetCurrentThread(),
234 &CopyOnOpen,
235 &EffectiveOnly,
236 &SubjectContext->ImpersonationLevel);
237 SubjectContext->PrimaryToken = PsReferencePrimaryToken (Process);
238 }
239
240
241 /*
242 * @unimplemented
243 */
244 VOID STDCALL
245 SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
246 {
247 UNIMPLEMENTED;
248 }
249
250
251 /*
252 * @implemented
253 */
254 VOID STDCALL
255 SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
256 {
257 ObDereferenceObject (SubjectContext->PrimaryToken);
258 if (SubjectContext->ClientToken != NULL)
259 {
260 ObDereferenceObject (SubjectContext->ClientToken);
261 }
262 }
263
264
265 /*
266 * @unimplemented
267 */
268 VOID STDCALL
269 SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
270 {
271 UNIMPLEMENTED;
272 }
273
274
275 /*
276 * @implemented
277 */
278 NTSTATUS STDCALL
279 SeDeassignSecurity(PSECURITY_DESCRIPTOR* SecurityDescriptor)
280 {
281 if ((*SecurityDescriptor) != NULL)
282 {
283 ExFreePool(*SecurityDescriptor);
284 (*SecurityDescriptor) = NULL;
285 }
286 return(STATUS_SUCCESS);
287 }
288
289
290 #if 0
291 VOID SepGetDefaultsSubjectContext(PSECURITY_SUBJECT_CONTEXT SubjectContext,
292 PSID* Owner,
293 PSID* PrimaryGroup,
294 PSID* ProcessOwner,
295 PSID* ProcessPrimaryGroup,
296 PACL* DefaultDacl)
297 {
298 PACCESS_TOKEN Token;
299
300 if (SubjectContext->ClientToken != NULL)
301 {
302 Token = SubjectContext->ClientToken;
303 }
304 else
305 {
306 Token = SubjectContext->PrimaryToken;
307 }
308 *Owner = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid;
309 *PrimaryGroup = Token->PrimaryGroup;
310 *DefaultDacl = Token->DefaultDacl;
311 *ProcessOwner = SubjectContext->PrimaryToken->
312 UserAndGroups[Token->DefaultOwnerIndex].Sid;
313 *ProcessPrimaryGroup = SubjectContext->PrimaryToken->PrimaryGroup;
314 }
315
316 NTSTATUS SepInheritAcl(PACL Acl,
317 BOOLEAN IsDirectoryObject,
318 PSID Owner,
319 PSID PrimaryGroup,
320 PACL DefaultAcl,
321 PSID ProcessOwner,
322 PSID ProcessGroup,
323 PGENERIC_MAPPING GenericMapping)
324 {
325 if (Acl == NULL)
326 {
327 return(STATUS_UNSUCCESSFUL);
328 }
329 if (Acl->AclRevision != 2 &&
330 Acl->AclRevision != 3 )
331 {
332 return(STATUS_UNSUCCESSFUL);
333 }
334
335 }
336 #endif
337
338 /*
339 * @unimplemented
340 */
341 NTSTATUS STDCALL
342 SeAssignSecurity(PSECURITY_DESCRIPTOR ParentDescriptor,
343 PSECURITY_DESCRIPTOR ExplicitDescriptor,
344 PSECURITY_DESCRIPTOR* NewDescriptor,
345 BOOLEAN IsDirectoryObject,
346 PSECURITY_SUBJECT_CONTEXT SubjectContext,
347 PGENERIC_MAPPING GenericMapping,
348 POOL_TYPE PoolType)
349 {
350 #if 0
351 PSECURITY_DESCRIPTOR Descriptor;
352 PSID Owner;
353 PSID PrimaryGroup;
354 PACL DefaultDacl;
355 PSID ProcessOwner;
356 PSID ProcessPrimaryGroup;
357 PACL Sacl;
358
359 if (ExplicitDescriptor == NULL)
360 {
361 RtlCreateSecurityDescriptor(&Descriptor, 1);
362 }
363 else
364 {
365 Descriptor = ExplicitDescriptor;
366 }
367 SeLockSubjectContext(SubjectContext);
368 SepGetDefaultsSubjectContext(SubjectContext,
369 &Owner,
370 &PrimaryGroup,
371 &DefaultDacl,
372 &ProcessOwner,
373 &ProcessPrimaryGroup);
374 if (Descriptor->Control & SE_SACL_PRESENT ||
375 Descriptor->Control & SE_SACL_DEFAULTED)
376 {
377 if (ParentDescriptor == NULL)
378 {
379 }
380 if (Descriptor->Control & SE_SACL_PRESENT ||
381 Descriptor->Sacl == NULL ||)
382 {
383 Sacl = NULL;
384 }
385 else
386 {
387 Sacl = Descriptor->Sacl;
388 if (Descriptor->Control & SE_SELF_RELATIVE)
389 {
390 Sacl = (PACL)(((PVOID)Sacl) + (PVOID)Descriptor);
391 }
392 }
393 SepInheritAcl(Sacl,
394 IsDirectoryObject,
395 Owner,
396 PrimaryGroup,
397 DefaultDacl,
398 ProcessOwner,
399 GenericMapping);
400 }
401 #else
402 UNIMPLEMENTED;
403 return(STATUS_NOT_IMPLEMENTED);
404 #endif
405 }
406
407 BOOLEAN SepSidInToken(PACCESS_TOKEN Token,
408 PSID Sid)
409 {
410 ULONG i;
411
412 if (Token->UserAndGroupCount == 0)
413 {
414 return(FALSE);
415 }
416
417 for (i=0; i<Token->UserAndGroupCount; i++)
418 {
419 if (RtlEqualSid(Sid, Token->UserAndGroups[i].Sid))
420 {
421 if (i == 0 ||
422 (!(Token->UserAndGroups[i].Attributes & SE_GROUP_ENABLED)))
423 {
424 return(TRUE);
425 }
426 return(FALSE);
427 }
428 }
429 return(FALSE);
430 }
431
432
433 /*
434 * @implemented
435 */
436 BOOLEAN STDCALL
437 SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
438 IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
439 IN BOOLEAN SubjectContextLocked,
440 IN ACCESS_MASK DesiredAccess,
441 IN ACCESS_MASK PreviouslyGrantedAccess,
442 OUT PPRIVILEGE_SET* Privileges,
443 IN PGENERIC_MAPPING GenericMapping,
444 IN KPROCESSOR_MODE AccessMode,
445 OUT PACCESS_MODE GrantedAccess,
446 OUT PNTSTATUS AccessStatus)
447 /*
448 * FUNCTION: Determines whether the requested access rights can be granted
449 * to an object protected by a security descriptor and an object owner
450 * ARGUMENTS:
451 * SecurityDescriptor = Security descriptor protecting the object
452 * SubjectSecurityContext = Subject's captured security context
453 * SubjectContextLocked = Indicates the user's subject context is locked
454 * DesiredAccess = Access rights the caller is trying to acquire
455 * PreviouslyGrantedAccess = Specified the access rights already granted
456 * Privileges = ?
457 * GenericMapping = Generic mapping associated with the object
458 * AccessMode = Access mode used for the check
459 * GrantedAccess (OUT) = On return specifies the access granted
460 * AccessStatus (OUT) = Status indicating why access was denied
461 * RETURNS: If access was granted, returns TRUE
462 */
463 {
464 ULONG i;
465 PACL Dacl;
466 BOOLEAN Present;
467 BOOLEAN Defaulted;
468 NTSTATUS Status;
469 PACE CurrentAce;
470 PSID Sid;
471 ACCESS_MASK CurrentAccess;
472
473 CurrentAccess = PreviouslyGrantedAccess;
474
475 /*
476 * Ignore the SACL for now
477 */
478
479 /*
480 * Check the DACL
481 */
482 Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
483 &Present,
484 &Dacl,
485 &Defaulted);
486 if (!NT_SUCCESS(Status))
487 {
488 return(Status);
489 }
490
491 CurrentAce = (PACE)(Dacl + 1);
492 for (i = 0; i < Dacl->AceCount; i++)
493 {
494 Sid = (PSID)(CurrentAce + 1);
495 if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
496 {
497 if (SepSidInToken(SubjectSecurityContext->ClientToken, Sid))
498 {
499 *AccessStatus = STATUS_ACCESS_DENIED;
500 *GrantedAccess = 0;
501 return(STATUS_SUCCESS);
502 }
503 }
504 if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
505 {
506 if (SepSidInToken(SubjectSecurityContext->ClientToken, Sid))
507 {
508 CurrentAccess = CurrentAccess |
509 CurrentAce->AccessMask;
510 }
511 }
512 }
513 if (!(CurrentAccess & DesiredAccess) &&
514 !((~CurrentAccess) & DesiredAccess))
515 {
516 *AccessStatus = STATUS_ACCESS_DENIED;
517 }
518 else
519 {
520 *AccessStatus = STATUS_SUCCESS;
521 }
522 *GrantedAccess = CurrentAccess;
523
524 return(STATUS_SUCCESS);
525 }
526
527 /* EOF */