Commit 4ad93416 authored by Robert Shearman's avatar Robert Shearman Committed by Alexandre Julliard

Implement NtAccessCheck.

parent 3889d950
......@@ -1153,23 +1153,85 @@ RtlImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
/******************************************************************************
* NtAccessCheck [NTDLL.@]
* ZwAccessCheck [NTDLL.@]
*
* Checks that a user represented by a token is allowed to access an object
* represented by a security descriptor.
*
* PARAMS
* SecurityDescriptor [I] The security descriptor of the object to check.
* ClientToken [I] Token of the user accessing the object.
* DesiredAccess [I] The desired access to the object.
* GenericMapping [I] Mapping used to transform access rights in the SD to their specific forms.
* PrivilegeSet [I/O] Privileges used during the access check.
* ReturnLength [O] Number of bytes stored into PrivilegeSet.
* GrantedAccess [O] The actual access rights granted.
* AccessStatus [O] The status of the access check.
*
* RETURNS
* NTSTATUS code.
*
* NOTES
* DesiredAccess may be MAXIMUM_ALLOWED, in which case the function determines
* the maximum access rights allowed by the SD and returns them in
* GrantedAccess.
* The SecurityDescriptor must have a valid owner and groups present,
* otherwise the function will fail.
*/
NTSTATUS WINAPI
NtAccessCheck(
IN PSECURITY_DESCRIPTOR SecurityDescriptor,
IN HANDLE ClientToken,
IN ACCESS_MASK DesiredAccess,
IN PGENERIC_MAPPING GenericMapping,
OUT PPRIVILEGE_SET PrivilegeSet,
OUT PULONG ReturnLength,
OUT PULONG GrantedAccess,
OUT NTSTATUS *AccessStatus)
PSECURITY_DESCRIPTOR SecurityDescriptor,
HANDLE ClientToken,
ACCESS_MASK DesiredAccess,
PGENERIC_MAPPING GenericMapping,
PPRIVILEGE_SET PrivilegeSet,
PULONG ReturnLength,
PULONG GrantedAccess,
NTSTATUS *AccessStatus)
{
FIXME("(%p, %p, %08lx, %p, %p, %p, %p, %p), stub\n",
SecurityDescriptor, ClientToken, DesiredAccess, GenericMapping,
PrivilegeSet, ReturnLength, GrantedAccess, AccessStatus);
*AccessStatus = STATUS_SUCCESS;
return STATUS_SUCCESS;
NTSTATUS status;
TRACE("(%p, %p, %08lx, %p, %p, %p, %p, %p), stub\n",
SecurityDescriptor, ClientToken, DesiredAccess, GenericMapping,
PrivilegeSet, ReturnLength, GrantedAccess, AccessStatus);
SERVER_START_REQ( access_check )
{
struct security_descriptor sd;
const SECURITY_DESCRIPTOR * RealSD = (const SECURITY_DESCRIPTOR *)SecurityDescriptor;
req->handle = ClientToken;
req->desired_access = DesiredAccess;
req->mapping_read = GenericMapping->GenericRead;
req->mapping_write = GenericMapping->GenericWrite;
req->mapping_execute = GenericMapping->GenericExecute;
req->mapping_all = GenericMapping->GenericAll;
/* marshal security descriptor */
sd.control = RealSD->Control;
sd.owner_len = RtlLengthSid( RealSD->Owner );
sd.group_len = RtlLengthSid( RealSD->Group );
sd.sacl_len = (RealSD->Sacl ? RealSD->Sacl->AclSize : 0);
sd.dacl_len = (RealSD->Dacl ? RealSD->Dacl->AclSize : 0);
wine_server_add_data( req, &sd, sizeof(sd) );
wine_server_add_data( req, RealSD->Owner, sd.owner_len );
wine_server_add_data( req, RealSD->Group, sd.group_len );
wine_server_add_data( req, RealSD->Sacl, sd.sacl_len );
wine_server_add_data( req, RealSD->Dacl, sd.dacl_len );
wine_server_set_reply( req, &PrivilegeSet->Privilege, *ReturnLength - FIELD_OFFSET( PRIVILEGE_SET, Privilege ) );
status = wine_server_call( req );
*ReturnLength = FIELD_OFFSET( PRIVILEGE_SET, Privilege ) + reply->privileges_len;
PrivilegeSet->PrivilegeCount = reply->privileges_len / sizeof(LUID_AND_ATTRIBUTES);
if (status == STATUS_SUCCESS)
*AccessStatus = reply->access_status;
*GrantedAccess = reply->access_granted;
}
SERVER_END_REQ;
return status;
}
/******************************************************************************
......
......@@ -3331,6 +3331,25 @@ struct duplicate_token_reply
obj_handle_t new_handle;
};
struct access_check_request
{
struct request_header __header;
obj_handle_t handle;
unsigned int desired_access;
unsigned int mapping_read;
unsigned int mapping_write;
unsigned int mapping_execute;
unsigned int mapping_all;
/* VARARG(sd,security_descriptor); */
};
struct access_check_reply
{
struct reply_header __header;
unsigned int access_granted;
unsigned int access_status;
unsigned int privileges_len;
/* VARARG(privileges,LUID_AND_ATTRIBUTES); */
};
struct create_mailslot_request
......@@ -3574,6 +3593,7 @@ enum request
REQ_get_token_privileges,
REQ_check_token_privileges,
REQ_duplicate_token,
REQ_access_check,
REQ_create_mailslot,
REQ_open_mailslot,
REQ_set_mailslot_info,
......@@ -3773,6 +3793,7 @@ union generic_request
struct get_token_privileges_request get_token_privileges_request;
struct check_token_privileges_request check_token_privileges_request;
struct duplicate_token_request duplicate_token_request;
struct access_check_request access_check_request;
struct create_mailslot_request create_mailslot_request;
struct open_mailslot_request open_mailslot_request;
struct set_mailslot_info_request set_mailslot_info_request;
......@@ -3970,11 +3991,12 @@ union generic_reply
struct get_token_privileges_reply get_token_privileges_reply;
struct check_token_privileges_reply check_token_privileges_reply;
struct duplicate_token_reply duplicate_token_reply;
struct access_check_reply access_check_reply;
struct create_mailslot_reply create_mailslot_reply;
struct open_mailslot_reply open_mailslot_reply;
struct set_mailslot_info_reply set_mailslot_info_reply;
};
#define SERVER_PROTOCOL_VERSION 175
#define SERVER_PROTOCOL_VERSION 176
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
......@@ -2344,6 +2344,20 @@ enum message_type
obj_handle_t new_handle; /* duplicated handle */
@END
@REQ(access_check)
obj_handle_t handle; /* handle to the token */
unsigned int desired_access; /* desired access to the object */
unsigned int mapping_read; /* mapping from generic read to specific rights */
unsigned int mapping_write; /* mapping from generic write to specific rights */
unsigned int mapping_execute; /* mapping from generic execute to specific rights */
unsigned int mapping_all; /* mapping from generic all to specific rights */
VARARG(sd,security_descriptor); /* security descriptor to check */
@REPLY
unsigned int access_granted; /* access rights actually granted */
unsigned int access_status; /* was access granted? */
unsigned int privileges_len; /* length needed to store privileges */
VARARG(privileges,LUID_AND_ATTRIBUTES); /* privileges used during access check */
@END
/* Create a mailslot */
@REQ(create_mailslot)
......
......@@ -292,6 +292,7 @@ DECL_HANDLER(adjust_token_privileges);
DECL_HANDLER(get_token_privileges);
DECL_HANDLER(check_token_privileges);
DECL_HANDLER(duplicate_token);
DECL_HANDLER(access_check);
DECL_HANDLER(create_mailslot);
DECL_HANDLER(open_mailslot);
DECL_HANDLER(set_mailslot_info);
......@@ -490,6 +491,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_get_token_privileges,
(req_handler)req_check_token_privileges,
(req_handler)req_duplicate_token,
(req_handler)req_access_check,
(req_handler)req_create_mailslot,
(req_handler)req_open_mailslot,
(req_handler)req_set_mailslot_info,
......
......@@ -2872,6 +2872,27 @@ static void dump_duplicate_token_reply( const struct duplicate_token_reply *req
fprintf( stderr, " new_handle=%p", req->new_handle );
}
static void dump_access_check_request( const struct access_check_request *req )
{
fprintf( stderr, " handle=%p,", req->handle );
fprintf( stderr, " desired_access=%08x,", req->desired_access );
fprintf( stderr, " mapping_read=%08x,", req->mapping_read );
fprintf( stderr, " mapping_write=%08x,", req->mapping_write );
fprintf( stderr, " mapping_execute=%08x,", req->mapping_execute );
fprintf( stderr, " mapping_all=%08x,", req->mapping_all );
fprintf( stderr, " sd=" );
dump_varargs_security_descriptor( cur_size );
}
static void dump_access_check_reply( const struct access_check_reply *req )
{
fprintf( stderr, " access_granted=%08x,", req->access_granted );
fprintf( stderr, " access_status=%08x,", req->access_status );
fprintf( stderr, " privileges_len=%08x,", req->privileges_len );
fprintf( stderr, " privileges=" );
dump_varargs_LUID_AND_ATTRIBUTES( cur_size );
}
static void dump_create_mailslot_request( const struct create_mailslot_request *req )
{
fprintf( stderr, " max_msgsize=%08x,", req->max_msgsize );
......@@ -3105,6 +3126,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_token_privileges_request,
(dump_func)dump_check_token_privileges_request,
(dump_func)dump_duplicate_token_request,
(dump_func)dump_access_check_request,
(dump_func)dump_create_mailslot_request,
(dump_func)dump_open_mailslot_request,
(dump_func)dump_set_mailslot_info_request,
......@@ -3300,6 +3322,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_token_privileges_reply,
(dump_func)dump_check_token_privileges_reply,
(dump_func)dump_duplicate_token_reply,
(dump_func)dump_access_check_reply,
(dump_func)dump_create_mailslot_reply,
(dump_func)dump_open_mailslot_reply,
(dump_func)dump_set_mailslot_info_reply,
......@@ -3495,6 +3518,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"get_token_privileges",
"check_token_privileges",
"duplicate_token",
"access_check",
"create_mailslot",
"open_mailslot",
"set_mailslot_info",
......
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