Disable debug messages.
[reactos.git] / reactos / ntoskrnl / se / priv.c
1 /* $Id: priv.c,v 1.8 2003/06/20 18:19:29 ekohl Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Security manager
6 * FILE: kernel/se/priv.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/se.h>
16
17 #define NDEBUG
18 #include <internal/debug.h>
19
20
21 /* GLOBALS *******************************************************************/
22
23 LUID SeCreateTokenPrivilege;
24 LUID SeAssignPrimaryTokenPrivilege;
25 LUID SeLockMemoryPrivilege;
26 LUID SeIncreaseQuotaPrivilege;
27 LUID SeUnsolicitedInputPrivilege;
28 LUID SeTcbPrivilege;
29 LUID SeSecurityPrivilege;
30 LUID SeTakeOwnershipPrivilege;
31 LUID SeLoadDriverPrivilege;
32 LUID SeCreatePagefilePrivilege;
33 LUID SeIncreaseBasePriorityPrivilege;
34 LUID SeSystemProfilePrivilege;
35 LUID SeSystemtimePrivilege;
36 LUID SeProfileSingleProcessPrivilege;
37 LUID SeCreatePermanentPrivilege;
38 LUID SeBackupPrivilege;
39 LUID SeRestorePrivilege;
40 LUID SeShutdownPrivilege;
41 LUID SeDebugPrivilege;
42 LUID SeAuditPrivilege;
43 LUID SeSystemEnvironmentPrivilege;
44 LUID SeChangeNotifyPrivilege;
45 LUID SeRemoteShutdownPrivilege;
46
47
48 /* FUNCTIONS ***************************************************************/
49
50 VOID
51 SepInitPrivileges (VOID)
52 {
53 SeCreateTokenPrivilege.LowPart = SE_CREATE_TOKEN_PRIVILEGE;
54 SeCreateTokenPrivilege.HighPart = 0;
55 SeAssignPrimaryTokenPrivilege.LowPart = SE_ASSIGNPRIMARYTOKEN_PRIVILEGE;
56 SeAssignPrimaryTokenPrivilege.HighPart = 0;
57 SeLockMemoryPrivilege.LowPart = SE_LOCK_MEMORY_PRIVILEGE;
58 SeLockMemoryPrivilege.HighPart = 0;
59 SeIncreaseQuotaPrivilege.LowPart = SE_INCREASE_QUOTA_PRIVILEGE;
60 SeIncreaseQuotaPrivilege.HighPart = 0;
61 SeUnsolicitedInputPrivilege.LowPart = SE_UNSOLICITED_INPUT_PRIVILEGE;
62 SeUnsolicitedInputPrivilege.HighPart = 0;
63 SeTcbPrivilege.LowPart = SE_TCB_PRIVILEGE;
64 SeTcbPrivilege.HighPart = 0;
65 SeSecurityPrivilege.LowPart = SE_SECURITY_PRIVILEGE;
66 SeSecurityPrivilege.HighPart = 0;
67 SeTakeOwnershipPrivilege.LowPart = SE_TAKE_OWNERSHIP_PRIVILEGE;
68 SeTakeOwnershipPrivilege.HighPart = 0;
69 SeLoadDriverPrivilege.LowPart = SE_LOAD_DRIVER_PRIVILEGE;
70 SeLoadDriverPrivilege.HighPart = 0;
71 SeSystemProfilePrivilege.LowPart = SE_SYSTEM_PROFILE_PRIVILEGE;
72 SeSystemProfilePrivilege.HighPart = 0;
73 SeSystemtimePrivilege.LowPart = SE_SYSTEMTIME_PRIVILEGE;
74 SeSystemtimePrivilege.HighPart = 0;
75 SeProfileSingleProcessPrivilege.LowPart = SE_PROF_SINGLE_PROCESS_PRIVILEGE;
76 SeProfileSingleProcessPrivilege.HighPart = 0;
77 SeIncreaseBasePriorityPrivilege.LowPart = SE_INC_BASE_PRIORITY_PRIVILEGE;
78 SeIncreaseBasePriorityPrivilege.HighPart = 0;
79 SeCreatePagefilePrivilege.LowPart = SE_CREATE_PAGEFILE_PRIVILEGE;
80 SeCreatePagefilePrivilege.HighPart = 0;
81 SeCreatePermanentPrivilege.LowPart = SE_CREATE_PERMANENT_PRIVILEGE;
82 SeCreatePermanentPrivilege.HighPart = 0;
83 SeBackupPrivilege.LowPart = SE_BACKUP_PRIVILEGE;
84 SeBackupPrivilege.HighPart = 0;
85 SeRestorePrivilege.LowPart = SE_RESTORE_PRIVILEGE;
86 SeRestorePrivilege.HighPart = 0;
87 SeShutdownPrivilege.LowPart = SE_SHUTDOWN_PRIVILEGE;
88 SeShutdownPrivilege.HighPart = 0;
89 SeDebugPrivilege.LowPart = SE_DEBUG_PRIVILEGE;
90 SeDebugPrivilege.HighPart = 0;
91 SeAuditPrivilege.LowPart = SE_AUDIT_PRIVILEGE;
92 SeAuditPrivilege.HighPart = 0;
93 SeSystemEnvironmentPrivilege.LowPart = SE_SYSTEM_ENVIRONMENT_PRIVILEGE;
94 SeSystemEnvironmentPrivilege.HighPart = 0;
95 SeChangeNotifyPrivilege.LowPart = SE_CHANGE_NOTIFY_PRIVILEGE;
96 SeChangeNotifyPrivilege.HighPart = 0;
97 SeRemoteShutdownPrivilege.LowPart = SE_REMOTE_SHUTDOWN_PRIVILEGE;
98 SeRemoteShutdownPrivilege.HighPart = 0;
99 }
100
101
102 BOOLEAN
103 SepPrivilegeCheck (PACCESS_TOKEN Token,
104 PLUID_AND_ATTRIBUTES Privileges,
105 ULONG PrivilegeCount,
106 ULONG PrivilegeControl,
107 KPROCESSOR_MODE PreviousMode)
108 {
109 ULONG i;
110 ULONG j;
111 ULONG k;
112
113 DPRINT ("SepPrivilegeCheck() called\n");
114
115 if (PreviousMode == KernelMode)
116 {
117 return TRUE;
118 }
119
120 k = 0;
121 if (PrivilegeCount > 0)
122 {
123 for (i = 0; i < Token->PrivilegeCount; i++)
124 {
125 for (j = 0; j < PrivilegeCount; j++)
126 {
127 if (Token->Privileges[i].Luid.LowPart == Privileges[j].Luid.LowPart &&
128 Token->Privileges[i].Luid.HighPart == Privileges[j].Luid.HighPart)
129 {
130 DPRINT ("Found privilege\n");
131 DPRINT ("Privilege attributes %lx\n",
132 Token->Privileges[i].Attributes);
133
134 if (Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED)
135 {
136 Privileges[j].Attributes |= SE_PRIVILEGE_USED_FOR_ACCESS;
137 k++;
138 }
139 }
140 }
141 }
142 }
143
144 if ((PrivilegeControl & PRIVILEGE_SET_ALL_NECESSARY) &&
145 PrivilegeCount == k)
146 {
147 return TRUE;
148 }
149
150 if (k > 0 &&
151 !(PrivilegeControl & PRIVILEGE_SET_ALL_NECESSARY))
152 {
153 return TRUE;
154 }
155
156 return FALSE;
157 }
158
159
160 NTSTATUS
161 SeCaptureLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Src,
162 ULONG PrivilegeCount,
163 KPROCESSOR_MODE PreviousMode,
164 PLUID_AND_ATTRIBUTES AllocatedMem,
165 ULONG AllocatedLength,
166 POOL_TYPE PoolType,
167 ULONG d,
168 PLUID_AND_ATTRIBUTES* Dest,
169 PULONG Length)
170 {
171 PLUID_AND_ATTRIBUTES* NewMem;
172 ULONG SrcLength;
173
174 if (PrivilegeCount == 0)
175 {
176 *Dest = 0;
177 *Length = 0;
178 return STATUS_SUCCESS;
179 }
180
181 if (PreviousMode == KernelMode && d == 0)
182 {
183 *Dest = Src;
184 return STATUS_SUCCESS;
185 }
186
187 SrcLength = ((PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES)) + 3) & 0xfc;
188 *Length = SrcLength;
189 if (AllocatedMem == NULL)
190 {
191 NewMem = ExAllocatePool (PoolType,
192 SrcLength);
193 *Dest = (PLUID_AND_ATTRIBUTES)NewMem;
194 if (NewMem == NULL)
195 {
196 return STATUS_UNSUCCESSFUL;
197 }
198 }
199 else
200 {
201 if (SrcLength > AllocatedLength)
202 {
203 return STATUS_UNSUCCESSFUL;
204 }
205 *Dest = AllocatedMem;
206 }
207 memmove (*Dest, Src, SrcLength);
208
209 return STATUS_SUCCESS;
210 }
211
212
213 VOID
214 SeReleaseLuidAndAttributesArray (PLUID_AND_ATTRIBUTES Privilege,
215 KPROCESSOR_MODE PreviousMode,
216 ULONG a)
217 {
218 ExFreePool (Privilege);
219 }
220
221
222 NTSTATUS STDCALL
223 NtPrivilegeCheck (IN HANDLE ClientToken,
224 IN PPRIVILEGE_SET RequiredPrivileges,
225 IN PBOOLEAN Result)
226 {
227 PLUID_AND_ATTRIBUTES Privilege;
228 PACCESS_TOKEN Token;
229 ULONG PrivilegeCount;
230 ULONG PrivilegeControl;
231 ULONG Length;
232 NTSTATUS Status;
233
234 Status = ObReferenceObjectByHandle (ClientToken,
235 0,
236 SepTokenObjectType,
237 UserMode,
238 (PVOID*)&Token,
239 NULL);
240 if (!NT_SUCCESS(Status))
241 {
242 return Status;
243 }
244
245 if (Token->TokenType == TokenImpersonation &&
246 Token->ImpersonationLevel < SecurityAnonymous)
247 {
248 ObDereferenceObject (Token);
249 return STATUS_UNSUCCESSFUL;
250 }
251
252 PrivilegeCount = RequiredPrivileges->PrivilegeCount;
253 PrivilegeControl = RequiredPrivileges->Control;
254 Privilege = 0;
255 Status = SeCaptureLuidAndAttributesArray (RequiredPrivileges->Privilege,
256 PrivilegeCount,
257 1,
258 0,
259 0,
260 1,
261 1,
262 &Privilege,
263 &Length);
264 if (!NT_SUCCESS(Status))
265 {
266 ObDereferenceObject (Token);
267 return STATUS_UNSUCCESSFUL;
268 }
269
270 *Result = SepPrivilegeCheck (Token,
271 Privilege,
272 PrivilegeCount,
273 PrivilegeControl,
274 UserMode);
275
276 memmove (RequiredPrivileges->Privilege,
277 Privilege,
278 Length);
279
280 SeReleaseLuidAndAttributesArray (Privilege,
281 UserMode,
282 1);
283
284 return STATUS_SUCCESS;
285 }
286
287
288 BOOLEAN STDCALL
289 SePrivilegeCheck (PPRIVILEGE_SET Privileges,
290 PSECURITY_SUBJECT_CONTEXT SubjectContext,
291 KPROCESSOR_MODE PreviousMode)
292 {
293 PACCESS_TOKEN Token = NULL;
294
295 if (SubjectContext->ClientToken == NULL)
296 {
297 Token = SubjectContext->PrimaryToken;
298 }
299 else
300 {
301 Token = SubjectContext->ClientToken;
302 if (SubjectContext->ImpersonationLevel < 2)
303 {
304 return FALSE;
305 }
306 }
307
308 return SepPrivilegeCheck (Token,
309 Privileges->Privilege,
310 Privileges->PrivilegeCount,
311 Privileges->Control,
312 PreviousMode);
313 }
314
315
316 BOOLEAN STDCALL
317 SeSinglePrivilegeCheck (IN LUID PrivilegeValue,
318 IN KPROCESSOR_MODE PreviousMode)
319 {
320 SECURITY_SUBJECT_CONTEXT SubjectContext;
321 PRIVILEGE_SET Priv;
322 BOOLEAN Result;
323
324 SeCaptureSubjectContext (&SubjectContext);
325
326 Priv.PrivilegeCount = 1;
327 Priv.Control = PRIVILEGE_SET_ALL_NECESSARY;
328 Priv.Privilege[0].Luid = PrivilegeValue;
329 Priv.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
330
331 Result = SePrivilegeCheck (&Priv,
332 &SubjectContext,
333 PreviousMode);
334
335 if (PreviousMode != KernelMode)
336 {
337 #if 0
338 SePrivilegedServiceAuditAlarm (0,
339 &SubjectContext,
340 &PrivilegeValue);
341 #endif
342 }
343
344 SeReleaseSubjectContext (&SubjectContext);
345
346 return Result;
347 }
348
349 /* EOF */