diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index fa084912d5..405f348139 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -78,6 +78,11 @@ extern int server_remove_fd_from_cache( obj_handle_t handle ); extern int server_get_unix_fd( obj_handle_t handle, unsigned int access, int *unix_fd, int *needs_close, enum server_fd_type *type, unsigned int *options ); +/* security descriptors */ +NTSTATUS NTDLL_create_struct_sd(PSECURITY_DESCRIPTOR nt_sd, struct security_descriptor **server_sd, + data_size_t *server_sd_len); +void NTDLL_free_struct_sd(struct security_descriptor *server_sd); + /* module handling */ extern NTSTATUS MODULE_DllThreadAttach( LPVOID lpReserved ); extern FARPROC RELAY_GetProcAddress( HMODULE module, const IMAGE_EXPORT_DIRECTORY *exports, diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c index 6fbcca8c64..191cd0763d 100644 --- a/dlls/ntdll/sync.c +++ b/dlls/ntdll/sync.c @@ -60,9 +60,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(ntdll); - -static NTSTATUS create_struct_sd(PSECURITY_DESCRIPTOR nt_sd, struct security_descriptor **server_sd, - data_size_t *server_sd_len) +/* creates a struct security_descriptor and contained information in one contiguous piece of memory */ +NTSTATUS NTDLL_create_struct_sd(PSECURITY_DESCRIPTOR nt_sd, struct security_descriptor **server_sd, + data_size_t *server_sd_len) { unsigned int len; PSID owner, group; @@ -124,7 +124,8 @@ static NTSTATUS create_struct_sd(PSECURITY_DESCRIPTOR nt_sd, struct security_des return STATUS_SUCCESS; } -static void free_struct_sd(struct security_descriptor *server_sd) +/* frees a struct security_descriptor allocated by NTDLL_create_struct_sd */ +void NTDLL_free_struct_sd(struct security_descriptor *server_sd) { RtlFreeHeap(GetProcessHeap(), 0, server_sd); } @@ -155,7 +156,7 @@ NTSTATUS WINAPI NtCreateSemaphore( OUT PHANDLE SemaphoreHandle, objattr.sd_len = 0; if (attr) { - ret = create_struct_sd( attr->SecurityDescriptor, &sd, &objattr.sd_len ); + ret = NTDLL_create_struct_sd( attr->SecurityDescriptor, &sd, &objattr.sd_len ); if (ret != STATUS_SUCCESS) return ret; } @@ -173,7 +174,7 @@ NTSTATUS WINAPI NtCreateSemaphore( OUT PHANDLE SemaphoreHandle, } SERVER_END_REQ; - free_struct_sd( sd ); + NTDLL_free_struct_sd( sd ); return ret; } @@ -263,7 +264,7 @@ NTSTATUS WINAPI NtCreateEvent( objattr.sd_len = 0; if (attr) { - ret = create_struct_sd( attr->SecurityDescriptor, &sd, &objattr.sd_len ); + ret = NTDLL_create_struct_sd( attr->SecurityDescriptor, &sd, &objattr.sd_len ); if (ret != STATUS_SUCCESS) return ret; } @@ -281,7 +282,7 @@ NTSTATUS WINAPI NtCreateEvent( } SERVER_END_REQ; - free_struct_sd( sd ); + NTDLL_free_struct_sd( sd ); return ret; } @@ -426,7 +427,7 @@ NTSTATUS WINAPI NtCreateMutant(OUT HANDLE* MutantHandle, objattr.sd_len = 0; if (attr) { - status = create_struct_sd( attr->SecurityDescriptor, &sd, &objattr.sd_len ); + status = NTDLL_create_struct_sd( attr->SecurityDescriptor, &sd, &objattr.sd_len ); if (status != STATUS_SUCCESS) return status; } @@ -443,7 +444,7 @@ NTSTATUS WINAPI NtCreateMutant(OUT HANDLE* MutantHandle, } SERVER_END_REQ; - free_struct_sd( sd ); + NTDLL_free_struct_sd( sd ); return status; } diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index 39d81ed743..2c08a16a4a 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -1855,11 +1855,21 @@ NTSTATUS WINAPI NtCreateSection( HANDLE *handle, ACCESS_MASK access, const OBJEC NTSTATUS ret; BYTE vprot; DWORD len = (attr && attr->ObjectName) ? attr->ObjectName->Length : 0; + struct security_descriptor *sd = NULL; + struct object_attributes objattr; /* Check parameters */ if (len > MAX_PATH*sizeof(WCHAR)) return STATUS_NAME_TOO_LONG; + objattr.rootdir = attr ? attr->RootDirectory : 0; + objattr.sd_len = 0; + if (attr) + { + ret = NTDLL_create_struct_sd( attr->SecurityDescriptor, &sd, &objattr.sd_len ); + if (ret != STATUS_SUCCESS) return ret; + } + vprot = VIRTUAL_GetProt( protect ); if (sec_flags & SEC_RESERVE) { @@ -1875,15 +1885,19 @@ NTSTATUS WINAPI NtCreateSection( HANDLE *handle, ACCESS_MASK access, const OBJEC { req->access = access; req->attributes = (attr) ? attr->Attributes : 0; - req->rootdir = attr ? attr->RootDirectory : 0; req->file_handle = file; req->size = size ? size->QuadPart : 0; req->protect = vprot; + wine_server_add_data( req, &objattr, sizeof(objattr) ); + if (objattr.sd_len) wine_server_add_data( req, sd, objattr.sd_len ); if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); ret = wine_server_call( req ); *handle = reply->handle; } SERVER_END_REQ; + + NTDLL_free_struct_sd( sd ); + return ret; } diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 823594806e..e7ce2cb636 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -1665,11 +1665,10 @@ struct create_mapping_request struct request_header __header; unsigned int access; unsigned int attributes; - obj_handle_t rootdir; file_pos_t size; int protect; obj_handle_t file_handle; - /* VARARG(name,unicode_str); */ + /* VARARG(objattr,object_attributes); */ }; struct create_mapping_reply { @@ -4878,6 +4877,6 @@ union generic_reply struct set_completion_info_reply set_completion_info_reply; }; -#define SERVER_PROTOCOL_VERSION 320 +#define SERVER_PROTOCOL_VERSION 321 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/mapping.c b/server/mapping.c index 33e4204699..8f1bf5c1e0 100644 --- a/server/mapping.c +++ b/server/mapping.c @@ -37,6 +37,7 @@ #include "handle.h" #include "thread.h" #include "request.h" +#include "security.h" struct mapping { @@ -281,7 +282,7 @@ static inline int get_file_size( struct file *file, file_pos_t *size ) static struct object *create_mapping( struct directory *root, const struct unicode_str *name, unsigned int attr, file_pos_t size, int protect, - obj_handle_t handle ) + obj_handle_t handle, const struct security_descriptor *sd ) { struct mapping *mapping; int access = 0; @@ -293,6 +294,10 @@ static struct object *create_mapping( struct directory *root, const struct unico if (get_error() == STATUS_OBJECT_NAME_EXISTS) return &mapping->obj; /* Nothing else to do */ + if (sd) default_set_sd( &mapping->obj, sd, OWNER_SECURITY_INFORMATION| + GROUP_SECURITY_INFORMATION| + DACL_SECURITY_INFORMATION| + SACL_SECURITY_INFORMATION ); mapping->header_size = 0; mapping->base = NULL; mapping->shared_file = NULL; @@ -394,13 +399,24 @@ DECL_HANDLER(create_mapping) struct object *obj; struct unicode_str name; struct directory *root = NULL; + const struct object_attributes *objattr = get_req_data(); + const struct security_descriptor *sd; reply->handle = 0; - get_req_unicode_str( &name ); - if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 ))) + + if (!objattr_is_valid( objattr, get_req_data_size() )) return; - if ((obj = create_mapping( root, &name, req->attributes, req->size, req->protect, req->file_handle ))) + sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL; + + /* get unicode string */ + name.len = ((get_req_data_size() - sizeof(*objattr) - objattr->sd_len) / sizeof(WCHAR)) * sizeof(WCHAR); + name.str = (const WCHAR *)get_req_data() + (sizeof(*objattr) + objattr->sd_len) / sizeof(WCHAR); + + if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) + return; + + if ((obj = create_mapping( root, &name, req->attributes, req->size, req->protect, req->file_handle, sd ))) { reply->handle = alloc_handle( current->process, obj, req->access, req->attributes ); release_object( obj ); diff --git a/server/protocol.def b/server/protocol.def index e486367d13..d336af6b4c 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1310,11 +1310,10 @@ enum char_info_mode @REQ(create_mapping) unsigned int access; /* wanted access rights */ unsigned int attributes; /* object attributes */ - obj_handle_t rootdir; /* root directory */ file_pos_t size; /* mapping size */ int protect; /* protection flags (see below) */ obj_handle_t file_handle; /* file handle */ - VARARG(name,unicode_str); /* object name */ + VARARG(objattr,object_attributes); /* object attributes */ @REPLY obj_handle_t handle; /* handle to the mapping */ @END diff --git a/server/trace.c b/server/trace.c index 377d9de2b1..30d6efd5e1 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1721,14 +1721,13 @@ static void dump_create_mapping_request( const struct create_mapping_request *re { fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " attributes=%08x,", req->attributes ); - fprintf( stderr, " rootdir=%p,", req->rootdir ); fprintf( stderr, " size=" ); dump_file_pos( &req->size ); fprintf( stderr, "," ); fprintf( stderr, " protect=%d,", req->protect ); fprintf( stderr, " file_handle=%p,", req->file_handle ); - fprintf( stderr, " name=" ); - dump_varargs_unicode_str( cur_size ); + fprintf( stderr, " objattr=" ); + dump_varargs_object_attributes( cur_size ); } static void dump_create_mapping_reply( const struct create_mapping_reply *req )