Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
133e0612
Commit
133e0612
authored
Feb 16, 2021
by
Zebediah Figura
Committed by
Alexandre Julliard
Feb 17, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
advapi32/tests: Add some tests for token elevation.
Signed-off-by:
Zebediah Figura
<
z.figura12@gmail.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
16955db2
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
263 additions
and
0 deletions
+263
-0
security.c
dlls/advapi32/tests/security.c
+263
-0
No files found.
dlls/advapi32/tests/security.c
View file @
133e0612
...
...
@@ -8019,6 +8019,268 @@ static void test_GetKernelObjectSecurity(void)
free
(
sd
);
}
static
void
check_different_token
(
HANDLE
token1
,
HANDLE
token2
)
{
TOKEN_STATISTICS
stats1
,
stats2
;
DWORD
size
;
BOOL
ret
;
ret
=
GetTokenInformation
(
token1
,
TokenStatistics
,
&
stats1
,
sizeof
(
stats1
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ret
=
GetTokenInformation
(
token2
,
TokenStatistics
,
&
stats2
,
sizeof
(
stats2
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ok
(
memcmp
(
&
stats1
.
TokenId
,
&
stats2
.
TokenId
,
sizeof
(
LUID
)),
"expected different IDs
\n
"
);
}
static
void
test_elevation
(
void
)
{
TOKEN_LINKED_TOKEN
linked
,
linked2
;
DWORD
orig_type
,
type
,
size
;
TOKEN_ELEVATION
elevation
;
HANDLE
token
,
token2
;
BOOL
ret
;
ret
=
OpenProcessToken
(
GetCurrentProcess
(),
TOKEN_QUERY
|
READ_CONTROL
|
TOKEN_DUPLICATE
|
TOKEN_ASSIGN_PRIMARY
|
TOKEN_ADJUST_PRIVILEGES
|
TOKEN_ADJUST_DEFAULT
,
&
token
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ret
=
GetTokenInformation
(
token
,
TokenElevationType
,
&
type
,
sizeof
(
type
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
orig_type
=
type
;
ret
=
GetTokenInformation
(
token
,
TokenElevation
,
&
elevation
,
sizeof
(
elevation
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ret
=
GetTokenInformation
(
token
,
TokenLinkedToken
,
&
linked
,
sizeof
(
linked
),
&
size
);
if
(
!
ret
&&
GetLastError
()
==
ERROR_NO_SUCH_LOGON_SESSION
)
/* fails on w2008s64 */
{
win_skip
(
"Failed to get linked token.
\n
"
);
CloseHandle
(
token
);
return
;
}
todo_wine
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
if
(
!
ret
)
return
;
if
(
type
==
TokenElevationTypeDefault
)
{
ok
(
elevation
.
TokenIsElevated
==
FALSE
,
"got elevation %#x
\n
"
,
elevation
.
TokenIsElevated
);
ok
(
!
linked
.
LinkedToken
,
"expected no linked token
\n
"
);
}
else
if
(
type
==
TokenElevationTypeLimited
)
{
ok
(
elevation
.
TokenIsElevated
==
FALSE
,
"got elevation %#x
\n
"
,
elevation
.
TokenIsElevated
);
ok
(
!!
linked
.
LinkedToken
,
"expected a linked token
\n
"
);
TEST_GRANTED_ACCESS
(
linked
.
LinkedToken
,
TOKEN_ALL_ACCESS
);
ret
=
GetTokenInformation
(
linked
.
LinkedToken
,
TokenElevationType
,
&
type
,
sizeof
(
type
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ok
(
type
==
TokenElevationTypeFull
,
"got type %#x
\n
"
,
type
);
ret
=
GetTokenInformation
(
linked
.
LinkedToken
,
TokenElevation
,
&
elevation
,
sizeof
(
elevation
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ok
(
elevation
.
TokenIsElevated
==
TRUE
,
"got elevation %#x
\n
"
,
elevation
.
TokenIsElevated
);
/* Asking for the linked token again gives us a different token. */
ret
=
GetTokenInformation
(
token
,
TokenLinkedToken
,
&
linked2
,
sizeof
(
linked2
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ret
=
GetTokenInformation
(
linked2
.
LinkedToken
,
TokenElevationType
,
&
type
,
sizeof
(
type
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ok
(
type
==
TokenElevationTypeFull
,
"got type %#x
\n
"
,
type
);
ret
=
GetTokenInformation
(
linked2
.
LinkedToken
,
TokenElevation
,
&
elevation
,
sizeof
(
elevation
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ok
(
elevation
.
TokenIsElevated
==
TRUE
,
"got elevation %#x
\n
"
,
elevation
.
TokenIsElevated
);
check_different_token
(
linked
.
LinkedToken
,
linked2
.
LinkedToken
);
CloseHandle
(
linked2
.
LinkedToken
);
/* Asking for the linked token's linked token gives us a new limited token. */
ret
=
GetTokenInformation
(
linked
.
LinkedToken
,
TokenLinkedToken
,
&
linked2
,
sizeof
(
linked2
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ret
=
GetTokenInformation
(
linked2
.
LinkedToken
,
TokenElevationType
,
&
type
,
sizeof
(
type
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ok
(
type
==
TokenElevationTypeLimited
,
"got type %#x
\n
"
,
type
);
ret
=
GetTokenInformation
(
linked2
.
LinkedToken
,
TokenElevation
,
&
elevation
,
sizeof
(
elevation
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ok
(
elevation
.
TokenIsElevated
==
FALSE
,
"got elevation %#x
\n
"
,
elevation
.
TokenIsElevated
);
check_different_token
(
token
,
linked2
.
LinkedToken
);
CloseHandle
(
linked2
.
LinkedToken
);
CloseHandle
(
linked
.
LinkedToken
);
type
=
TokenElevationTypeLimited
;
ret
=
SetTokenInformation
(
token
,
TokenElevationType
,
&
type
,
sizeof
(
type
));
ok
(
!
ret
,
"expected failure
\n
"
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"got error %u
\n
"
,
GetLastError
());
elevation
.
TokenIsElevated
=
FALSE
;
ret
=
SetTokenInformation
(
token
,
TokenElevation
,
&
elevation
,
sizeof
(
elevation
));
ok
(
!
ret
,
"expected failure
\n
"
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"got error %u
\n
"
,
GetLastError
());
}
else
{
ok
(
elevation
.
TokenIsElevated
==
TRUE
,
"got elevation %#x
\n
"
,
elevation
.
TokenIsElevated
);
ok
(
!!
linked
.
LinkedToken
,
"expected a linked token
\n
"
);
TEST_GRANTED_ACCESS
(
linked
.
LinkedToken
,
TOKEN_ALL_ACCESS
);
ret
=
GetTokenInformation
(
linked
.
LinkedToken
,
TokenElevationType
,
&
type
,
sizeof
(
type
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ok
(
type
==
TokenElevationTypeLimited
,
"got type %#x
\n
"
,
type
);
ret
=
GetTokenInformation
(
linked
.
LinkedToken
,
TokenElevation
,
&
elevation
,
sizeof
(
elevation
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ok
(
elevation
.
TokenIsElevated
==
FALSE
,
"got elevation %#x
\n
"
,
elevation
.
TokenIsElevated
);
/* Asking for the linked token again gives us a different token. */
ret
=
GetTokenInformation
(
token
,
TokenLinkedToken
,
&
linked2
,
sizeof
(
linked2
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ret
=
GetTokenInformation
(
linked2
.
LinkedToken
,
TokenElevationType
,
&
type
,
sizeof
(
type
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ok
(
type
==
TokenElevationTypeLimited
,
"got type %#x
\n
"
,
type
);
ret
=
GetTokenInformation
(
linked2
.
LinkedToken
,
TokenElevation
,
&
elevation
,
sizeof
(
elevation
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ok
(
elevation
.
TokenIsElevated
==
FALSE
,
"got elevation %#x
\n
"
,
elevation
.
TokenIsElevated
);
check_different_token
(
linked
.
LinkedToken
,
linked2
.
LinkedToken
);
CloseHandle
(
linked2
.
LinkedToken
);
/* Asking for the linked token's linked token gives us a new elevated token. */
ret
=
GetTokenInformation
(
linked
.
LinkedToken
,
TokenLinkedToken
,
&
linked2
,
sizeof
(
linked2
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ret
=
GetTokenInformation
(
linked2
.
LinkedToken
,
TokenElevationType
,
&
type
,
sizeof
(
type
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ok
(
type
==
TokenElevationTypeFull
,
"got type %#x
\n
"
,
type
);
ret
=
GetTokenInformation
(
linked2
.
LinkedToken
,
TokenElevation
,
&
elevation
,
sizeof
(
elevation
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ok
(
elevation
.
TokenIsElevated
==
TRUE
,
"got elevation %#x
\n
"
,
elevation
.
TokenIsElevated
);
check_different_token
(
token
,
linked2
.
LinkedToken
);
CloseHandle
(
linked2
.
LinkedToken
);
CloseHandle
(
linked
.
LinkedToken
);
type
=
TokenElevationTypeLimited
;
ret
=
SetTokenInformation
(
token
,
TokenElevationType
,
&
type
,
sizeof
(
type
));
ok
(
!
ret
,
"expected failure
\n
"
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"got error %u
\n
"
,
GetLastError
());
elevation
.
TokenIsElevated
=
FALSE
;
ret
=
SetTokenInformation
(
token
,
TokenElevation
,
&
elevation
,
sizeof
(
elevation
));
ok
(
!
ret
,
"expected failure
\n
"
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"got error %u
\n
"
,
GetLastError
());
}
ret
=
DuplicateTokenEx
(
token
,
TOKEN_ALL_ACCESS
,
NULL
,
SecurityAnonymous
,
TokenPrimary
,
&
token2
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ret
=
GetTokenInformation
(
token2
,
TokenElevationType
,
&
type
,
sizeof
(
type
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ok
(
type
==
orig_type
,
"expected same type
\n
"
);
ret
=
GetTokenInformation
(
token2
,
TokenElevation
,
&
elevation
,
sizeof
(
elevation
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ok
(
elevation
.
TokenIsElevated
==
(
type
==
TokenElevationTypeFull
),
"got elevation %#x
\n
"
,
elevation
.
TokenIsElevated
);
ret
=
GetTokenInformation
(
token2
,
TokenLinkedToken
,
&
linked
,
sizeof
(
linked
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
if
(
type
==
TokenElevationTypeDefault
)
ok
(
!
linked
.
LinkedToken
,
"expected no linked token
\n
"
);
else
ok
(
!!
linked
.
LinkedToken
,
"expected a linked token
\n
"
);
CloseHandle
(
linked
.
LinkedToken
);
CloseHandle
(
token2
);
ret
=
CreateRestrictedToken
(
token
,
0
,
0
,
NULL
,
0
,
NULL
,
0
,
NULL
,
&
token2
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ret
=
GetTokenInformation
(
token2
,
TokenElevationType
,
&
type
,
sizeof
(
type
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ok
(
type
==
orig_type
,
"expected same type
\n
"
);
ret
=
GetTokenInformation
(
token2
,
TokenElevation
,
&
elevation
,
sizeof
(
elevation
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ok
(
elevation
.
TokenIsElevated
==
(
type
==
TokenElevationTypeFull
),
"got elevation %#x
\n
"
,
elevation
.
TokenIsElevated
);
ret
=
GetTokenInformation
(
token2
,
TokenLinkedToken
,
&
linked
,
sizeof
(
linked
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
if
(
type
==
TokenElevationTypeDefault
)
ok
(
!
linked
.
LinkedToken
,
"expected no linked token
\n
"
);
else
ok
(
!!
linked
.
LinkedToken
,
"expected a linked token
\n
"
);
CloseHandle
(
linked
.
LinkedToken
);
CloseHandle
(
token2
);
if
(
type
!=
TokenElevationTypeDefault
)
{
char
prev_privs_buffer
[
128
],
acl_buffer
[
256
],
prev_acl_buffer
[
256
];
TOKEN_PRIVILEGES
privs
,
*
prev_privs
=
(
TOKEN_PRIVILEGES
*
)
prev_privs_buffer
;
TOKEN_DEFAULT_DACL
*
prev_acl
=
(
TOKEN_DEFAULT_DACL
*
)
prev_acl_buffer
;
TOKEN_DEFAULT_DACL
*
ret_acl
=
(
TOKEN_DEFAULT_DACL
*
)
acl_buffer
;
TOKEN_DEFAULT_DACL
default_acl
;
PRIVILEGE_SET
priv_set
;
BOOL
ret
,
is_member
;
DWORD
size
;
ACL
acl
;
/* Linked tokens do not preserve privilege modifications. */
privs
.
PrivilegeCount
=
1
;
ret
=
LookupPrivilegeValueA
(
NULL
,
"SeChangeNotifyPrivilege"
,
&
privs
.
Privileges
[
0
].
Luid
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
privs
.
Privileges
[
0
].
Attributes
=
SE_PRIVILEGE_REMOVED
;
ret
=
AdjustTokenPrivileges
(
token
,
FALSE
,
&
privs
,
sizeof
(
prev_privs_buffer
),
prev_privs
,
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
priv_set
.
PrivilegeCount
=
1
;
priv_set
.
Control
=
0
;
priv_set
.
Privilege
[
0
]
=
privs
.
Privileges
[
0
];
ret
=
PrivilegeCheck
(
token
,
&
priv_set
,
&
is_member
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ok
(
!
is_member
,
"not a member
\n
"
);
ret
=
GetTokenInformation
(
token
,
TokenLinkedToken
,
&
linked
,
sizeof
(
linked
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ret
=
PrivilegeCheck
(
linked
.
LinkedToken
,
&
priv_set
,
&
is_member
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ok
(
is_member
,
"not a member
\n
"
);
CloseHandle
(
linked
.
LinkedToken
);
ret
=
AdjustTokenPrivileges
(
token
,
FALSE
,
prev_privs
,
0
,
NULL
,
NULL
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
/* Linked tokens do not preserve default DACL modifications. */
ret
=
GetTokenInformation
(
token
,
TokenDefaultDacl
,
prev_acl
,
sizeof
(
prev_acl_buffer
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ok
(
prev_acl
->
DefaultDacl
->
AceCount
,
"expected non-empty default DACL
\n
"
);
InitializeAcl
(
&
acl
,
sizeof
(
acl
),
ACL_REVISION
);
default_acl
.
DefaultDacl
=
&
acl
;
ret
=
SetTokenInformation
(
token
,
TokenDefaultDacl
,
&
default_acl
,
sizeof
(
default_acl
));
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ret
=
GetTokenInformation
(
token
,
TokenDefaultDacl
,
ret_acl
,
sizeof
(
acl_buffer
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ok
(
!
ret_acl
->
DefaultDacl
->
AceCount
,
"expected empty default DACL
\n
"
);
ret
=
GetTokenInformation
(
token
,
TokenLinkedToken
,
&
linked
,
sizeof
(
linked
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ret
=
GetTokenInformation
(
linked
.
LinkedToken
,
TokenDefaultDacl
,
ret_acl
,
sizeof
(
acl_buffer
),
&
size
);
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
ok
(
ret_acl
->
DefaultDacl
->
AceCount
,
"expected non-empty default DACL
\n
"
);
CloseHandle
(
linked
.
LinkedToken
);
ret
=
SetTokenInformation
(
token
,
TokenDefaultDacl
,
prev_acl
,
sizeof
(
*
prev_acl
));
ok
(
ret
,
"got error %u
\n
"
,
GetLastError
());
}
CloseHandle
(
token
);
}
START_TEST
(
security
)
{
init
();
...
...
@@ -8086,6 +8348,7 @@ START_TEST(security)
test_pseudo_handle_security
();
test_duplicate_token
();
test_GetKernelObjectSecurity
();
test_elevation
();
/* Must be the last test, modifies process token */
test_token_security_descriptor
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment