server: Add get_token_impersonation_level server call for retrieving the impersonation level from a token.

Add tests for GetTokenInformation(TokenImpersonationLevel).
This commit is contained in:
Rob Shearman 2007-02-21 17:10:45 +00:00 committed by Alexandre Julliard
parent 6a76a0ac7a
commit d342d1413c
7 changed files with 89 additions and 6 deletions

View File

@ -840,7 +840,7 @@ static void test_AccessCheck(void)
/* test GetTokenInformation for the various attributes */
static void test_token_attr(void)
{
HANDLE Token;
HANDLE Token, ImpersonationToken;
DWORD Size;
TOKEN_PRIVILEGES *Privileges;
TOKEN_GROUPS *Groups;
@ -848,6 +848,7 @@ static void test_token_attr(void)
BOOL ret;
DWORD i, GLE;
LPSTR SidString;
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
/* cygwin-like use case */
ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &Token);
@ -855,16 +856,20 @@ static void test_token_attr(void)
if (ret)
{
BYTE buf[1024];
DWORD bufsize = sizeof(buf);
ret = GetTokenInformation(Token, TokenUser,(void*)buf, bufsize, &bufsize);
Size = sizeof(buf);
ret = GetTokenInformation(Token, TokenUser,(void*)buf, Size, &Size);
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);
}
if(!pConvertSidToStringSidA)
return;
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &Token);
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_DUPLICATE, &Token);
GLE = GetLastError();
ok(ret || (GLE == ERROR_CALL_NOT_IMPLEMENTED),
"OpenProcessToken failed with error %d\n", GLE);
@ -928,6 +933,17 @@ static void test_token_attr(void)
trace("\t%s, 0x%x\n", Name, Privileges->Privileges[i].Attributes);
}
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

View File

@ -217,8 +217,10 @@ NTSTATUS WINAPI NtQueryInformationToken(
case TokenType:
len = sizeof (TOKEN_TYPE);
break;
#if 0
case TokenImpersonationLevel:
len = sizeof(SECURITY_IMPERSONATION_LEVEL);
break;
#if 0
case TokenStatistics:
#endif /* 0 */
default:
@ -352,6 +354,17 @@ NTSTATUS WINAPI NtQueryInformationToken(
owner->Owner = sid;
}
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:
{
ERR("Unhandled Token Information class %d!\n", tokeninfoclass);

View File

@ -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
{
REQ_new_process,
@ -4210,6 +4222,7 @@ enum request
REQ_open_symlink,
REQ_query_symlink,
REQ_get_object_info,
REQ_get_token_impersonation_level,
REQ_NB_REQUESTS
};
@ -4433,6 +4446,7 @@ union generic_request
struct open_symlink_request open_symlink_request;
struct query_symlink_request query_symlink_request;
struct get_object_info_request get_object_info_request;
struct get_token_impersonation_level_request get_token_impersonation_level_request;
};
union generic_reply
{
@ -4654,8 +4668,9 @@ union generic_reply
struct open_symlink_reply open_symlink_reply;
struct query_symlink_reply query_symlink_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 */

View File

@ -2862,3 +2862,10 @@ enum message_type
unsigned int access; /* granted access mask */
unsigned int ref_count; /* object ref count */
@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

View File

@ -326,6 +326,7 @@ DECL_HANDLER(create_symlink);
DECL_HANDLER(open_symlink);
DECL_HANDLER(query_symlink);
DECL_HANDLER(get_object_info);
DECL_HANDLER(get_token_impersonation_level);
#ifdef WANT_REQUEST_HANDLERS
@ -548,6 +549,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_open_symlink,
(req_handler)req_query_symlink,
(req_handler)req_get_object_info,
(req_handler)req_get_token_impersonation_level,
};
#endif /* WANT_REQUEST_HANDLERS */

View File

@ -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)
{
data_size_t sd_size = get_req_data_size();

View File

@ -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 );
}
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] = {
(dump_func)dump_new_process_request,
(dump_func)dump_get_new_process_info_request,
@ -3660,6 +3670,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_open_symlink_request,
(dump_func)dump_query_symlink_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] = {
@ -3879,6 +3890,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_open_symlink_reply,
(dump_func)dump_query_symlink_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] = {
@ -4098,6 +4110,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"open_symlink",
"query_symlink",
"get_object_info",
"get_token_impersonation_level",
};
static const struct