Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentoken.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS system libraries 00004 * FILE: lib/advapi32/token/token.c 00005 * PURPOSE: Token functions 00006 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl) 00007 * UPDATE HISTORY: 00008 * Created 01/11/98 00009 */ 00010 00011 #include <advapi32.h> 00012 WINE_DEFAULT_DEBUG_CHANNEL(advapi); 00013 00014 /* 00015 * @implemented 00016 */ 00017 BOOL WINAPI 00018 AdjustTokenGroups(HANDLE TokenHandle, 00019 BOOL ResetToDefault, 00020 PTOKEN_GROUPS NewState, 00021 DWORD BufferLength, 00022 PTOKEN_GROUPS PreviousState, 00023 PDWORD ReturnLength) 00024 { 00025 NTSTATUS Status; 00026 00027 Status = NtAdjustGroupsToken(TokenHandle, 00028 ResetToDefault, 00029 NewState, 00030 BufferLength, 00031 PreviousState, 00032 (PULONG)ReturnLength); 00033 if (!NT_SUCCESS(Status)) 00034 { 00035 SetLastError(RtlNtStatusToDosError(Status)); 00036 return FALSE; 00037 } 00038 00039 return TRUE; 00040 } 00041 00042 00043 /* 00044 * @implemented 00045 */ 00046 BOOL WINAPI 00047 AdjustTokenPrivileges(HANDLE TokenHandle, 00048 BOOL DisableAllPrivileges, 00049 PTOKEN_PRIVILEGES NewState, 00050 DWORD BufferLength, 00051 PTOKEN_PRIVILEGES PreviousState, 00052 PDWORD ReturnLength) 00053 { 00054 NTSTATUS Status; 00055 00056 Status = NtAdjustPrivilegesToken(TokenHandle, 00057 DisableAllPrivileges, 00058 NewState, 00059 BufferLength, 00060 PreviousState, 00061 (PULONG)ReturnLength); 00062 if (STATUS_NOT_ALL_ASSIGNED == Status) 00063 { 00064 SetLastError(ERROR_NOT_ALL_ASSIGNED); 00065 return TRUE; 00066 } 00067 00068 if (!NT_SUCCESS(Status)) 00069 { 00070 SetLastError(RtlNtStatusToDosError(Status)); 00071 return FALSE; 00072 } 00073 00074 /* AdjustTokenPrivileges is documented to do this */ 00075 SetLastError(ERROR_SUCCESS); 00076 00077 return TRUE; 00078 } 00079 00080 00081 /* 00082 * @implemented 00083 */ 00084 BOOL WINAPI 00085 GetTokenInformation(HANDLE TokenHandle, 00086 TOKEN_INFORMATION_CLASS TokenInformationClass, 00087 LPVOID TokenInformation, 00088 DWORD TokenInformationLength, 00089 PDWORD ReturnLength) 00090 { 00091 NTSTATUS Status; 00092 00093 Status = NtQueryInformationToken(TokenHandle, 00094 TokenInformationClass, 00095 TokenInformation, 00096 TokenInformationLength, 00097 (PULONG)ReturnLength); 00098 if (!NT_SUCCESS(Status)) 00099 { 00100 SetLastError(RtlNtStatusToDosError(Status)); 00101 return FALSE; 00102 } 00103 00104 return TRUE; 00105 } 00106 00107 00108 /* 00109 * @implemented 00110 */ 00111 BOOL WINAPI 00112 SetTokenInformation(HANDLE TokenHandle, 00113 TOKEN_INFORMATION_CLASS TokenInformationClass, 00114 LPVOID TokenInformation, 00115 DWORD TokenInformationLength) 00116 { 00117 NTSTATUS Status; 00118 00119 Status = NtSetInformationToken(TokenHandle, 00120 TokenInformationClass, 00121 TokenInformation, 00122 TokenInformationLength); 00123 if (!NT_SUCCESS(Status)) 00124 { 00125 SetLastError(RtlNtStatusToDosError(Status)); 00126 return FALSE; 00127 } 00128 00129 return TRUE; 00130 } 00131 00132 00133 /* 00134 * @implemented 00135 */ 00136 BOOL 00137 WINAPI 00138 AccessCheck(IN PSECURITY_DESCRIPTOR pSecurityDescriptor, 00139 IN HANDLE ClientToken, 00140 IN DWORD DesiredAccess, 00141 IN PGENERIC_MAPPING GenericMapping, 00142 OUT PPRIVILEGE_SET PrivilegeSet OPTIONAL, 00143 IN OUT LPDWORD PrivilegeSetLength, 00144 OUT LPDWORD GrantedAccess, 00145 OUT LPBOOL AccessStatus) 00146 { 00147 NTSTATUS Status; 00148 NTSTATUS NtAccessStatus; 00149 00150 /* Do the access check */ 00151 Status = NtAccessCheck(pSecurityDescriptor, 00152 ClientToken, 00153 DesiredAccess, 00154 GenericMapping, 00155 PrivilegeSet, 00156 (PULONG)PrivilegeSetLength, 00157 (PACCESS_MASK)GrantedAccess, 00158 &NtAccessStatus); 00159 00160 /* See if the access check operation succeeded */ 00161 if (!NT_SUCCESS(Status)) 00162 { 00163 /* Check failed */ 00164 SetLastError(RtlNtStatusToDosError(Status)); 00165 return FALSE; 00166 } 00167 00168 /* Now check the access status */ 00169 if (!NT_SUCCESS(NtAccessStatus)) 00170 { 00171 /* Access denied */ 00172 SetLastError(RtlNtStatusToDosError(NtAccessStatus)); 00173 *AccessStatus = FALSE; 00174 } 00175 else 00176 { 00177 /* Access granted */ 00178 *AccessStatus = TRUE; 00179 } 00180 00181 /* Check succeeded */ 00182 return TRUE; 00183 } 00184 00185 /* 00186 * @unimplemented 00187 */ 00188 BOOL WINAPI AccessCheckByType( 00189 PSECURITY_DESCRIPTOR pSecurityDescriptor, 00190 PSID PrincipalSelfSid, 00191 HANDLE ClientToken, 00192 DWORD DesiredAccess, 00193 POBJECT_TYPE_LIST ObjectTypeList, 00194 DWORD ObjectTypeListLength, 00195 PGENERIC_MAPPING GenericMapping, 00196 PPRIVILEGE_SET PrivilegeSet, 00197 LPDWORD PrivilegeSetLength, 00198 LPDWORD GrantedAccess, 00199 LPBOOL AccessStatus) 00200 { 00201 FIXME("stub\n"); 00202 00203 *AccessStatus = TRUE; 00204 00205 return !*AccessStatus; 00206 } 00207 00208 /* 00209 * @implemented 00210 */ 00211 BOOL WINAPI 00212 OpenProcessToken(HANDLE ProcessHandle, 00213 DWORD DesiredAccess, 00214 PHANDLE TokenHandle) 00215 { 00216 NTSTATUS Status; 00217 00218 Status = NtOpenProcessToken(ProcessHandle, 00219 DesiredAccess, 00220 TokenHandle); 00221 if (!NT_SUCCESS(Status)) 00222 { 00223 SetLastError(RtlNtStatusToDosError(Status)); 00224 return FALSE; 00225 } 00226 00227 return TRUE; 00228 } 00229 00230 00231 /* 00232 * @implemented 00233 */ 00234 BOOL WINAPI 00235 OpenThreadToken(HANDLE ThreadHandle, 00236 DWORD DesiredAccess, 00237 BOOL OpenAsSelf, 00238 PHANDLE TokenHandle) 00239 { 00240 NTSTATUS Status; 00241 00242 Status = NtOpenThreadToken(ThreadHandle, 00243 DesiredAccess, 00244 OpenAsSelf, 00245 TokenHandle); 00246 if (!NT_SUCCESS(Status)) 00247 { 00248 SetLastError(RtlNtStatusToDosError(Status)); 00249 return FALSE; 00250 } 00251 00252 return TRUE; 00253 } 00254 00255 00256 /* 00257 * @implemented 00258 */ 00259 BOOL WINAPI 00260 SetThreadToken(IN PHANDLE ThreadHandle OPTIONAL, 00261 IN HANDLE TokenHandle) 00262 { 00263 NTSTATUS Status; 00264 HANDLE hThread; 00265 00266 hThread = (ThreadHandle != NULL) ? *ThreadHandle : NtCurrentThread(); 00267 00268 Status = NtSetInformationThread(hThread, 00269 ThreadImpersonationToken, 00270 &TokenHandle, 00271 sizeof(HANDLE)); 00272 if (!NT_SUCCESS(Status)) 00273 { 00274 SetLastError(RtlNtStatusToDosError(Status)); 00275 return FALSE; 00276 } 00277 00278 return TRUE; 00279 } 00280 00281 00282 /* 00283 * @implemented 00284 */ 00285 BOOL WINAPI 00286 DuplicateTokenEx(IN HANDLE ExistingTokenHandle, 00287 IN DWORD dwDesiredAccess, 00288 IN LPSECURITY_ATTRIBUTES lpTokenAttributes OPTIONAL, 00289 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, 00290 IN TOKEN_TYPE TokenType, 00291 OUT PHANDLE DuplicateTokenHandle) 00292 { 00293 OBJECT_ATTRIBUTES ObjectAttributes; 00294 NTSTATUS Status; 00295 SECURITY_QUALITY_OF_SERVICE Sqos; 00296 00297 Sqos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); 00298 Sqos.ImpersonationLevel = ImpersonationLevel; 00299 Sqos.ContextTrackingMode = 0; 00300 Sqos.EffectiveOnly = FALSE; 00301 00302 if (lpTokenAttributes != NULL) 00303 { 00304 InitializeObjectAttributes(&ObjectAttributes, 00305 NULL, 00306 lpTokenAttributes->bInheritHandle ? OBJ_INHERIT : 0, 00307 NULL, 00308 lpTokenAttributes->lpSecurityDescriptor); 00309 } 00310 else 00311 { 00312 InitializeObjectAttributes(&ObjectAttributes, 00313 NULL, 00314 0, 00315 NULL, 00316 NULL); 00317 } 00318 00319 ObjectAttributes.SecurityQualityOfService = &Sqos; 00320 00321 Status = NtDuplicateToken(ExistingTokenHandle, 00322 dwDesiredAccess, 00323 &ObjectAttributes, 00324 FALSE, 00325 TokenType, 00326 DuplicateTokenHandle); 00327 if (!NT_SUCCESS(Status)) 00328 { 00329 SetLastError(RtlNtStatusToDosError(Status)); 00330 return FALSE; 00331 } 00332 00333 return TRUE; 00334 } 00335 00336 00337 /* 00338 * @implemented 00339 */ 00340 BOOL WINAPI 00341 DuplicateToken(IN HANDLE ExistingTokenHandle, 00342 IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, 00343 OUT PHANDLE DuplicateTokenHandle) 00344 { 00345 return DuplicateTokenEx(ExistingTokenHandle, 00346 TOKEN_IMPERSONATE | TOKEN_QUERY, 00347 NULL, 00348 ImpersonationLevel, 00349 TokenImpersonation, 00350 DuplicateTokenHandle); 00351 } 00352 00353 00354 /* 00355 * @implemented 00356 */ 00357 BOOL WINAPI 00358 CheckTokenMembership(IN HANDLE ExistingTokenHandle, 00359 IN PSID SidToCheck, 00360 OUT PBOOL IsMember) 00361 { 00362 PISECURITY_DESCRIPTOR SecurityDescriptor = NULL; 00363 ACCESS_MASK GrantedAccess; 00364 struct 00365 { 00366 PRIVILEGE_SET PrivilegeSet; 00367 LUID_AND_ATTRIBUTES Privileges[4]; 00368 } PrivBuffer; 00369 ULONG PrivBufferSize = sizeof(PrivBuffer); 00370 GENERIC_MAPPING GenericMapping = 00371 { 00372 STANDARD_RIGHTS_READ, 00373 STANDARD_RIGHTS_WRITE, 00374 STANDARD_RIGHTS_EXECUTE, 00375 STANDARD_RIGHTS_ALL 00376 }; 00377 PACL Dacl; 00378 ULONG SidLen; 00379 HANDLE hToken = NULL; 00380 NTSTATUS Status, AccessStatus; 00381 00382 /* doesn't return gracefully if IsMember is NULL! */ 00383 *IsMember = FALSE; 00384 00385 SidLen = RtlLengthSid(SidToCheck); 00386 00387 if (ExistingTokenHandle == NULL) 00388 { 00389 Status = NtOpenThreadToken(NtCurrentThread(), 00390 TOKEN_QUERY, 00391 FALSE, 00392 &hToken); 00393 00394 if (Status == STATUS_NO_TOKEN) 00395 { 00396 /* we're not impersonating, open the primary token */ 00397 Status = NtOpenProcessToken(NtCurrentProcess(), 00398 TOKEN_QUERY | TOKEN_DUPLICATE, 00399 &hToken); 00400 if (NT_SUCCESS(Status)) 00401 { 00402 HANDLE hNewToken = FALSE; 00403 BOOL DupRet; 00404 00405 /* duplicate the primary token to create an impersonation token */ 00406 DupRet = DuplicateTokenEx(hToken, 00407 TOKEN_QUERY | TOKEN_IMPERSONATE, 00408 NULL, 00409 SecurityImpersonation, 00410 TokenImpersonation, 00411 &hNewToken); 00412 00413 NtClose(hToken); 00414 00415 if (!DupRet) 00416 { 00417 WARN("Failed to duplicate the primary token!\n"); 00418 return FALSE; 00419 } 00420 00421 hToken = hNewToken; 00422 } 00423 } 00424 00425 if (!NT_SUCCESS(Status)) 00426 { 00427 goto Cleanup; 00428 } 00429 } 00430 else 00431 { 00432 hToken = ExistingTokenHandle; 00433 } 00434 00435 /* create a security descriptor */ 00436 SecurityDescriptor = RtlAllocateHeap(RtlGetProcessHeap(), 00437 0, 00438 sizeof(SECURITY_DESCRIPTOR) + 00439 sizeof(ACL) + SidLen + 00440 sizeof(ACCESS_ALLOWED_ACE)); 00441 if (SecurityDescriptor == NULL) 00442 { 00443 Status = STATUS_INSUFFICIENT_RESOURCES; 00444 goto Cleanup; 00445 } 00446 00447 Status = RtlCreateSecurityDescriptor(SecurityDescriptor, 00448 SECURITY_DESCRIPTOR_REVISION); 00449 if (!NT_SUCCESS(Status)) 00450 { 00451 goto Cleanup; 00452 } 00453 00454 /* set the owner and group */ 00455 Status = RtlSetOwnerSecurityDescriptor(SecurityDescriptor, 00456 SidToCheck, 00457 FALSE); 00458 if (!NT_SUCCESS(Status)) 00459 { 00460 goto Cleanup; 00461 } 00462 00463 Status = RtlSetGroupSecurityDescriptor(SecurityDescriptor, 00464 SidToCheck, 00465 FALSE); 00466 if (!NT_SUCCESS(Status)) 00467 { 00468 goto Cleanup; 00469 } 00470 00471 /* create the DACL */ 00472 Dacl = (PACL)(SecurityDescriptor + 1); 00473 Status = RtlCreateAcl(Dacl, 00474 sizeof(ACL) + SidLen + sizeof(ACCESS_ALLOWED_ACE), 00475 ACL_REVISION); 00476 if (!NT_SUCCESS(Status)) 00477 { 00478 goto Cleanup; 00479 } 00480 00481 Status = RtlAddAccessAllowedAce(Dacl, 00482 ACL_REVISION, 00483 0x1, 00484 SidToCheck); 00485 if (!NT_SUCCESS(Status)) 00486 { 00487 goto Cleanup; 00488 } 00489 00490 /* assign the DACL to the security descriptor */ 00491 Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor, 00492 TRUE, 00493 Dacl, 00494 FALSE); 00495 if (!NT_SUCCESS(Status)) 00496 { 00497 goto Cleanup; 00498 } 00499 00500 /* it's time to perform the access check. Just use _some_ desired access right 00501 (same as for the ACE) and see if we're getting it granted. This indicates 00502 our SID is a member of the token. We however can't use a generic access 00503 right as those aren't mapped and return an error (STATUS_GENERIC_NOT_MAPPED). */ 00504 Status = NtAccessCheck(SecurityDescriptor, 00505 hToken, 00506 0x1, 00507 &GenericMapping, 00508 &PrivBuffer.PrivilegeSet, 00509 &PrivBufferSize, 00510 &GrantedAccess, 00511 &AccessStatus); 00512 if (NT_SUCCESS(Status) && NT_SUCCESS(AccessStatus) && (GrantedAccess == 0x1)) 00513 { 00514 *IsMember = TRUE; 00515 } 00516 00517 Cleanup: 00518 if (hToken != NULL && hToken != ExistingTokenHandle) 00519 { 00520 NtClose(hToken); 00521 } 00522 00523 if (SecurityDescriptor != NULL) 00524 { 00525 RtlFreeHeap(RtlGetProcessHeap(), 00526 0, 00527 SecurityDescriptor); 00528 } 00529 00530 if (!NT_SUCCESS(Status)) 00531 { 00532 SetLastError(RtlNtStatusToDosError(Status)); 00533 return FALSE; 00534 } 00535 00536 return TRUE; 00537 } 00538 00539 00540 /* 00541 * @implemented 00542 */ 00543 BOOL WINAPI 00544 IsTokenRestricted(HANDLE TokenHandle) 00545 { 00546 ULONG RetLength; 00547 PTOKEN_GROUPS lpGroups; 00548 NTSTATUS Status; 00549 BOOL Ret = FALSE; 00550 00551 /* determine the required buffer size and allocate enough memory to read the 00552 list of restricted SIDs */ 00553 Status = NtQueryInformationToken(TokenHandle, 00554 TokenRestrictedSids, 00555 NULL, 00556 0, 00557 &RetLength); 00558 if (Status != STATUS_BUFFER_TOO_SMALL) 00559 { 00560 SetLastError(RtlNtStatusToDosError(Status)); 00561 return FALSE; 00562 } 00563 00564 AllocAndReadRestrictedSids: 00565 lpGroups = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(), 00566 0, 00567 RetLength); 00568 if (lpGroups == NULL) 00569 { 00570 SetLastError(ERROR_OUTOFMEMORY); 00571 return FALSE; 00572 } 00573 00574 /* actually read the list of the restricted SIDs */ 00575 Status = NtQueryInformationToken(TokenHandle, 00576 TokenRestrictedSids, 00577 lpGroups, 00578 RetLength, 00579 &RetLength); 00580 if (NT_SUCCESS(Status)) 00581 { 00582 Ret = (lpGroups->GroupCount != 0); 00583 } 00584 else if (Status == STATUS_BUFFER_TOO_SMALL) 00585 { 00586 /* looks like the token was modified in the meanwhile, let's just try again */ 00587 HeapFree(GetProcessHeap(), 00588 0, 00589 lpGroups); 00590 00591 goto AllocAndReadRestrictedSids; 00592 } 00593 else 00594 { 00595 SetLastError(RtlNtStatusToDosError(Status)); 00596 } 00597 00598 /* free allocated memory */ 00599 HeapFree(GetProcessHeap(), 00600 0, 00601 lpGroups); 00602 00603 return Ret; 00604 } 00605 00606 00607 BOOL WINAPI 00608 CreateRestrictedToken(HANDLE TokenHandle, 00609 DWORD Flags, 00610 DWORD DisableSidCount, 00611 PSID_AND_ATTRIBUTES pSidAndAttributes, 00612 DWORD DeletePrivilegeCount, 00613 PLUID_AND_ATTRIBUTES pLUIDAndAttributes, 00614 DWORD RestrictedSidCount, 00615 PSID_AND_ATTRIBUTES pSIDAndAttributes, 00616 PHANDLE NewTokenHandle) 00617 { 00618 UNIMPLEMENTED; 00619 return FALSE; 00620 } 00621 00622 00623 /* 00624 * @unimplemented 00625 */ 00626 PSID 00627 WINAPI 00628 GetSiteSidFromToken(IN HANDLE TokenHandle) 00629 { 00630 PTOKEN_GROUPS RestrictedSids; 00631 ULONG RetLen; 00632 UINT i; 00633 NTSTATUS Status; 00634 PSID PSiteSid = NULL; 00635 SID_IDENTIFIER_AUTHORITY InternetSiteAuthority = {SECURITY_INTERNETSITE_AUTHORITY}; 00636 00637 Status = NtQueryInformationToken(TokenHandle, 00638 TokenRestrictedSids, 00639 NULL, 00640 0, 00641 &RetLen); 00642 if (Status != STATUS_BUFFER_TOO_SMALL) 00643 { 00644 SetLastError(RtlNtStatusToDosError(Status)); 00645 return NULL; 00646 } 00647 00648 RestrictedSids = (PTOKEN_GROUPS)RtlAllocateHeap(RtlGetProcessHeap(), 00649 0, 00650 RetLen); 00651 if (RestrictedSids == NULL) 00652 { 00653 SetLastError(ERROR_OUTOFMEMORY); 00654 return NULL; 00655 } 00656 00657 Status = NtQueryInformationToken(TokenHandle, 00658 TokenRestrictedSids, 00659 RestrictedSids, 00660 RetLen, 00661 &RetLen); 00662 if (NT_SUCCESS(Status)) 00663 { 00664 for (i = 0; i < RestrictedSids->GroupCount; i++) 00665 { 00666 SID* RSSid = RestrictedSids->Groups[i].Sid; 00667 00668 if (RtlCompareMemory(&(RSSid->IdentifierAuthority), 00669 &InternetSiteAuthority, 00670 sizeof(SID_IDENTIFIER_AUTHORITY)) == 00671 sizeof(SID_IDENTIFIER_AUTHORITY)) 00672 { 00673 PSiteSid = RtlAllocateHeap(RtlGetProcessHeap(), 00674 0, 00675 RtlLengthSid((RestrictedSids-> 00676 Groups[i]).Sid)); 00677 if (PSiteSid == NULL) 00678 { 00679 SetLastError(ERROR_OUTOFMEMORY); 00680 } 00681 else 00682 { 00683 RtlCopySid(RtlLengthSid(RestrictedSids->Groups[i].Sid), 00684 PSiteSid, 00685 RestrictedSids->Groups[i].Sid); 00686 } 00687 00688 break; 00689 } 00690 } 00691 } 00692 else 00693 { 00694 SetLastError(RtlNtStatusToDosError(Status)); 00695 } 00696 00697 RtlFreeHeap(RtlGetProcessHeap(), 0, RestrictedSids); 00698 return PSiteSid; 00699 } 00700 00701 00702 BOOL 00703 WINAPI 00704 CreateProcessWithTokenW(IN HANDLE hToken, 00705 IN DWORD dwLogonFlags, 00706 IN LPCWSTR lpApplicationName OPTIONAL, 00707 IN OUT LPWSTR lpCommandLine OPTIONAL, 00708 IN DWORD dwCreationFlags, 00709 IN LPVOID lpEnvironment OPTIONAL, 00710 IN LPCWSTR lpCurrentDirectory OPTIONAL, 00711 IN LPSTARTUPINFOW lpStartupInfo, 00712 OUT LPPROCESS_INFORMATION lpProcessInfo) 00713 { 00714 UNIMPLEMENTED; 00715 return FALSE; 00716 } Generated on Sat May 26 2012 04:21:14 for ReactOS by
1.7.6.1
|