Commit d342d141 authored by Rob Shearman's avatar Rob Shearman Committed by Alexandre Julliard

server: Add get_token_impersonation_level server call for retrieving the…

server: Add get_token_impersonation_level server call for retrieving the impersonation level from a token. Add tests for GetTokenInformation(TokenImpersonationLevel).
parent 6a76a0ac
...@@ -840,7 +840,7 @@ static void test_AccessCheck(void) ...@@ -840,7 +840,7 @@ static void test_AccessCheck(void)
/* test GetTokenInformation for the various attributes */ /* test GetTokenInformation for the various attributes */
static void test_token_attr(void) static void test_token_attr(void)
{ {
HANDLE Token; HANDLE Token, ImpersonationToken;
DWORD Size; DWORD Size;
TOKEN_PRIVILEGES *Privileges; TOKEN_PRIVILEGES *Privileges;
TOKEN_GROUPS *Groups; TOKEN_GROUPS *Groups;
...@@ -848,6 +848,7 @@ static void test_token_attr(void) ...@@ -848,6 +848,7 @@ static void test_token_attr(void)
BOOL ret; BOOL ret;
DWORD i, GLE; DWORD i, GLE;
LPSTR SidString; LPSTR SidString;
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
/* cygwin-like use case */ /* cygwin-like use case */
ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &Token); ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &Token);
...@@ -855,16 +856,20 @@ static void test_token_attr(void) ...@@ -855,16 +856,20 @@ static void test_token_attr(void)
if (ret) if (ret)
{ {
BYTE buf[1024]; BYTE buf[1024];
DWORD bufsize = sizeof(buf); Size = sizeof(buf);
ret = GetTokenInformation(Token, TokenUser,(void*)buf, bufsize, &bufsize); ret = GetTokenInformation(Token, TokenUser,(void*)buf, Size, &Size);
ok(ret, "GetTokenInformation failed with error %d\n", GetLastError()); ok(ret, "GetTokenInformation failed with error %d\n", GetLastError());
Size = sizeof(ImpersonationLevel);
ret = GetTokenInformation(Token, TokenImpersonationLevel, &ImpersonationLevel, Size, &Size);
GLE = GetLastError();
ok(!ret && (GLE == ERROR_INVALID_PARAMETER), "GetTokenInformation(TokenImpersonationLevel) on primary token should have failed with ERROR_INVALID_PARAMETER instead of %d\n", GLE);
CloseHandle(Token); CloseHandle(Token);
} }
if(!pConvertSidToStringSidA) if(!pConvertSidToStringSidA)
return; return;
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &Token); ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_DUPLICATE, &Token);
GLE = GetLastError(); GLE = GetLastError();
ok(ret || (GLE == ERROR_CALL_NOT_IMPLEMENTED), ok(ret || (GLE == ERROR_CALL_NOT_IMPLEMENTED),
"OpenProcessToken failed with error %d\n", GLE); "OpenProcessToken failed with error %d\n", GLE);
...@@ -928,6 +933,17 @@ static void test_token_attr(void) ...@@ -928,6 +933,17 @@ static void test_token_attr(void)
trace("\t%s, 0x%x\n", Name, Privileges->Privileges[i].Attributes); trace("\t%s, 0x%x\n", Name, Privileges->Privileges[i].Attributes);
} }
HeapFree(GetProcessHeap(), 0, Privileges); HeapFree(GetProcessHeap(), 0, Privileges);
ret = DuplicateToken(Token, SecurityAnonymous, &ImpersonationToken);
ok(ret, "DuplicateToken failed with error %d\n", GetLastError());
Size = sizeof(ImpersonationLevel);
ret = GetTokenInformation(ImpersonationToken, TokenImpersonationLevel, &ImpersonationLevel, Size, &Size);
ok(ret, "GetTokenInformation(TokenImpersonationLevel) failed with error %d\n", GetLastError());
ok(ImpersonationLevel == SecurityAnonymous, "ImpersonationLevel should have been SecurityAnonymous instead of %d\n", ImpersonationLevel);
CloseHandle(ImpersonationToken);
CloseHandle(Token);
} }
typedef union _MAX_SID typedef union _MAX_SID
......
...@@ -217,8 +217,10 @@ NTSTATUS WINAPI NtQueryInformationToken( ...@@ -217,8 +217,10 @@ NTSTATUS WINAPI NtQueryInformationToken(
case TokenType: case TokenType:
len = sizeof (TOKEN_TYPE); len = sizeof (TOKEN_TYPE);
break; break;
#if 0
case TokenImpersonationLevel: case TokenImpersonationLevel:
len = sizeof(SECURITY_IMPERSONATION_LEVEL);
break;
#if 0
case TokenStatistics: case TokenStatistics:
#endif /* 0 */ #endif /* 0 */
default: default:
...@@ -352,6 +354,17 @@ NTSTATUS WINAPI NtQueryInformationToken( ...@@ -352,6 +354,17 @@ NTSTATUS WINAPI NtQueryInformationToken(
owner->Owner = sid; owner->Owner = sid;
} }
break; break;
case TokenImpersonationLevel:
SERVER_START_REQ( get_token_impersonation_level )
{
SECURITY_IMPERSONATION_LEVEL *impersonation_level = tokeninfo;
req->handle = token;
status = wine_server_call( req );
if (status == STATUS_SUCCESS)
*impersonation_level = reply->impersonation_level;
}
SERVER_END_REQ;
break;
default: default:
{ {
ERR("Unhandled Token Information class %d!\n", tokeninfoclass); ERR("Unhandled Token Information class %d!\n", tokeninfoclass);
......
...@@ -3992,6 +3992,18 @@ struct get_object_info_reply ...@@ -3992,6 +3992,18 @@ struct get_object_info_reply
}; };
struct get_token_impersonation_level_request
{
struct request_header __header;
obj_handle_t handle;
};
struct get_token_impersonation_level_reply
{
struct reply_header __header;
int impersonation_level;
};
enum request enum request
{ {
REQ_new_process, REQ_new_process,
...@@ -4210,6 +4222,7 @@ enum request ...@@ -4210,6 +4222,7 @@ enum request
REQ_open_symlink, REQ_open_symlink,
REQ_query_symlink, REQ_query_symlink,
REQ_get_object_info, REQ_get_object_info,
REQ_get_token_impersonation_level,
REQ_NB_REQUESTS REQ_NB_REQUESTS
}; };
...@@ -4433,6 +4446,7 @@ union generic_request ...@@ -4433,6 +4446,7 @@ union generic_request
struct open_symlink_request open_symlink_request; struct open_symlink_request open_symlink_request;
struct query_symlink_request query_symlink_request; struct query_symlink_request query_symlink_request;
struct get_object_info_request get_object_info_request; struct get_object_info_request get_object_info_request;
struct get_token_impersonation_level_request get_token_impersonation_level_request;
}; };
union generic_reply union generic_reply
{ {
...@@ -4654,8 +4668,9 @@ union generic_reply ...@@ -4654,8 +4668,9 @@ union generic_reply
struct open_symlink_reply open_symlink_reply; struct open_symlink_reply open_symlink_reply;
struct query_symlink_reply query_symlink_reply; struct query_symlink_reply query_symlink_reply;
struct get_object_info_reply get_object_info_reply; struct get_object_info_reply get_object_info_reply;
struct get_token_impersonation_level_reply get_token_impersonation_level_reply;
}; };
#define SERVER_PROTOCOL_VERSION 277 #define SERVER_PROTOCOL_VERSION 278
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -2862,3 +2862,10 @@ enum message_type ...@@ -2862,3 +2862,10 @@ enum message_type
unsigned int access; /* granted access mask */ unsigned int access; /* granted access mask */
unsigned int ref_count; /* object ref count */ unsigned int ref_count; /* object ref count */
@END @END
/* Query the impersonation level of an impersonation token */
@REQ(get_token_impersonation_level)
obj_handle_t handle; /* handle to the object */
@REPLY
int impersonation_level; /* impersonation level of the impersonation token */
@END
...@@ -326,6 +326,7 @@ DECL_HANDLER(create_symlink); ...@@ -326,6 +326,7 @@ DECL_HANDLER(create_symlink);
DECL_HANDLER(open_symlink); DECL_HANDLER(open_symlink);
DECL_HANDLER(query_symlink); DECL_HANDLER(query_symlink);
DECL_HANDLER(get_object_info); DECL_HANDLER(get_object_info);
DECL_HANDLER(get_token_impersonation_level);
#ifdef WANT_REQUEST_HANDLERS #ifdef WANT_REQUEST_HANDLERS
...@@ -548,6 +549,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = ...@@ -548,6 +549,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_open_symlink, (req_handler)req_open_symlink,
(req_handler)req_query_symlink, (req_handler)req_query_symlink,
(req_handler)req_get_object_info, (req_handler)req_get_object_info,
(req_handler)req_get_token_impersonation_level,
}; };
#endif /* WANT_REQUEST_HANDLERS */ #endif /* WANT_REQUEST_HANDLERS */
......
...@@ -1386,6 +1386,23 @@ DECL_HANDLER(get_token_groups) ...@@ -1386,6 +1386,23 @@ DECL_HANDLER(get_token_groups)
} }
} }
DECL_HANDLER(get_token_impersonation_level)
{
struct token *token;
if ((token = (struct token *)get_handle_obj( current->process, req->handle,
TOKEN_QUERY,
&token_ops )))
{
if (token->primary)
set_error( STATUS_INVALID_PARAMETER );
else
reply->impersonation_level = token->impersonation_level;
release_object( token );
}
}
DECL_HANDLER(set_security_object) DECL_HANDLER(set_security_object)
{ {
data_size_t sd_size = get_req_data_size(); data_size_t sd_size = get_req_data_size();
......
...@@ -3443,6 +3443,16 @@ static void dump_get_object_info_reply( const struct get_object_info_reply *req ...@@ -3443,6 +3443,16 @@ static void dump_get_object_info_reply( const struct get_object_info_reply *req
fprintf( stderr, " ref_count=%08x", req->ref_count ); fprintf( stderr, " ref_count=%08x", req->ref_count );
} }
static void dump_get_token_impersonation_level_request( const struct get_token_impersonation_level_request *req )
{
fprintf( stderr, " handle=%p", req->handle );
}
static void dump_get_token_impersonation_level_reply( const struct get_token_impersonation_level_reply *req )
{
fprintf( stderr, " impersonation_level=%d", req->impersonation_level );
}
static const dump_func req_dumpers[REQ_NB_REQUESTS] = { static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_new_process_request, (dump_func)dump_new_process_request,
(dump_func)dump_get_new_process_info_request, (dump_func)dump_get_new_process_info_request,
...@@ -3660,6 +3670,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { ...@@ -3660,6 +3670,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_open_symlink_request, (dump_func)dump_open_symlink_request,
(dump_func)dump_query_symlink_request, (dump_func)dump_query_symlink_request,
(dump_func)dump_get_object_info_request, (dump_func)dump_get_object_info_request,
(dump_func)dump_get_token_impersonation_level_request,
}; };
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
...@@ -3879,6 +3890,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { ...@@ -3879,6 +3890,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_open_symlink_reply, (dump_func)dump_open_symlink_reply,
(dump_func)dump_query_symlink_reply, (dump_func)dump_query_symlink_reply,
(dump_func)dump_get_object_info_reply, (dump_func)dump_get_object_info_reply,
(dump_func)dump_get_token_impersonation_level_reply,
}; };
static const char * const req_names[REQ_NB_REQUESTS] = { static const char * const req_names[REQ_NB_REQUESTS] = {
...@@ -4098,6 +4110,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { ...@@ -4098,6 +4110,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"open_symlink", "open_symlink",
"query_symlink", "query_symlink",
"get_object_info", "get_object_info",
"get_token_impersonation_level",
}; };
static const struct static const struct
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment