[NTOS:SE] HACK: Temporarily add the Local group SID to the system token Temporarily add the local group to the system token so that Virtualbox GA services can properly set up network drives for shared folders. What happens is that a security descriptor has a DACL with only one ACE that grants access to Local SID (presumably coming from Vbox?) but the client token is that of the service which is a SYSTEM token. Perhaps we are not impersonating the right user or whatever else. This is only a temporary placebo, until a proper solution is found. CORE-18250
[NTOS:SE] HACK: Temporarily grant access to the client if empty generic mapping was passed Certain apps such as AIM installer passes an empty generic mapping (this can be understood with their generic masks set to 0) and our code tries to map the access right from an ACE with the mapping provided by AccessCheck. This can lead to a bug where we would not be able to decode the generic right from an ACE as we need a proper generic mapping in order to do so. A mask right that is not decoded it cannot be used to mask out the remaining rights, further resulting into a denied access right. What Windows does instead is they are mapping the ACE's rights in another place, presumably when setting security data to an object, and they are using the generic mapping passed by the kernel. What we can do for the time being is to temporarily grant access to the client, but only if they are an administrator. CORE-18576
[NTOS:SE] Cast the ACE to known ACE type variants on SepGetSidFromAce ACCESS_DENIED_ACE_TYPE, ACCESS_ALLOWED_ACE_TYPE, SYSTEM_AUDIT_ACE_TYPE and SYSTEM_ALARM_ACE_TYPE belong to the same commonly internal ACE type, aka KNOWN_ACE, as each of these ACEs have the same structure field offsets. The only difference are ACCESS_DENIED_OBJECT_ACE_TYPE and ACCESS_ALLOWED_OBJECT_ACE_TYPE as they have their own internal ACE type variant, the KNOWN_OBJECT_ACE structure. The general guideline is that public ACE structure variants have to be used elsehwere such as in UM whilst the kernel has to use the internal known ACE type variants when possible.
[NTOS:SE] Implement access security checks by type - Implement SepDenyAccessObjectTypeResultList, SepAllowAccessObjectTypeResultList, SepDenyAccessObjectTypeList and SepAllowAccessObjectTypeList. These routines will be used to grant or deny access to sub-objects of an object in the list. - Refactor SepAnalyzeAcesFromDacl and SepAccessCheck to accomodate the newly implemented access check by type mechanism. - SepAccessCheck will now be SepAccessCheckWorker, a worker helper function that further abstracts the access check mechanism in the kernel. Whereas the SepAccessCheck name will be used as a centralized function used by the access check NT system calls. - Deprecate SepGetSDOwner and SepGetSDGroup in favor of SepGetOwnerFromDescriptor and SepGetGroupFromDescriptor. The former functions were buggy as they might potentially return garbage data if either the owner or group were passed as NULL to a security descriptor, hence a second chance exception fault. This was caught when writing tests for NtAccessCheckByType. - Shorten the debug prints by removing the name of the functions, the person who reads the debugger output has to look at the source code anyway.
[NTOS:SE] Declare function prototypes & add OBJECT_TYPE_LIST_INTERNAL OBJECT_TYPE_LIST_INTERNAL will serve as an internal kernel data structure to hold validated object type contents that are copied from UM. The difference between the public and the internal one is that the internal structure has an additional member for access check rights that have been granted on each object element in the list.
[NTOS:SE] Refactor SeTokenCanImpersonate - Refactor most of the code, since there's quite some stuff that don't make much sense. For instance ImpersonationLevel is basically the requested impersonation level a server asks for. PsImpersonateClient doesn't explicitly say that SecurityAnonymous and SecurityIdentification are not allowed. If the server was to give such levels it simply means it doesn't want to impersonate the client. Another thing that doesn't make much sense is that we check if the client is associated with an anonymous token, then avoid impersonating regular anonymous tokens that weren't created by the system. Only system can create such tokens and an anonymous token basically means a token with hidden security info. - Check that the server is within the same client logon session. - If the server is granted the SeImpersonatePrivilege privilege, allow impersonation regardless of the conditions we want to check for. - Update the documentation and code comments.
[NTOS:SE] Grant the SYSTEM process the missing privileges - Add the missing privileges to the SYSTEM privileges which might be needed, notably SeUndockPrivilege, SeManageVolumePrivilege, SeCreateGlobalPrivilege and SeImpersonatePrivilege. Specifically SeImpersonatePrivilege is important here because with it we allow system components of the core OS to perform certain system tasks. - Declare the Groups array with a maximum of 3 elements in SepCreateSystemProcessToken and 1 element in SepCreateSystemAnonymousLogonToken respectively, because previously this array was oversized with most of free space left as a waste. - Avoid hardcoding the size value of the Privilege array, instead initialize it by hand and compute the exact number of elements with RTL_NUMBER_OF.
[NTOS:SE] Refactor NtOpenThreadTokenEx - Wrap most of the code into a new private routine, SepOpenThreadToken. And properly fail gracefully if we fail to open a thread's token instead of just keeping going. - Do not use the same thread object that we have referenced in NtOpenThreadTokenEx to do a copy of the access token in case we can't open it directly. Instead we must reference a new object with full access, solely used for the purpose to do our required operations. - Add debug prints CORE-18986
[NTOS:SE] Make an access token effective after the end of token duplication Removing any disabled privileges or groups in the middle of token dynamic part allocation can pose problems. During the operation of making an access token as effective, we are toying with the privileges and groups arrays of the token. After that we are allocating the dynamic part and set EndMem (the end tail of the memory part) to that dynamic part, previously it was set to the variable part. As a matter of fact we are making the token effective in the middle where EndMem still points to VariablePart, thus DynamicPart will end up with memory pool blocks butchered in the pool list. Another problem, albeit not related to the DynamicPart corruption, is that the code starts iterating over the UserAndGroups array from 0, which is the actual user. One cannot simply remove the user from the array, so we have to start looping right from the groups. Move the token effective code part at the end of the SepDuplicateToken function, which fixes the random pool corruptions caused by the butchered DynamicPart. CORE-18986
[NTOS:SE][FORMATTING] Fix the file header This fixes the copyright file header at the top of the file, reflecting the Coding Style rules. No code changes!
[NTOS:SE] Do not allocate memory pool just for the access rights Access check is an expensive operation, that is, whenever an access to an object is performed an access check has to be done to ensure the access can be allowed to the calling thread who attempts to access such object. Currently SepAnalyzeAcesFromDacl allocates a block of pool memory for access check rights, nagging the Memory Manager like a desperate naughty creep. So instead initialize the access rights as a simple variable in SepAccessCheck and pass it out as an address to SepAnalyzeAcesFromDacl so that the function will fill it up with access rights. This helps with performance, avoiding wasting a few bits of memory just to hold these access rights. In addition to that, add a few asserts and fix the copyright header on both se.h and accesschk.c, to reflect the Coding Style rules.
[NTOS:SE] Dump security debug info in case no every right has been granted in SepAccessCheck The "failed to grant access rights" message isn't enough to understand what kind of access rights haven't been granted and why. Dumping information of the captured security descriptor, the ACL and its ACEs with mask rights and token SIDs should be enough to understand the reason of the failure in question.
[NTOS:SE] Fix new dynamic length calculation in TokenPrimaryGroup case Not only primary group assignation was broken but new dynamic length calculation is also broken. The length of the captured SID is not taken into account so the new dynamic length gets only the size of the default ACL present in an access token. Therefore, the condition is always FALSE and the code never jumps to the STATUS_ALLOTTED_SPACE_EXCEEDED branch because the length will always be small than the charged dynamic length. Addendum to 86bde3c.