Jacek Caban : server: Share security descriptor among all pipe instances.

Alexandre Julliard julliard at winehq.org
Tue Feb 27 17:29:33 CST 2018


Module: wine
Branch: master
Commit: 1ce2201ed8bab2569b5cd1dbed7ae7665f76a515
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=1ce2201ed8bab2569b5cd1dbed7ae7665f76a515

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Feb 26 19:25:08 2018 +0100

server: Share security descriptor among all pipe instances.

Based on patch by Jonathan Doron.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/tests/pipe.c | 21 ++++++++++----------
 server/named_pipe.c     | 52 +++++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 55 insertions(+), 18 deletions(-)

diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c
index 235ab12..5cbf6e7 100644
--- a/dlls/ntdll/tests/pipe.c
+++ b/dlls/ntdll/tests/pipe.c
@@ -1209,7 +1209,7 @@ static void test_file_info(void)
     CloseHandle( client );
 }
 
-static PSECURITY_DESCRIPTOR get_security_descriptor(HANDLE handle)
+static PSECURITY_DESCRIPTOR get_security_descriptor(HANDLE handle, BOOL todo)
 {
     SECURITY_DESCRIPTOR *sec_desc;
     ULONG length = 0;
@@ -1217,8 +1217,10 @@ static PSECURITY_DESCRIPTOR get_security_descriptor(HANDLE handle)
 
     status = NtQuerySecurityObject(handle, GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION,
                                    NULL, 0, &length);
+    todo_wine_if(todo && status == STATUS_PIPE_DISCONNECTED)
     ok(status == STATUS_BUFFER_TOO_SMALL,
        "Failed to query object security descriptor length: %08x\n", status);
+    if(status != STATUS_BUFFER_TOO_SMALL) return NULL;
     ok(length != 0, "length = 0\n");
 
     sec_desc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, length);
