From b31ed58b96ecc5d8efc4ea4986333612070be184 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Wed, 12 Nov 2014 11:25:23 +0100 Subject: [PATCH] server: Set the security descriptor of named pipe objects. --- dlls/ntdll/file.c | 19 +++++++++++++++---- include/wine/server_protocol.h | 10 ++++------ server/named_pipe.c | 21 +++++++++++++++++---- server/protocol.def | 3 +-- server/request.h | 18 ++++++++---------- server/trace.c | 4 +--- 6 files changed, 46 insertions(+), 29 deletions(-) diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index 92d9829ecec..56ea3983487 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -3043,7 +3043,9 @@ NTSTATUS WINAPI NtCreateNamedPipeFile( PHANDLE handle, ULONG access, ULONG inbound_quota, ULONG outbound_quota, PLARGE_INTEGER timeout) { - NTSTATUS status; + struct security_descriptor *sd = NULL; + struct object_attributes objattr; + NTSTATUS status; TRACE("(%p %x %s %p %x %d %x %d %d %d %d %d %d %p)\n", handle, access, debugstr_w(attr->ObjectName->Buffer), iosb, sharing, dispo, @@ -3054,11 +3056,17 @@ NTSTATUS WINAPI NtCreateNamedPipeFile( PHANDLE handle, ULONG access, if (timeout->QuadPart > 0) FIXME("Wrong time %s\n", wine_dbgstr_longlong(timeout->QuadPart)); + objattr.rootdir = wine_server_obj_handle( attr->RootDirectory ); + objattr.sd_len = 0; + objattr.name_len = attr->ObjectName->Length; + + status = NTDLL_create_struct_sd( attr->SecurityDescriptor, &sd, &objattr.sd_len ); + if (status != STATUS_SUCCESS) return status; + SERVER_START_REQ( create_named_pipe ) { req->access = access; req->attributes = attr->Attributes; - req->rootdir = wine_server_obj_handle( attr->RootDirectory ); req->options = options; req->sharing = sharing; req->flags = @@ -3069,12 +3077,15 @@ NTSTATUS WINAPI NtCreateNamedPipeFile( PHANDLE handle, ULONG access, req->outsize = outbound_quota; req->insize = inbound_quota; req->timeout = timeout->QuadPart; - wine_server_add_data( req, attr->ObjectName->Buffer, - attr->ObjectName->Length ); + wine_server_add_data( req, &objattr, sizeof(objattr) ); + if (objattr.sd_len) wine_server_add_data( req, sd, objattr.sd_len ); + wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length ); status = wine_server_call( req ); if (!status) *handle = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; + + NTDLL_free_struct_sd( sd ); return status; } diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index cc966f299e4..e0c3474a47b 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -2960,7 +2960,7 @@ struct accept_hardware_message_request struct request_header __header; unsigned int hw_id; int remove; - user_handle_t new_win; + char __pad_20[4]; }; struct accept_hardware_message_reply { @@ -3146,17 +3146,15 @@ struct create_named_pipe_request struct request_header __header; unsigned int access; unsigned int attributes; - obj_handle_t rootdir; unsigned int options; unsigned int sharing; unsigned int maxinstances; unsigned int outsize; unsigned int insize; - char __pad_44[4]; timeout_t timeout; unsigned int flags; - /* VARARG(name,unicode_str); */ - char __pad_60[4]; + /* VARARG(objattr,object_attributes); */ + char __pad_52[4]; }; struct create_named_pipe_reply { @@ -5849,6 +5847,6 @@ union generic_reply struct set_suspend_context_reply set_suspend_context_reply; }; -#define SERVER_PROTOCOL_VERSION 457 +#define SERVER_PROTOCOL_VERSION 458 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/named_pipe.c b/server/named_pipe.c index 3750d25e790..047b62caaea 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -52,6 +52,7 @@ #include "handle.h" #include "thread.h" #include "request.h" +#include "security.h" enum pipe_state { @@ -689,7 +690,7 @@ static obj_handle_t pipe_server_ioctl( struct fd *fd, ioctl_code_t code, const a } static struct named_pipe *create_named_pipe( struct directory *root, const struct unicode_str *name, - unsigned int attr ) + unsigned int attr, const struct security_descriptor *sd ) { struct object *obj; struct named_pipe *pipe = NULL; @@ -954,6 +955,8 @@ DECL_HANDLER(create_named_pipe) struct pipe_server *server; struct unicode_str name; struct directory *root = NULL; + const struct object_attributes *objattr = get_req_data(); + const struct security_descriptor *sd; if (!req->sharing || (req->sharing & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) || (!(req->flags & NAMED_PIPE_MESSAGE_STREAM_WRITE) && (req->flags & NAMED_PIPE_MESSAGE_STREAM_READ))) @@ -963,11 +966,17 @@ DECL_HANDLER(create_named_pipe) } 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; - pipe = create_named_pipe( root, &name, req->attributes | OBJ_OPENIF ); + sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL; + objattr_get_name( objattr, &name ); + + if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) + return; + + pipe = create_named_pipe( root, &name, req->attributes | OBJ_OPENIF, sd ); if (root) release_object( root ); if (!pipe) return; @@ -1007,6 +1016,10 @@ DECL_HANDLER(create_named_pipe) { reply->handle = alloc_handle( current->process, server, req->access, req->attributes ); server->pipe->instances++; + if (sd) default_set_sd( &server->obj, sd, OWNER_SECURITY_INFORMATION | + GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION | + SACL_SECURITY_INFORMATION ); release_object( server ); } diff --git a/server/protocol.def b/server/protocol.def index 4854e3dcb51..fc6bec568e8 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2274,7 +2274,6 @@ enum message_type @REQ(create_named_pipe) unsigned int access; unsigned int attributes; /* object attributes */ - obj_handle_t rootdir; /* root directory */ unsigned int options; unsigned int sharing; unsigned int maxinstances; @@ -2282,7 +2281,7 @@ enum message_type unsigned int insize; timeout_t timeout; unsigned int flags; - VARARG(name,unicode_str); /* pipe name */ + VARARG(objattr,object_attributes); /* object attributes */ @REPLY obj_handle_t handle; /* handle to the pipe */ @END diff --git a/server/request.h b/server/request.h index c75a6363bc9..e28757c44cb 100644 --- a/server/request.h +++ b/server/request.h @@ -1454,7 +1454,6 @@ C_ASSERT( FIELD_OFFSET(struct reply_message_request, result) == 16 ); C_ASSERT( sizeof(struct reply_message_request) == 24 ); C_ASSERT( FIELD_OFFSET(struct accept_hardware_message_request, hw_id) == 12 ); C_ASSERT( FIELD_OFFSET(struct accept_hardware_message_request, remove) == 16 ); -C_ASSERT( FIELD_OFFSET(struct accept_hardware_message_request, new_win) == 20 ); C_ASSERT( sizeof(struct accept_hardware_message_request) == 24 ); C_ASSERT( FIELD_OFFSET(struct get_message_reply_request, cancel) == 12 ); C_ASSERT( sizeof(struct get_message_reply_request) == 16 ); @@ -1518,15 +1517,14 @@ C_ASSERT( sizeof(struct get_ioctl_result_request) == 24 ); C_ASSERT( sizeof(struct get_ioctl_result_reply) == 8 ); C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, access) == 12 ); C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, attributes) == 16 ); -C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, rootdir) == 20 ); -C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, options) == 24 ); -C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, sharing) == 28 ); -C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, maxinstances) == 32 ); -C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, outsize) == 36 ); -C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, insize) == 40 ); -C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, timeout) == 48 ); -C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, flags) == 56 ); -C_ASSERT( sizeof(struct create_named_pipe_request) == 64 ); +C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, options) == 20 ); +C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, sharing) == 24 ); +C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, maxinstances) == 28 ); +C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, outsize) == 32 ); +C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, insize) == 36 ); +C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, timeout) == 40 ); +C_ASSERT( FIELD_OFFSET(struct create_named_pipe_request, flags) == 48 ); +C_ASSERT( sizeof(struct create_named_pipe_request) == 56 ); C_ASSERT( FIELD_OFFSET(struct create_named_pipe_reply, handle) == 8 ); C_ASSERT( sizeof(struct create_named_pipe_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct get_named_pipe_info_request, handle) == 12 ); diff --git a/server/trace.c b/server/trace.c index 8458f22289e..dd20c04ef6e 100644 --- a/server/trace.c +++ b/server/trace.c @@ -2628,7 +2628,6 @@ static void dump_accept_hardware_message_request( const struct accept_hardware_m { fprintf( stderr, " hw_id=%08x", req->hw_id ); fprintf( stderr, ", remove=%d", req->remove ); - fprintf( stderr, ", new_win=%08x", req->new_win ); } static void dump_get_message_reply_request( const struct get_message_reply_request *req ) @@ -2747,7 +2746,6 @@ static void dump_create_named_pipe_request( const struct create_named_pipe_reque { fprintf( stderr, " access=%08x", req->access ); fprintf( stderr, ", attributes=%08x", req->attributes ); - fprintf( stderr, ", rootdir=%04x", req->rootdir ); fprintf( stderr, ", options=%08x", req->options ); fprintf( stderr, ", sharing=%08x", req->sharing ); fprintf( stderr, ", maxinstances=%08x", req->maxinstances ); @@ -2755,7 +2753,7 @@ static void dump_create_named_pipe_request( const struct create_named_pipe_reque fprintf( stderr, ", insize=%08x", req->insize ); dump_timeout( ", timeout=", &req->timeout ); fprintf( stderr, ", flags=%08x", req->flags ); - dump_varargs_unicode_str( ", name=", cur_size ); + dump_varargs_object_attributes( ", objattr=", cur_size ); } static void dump_create_named_pipe_reply( const struct create_named_pipe_reply *req )