Fixed some more ntoskrnl exports
[reactos.git] / reactos / ntoskrnl / se / token.c
1 /* $Id: token.c,v 1.5 2000/05/09 21:30:39 ekohl Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Security manager
6 * FILE: kernel/se/token.c
7 * PROGRAMER: David Welch <welch@cwcom.net>
8 * REVISION HISTORY:
9 * 26/07/98: Added stubs for security functions
10 */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ddk/ntddk.h>
15
16 #include <internal/debug.h>
17
18 /* GLOBALS *******************************************************************/
19
20 POBJECT_TYPE SeTokenType = NULL;
21
22 /* FUNCTIONS *****************************************************************/
23
24 VOID SepFreeProxyData(PVOID ProxyData)
25 {
26 UNIMPLEMENTED;
27 }
28
29 NTSTATUS SepCopyProxyData(PVOID* Dest, PVOID Src)
30 {
31 UNIMPLEMENTED;
32 }
33
34 NTSTATUS SeExchangePrimaryToken(PEPROCESS Process,
35 PACCESS_TOKEN NewToken,
36 PACCESS_TOKEN* OldTokenP)
37 {
38 PACCESS_TOKEN OldToken;
39
40 if (NewToken->TokenType != TokenPrimary)
41 {
42 return(STATUS_UNSUCCESSFUL);
43 }
44 if (NewToken->TokenInUse != 0)
45 {
46 return(STATUS_UNSUCCESSFUL);
47 }
48 OldToken = Process->Token;
49 Process->Token = NewToken;
50 NewToken->TokenInUse = 1;
51 ObReferenceObjectByPointer(NewToken,
52 GENERIC_ALL,
53 SeTokenType,
54 KernelMode);
55 OldToken->TokenInUse = 0;
56 *OldTokenP = OldToken;
57 return(STATUS_SUCCESS);
58 }
59
60 NTSTATUS SepDuplicationToken(PACCESS_TOKEN Token,
61 POBJECT_ATTRIBUTES ObjectAttributes,
62 TOKEN_TYPE TokenType,
63 SECURITY_IMPERSONATION_LEVEL Level,
64 SECURITY_IMPERSONATION_LEVEL ExistingLevel,
65 KPROCESSOR_MODE PreviousMode,
66 PACCESS_TOKEN* NewAccessToken)
67 {
68 UNIMPLEMENTED;
69 }
70
71 NTSTATUS SeCopyClientToken(PACCESS_TOKEN Token,
72 SECURITY_IMPERSONATION_LEVEL Level,
73 KPROCESSOR_MODE PreviousMode,
74 PACCESS_TOKEN* NewToken)
75 {
76 NTSTATUS Status;
77 OBJECT_ATTRIBUTES ObjectAttributes;
78
79 InitializeObjectAttributes(&ObjectAttributes,
80 NULL,
81 0,
82 NULL,
83 NULL);
84 Status = SepDuplicationToken(Token,
85 &ObjectAttributes,
86 0,
87 SecurityIdentification,
88 Level,
89 PreviousMode,
90 NewToken);
91 return(Status);
92 }
93
94 NTSTATUS
95 STDCALL
96 SeCreateClientSecurity (
97 PETHREAD Thread,
98 PSECURITY_QUALITY_OF_SERVICE Qos,
99 ULONG e,
100 PSE_SOME_STRUCT2 f
101 )
102 {
103 TOKEN_TYPE TokenType;
104 UCHAR b;
105 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
106 PACCESS_TOKEN Token;
107 ULONG g;
108 PACCESS_TOKEN NewToken;
109
110 Token = PsReferenceEffectiveToken(Thread,
111 &TokenType,
112 &b,
113 &ImpersonationLevel);
114 if (TokenType != 2)
115 {
116 f->Unknown9 = Qos->EffectiveOnly;
117 }
118 else
119 {
120 if (Qos->ImpersonationLevel > ImpersonationLevel)
121 {
122 if (Token != NULL)
123 {
124 ObDereferenceObject(Token);
125 }
126 return(STATUS_UNSUCCESSFUL);
127 }
128 if (ImpersonationLevel == 0 ||
129 ImpersonationLevel == 1 ||
130 (e != 0 && ImpersonationLevel != 3))
131 {
132 if (Token != NULL)
133 {
134 ObDereferenceObject(Token);
135 }
136 return(STATUS_UNSUCCESSFUL);
137 }
138 if (b != 0 ||
139 Qos->EffectiveOnly != 0)
140 {
141 f->Unknown9 = 1;
142 }
143 else
144 {
145 f->Unknown9 = 0;
146 }
147 }
148
149 if (Qos->ContextTrackingMode == 0)
150 {
151 f->Unknown8 = 0;
152 g = SeCopyClientToken(Token, ImpersonationLevel, 0, &NewToken);
153 if (g >= 0)
154 {
155 // ObDeleteCapturedInsertInfo(NewToken);
156 }
157 if (TokenType == TokenPrimary || Token != NULL)
158 {
159 ObDereferenceObject(Token);
160 }
161 if (g < 0)
162 {
163 return(g);
164 }
165 }
166 else
167 {
168 f->Unknown8 = 1;
169 if (e != 0)
170 {
171 // SeGetTokenControlInformation(Token, &f->Unknown11);
172 }
173 NewToken = Token;
174 }
175 f->Unknown1 = 0xc;
176 f->Level = Qos->ImpersonationLevel;
177 f->ContextTrackingMode = Qos->ContextTrackingMode;
178 f->EffectiveOnly = Qos->EffectiveOnly;
179 f->Unknown10 = e;
180 f->Token = NewToken;
181
182 return(STATUS_SUCCESS);
183 }
184
185
186 VOID
187 STDCALL
188 SeImpersonateClient (
189 PSE_SOME_STRUCT2 a,
190 PETHREAD Thread
191 )
192 {
193 UCHAR b;
194
195 if (a->Unknown8 == 0)
196 {
197 b = a->EffectiveOnly;
198 }
199 else
200 {
201 b = a->Unknown9;
202 }
203 if (Thread == NULL)
204 {
205 Thread = PsGetCurrentThread();
206 }
207 PsImpersonateClient(Thread,
208 a->Token,
209 1,
210 (ULONG)b,
211 a->Level);
212 }
213
214 VOID SeInitializeTokenManager(VOID)
215 {
216 UNICODE_STRING TypeName;
217
218 RtlInitUnicodeString(&TypeName, L"Token");
219
220 SeTokenType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
221
222 SeTokenType->MaxObjects = ULONG_MAX;
223 SeTokenType->MaxHandles = ULONG_MAX;
224 SeTokenType->TotalObjects = 0;
225 SeTokenType->TotalHandles = 0;
226 SeTokenType->PagedPoolCharge = 0;
227 SeTokenType->NonpagedPoolCharge = 0;
228 SeTokenType->Dump = NULL;
229 SeTokenType->Open = NULL;
230 SeTokenType->Close = NULL;
231 SeTokenType->Delete = NULL;
232 SeTokenType->Parse = NULL;
233 SeTokenType->Security = NULL;
234 SeTokenType->QueryName = NULL;
235 SeTokenType->OkayToClose = NULL;
236 SeTokenType->Create = NULL;
237
238 }
239
240 NTSTATUS RtlCopySidAndAttributesArray(ULONG Count, // ebp + 8
241 PSID_AND_ATTRIBUTES Src, // ebp + C
242 ULONG MaxLength, // ebp + 10
243 PSID_AND_ATTRIBUTES Dest, // ebp + 14
244 PVOID e, // ebp + 18
245 PVOID* f, // ebp + 1C
246 PULONG g) // ebp + 20
247 {
248 ULONG Length; // ebp - 4
249 ULONG i;
250
251 Length = MaxLength;
252
253 for (i=0; i<Count; i++)
254 {
255 if (RtlLengthSid(Src[i].Sid) > Length)
256 {
257 return(STATUS_UNSUCCESSFUL);
258 }
259 Length = Length - RtlLengthSid(Src[i].Sid);
260 Dest[i].Sid = e;
261 Dest[i].Attributes = Src[i].Attributes;
262 RtlCopySid(RtlLengthSid(Src[i].Sid), e, Src[i].Sid);
263 e = e + RtlLengthSid(Src[i].Sid) + sizeof(ULONG);
264 }
265 *f = e;
266 *g = Length;
267 return(STATUS_SUCCESS);
268 }
269
270 NTSTATUS STDCALL NtQueryInformationToken(IN HANDLE TokenHandle,
271 IN TOKEN_INFORMATION_CLASS
272 TokenInformationClass,
273 OUT PVOID TokenInformation,
274 IN ULONG TokenInformationLength,
275 OUT PULONG ReturnLength)
276 {
277 NTSTATUS Status;
278 PACCESS_TOKEN Token;
279 PVOID UnusedInfo;
280 PVOID EndMem;
281 PTOKEN_GROUPS PtrTokenGroups;
282 PTOKEN_DEFAULT_DACL PtrDefaultDacl;
283 PTOKEN_STATISTICS PtrTokenStatistics;
284
285 Status = ObReferenceObjectByHandle(TokenHandle,
286 0,
287 SeTokenType,
288 UserMode,
289 (PVOID*)&Token,
290 NULL);
291 if (!NT_SUCCESS(Status))
292 {
293 return(Status);
294 }
295
296 switch (TokenInformationClass)
297 {
298 case TokenUser:
299 Status = RtlCopySidAndAttributesArray(1,
300 Token->UserAndGroups,
301 TokenInformationLength,
302 TokenInformation,
303 TokenInformation + 8,
304 &UnusedInfo,
305 ReturnLength);
306 if (!NT_SUCCESS(Status))
307 {
308 ObDereferenceObject(Token);
309 return(Status);
310 }
311 break;
312
313
314 case TokenGroups:
315 EndMem = TokenInformation +
316 Token->UserAndGroupCount * sizeof(SID_AND_ATTRIBUTES);
317 PtrTokenGroups = (PTOKEN_GROUPS)TokenInformation;
318 PtrTokenGroups->GroupCount = Token->UserAndGroupCount - 1;
319 Status = RtlCopySidAndAttributesArray(Token->UserAndGroupCount - 1,
320 &Token->UserAndGroups[1],
321 TokenInformationLength,
322 PtrTokenGroups->Groups,
323 EndMem,
324 &UnusedInfo,
325 ReturnLength);
326 if (!NT_SUCCESS(Status))
327 {
328 ObDereferenceObject(Token);
329 return(Status);
330 }
331 break;
332
333 case TokenPrivileges:
334 break;
335
336 case TokenOwner:
337 ((PTOKEN_OWNER)TokenInformation)->Owner =
338 (PSID)(((PTOKEN_OWNER)TokenInformation) + 1);
339 RtlCopySid(TokenInformationLength - sizeof(TOKEN_OWNER),
340 ((PTOKEN_OWNER)TokenInformation)->Owner,
341 Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
342 break;
343
344 case TokenPrimaryGroup:
345 ((PTOKEN_PRIMARY_GROUP)TokenInformation)->PrimaryGroup =
346 (PSID)(((PTOKEN_PRIMARY_GROUP)TokenInformation) + 1);
347 RtlCopySid(TokenInformationLength - sizeof(TOKEN_OWNER),
348 ((PTOKEN_PRIMARY_GROUP)TokenInformation)->PrimaryGroup,
349 Token->PrimaryGroup);
350 break;
351
352 case TokenDefaultDacl:
353 PtrDefaultDacl = (PTOKEN_DEFAULT_DACL)TokenInformation;
354 PtrDefaultDacl->DefaultDacl = (PACL)(PtrDefaultDacl + 1);
355 memmove(PtrDefaultDacl->DefaultDacl,
356 Token->DefaultDacl,
357 Token->DefaultDacl->AclSize);
358 break;
359
360 case TokenSource:
361 memcpy(TokenInformation, &Token->TokenSource, sizeof(TOKEN_SOURCE));
362 break;
363
364 case TokenType:
365 *((PTOKEN_TYPE)TokenInformation) = Token->TokenType;
366 break;
367
368 case TokenImpersonationLevel:
369 *((PSECURITY_IMPERSONATION_LEVEL)TokenInformation) =
370 Token->ImpersonationLevel;
371 break;
372
373 case TokenStatistics:
374 PtrTokenStatistics = (PTOKEN_STATISTICS)TokenInformation;
375 PtrTokenStatistics->TokenId = Token->TokenId;
376 PtrTokenStatistics->AuthenticationId = Token->AuthenticationId;
377 PtrTokenStatistics->ExpirationTime = Token->ExpirationTime;
378 PtrTokenStatistics->TokenType = Token->TokenType;
379 PtrTokenStatistics->ImpersonationLevel = Token->ImpersonationLevel;
380 PtrTokenStatistics->DynamicCharged = Token->DynamicCharged;
381 PtrTokenStatistics->DynamicAvailable = Token->DynamicAvailable;
382 PtrTokenStatistics->GroupCount = Token->UserAndGroupCount - 1;
383 PtrTokenStatistics->PrivilegeCount = Token->PrivilegeCount;
384 PtrTokenStatistics->ModifiedId = Token->ModifiedId;
385 break;
386 }
387
388 ObDereferenceObject(Token);
389 return(STATUS_SUCCESS);
390 }
391
392
393
394
395 NTSTATUS
396 STDCALL
397 NtSetInformationToken(
398 IN HANDLE TokenHandle,
399 IN TOKEN_INFORMATION_CLASS TokenInformationClass,
400 OUT PVOID TokenInformation,
401 IN ULONG TokenInformationLength
402 )
403 {
404 UNIMPLEMENTED;
405 }
406
407 NTSTATUS STDCALL NtDuplicateToken(IN HANDLE ExistingTokenHandle,
408 IN ACCESS_MASK DesiredAccess,
409 IN POBJECT_ATTRIBUTES ObjectAttributes,
410 IN SECURITY_IMPERSONATION_LEVEL
411 ImpersonationLevel,
412 IN TOKEN_TYPE TokenType,
413 OUT PHANDLE NewTokenHandle)
414 {
415 #if 0
416 PACCESS_TOKEN Token;
417 PACCESS_TOKEN NewToken;
418 NTSTATUS Status;
419 ULONG ExistingImpersonationLevel;
420
421 Status = ObReferenceObjectByHandle(ExistingTokenHandle,
422 ?,
423 SeTokenType,
424 UserMode,
425 (PVOID*)&Token,
426 NULL);
427
428 ExistingImpersonationLevel = Token->ImpersonationLevel;
429 SepDuplicateToken(Token,
430 ObjectAttributes,
431 ImpersonationLevel,
432 TokenType,
433 ExistingImpersonationLevel,
434 KeGetPreviousMode(),
435 &NewToken);
436 #else
437 UNIMPLEMENTED;
438 #endif
439 }
440
441 VOID SepAdjustGroups(PACCESS_TOKEN Token,
442 ULONG a,
443 BOOLEAN ResetToDefault,
444 PSID_AND_ATTRIBUTES Groups,
445 ULONG b,
446 KPROCESSOR_MODE PreviousMode,
447 ULONG c,
448 PULONG d,
449 PULONG e,
450 PULONG f)
451 {
452 UNIMPLEMENTED;
453 }
454
455 NTSTATUS STDCALL NtAdjustGroupsToken(IN HANDLE TokenHandle,
456 IN BOOLEAN ResetToDefault,
457 IN PTOKEN_GROUPS NewState,
458 IN ULONG BufferLength,
459 OUT PTOKEN_GROUPS PreviousState OPTIONAL,
460 OUT PULONG ReturnLength)
461 {
462 #if 0
463 NTSTATUS Status;
464 PACCESS_TOKEN Token;
465 ULONG a;
466 ULONG b;
467 ULONG c;
468
469 Status = ObReferenceObjectByHandle(TokenHandle,
470 ?,
471 SeTokenType,
472 UserMode,
473 (PVOID*)&Token,
474 NULL);
475
476
477 SepAdjustGroups(Token,
478 0,
479 ResetToDefault,
480 NewState->Groups,
481 ?,
482 PreviousState,
483 0,
484 &a,
485 &b,
486 &c);
487 #else
488 UNIMPLEMENTED;
489 #endif
490 }
491
492 #if 0
493 NTSTATUS SepAdjustPrivileges(PACCESS_TOKEN Token, // 0x8
494 ULONG a, // 0xC
495 KPROCESSOR_MODE PreviousMode, // 0x10
496 ULONG PrivilegeCount, // 0x14
497 PLUID_AND_ATTRIBUTES Privileges, // 0x18
498 PTOKEN_PRIVILEGES* PreviousState, // 0x1C
499 PULONG b, // 0x20
500 PULONG c, // 0x24
501 PULONG d) // 0x28
502 {
503 ULONG i;
504
505 *c = 0;
506 if (Token->PrivilegeCount > 0)
507 {
508 for (i=0; i<Token->PrivilegeCount; i++)
509 {
510 if (PreviousMode != 0)
511 {
512 if (!(Token->Privileges[i]->Attributes &
513 SE_PRIVILEGE_ENABLED))
514 {
515 if (a != 0)
516 {
517 if (PreviousState != NULL)
518 {
519 memcpy(&PreviousState[i],
520 &Token->Privileges[i],
521 sizeof(LUID_AND_ATTRIBUTES));
522 }
523 Token->Privileges[i].Attributes =
524 Token->Privileges[i].Attributes &
525 (~SE_PRIVILEGE_ENABLED);
526 }
527 }
528 }
529 }
530 }
531 if (PreviousMode != 0)
532 {
533 Token->TokenFlags = Token->TokenFlags & (~1);
534 }
535 else
536 {
537 if (PrivilegeCount <= ?)
538 {
539
540 }
541 }
542 if (
543 }
544 #endif
545
546 NTSTATUS STDCALL NtAdjustPrivilegesToken(IN HANDLE TokenHandle,
547 IN BOOLEAN DisableAllPrivileges,
548 IN PTOKEN_PRIVILEGES NewState,
549 IN ULONG BufferLength,
550 OUT PTOKEN_PRIVILEGES PreviousState,
551 OUT PULONG ReturnLength)
552 {
553 #if 0
554 ULONG PrivilegeCount;
555 ULONG Length;
556 PSID_AND_ATTRIBUTES Privileges;
557 ULONG a;
558 ULONG b;
559 ULONG c;
560
561 PrivilegeCount = NewState->PrivilegeCount;
562
563 SeCaptureLuidAndAttributesArray(NewState->Privileges,
564 &PrivilegeCount,
565 KeGetPreviousMode(),
566 NULL,
567 0,
568 NonPagedPool,
569 1,
570 &Privileges.
571 &Length);
572 SepAdjustPrivileges(Token,
573 0,
574 KeGetPreviousMode(),
575 PrivilegeCount,
576 Privileges,
577 PreviousState,
578 &a,
579 &b,
580 &c);
581 #else
582 UNIMPLEMENTED;
583 #endif
584 }
585
586 NTSTATUS STDCALL NtCreateToken(OUT PHANDLE TokenHandle,
587 IN ACCESS_MASK DesiredAccess,
588 IN POBJECT_ATTRIBUTES ObjectAttributes,
589 IN TOKEN_TYPE TokenType,
590 IN PLUID AuthenticationId,
591 IN PLARGE_INTEGER ExpirationTime,
592 IN PTOKEN_USER TokenUser,
593 IN PTOKEN_GROUPS TokenGroups,
594 IN PTOKEN_PRIVILEGES TokenPrivileges,
595 IN PTOKEN_OWNER TokenOwner,
596 IN PTOKEN_PRIMARY_GROUP TokenPrimaryGroup,
597 IN PTOKEN_DEFAULT_DACL TokenDefaultDacl,
598 IN PTOKEN_SOURCE TokenSource)
599 {
600 #if 0
601 PACCESS_TOKEN AccessToken;
602 NTSTATUS Status;
603
604 Status = ObCreateObject(TokenHandle,
605 DesiredAccess,
606 ObjectAttributes,
607 SeTokenType);
608 if (!NT_SUCCESS(Status))
609 {
610 return(Status);
611 }
612
613 AccessToken->TokenType = TokenType;
614 RtlCopyLuid(&AccessToken->AuthenticationId, AuthenticationId);
615 AccessToken->ExpirationTime = *ExpirationTime;
616 AccessToken->
617 #endif
618 UNIMPLEMENTED;
619 }
620
621
622 /* EOF */