@@ -1295,7 +1297,8 @@ static void _test_group(unsigned line, HANDLE handle, SID *expected_sid, BOOL to
     PSID group_sid;
     NTSTATUS status;
 
-    sec_desc = get_security_descriptor(handle);
+    sec_desc = get_security_descriptor(handle, todo);
+    if (!sec_desc) return;
 
     status = RtlGetGroupSecurityDescriptor(sec_desc, &group_sid, &defaulted);
     ok_(__FILE__,line)(status == STATUS_SUCCESS,
@@ -1351,13 +1354,13 @@ static void test_security_info(void)
     ok(status == STATUS_SUCCESS, "NtSetSecurityObject failed: %08x\n", status);
 
     test_group(server, world_sid, FALSE);
-    test_group(client, world_sid, TRUE);
+    test_group(client, world_sid, FALSE);
 
     /* new instance of pipe server has the same security descriptor */
     server2 = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE, 10,
                                0x20000, 0x20000, 0, NULL);
     ok(server2 != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %u\n", GetLastError());
-    test_group(server2, world_sid, TRUE);
+    test_group(server2, world_sid, FALSE);
 
     /* set client group, server changes as well */
     ret = SetSecurityDescriptorGroup(sec_desc, local_sid, FALSE);
@@ -1366,8 +1369,8 @@ static void test_security_info(void)
     ok(status == STATUS_SUCCESS, "NtSetSecurityObject failed: %08x\n", status);
 
     test_group(server, local_sid, FALSE);
-    test_group(client, local_sid, TRUE);
-    test_group(server2, local_sid, TRUE);
+    test_group(client, local_sid, FALSE);
+    test_group(server2, local_sid, FALSE);
 
     CloseHandle(server);
     /* SD is preserved after closing server object */
@@ -1378,19 +1381,17 @@ static void test_security_info(void)
     client = CreateFileA(PIPENAME, GENERIC_ALL, 0, NULL, OPEN_EXISTING, 0, NULL);
     ok(client != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError());
 
-    test_group(client, local_sid, TRUE);
+    test_group(client, local_sid, FALSE);
 
     ret = DisconnectNamedPipe(server);
     ok(ret, "DisconnectNamedPipe failed: %u\n", GetLastError());
 
     /* disconnected server may be queried for security info, but client does not */
-    test_group(server, local_sid, TRUE);
+    test_group(server, local_sid, FALSE);
     status = NtQuerySecurityObject(client, GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION,
                                    NULL, 0, &length);
-    todo_wine
     ok(status == STATUS_PIPE_DISCONNECTED, "NtQuerySecurityObject returned %08x\n", status);
     status = NtSetSecurityObject(client, GROUP_SECURITY_INFORMATION, sec_desc);
-    todo_wine
     ok(status == STATUS_PIPE_DISCONNECTED, "NtQuerySecurityObject returned %08x\n", status);
 
     /* attempting to create another pipe instance with specified sd fails */
diff --git a/server/named_pipe.c b/server/named_pipe.c
index c6b37ce..c77b07f 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -150,6 +150,9 @@ static void pipe_end_reselect_async( struct fd *fd, struct async_queue *queue );
 
 /* server end functions */
 static void pipe_server_dump( struct object *obj, int verbose );
+static struct security_descriptor *pipe_server_get_sd( struct object *obj );
+static int pipe_server_set_sd( struct object *obj, const struct security_descriptor *sd,
+                               unsigned int set_info );
 static void pipe_server_destroy( struct object *obj);
 static int pipe_server_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
 static void pipe_server_get_file_info( struct fd *fd, unsigned int info_class );
@@ -166,8 +169,8 @@ static const struct object_ops pipe_server_ops =
     no_signal,                    /* signal */
     pipe_end_get_fd,              /* get_fd */
     default_fd_map_access,        /* map_access */
-    default_get_sd,               /* get_sd */
-    default_set_sd,               /* set_sd */
+    pipe_server_get_sd,           /* get_sd */
+    pipe_server_set_sd,           /* set_sd */
     no_lookup_name,               /* lookup_name */
     no_link_name,                 /* link_name */
     NULL,                         /* unlink_name */
@@ -193,6 +196,9 @@ static const struct fd_ops pipe_server_fd_ops =
 
 /* client end functions */
 static void pipe_client_dump( struct object *obj, int verbose );
+static struct security_descriptor *pipe_client_get_sd( struct object *obj );
+static int pipe_client_set_sd( struct object *obj, const struct security_descriptor *sd,
+                               unsigned int set_info );
 static void pipe_client_destroy( struct object *obj );
 static int pipe_client_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
 static void pipe_client_get_file_info( struct fd *fd, unsigned int info_class );
@@ -209,8 +215,8 @@ static const struct object_ops pipe_client_ops =
     no_signal,                    /* signal */
     pipe_end_get_fd,              /* get_fd */
     default_fd_map_access,        /* map_access */
-    default_get_sd,               /* get_sd */
-    default_set_sd,               /* set_sd */
+    pipe_client_get_sd,           /* get_sd */
+    pipe_client_set_sd,           /* set_sd */
     no_lookup_name,               /* lookup_name */
     no_link_name,                 /* link_name */
     NULL,                         /* unlink_name */
@@ -583,6 +589,36 @@ static void pipe_end_get_file_info( struct fd *fd, struct named_pipe *pipe, unsi
     }
 }
 
+static struct security_descriptor *pipe_server_get_sd( struct object *obj )
+{
+    struct pipe_server *server = (struct pipe_server *) obj;
+    return default_get_sd( &server->pipe->obj );
+}
+
+static struct security_descriptor *pipe_client_get_sd( struct object *obj )
+{
+    struct pipe_client *client = (struct pipe_client *) obj;
+    if (client->server) return default_get_sd( &client->server->pipe->obj );
+    set_error( STATUS_PIPE_DISCONNECTED );
+    return NULL;
+}
+
+static int pipe_server_set_sd( struct object *obj, const struct security_descriptor *sd,
+                               unsigned int set_info )
+{
+    struct pipe_server *server = (struct pipe_server *) obj;
+    return default_set_sd( &server->pipe->obj, sd, set_info );
+}
+
+static int pipe_client_set_sd( struct object *obj, const struct security_descriptor *sd,
+                               unsigned int set_info )
+{
+    struct pipe_client *client = (struct pipe_client *) obj;
+    if (client->server) return default_set_sd( &client->server->pipe->obj, sd, set_info );
+    set_error( STATUS_PIPE_DISCONNECTED );
+    return 0;
+}
+
 static void pipe_server_get_file_info( struct fd *fd, unsigned int info_class )
 {
     struct pipe_server *server = get_fd_user( fd );
@@ -1170,6 +1206,10 @@ DECL_HANDLER(create_named_pipe)
         pipe->timeout = req->timeout;
         pipe->flags = req->flags & NAMED_PIPE_MESSAGE_STREAM_WRITE;
         pipe->sharing = req->sharing;
+        if (sd) default_set_sd( &pipe->obj, sd, OWNER_SECURITY_INFORMATION |
+                                                GROUP_SECURITY_INFORMATION |
+                                                DACL_SECURITY_INFORMATION |
+                                                SACL_SECURITY_INFORMATION );
     }
     else
     {
@@ -1193,10 +1233,6 @@ DECL_HANDLER(create_named_pipe)
     {
         reply->handle = alloc_handle( current->process, server, req->access, objattr->attributes );
         server->pipe->instances++;
-        if (sd) default_set_sd( &server->pipe_end.obj, sd, OWNER_SECURITY_INFORMATION |
-                                                           GROUP_SECURITY_INFORMATION |
-                                                           DACL_SECURITY_INFORMATION |
-                                                           SACL_SECURITY_INFORMATION );
         release_object( server );
     }
 




More information about the wine-cvs mailing list