3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Security manager
6 * FILE: kernel/se/priv.c
9 * 26/07/98: Added stubs for security functions
12 /* INCLUDES *****************************************************************/
14 #include <ddk/ntddk.h>
15 #include <internal/se.h>
17 #include <internal/debug.h>
20 /* GLOBALS *******************************************************************/
22 LUID SeCreateTokenPrivilege;
23 LUID SeAssignPrimaryTokenPrivilege;
24 LUID SeLockMemoryPrivilege;
25 LUID SeIncreaseQuotaPrivilege;
26 LUID SeUnsolicitedInputPrivilege;
28 LUID SeSecurityPrivilege;
29 LUID SeTakeOwnershipPrivilege;
30 LUID SeLoadDriverPrivilege;
31 LUID SeCreatePagefilePrivilege;
32 LUID SeIncreaseBasePriorityPrivilege;
33 LUID SeSystemProfilePrivilege;
34 LUID SeSystemtimePrivilege;
35 LUID SeProfileSingleProcessPrivilege;
36 LUID SeCreatePermanentPrivilege;
37 LUID SeBackupPrivilege;
38 LUID SeRestorePrivilege;
39 LUID SeShutdownPrivilege;
40 LUID SeDebugPrivilege;
41 LUID SeAuditPrivilege;
42 LUID SeSystemEnvironmentPrivilege;
43 LUID SeChangeNotifyPrivilege;
44 LUID SeRemoteShutdownPrivilege;
47 /* FUNCTIONS ***************************************************************/
50 SepInitPrivileges(VOID)
52 SeCreateTokenPrivilege.QuadPart = SE_CREATE_TOKEN_PRIVILEGE;
53 SeAssignPrimaryTokenPrivilege.QuadPart = SE_ASSIGNPRIMARYTOKEN_PRIVILEGE;
54 SeLockMemoryPrivilege.QuadPart = SE_LOCK_MEMORY_PRIVILEGE;
55 SeIncreaseQuotaPrivilege.QuadPart = SE_INCREASE_QUOTA_PRIVILEGE;
56 SeUnsolicitedInputPrivilege.QuadPart = SE_UNSOLICITED_INPUT_PRIVILEGE;
57 SeTcbPrivilege.QuadPart = SE_TCB_PRIVILEGE;
58 SeSecurityPrivilege.QuadPart = SE_SECURITY_PRIVILEGE;
59 SeTakeOwnershipPrivilege.QuadPart = SE_TAKE_OWNERSHIP_PRIVILEGE;
60 SeLoadDriverPrivilege.QuadPart = SE_LOAD_DRIVER_PRIVILEGE;
61 SeSystemProfilePrivilege.QuadPart = SE_SYSTEM_PROFILE_PRIVILEGE;
62 SeSystemtimePrivilege.QuadPart = SE_SYSTEMTIME_PRIVILEGE;
63 SeProfileSingleProcessPrivilege.QuadPart = SE_PROF_SINGLE_PROCESS_PRIVILEGE;
64 SeIncreaseBasePriorityPrivilege.QuadPart = SE_INC_BASE_PRIORITY_PRIVILEGE;
65 SeCreatePagefilePrivilege.QuadPart = SE_CREATE_PAGEFILE_PRIVILEGE;
66 SeCreatePermanentPrivilege.QuadPart = SE_CREATE_PERMANENT_PRIVILEGE;
67 SeBackupPrivilege.QuadPart = SE_BACKUP_PRIVILEGE;
68 SeRestorePrivilege.QuadPart = SE_RESTORE_PRIVILEGE;
69 SeShutdownPrivilege.QuadPart = SE_SHUTDOWN_PRIVILEGE;
70 SeDebugPrivilege.QuadPart = SE_DEBUG_PRIVILEGE;
71 SeAuditPrivilege.QuadPart = SE_AUDIT_PRIVILEGE;
72 SeSystemEnvironmentPrivilege.QuadPart = SE_SYSTEM_ENVIRONMENT_PRIVILEGE;
73 SeChangeNotifyPrivilege.QuadPart = SE_CHANGE_NOTIFY_PRIVILEGE;
74 SeRemoteShutdownPrivilege.QuadPart = SE_REMOTE_SHUTDOWN_PRIVILEGE;
78 BOOLEAN SepPrivilegeCheck(PACCESS_TOKEN Token,
79 PLUID_AND_ATTRIBUTES Privileges,
81 ULONG PrivilegeControl,
82 KPROCESSOR_MODE PreviousMode)
85 PLUID_AND_ATTRIBUTES Current;
89 if (PreviousMode == KernelMode)
95 if (PrivilegeCount != 0)
100 i = Token->PrivilegeCount;
101 Current = Token->Privileges;
102 for (i = 0; i < Token->PrivilegeCount; i++)
104 if (!(Current[i].Attributes & SE_PRIVILEGE_ENABLED) &&
105 Privileges[i].Luid.u.LowPart ==
106 Current[i].Luid.u.LowPart &&
107 Privileges[i].Luid.u.HighPart ==
108 Current[i].Luid.u.HighPart)
110 Privileges[i].Attributes =
111 Privileges[i].Attributes |
112 SE_PRIVILEGE_USED_FOR_ACCESS;
121 if ((PrivilegeControl & PRIVILEGE_SET_ALL_NECESSARY) &&
128 !(PrivilegeControl & PRIVILEGE_SET_ALL_NECESSARY))
137 NTSTATUS SeCaptureLuidAndAttributesArray(PLUID_AND_ATTRIBUTES Src,
138 ULONG PrivilegeCount,
139 KPROCESSOR_MODE PreviousMode,
140 PLUID_AND_ATTRIBUTES AllocatedMem,
141 ULONG AllocatedLength,
144 PLUID_AND_ATTRIBUTES* Dest,
147 PLUID_AND_ATTRIBUTES* NewMem;
150 if (PrivilegeCount == 0)
154 return(STATUS_SUCCESS);
156 if (PreviousMode == 0 && d == 0)
159 return(STATUS_SUCCESS);
161 SrcLength = ((PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES)) + 3) & 0xfc;
163 if (AllocatedMem == NULL)
165 NewMem = ExAllocatePool(PoolType, SrcLength);
166 *Dest = (PLUID_AND_ATTRIBUTES)NewMem;
169 return(STATUS_UNSUCCESSFUL);
174 if (SrcLength > AllocatedLength)
176 return(STATUS_UNSUCCESSFUL);
178 *Dest = AllocatedMem;
180 memmove(*Dest, Src, SrcLength);
181 return(STATUS_SUCCESS);
185 SeReleaseLuidAndAttributesArray(PLUID_AND_ATTRIBUTES Privilege,
186 KPROCESSOR_MODE PreviousMode,
189 ExFreePool(Privilege);
193 NtPrivilegeCheck(IN HANDLE ClientToken,
194 IN PPRIVILEGE_SET RequiredPrivileges,
199 ULONG PrivilegeCount;
201 ULONG PrivilegeControl;
202 PLUID_AND_ATTRIBUTES Privilege;
205 Status = ObReferenceObjectByHandle(ClientToken,
211 if (!NT_SUCCESS(Status))
215 if (Token->TokenType == TokenImpersonation &&
216 Token->ImpersonationLevel < SecurityAnonymous)
218 ObDereferenceObject(Token);
219 return(STATUS_UNSUCCESSFUL);
221 PrivilegeCount = RequiredPrivileges->PrivilegeCount;
222 PrivilegeControl = RequiredPrivileges->Control;
224 Status = SeCaptureLuidAndAttributesArray(RequiredPrivileges->Privilege,
233 if (!NT_SUCCESS(Status))
235 ObDereferenceObject(Token);
236 return(STATUS_UNSUCCESSFUL);
238 TResult = SepPrivilegeCheck(Token,
243 memmove(RequiredPrivileges->Privilege, Privilege, Length);
245 SeReleaseLuidAndAttributesArray(Privilege, UserMode, 1);
246 return(STATUS_SUCCESS);
250 SePrivilegeCheck(PPRIVILEGE_SET Privileges,
251 PSECURITY_SUBJECT_CONTEXT SubjectContext,
252 KPROCESSOR_MODE PreviousMode)
254 PACCESS_TOKEN Token = NULL;
256 if (SubjectContext->ClientToken == NULL)
258 Token = SubjectContext->PrimaryToken;
262 Token = SubjectContext->ClientToken;
263 if (SubjectContext->ImpersonationLevel < 2)
269 return(SepPrivilegeCheck(Token,
270 Privileges->Privilege,
271 Privileges->PrivilegeCount,
277 SeSinglePrivilegeCheck(IN LUID PrivilegeValue,
278 IN KPROCESSOR_MODE PreviousMode)
280 SECURITY_SUBJECT_CONTEXT SubjectContext;
284 SeCaptureSubjectContext(&SubjectContext);
286 Priv.PrivilegeCount = 1;
288 Priv.Privilege[0].Luid = PrivilegeValue;
289 Priv.Privilege[0].Attributes = 0;
291 r = SePrivilegeCheck(&Priv,
295 if (PreviousMode != KernelMode)
298 SePrivilegeServiceAuditAlarm(0,
303 SeReleaseSubjectContext(&SubjectContext);