From 3c1f5962482e7acf531f57f49d923d9c4e5278b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Fri, 4 Aug 2017 02:51:57 +0200 Subject: [PATCH] advapi32: Implement CreateRestrictedToken. --- dlls/kernelbase/security.c | 103 ++++++++++++++++++++++++++++++------- 1 file changed, 84 insertions(+), 19 deletions(-) diff --git a/dlls/kernelbase/security.c b/dlls/kernelbase/security.c index 2e75e81ed77..97f6ee6a2fd 100644 --- a/dlls/kernelbase/security.c +++ b/dlls/kernelbase/security.c @@ -592,31 +592,96 @@ exit: return ret; } +static BOOL allocate_groups(TOKEN_GROUPS **groups_ret, SID_AND_ATTRIBUTES *sids, DWORD count) +{ + TOKEN_GROUPS *groups; + DWORD i; + + if (!count) + { + *groups_ret = NULL; + return TRUE; + } + + groups = (TOKEN_GROUPS *)heap_alloc(FIELD_OFFSET(TOKEN_GROUPS, Groups) + + count * sizeof(SID_AND_ATTRIBUTES)); + if (!groups) + { + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + + groups->GroupCount = count; + for (i = 0; i < count; i++) + groups->Groups[i] = sids[i]; + + *groups_ret = groups; + return TRUE; +} + +static BOOL allocate_privileges(TOKEN_PRIVILEGES **privileges_ret, LUID_AND_ATTRIBUTES *privs, DWORD count) +{ + TOKEN_PRIVILEGES *privileges; + DWORD i; + + if (!count) + { + *privileges_ret = NULL; + return TRUE; + } + + privileges = (TOKEN_PRIVILEGES *)heap_alloc(FIELD_OFFSET(TOKEN_PRIVILEGES, Privileges) + + count * sizeof(LUID_AND_ATTRIBUTES)); + if (!privileges) + { + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + + privileges->PrivilegeCount = count; + for (i = 0; i < count; i++) + privileges->Privileges[i] = privs[i]; + + *privileges_ret = privileges; + return TRUE; +} + /************************************************************************* * CreateRestrictedToken (kernelbase.@) */ -BOOL WINAPI CreateRestrictedToken( HANDLE token, DWORD flags, - DWORD disable_count, PSID_AND_ATTRIBUTES disable_sids, - DWORD delete_count, PLUID_AND_ATTRIBUTES delete_privs, - DWORD restrict_count, PSID_AND_ATTRIBUTES restrict_sids, PHANDLE ret ) +BOOL WINAPI CreateRestrictedToken( HANDLE baseToken, DWORD flags, + DWORD nDisableSids, PSID_AND_ATTRIBUTES disableSids, + DWORD nDeletePrivs, PLUID_AND_ATTRIBUTES deletePrivs, + DWORD nRestrictSids, PSID_AND_ATTRIBUTES restrictSids, PHANDLE newToken ) { - TOKEN_TYPE type; - SECURITY_IMPERSONATION_LEVEL level = SecurityAnonymous; - DWORD size; + TOKEN_PRIVILEGES *delete_privs = NULL; + TOKEN_GROUPS *disable_groups = NULL; + TOKEN_GROUPS *restrict_sids = NULL; + BOOL ret = FALSE; - FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n", - token, flags, disable_count, disable_sids, delete_count, delete_privs, - restrict_count, restrict_sids, ret ); + TRACE("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p)\n", + baseToken, flags, nDisableSids, disableSids, + nDeletePrivs, deletePrivs, + nRestrictSids, restrictSids, + newToken); + + if (!allocate_groups(&disable_groups, disableSids, nDisableSids)) + goto done; + + if (!allocate_privileges(&delete_privs, deletePrivs, nDeletePrivs)) + goto done; + + if (!allocate_groups(&restrict_sids, restrictSids, nRestrictSids)) + goto done; + + ret = set_ntstatus(NtFilterToken(baseToken, flags, disable_groups, delete_privs, restrict_sids, newToken)); + +done: + heap_free(disable_groups); + heap_free(delete_privs); + heap_free(restrict_sids); + return ret; - size = sizeof(type); - if (!GetTokenInformation( token, TokenType, &type, size, &size )) return FALSE; - if (type == TokenImpersonation) - { - size = sizeof(level); - if (!GetTokenInformation( token, TokenImpersonationLevel, &level, size, &size )) - return FALSE; - } - return DuplicateTokenEx( token, MAXIMUM_ALLOWED, NULL, level, type, ret ); } /****************************************************************************** -- 2.20.1