From 0ff07b77e5658310d1e7a57b1b4b4b7591e3422c Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Wed, 15 Oct 2014 10:02:22 +0200
Subject: server: Support for thread and process security descriptors in
 new_process wineserver call. (try 2)

Based on a patch by Joris van der Wel.

Needs ./tools/make_requests
---
 dlls/kernel32/process.c |  2 ++
 server/process.c        | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-
 server/protocol.def     |  6 +++++-
 3 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index b0c06e3..03f3bac 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -2042,6 +2042,8 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
         req->thread_attr    = (tsa && (tsa->nLength >= sizeof(*tsa)) && tsa->bInheritHandle) ? OBJ_INHERIT : 0;
         req->cpu            = cpu;
         req->info_size      = startup_info_size;
+        req->env_size       = (env_end - env) * sizeof(WCHAR);
+        req->process_sd_size = 0;
 
         wine_server_add_data( req, startup_info, startup_info_size );
         wine_server_add_data( req, env, (env_end - env) * sizeof(WCHAR) );
diff --git a/server/process.c b/server/process.c
index e00b429..d2b3c48 100644
--- a/server/process.c
+++ b/server/process.c
@@ -1083,6 +1083,7 @@ DECL_HANDLER(new_process)
     struct process *process;
     struct process *parent = current->process;
     int socket_fd = thread_get_inflight_fd( current, req->socket_fd );
+    const struct security_descriptor *process_sd = NULL, *thread_sd = NULL;
 
     if (socket_fd == -1)
     {
@@ -1138,7 +1139,7 @@ DECL_HANDLER(new_process)
         goto done;
     }
 
-    info->data_size = get_req_data_size();
+    info->data_size = min( get_req_data_size(), req->info_size + req->env_size );
     info->info_size = min( req->info_size, info->data_size );
 
     if (req->info_size < sizeof(*info->data))
@@ -1179,6 +1180,34 @@ DECL_HANDLER(new_process)
 #undef FIXUP_LEN
     }
 
+    if (get_req_data_size() > req->info_size + req->env_size)
+    {
+        data_size_t sd_size, pos = req->info_size + req->env_size;
+
+        /* verify process sd */
+        if ((sd_size = min( get_req_data_size() - pos, req->process_sd_size )))
+        {
+            process_sd = (const struct security_descriptor *)((const char *)get_req_data() + pos);
+            if (!sd_is_valid( process_sd, sd_size ))
+            {
+                set_error( STATUS_INVALID_SECURITY_DESCR );
+                goto done;
+            }
+            pos += sd_size;
+        }
+
+        /* verify thread sd */
+        if ((sd_size = get_req_data_size() - pos))
+        {
+            thread_sd = (const struct security_descriptor *)((const char *)get_req_data() + pos);
+            if (!sd_is_valid( thread_sd, sd_size ))
+            {
+                set_error( STATUS_INVALID_SECURITY_DESCR );
+                goto done;
+            }
+        }
+    }
+
     if (!(thread = create_process( socket_fd, current, req->inherit_all ))) goto done;
     process = thread->process;
     process->startup_info = (struct startup_info *)grab_object( info );
@@ -1241,6 +1270,25 @@ DECL_HANDLER(new_process)
     reply->phandle = alloc_handle( parent, process, req->process_access, req->process_attr );
     reply->thandle = alloc_handle( parent, thread, req->thread_access, req->thread_attr );
 
+    if (process_sd)
+    {
+        default_set_sd( &process->obj, process_sd,
+                        OWNER_SECURITY_INFORMATION |
+                        GROUP_SECURITY_INFORMATION |
+                        DACL_SECURITY_INFORMATION |
+                        SACL_SECURITY_INFORMATION );
+    }
+
+    if (thread_sd)
+    {
+        set_sd_defaults_from_token( &thread->obj, thread_sd,
+                                    OWNER_SECURITY_INFORMATION |
+                                    GROUP_SECURITY_INFORMATION |
+                                    DACL_SECURITY_INFORMATION |
+                                    SACL_SECURITY_INFORMATION,
+                                    process->token );
+    }
+
  done:
     release_object( info );
 }
diff --git a/server/protocol.def b/server/protocol.def
index c313006..5f9461f 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -715,8 +715,12 @@ struct rawinput_device
     unsigned int thread_attr;    /* attributes for thread object */
     cpu_type_t   cpu;            /* CPU that the new process will use */
     data_size_t  info_size;      /* size of startup info */
+    data_size_t  env_size;       /* size of the environment */
+    data_size_t  process_sd_size;/* size of the process security descriptor */
     VARARG(info,startup_info,info_size); /* startup information */
-    VARARG(env,unicode_str);     /* environment for new process */
+    VARARG(env,unicode_str,env_size);                       /* environment for new process */
+    VARARG(process_sd,security_descriptor,process_sd_size); /* security descriptor to set on the process */
+    VARARG(thread_sd,security_descriptor);                  /* security descriptor to set on the thread */
 @REPLY
     obj_handle_t info;           /* new process info handle */
     process_id_t pid;            /* process id */
-- 
2.5.0

