finished applying @implemented and @unimplemented comments and remove the comments...
[reactos.git] / reactos / ntoskrnl / se / semgr.c
1 /* $Id: semgr.c,v 1.25 2003/07/11 01:23:16 royce 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
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
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 'Security' directory!\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
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 NTSTATUS STDCALL
190 NtPrivilegedServiceAuditAlarm(IN PUNICODE_STRING SubsystemName,
191 IN PUNICODE_STRING ServiceName,
192 IN HANDLE ClientToken,
193 IN PPRIVILEGE_SET Privileges,
194 IN BOOLEAN AccessGranted)
195 {
196 UNIMPLEMENTED;
197 }
198
199
200 NTSTATUS STDCALL
201 NtPrivilegeObjectAuditAlarm(IN PUNICODE_STRING SubsystemName,
202 IN PVOID HandleId,
203 IN HANDLE ClientToken,
204 IN ULONG DesiredAccess,
205 IN PPRIVILEGE_SET Privileges,
206 IN BOOLEAN AccessGranted)
207 {
208 UNIMPLEMENTED;
209 }
210
211
212 NTSTATUS STDCALL
213 NtOpenObjectAuditAlarm(IN PUNICODE_STRING SubsystemName,
214 IN PVOID HandleId,
215 IN POBJECT_ATTRIBUTES ObjectAttributes,
216 IN HANDLE ClientToken,
217 IN ULONG DesiredAccess,
218 IN ULONG GrantedAccess,
219 IN PPRIVILEGE_SET Privileges,
220 IN BOOLEAN ObjectCreation,
221 IN BOOLEAN AccessGranted,
222 OUT PBOOLEAN GenerateOnClose)
223 {
224 UNIMPLEMENTED;
225 }
226
227
228 NTSTATUS STDCALL
229 NtAccessCheckAndAuditAlarm(IN PUNICODE_STRING SubsystemName,
230 IN PHANDLE ObjectHandle,
231 IN POBJECT_ATTRIBUTES ObjectAttributes,
232 IN ACCESS_MASK DesiredAccess,
233 IN PGENERIC_MAPPING GenericMapping,
234 IN BOOLEAN ObjectCreation,
235 OUT PULONG GrantedAccess,
236 OUT PBOOLEAN AccessStatus,
237 OUT PBOOLEAN GenerateOnClose
238 )
239 {
240 UNIMPLEMENTED;
241 }
242
243
244 /*
245 * @unimplemented
246 */
247 NTSTATUS STDCALL
248 NtAllocateUuids(PULARGE_INTEGER Time,
249 PULONG Range,
250 PULONG Sequence)
251 {
252 UNIMPLEMENTED;
253 }
254
255
256 NTSTATUS STDCALL
257 NtCloseObjectAuditAlarm(IN PUNICODE_STRING SubsystemName,
258 IN PVOID HandleId,
259 IN BOOLEAN GenerateOnClose)
260 {
261 UNIMPLEMENTED;
262 }
263
264
265 NTSTATUS STDCALL
266 NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
267 IN HANDLE ClientToken,
268 IN ACCESS_MASK DesiredAccess,
269 IN PGENERIC_MAPPING GenericMapping,
270 OUT PPRIVILEGE_SET PrivilegeSet,
271 OUT PULONG ReturnLength,
272 OUT PULONG GrantedAccess,
273 OUT PBOOLEAN AccessStatus)
274 {
275 UNIMPLEMENTED;
276 }
277
278
279 NTSTATUS STDCALL
280 NtDeleteObjectAuditAlarm(IN PUNICODE_STRING SubsystemName,
281 IN PVOID HandleId,
282 IN BOOLEAN GenerateOnClose)
283 {
284 UNIMPLEMENTED;
285 }
286
287
288
289 /*
290 * @implemented
291 */
292 VOID STDCALL SeReleaseSubjectContext (PSECURITY_SUBJECT_CONTEXT SubjectContext)
293 {
294 ObDereferenceObject(SubjectContext->PrimaryToken);
295 if (SubjectContext->ClientToken != NULL)
296 {
297 ObDereferenceObject(SubjectContext->ClientToken);
298 }
299 }
300
301 /*
302 * @implemented
303 */
304 VOID STDCALL SeCaptureSubjectContext (PSECURITY_SUBJECT_CONTEXT SubjectContext)
305 {
306 PEPROCESS Process;
307 ULONG a;
308 ULONG b;
309
310 Process = PsGetCurrentThread()->ThreadsProcess;
311
312 SubjectContext->ProcessAuditId = Process;
313 SubjectContext->ClientToken =
314 PsReferenceImpersonationToken(PsGetCurrentThread(),
315 &a,
316 &b,
317 &SubjectContext->ImpersonationLevel);
318 SubjectContext->PrimaryToken = PsReferencePrimaryToken(Process);
319 }
320
321
322 /*
323 * @implemented
324 */
325 NTSTATUS STDCALL
326 SeDeassignSecurity(PSECURITY_DESCRIPTOR* SecurityDescriptor)
327 {
328 if ((*SecurityDescriptor) != NULL)
329 {
330 ExFreePool(*SecurityDescriptor);
331 (*SecurityDescriptor) = NULL;
332 }
333 return(STATUS_SUCCESS);
334 }
335
336
337 #if 0
338 VOID SepGetDefaultsSubjectContext(PSECURITY_SUBJECT_CONTEXT SubjectContext,
339 PSID* Owner,
340 PSID* PrimaryGroup,
341 PSID* ProcessOwner,
342 PSID* ProcessPrimaryGroup,
343 PACL* DefaultDacl)
344 {
345 PACCESS_TOKEN Token;
346
347 if (SubjectContext->ClientToken != NULL)
348 {
349 Token = SubjectContext->ClientToken;
350 }
351 else
352 {
353 Token = SubjectContext->PrimaryToken;
354 }
355 *Owner = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid;
356 *PrimaryGroup = Token->PrimaryGroup;
357 *DefaultDacl = Token->DefaultDacl;
358 *ProcessOwner = SubjectContext->PrimaryToken->
359 UserAndGroups[Token->DefaultOwnerIndex].Sid;
360 *ProcessPrimaryGroup = SubjectContext->PrimaryToken->PrimaryGroup;
361 }
362
363 NTSTATUS SepInheritAcl(PACL Acl,
364 BOOLEAN IsDirectoryObject,
365 PSID Owner,
366 PSID PrimaryGroup,
367 PACL DefaultAcl,
368 PSID ProcessOwner,
369 PSID ProcessGroup,
370 PGENERIC_MAPPING GenericMapping)
371 {
372 if (Acl == NULL)
373 {
374 return(STATUS_UNSUCCESSFUL);
375 }
376 if (Acl->AclRevision != 2 &&
377 Acl->AclRevision != 3 )
378 {
379 return(STATUS_UNSUCCESSFUL);
380 }
381
382 }
383 #endif
384
385 /*
386 * @unimplemented
387 */
388 NTSTATUS STDCALL
389 SeAssignSecurity(PSECURITY_DESCRIPTOR ParentDescriptor,
390 PSECURITY_DESCRIPTOR ExplicitDescriptor,
391 PSECURITY_DESCRIPTOR* NewDescriptor,
392 BOOLEAN IsDirectoryObject,
393 PSECURITY_SUBJECT_CONTEXT SubjectContext,
394 PGENERIC_MAPPING GenericMapping,
395 POOL_TYPE PoolType)
396 {
397 #if 0
398 PSECURITY_DESCRIPTOR Descriptor;
399 PSID Owner;
400 PSID PrimaryGroup;
401 PACL DefaultDacl;
402 PSID ProcessOwner;
403 PSID ProcessPrimaryGroup;
404 PACL Sacl;
405
406 if (ExplicitDescriptor == NULL)
407 {
408 RtlCreateSecurityDescriptor(&Descriptor, 1);
409 }
410 else
411 {
412 Descriptor = ExplicitDescriptor;
413 }
414 SeLockSubjectContext(SubjectContext);
415 SepGetDefaultsSubjectContext(SubjectContext,
416 &Owner,
417 &PrimaryGroup,
418 &DefaultDacl,
419 &ProcessOwner,
420 &ProcessPrimaryGroup);
421 if (Descriptor->Control & SE_SACL_PRESENT ||
422 Descriptor->Control & SE_SACL_DEFAULTED)
423 {
424 if (ParentDescriptor == NULL)
425 {
426 }
427 if (Descriptor->Control & SE_SACL_PRESENT ||
428 Descriptor->Sacl == NULL ||)
429 {
430 Sacl = NULL;
431 }
432 else
433 {
434 Sacl = Descriptor->Sacl;
435 if (Descriptor->Control & SE_SELF_RELATIVE)
436 {
437 Sacl = (PACL)(((PVOID)Sacl) + (PVOID)Descriptor);
438 }
439 }
440 SepInheritAcl(Sacl,
441 IsDirectoryObject,
442 Owner,
443 PrimaryGroup,
444 DefaultDacl,
445 ProcessOwner,
446 GenericMapping);
447 }
448 #else
449 UNIMPLEMENTED;
450 #endif
451 }
452
453 BOOLEAN SepSidInToken(PACCESS_TOKEN Token,
454 PSID Sid)
455 {
456 ULONG i;
457
458 if (Token->UserAndGroupCount == 0)
459 {
460 return(FALSE);
461 }
462
463 for (i=0; i<Token->UserAndGroupCount; i++)
464 {
465 if (RtlEqualSid(Sid, Token->UserAndGroups[i].Sid))
466 {
467 if (i == 0 ||
468 (!(Token->UserAndGroups[i].Attributes & SE_GROUP_ENABLED)))
469 {
470 return(TRUE);
471 }
472 return(FALSE);
473 }
474 }
475 return(FALSE);
476 }
477
478
479 /*
480 * @implemented
481 */
482 BOOLEAN STDCALL
483 SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
484 IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
485 IN BOOLEAN SubjectContextLocked,
486 IN ACCESS_MASK DesiredAccess,
487 IN ACCESS_MASK PreviouslyGrantedAccess,
488 OUT PPRIVILEGE_SET* Privileges,
489 IN PGENERIC_MAPPING GenericMapping,
490 IN KPROCESSOR_MODE AccessMode,
491 OUT PACCESS_MODE GrantedAccess,
492 OUT PNTSTATUS AccessStatus)
493 /*
494 * FUNCTION: Determines whether the requested access rights can be granted
495 * to an object protected by a security descriptor and an object owner
496 * ARGUMENTS:
497 * SecurityDescriptor = Security descriptor protecting the object
498 * SubjectSecurityContext = Subject's captured security context
499 * SubjectContextLocked = Indicates the user's subject context is locked
500 * DesiredAccess = Access rights the caller is trying to acquire
501 * PreviouslyGrantedAccess = Specified the access rights already granted
502 * Privileges = ?
503 * GenericMapping = Generic mapping associated with the object
504 * AccessMode = Access mode used for the check
505 * GrantedAccess (OUT) = On return specifies the access granted
506 * AccessStatus (OUT) = Status indicating why access was denied
507 * RETURNS: If access was granted, returns TRUE
508 */
509 {
510 ULONG i;
511 PACL Dacl;
512 BOOLEAN Present;
513 BOOLEAN Defaulted;
514 NTSTATUS Status;
515 PACE CurrentAce;
516 PSID Sid;
517 ACCESS_MASK CurrentAccess;
518
519 CurrentAccess = PreviouslyGrantedAccess;
520
521 /*
522 * Ignore the SACL for now
523 */
524
525 /*
526 * Check the DACL
527 */
528 Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
529 &Present,
530 &Dacl,
531 &Defaulted);
532 if (!NT_SUCCESS(Status))
533 {
534 return(Status);
535 }
536
537 CurrentAce = (PACE)(Dacl + 1);
538 for (i = 0; i < Dacl->AceCount; i++)
539 {
540 Sid = (PSID)(CurrentAce + 1);
541 if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
542 {
543 if (SepSidInToken(SubjectSecurityContext->ClientToken, Sid))
544 {
545 *AccessStatus = STATUS_ACCESS_DENIED;
546 *GrantedAccess = 0;
547 return(STATUS_SUCCESS);
548 }
549 }
550 if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
551 {
552 if (SepSidInToken(SubjectSecurityContext->ClientToken, Sid))
553 {
554 CurrentAccess = CurrentAccess |
555 CurrentAce->AccessMask;
556 }
557 }
558 }
559 if (!(CurrentAccess & DesiredAccess) &&
560 !((~CurrentAccess) & DesiredAccess))
561 {
562 *AccessStatus = STATUS_ACCESS_DENIED;
563 }
564 else
565 {
566 *AccessStatus = STATUS_SUCCESS;
567 }
568 *GrantedAccess = CurrentAccess;
569
570 return(STATUS_SUCCESS);
571 }
572
573
574 /* EOF */