Zebediah Figura : kernelbase: Implement CreateRestrictedToken().

Alexandre Julliard julliard at winehq.org
Wed Sep 23 15:47:14 CDT 2020


Module: wine
Branch: master
Commit: 6946d78ed9e88536951357ae5574e251f0007006
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=6946d78ed9e88536951357ae5574e251f0007006

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Tue Sep 22 17:31:16 2020 -0500

kernelbase: Implement CreateRestrictedToken().

Based on a patch by Michael Müller.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/advapi32/tests/security.c | 26 ++++++++++-----------
 dlls/kernelbase/security.c     | 51 +++++++++++++++++++++++++++++-------------
 2 files changed, 48 insertions(+), 29 deletions(-)

diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index 957ebc3036..6919ea64ce 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -5237,7 +5237,7 @@ static void test_CreateRestrictedToken(void)
     is_member = TRUE;
     ret = pCheckTokenMembership(r_token, removed_sid, &is_member);
     ok(ret, "got error %d\n", GetLastError());
-    todo_wine ok(!is_member, "not a member\n");
+    ok(!is_member, "not a member\n");
 
     ret = GetTokenInformation(r_token, TokenGroups, NULL, 0, &size);
     ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d with error %d\n",
@@ -5251,8 +5251,8 @@ static void test_CreateRestrictedToken(void)
         if (EqualSid(groups2->Groups[i].Sid, removed_sid))
         {
             DWORD attr = groups2->Groups[i].Attributes;
-            todo_wine ok(attr & SE_GROUP_USE_FOR_DENY_ONLY, "got wrong attributes %#x\n", attr);
-            todo_wine ok(!(attr & SE_GROUP_ENABLED), "got wrong attributes %#x\n", attr);
+            ok(attr & SE_GROUP_USE_FOR_DENY_ONLY, "got wrong attributes %#x\n", attr);
+            ok(!(attr & SE_GROUP_ENABLED), "got wrong attributes %#x\n", attr);
             break;
         }
     }
@@ -5307,7 +5307,7 @@ static void test_CreateRestrictedToken(void)
     priv_set.Privilege[0].Attributes = 0;
     ret = PrivilegeCheck(r_token, &priv_set, &is_member);
     ok(ret, "got error %u\n", GetLastError());
-    todo_wine ok(!is_member, "privilege should not be enabled\n");
+    ok(!is_member, "privilege should not be enabled\n");
 
     ret = GetTokenInformation(r_token, TokenPrivileges, privs, sizeof(privs_buffer), &size);
     ok(ret, "got error %u\n", GetLastError());
@@ -5318,7 +5318,7 @@ static void test_CreateRestrictedToken(void)
         if (!memcmp(&privs->Privileges[i].Luid, &luid, sizeof(luid)))
             is_member = TRUE;
     }
-    todo_wine ok(!is_member, "disabled privilege should not be present\n");
+    ok(!is_member, "disabled privilege should not be present\n");
 
     CloseHandle(r_token);
 
@@ -7679,8 +7679,8 @@ static void test_duplicate_handle_access(void)
 
     SetLastError(0xdeadbeef);
     event2 = OpenEventA(EVENT_MODIFY_STATE, FALSE, "test_dup");
-    todo_wine ok(!event2, "expected failure\n");
-    todo_wine ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %u\n", GetLastError());
+    ok(!event2, "expected failure\n");
+    ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %u\n", GetLastError());
 
     ret = DuplicateHandle(GetCurrentProcess(), all_event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0);
     ok(ret, "got error %u\n", GetLastError());
@@ -7688,8 +7688,8 @@ static void test_duplicate_handle_access(void)
 
     SetLastError(0xdeadbeef);
     ret = DuplicateHandle(GetCurrentProcess(), sync_event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0);
-    todo_wine ok(!ret, "expected failure\n");
-    todo_wine ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %u\n", GetLastError());
+    ok(!ret, "expected failure\n");
+    ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %u\n", GetLastError());
 
     ret = RevertToSelf();
     ok(ret, "got error %u\n", GetLastError());
