server: Implement setting a security descriptor when duplicating tokens.

Signed-off-by: Matteo Bruni <mbruni@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Michael Müller 2017-06-14 20:20:43 +02:00 committed by Alexandre Julliard
parent 187b53e5a5
commit 7c08e787b1
8 changed files with 26 additions and 13 deletions

View File

@ -83,11 +83,15 @@ NTSTATUS WINAPI NtDuplicateToken(
OUT PHANDLE NewToken)
{
NTSTATUS status;
data_size_t len;
struct object_attributes *objattr;
TRACE("(%p,0x%08x,%s,0x%08x,0x%08x,%p)\n",
ExistingToken, DesiredAccess, debugstr_ObjectAttributes(ObjectAttributes),
ImpersonationLevel, TokenType, NewToken);
if ((status = alloc_object_attributes( ObjectAttributes, &objattr, &len ))) return status;
if (ObjectAttributes && ObjectAttributes->SecurityQualityOfService)
{
SECURITY_QUALITY_OF_SERVICE *SecurityQOS = ObjectAttributes->SecurityQualityOfService;
@ -102,14 +106,15 @@ NTSTATUS WINAPI NtDuplicateToken(
{
req->handle = wine_server_obj_handle( ExistingToken );
req->access = DesiredAccess;
req->attributes = ObjectAttributes ? ObjectAttributes->Attributes : 0;
req->primary = (TokenType == TokenPrimary);
req->impersonation_level = ImpersonationLevel;
wine_server_add_data( req, objattr, len );
status = wine_server_call( req );
if (!status) *NewToken = wine_server_ptr_handle( reply->new_handle );
}
SERVER_END_REQ;
RtlFreeHeap( GetProcessHeap(), 0, objattr );
return status;
}

View File

@ -4732,9 +4732,10 @@ struct duplicate_token_request
struct request_header __header;
obj_handle_t handle;
unsigned int access;
unsigned int attributes;
int primary;
int impersonation_level;
/* VARARG(objattr,object_attributes); */
char __pad_28[4];
};
struct duplicate_token_reply
{
@ -6418,6 +6419,6 @@ union generic_reply
struct terminate_job_reply terminate_job_reply;
};
#define SERVER_PROTOCOL_VERSION 532
#define SERVER_PROTOCOL_VERSION 533
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -565,7 +565,7 @@ struct thread *create_process( int fd, struct thread *parent_thread, int inherit
: alloc_handle_table( process, 0 );
/* Note: for security reasons, starting a new process does not attempt
* to use the current impersonation token for the new process */
process->token = token_duplicate( parent->token, TRUE, 0 );
process->token = token_duplicate( parent->token, TRUE, 0, NULL );
process->affinity = parent->affinity;
}
if (!process->handles || !process->token) goto error;

View File

@ -3316,9 +3316,9 @@ enum caret_state
@REQ(duplicate_token)
obj_handle_t handle; /* handle to the token to duplicate */
unsigned int access; /* access rights to the new token */
unsigned int attributes; /* object attributes */
int primary; /* is the new token to be a primary one? */
int impersonation_level; /* impersonation level of the new token */
VARARG(objattr,object_attributes); /* object attributes */
@REPLY
obj_handle_t new_handle; /* duplicated handle */
@END

View File

@ -2113,9 +2113,8 @@ C_ASSERT( FIELD_OFFSET(struct check_token_privileges_reply, has_privileges) == 8
C_ASSERT( sizeof(struct check_token_privileges_reply) == 16 );
C_ASSERT( FIELD_OFFSET(struct duplicate_token_request, handle) == 12 );
C_ASSERT( FIELD_OFFSET(struct duplicate_token_request, access) == 16 );
C_ASSERT( FIELD_OFFSET(struct duplicate_token_request, attributes) == 20 );
C_ASSERT( FIELD_OFFSET(struct duplicate_token_request, primary) == 24 );
C_ASSERT( FIELD_OFFSET(struct duplicate_token_request, impersonation_level) == 28 );
C_ASSERT( FIELD_OFFSET(struct duplicate_token_request, primary) == 20 );
C_ASSERT( FIELD_OFFSET(struct duplicate_token_request, impersonation_level) == 24 );
C_ASSERT( sizeof(struct duplicate_token_request) == 32 );
C_ASSERT( FIELD_OFFSET(struct duplicate_token_reply, new_handle) == 8 );
C_ASSERT( sizeof(struct duplicate_token_reply) == 16 );

View File

@ -53,7 +53,7 @@ extern const PSID security_builtin_admins_sid;
extern struct token *token_create_admin(void);
extern struct token *token_duplicate( struct token *src_token, unsigned primary,
int impersonation_level );
int impersonation_level, const struct security_descriptor *sd );
extern int token_check_privileges( struct token *token, int all_required,
const LUID_AND_ATTRIBUTES *reqprivs,
unsigned int count, LUID_AND_ATTRIBUTES *usedprivs);

View File

@ -622,7 +622,7 @@ static struct token *create_token( unsigned primary, const SID *user,
}
struct token *token_duplicate( struct token *src_token, unsigned primary,
int impersonation_level )
int impersonation_level, const struct security_descriptor *sd )
{
const luid_t *modified_id =
primary || (impersonation_level == src_token->impersonation_level) ?
@ -672,6 +672,9 @@ struct token *token_duplicate( struct token *src_token, unsigned primary,
return NULL;
}
if (sd) default_set_sd( &token->obj, sd, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION );
return token;
}
@ -1240,15 +1243,20 @@ DECL_HANDLER(get_token_privileges)
DECL_HANDLER(duplicate_token)
{
struct token *src_token;
struct unicode_str name;
const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, NULL );
if (!objattr) return;
if ((src_token = (struct token *)get_handle_obj( current->process, req->handle,
TOKEN_DUPLICATE,
&token_ops )))
{
struct token *token = token_duplicate( src_token, req->primary, req->impersonation_level );
struct token *token = token_duplicate( src_token, req->primary, req->impersonation_level, sd );
if (token)
{
reply->new_handle = alloc_handle( current->process, token, req->access, req->attributes);
reply->new_handle = alloc_handle_no_access_check( current->process, token, req->access, objattr->attributes );
release_object( token );
}
release_object( src_token );

View File

@ -3927,9 +3927,9 @@ static void dump_duplicate_token_request( const struct duplicate_token_request *
{
fprintf( stderr, " handle=%04x", req->handle );
fprintf( stderr, ", access=%08x", req->access );
fprintf( stderr, ", attributes=%08x", req->attributes );
fprintf( stderr, ", primary=%d", req->primary );
fprintf( stderr, ", impersonation_level=%d", req->impersonation_level );
dump_varargs_object_attributes( ", objattr=", cur_size );
}
static void dump_duplicate_token_reply( const struct duplicate_token_reply *req )