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:
parent
187b53e5a5
commit
7c08e787b1
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 )
|
||||
|
|
Loading…
Reference in New Issue