@@ -7751,13 +7751,13 @@ static void test_duplicate_handle_access_child(void)
 
     SetLastError(0xdeadbeef);
     ret = DuplicateHandle(process, event, process, &event2, EVENT_MODIFY_STATE, FALSE, 0);
-    todo_wine ok(!ret, "expected failure\n");
-    todo_wine ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %u\n", GetLastError());
+    ok(!ret, "expected failure\n");
+    ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %u\n", GetLastError());
 
     SetLastError(0xdeadbeef);
     ret = DuplicateHandle(process, event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0);
-    todo_wine ok(!ret, "expected failure\n");
-    todo_wine ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %u\n", GetLastError());
+    ok(!ret, "expected failure\n");
+    ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %u\n", GetLastError());
 
     ret = RevertToSelf();
     ok(ret, "failed to revert, error %u\n", GetLastError());
diff --git a/dlls/kernelbase/security.c b/dlls/kernelbase/security.c
index 72bb5892d3..97943048b0 100644
--- a/dlls/kernelbase/security.c
+++ b/dlls/kernelbase/security.c
@@ -646,27 +646,46 @@ exit:
  * 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 )
+                                   DWORD disable_sid_count, SID_AND_ATTRIBUTES *disable_sids,
+                                   DWORD delete_priv_count, LUID_AND_ATTRIBUTES *delete_privs,
+                                   DWORD restrict_sid_count, SID_AND_ATTRIBUTES *restrict_sids, HANDLE *ret )
 {
-    TOKEN_TYPE type;
-    SECURITY_IMPERSONATION_LEVEL level = SecurityAnonymous;
-    DWORD size;
+    TOKEN_PRIVILEGES *nt_privs = NULL;
+    TOKEN_GROUPS *nt_disable_sids = NULL, *nt_restrict_sids = NULL;
+    NTSTATUS status = STATUS_NO_MEMORY;
 
-    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("token %p, flags %#x, disable_sids %u %p, delete_privs %u %p, restrict_sids %u %p, ret %p\n",
+            token, flags, disable_sid_count, disable_sids, delete_priv_count, delete_privs,
+            restrict_sid_count, restrict_sids, ret);
 
-    size = sizeof(type);
-    if (!GetTokenInformation( token, TokenType, &type, size, &size )) return FALSE;
-    if (type == TokenImpersonation)
+    if (disable_sid_count)
     {
-        size = sizeof(level);
-        if (!GetTokenInformation( token, TokenImpersonationLevel, &level, size, &size ))
-            return FALSE;
+        if (!(nt_disable_sids = heap_alloc( offsetof( TOKEN_GROUPS, Groups[disable_sid_count] ) ))) goto out;
+        nt_disable_sids->GroupCount = disable_sid_count;
+        memcpy( nt_disable_sids->Groups, disable_sids, disable_sid_count * sizeof(SID_AND_ATTRIBUTES) );
+    }
+
+    if (delete_priv_count)
+    {
+        if (!(nt_privs = heap_alloc( offsetof( TOKEN_GROUPS, Groups[delete_priv_count] ) ))) goto out;
+        nt_privs->PrivilegeCount = delete_priv_count;
+        memcpy( nt_privs->Privileges, delete_privs, delete_priv_count * sizeof(SID_AND_ATTRIBUTES) );
     }
-    return DuplicateTokenEx( token, MAXIMUM_ALLOWED, NULL, level, type, ret );
+
+    if (restrict_sid_count)
+    {
+        if (!(nt_restrict_sids = heap_alloc( offsetof( TOKEN_GROUPS, Groups[restrict_sid_count] ) ))) goto out;
+        nt_restrict_sids->GroupCount = restrict_sid_count;
+        memcpy( nt_restrict_sids->Groups, restrict_sids, restrict_sid_count * sizeof(SID_AND_ATTRIBUTES) );
+    }
+
+    status = NtFilterToken(token, flags, nt_disable_sids, nt_privs, nt_restrict_sids, ret);
+
+out:
+    heap_free(nt_disable_sids);
+    heap_free(nt_privs);
+    heap_free(nt_restrict_sids);
+    return set_ntstatus( status );
 }
 
 /******************************************************************************




More information about the wine-cvs mailing list