You've already forked wine-staging
mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-04-13 14:42:51 -07:00
Compare commits
19 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
4b95841bdb | ||
|
180fa60a17 | ||
|
9d3369d7a6 | ||
|
2bb1b96f06 | ||
|
2bfe73c2b7 | ||
|
8e2ab550d8 | ||
|
7f5e6044ee | ||
|
db0464c6f2 | ||
|
80455f2b22 | ||
|
ce40587ef4 | ||
|
4ad4f948c3 | ||
|
1fbebd0a1a | ||
|
1761c9534e | ||
|
b500367ff7 | ||
|
5721ee15c9 | ||
|
56264645ad | ||
|
113b554090 | ||
|
24c6b554c9 | ||
|
b861c5731d |
23
README.md
23
README.md
@@ -1,17 +1,20 @@
|
||||
wine-compholio-daily
|
||||
====================
|
||||
wine-compholio
|
||||
==============
|
||||
|
||||
Daily updates for the Wine "Compholio" Edition.
|
||||
The Wine "Compholio" Edition repository includes a variety of patches for Wine to run common Windows applications under Linux.
|
||||
|
||||
Current patches include:
|
||||
* Support for interface change notifications (http://bugs.winehq.org/show_bug.cgi?id=32328)
|
||||
* Support for stored file ACLs (http://bugs.winehq.org/show_bug.cgi?id=31858)
|
||||
* Support for inherited file ACLs (http://bugs.winehq.org/show_bug.cgi?id=34406)
|
||||
* Support for Junction Points (http://bugs.winehq.org/show_bug.cgi?id=12401)
|
||||
* Support for TransmitFile (http://bugs.winehq.org/show_bug.cgi?id=5048)
|
||||
|
||||
* Support for interface change notifications ([Wine Bug #32328](http://bugs.winehq.org/show_bug.cgi?id=32328))
|
||||
* Support for stored file ACLs ([Wine Bug #31858](http://bugs.winehq.org/show_bug.cgi?id=31858))
|
||||
* Support for inherited file ACLs ([Wine Bug #34406](http://bugs.winehq.org/show_bug.cgi?id=34406))
|
||||
* Support for Junction Points ([Wine Bug #12401](http://bugs.winehq.org/show_bug.cgi?id=12401))
|
||||
* Support for TransmitFile ([Wine Bug #5048](http://bugs.winehq.org/show_bug.cgi?id=5048))
|
||||
* Support for GetVolumePathName
|
||||
* Implement an Arial replacement font (http://bugs.winehq.org/show_bug.cgi?id=32323)
|
||||
* Workaround for TransactNamedPipe not being supported (http://bugs.winehq.org/show_bug.cgi?id=17273)
|
||||
* Implement an Arial replacement font ([Wine Bug #32323](http://bugs.winehq.org/show_bug.cgi?id=32323))
|
||||
* Workaround for TransactNamedPipe not being supported ([Wine Bug #17273](http://bugs.winehq.org/show_bug.cgi?id=17273))
|
||||
* Fix incorrect scaling for DECIMAL values in VarDecAdd ([Wine Bug #31269](http://bugs.winehq.org/show_bug.cgi?id=31269))
|
||||
* Return NULL-terminated list of arguments in CommandLineToArgvW ([Wine Bug #22829](http://bugs.winehq.org/show_bug.cgi?id=22829))
|
||||
* XEMBED support for embedding Wine windows inside Linux applications
|
||||
* Reduced SetTimer minimum value from 15 ms to 5 ms (improves Silverlight framerates)
|
||||
* Lockfree algorithm for filedescriptor cache (improves file access speed)
|
||||
|
13
debian/changelog
vendored
13
debian/changelog
vendored
@@ -1,3 +1,16 @@
|
||||
wine-compholio (1.7.22) unstable; urgency=low
|
||||
* Implement passing ACLs to CreateProcess.
|
||||
* Removed several patches (accepted upstream).
|
||||
* Added NT4 support to the process ACL tests.
|
||||
* Implement RegSetKeySecurity on top of NtSetSecurityObject.
|
||||
* Updated RegSetKeySecurity patch to work with special root keys.
|
||||
* Add patch for wtsapi32.WTSEnumerateProcessesW function.
|
||||
* Fix incorrect scaling for DECIMAL values in VarDecAdd.
|
||||
* Updated main extended attributes patch to include BSD support.
|
||||
* Return NULL-terminated list of arguments in CommandLineToArgvW.
|
||||
* Updated main extended attributes patch to include additional data checks.
|
||||
-- Erich E. Hoover <erich.e.hoover@gmail.com> Fri, 11 Jul 2014 13:00:03 -0600
|
||||
|
||||
wine-compholio (1.7.21) unstable; urgency=low
|
||||
* Remove several patches (accepted upstream).
|
||||
-- Sebastian Lackner <sebastian@fds-team.de> Fri, 27 Jun 2014 23:08:48 -0600
|
||||
|
26
debian/tools/gitapply.sh
vendored
26
debian/tools/gitapply.sh
vendored
@@ -31,7 +31,7 @@ warning()
|
||||
usage()
|
||||
{
|
||||
echo ""
|
||||
echo "Usage: ./gitapply [-v] [-d DIRECTORY]"
|
||||
echo "Usage: ./gitapply [--nogit] [-v] [-d DIRECTORY]"
|
||||
echo ""
|
||||
echo "Reads patch data from stdin and applies the patch to the current"
|
||||
echo "directory or the directory given via commandline."
|
||||
@@ -46,6 +46,14 @@ while [[ $# > 0 ]]; do
|
||||
cmd="$1"; shift
|
||||
case "$cmd" in
|
||||
|
||||
--nogit)
|
||||
nogit=1
|
||||
;;
|
||||
|
||||
-v)
|
||||
verbose=1
|
||||
;;
|
||||
|
||||
--directory=*)
|
||||
cd "${cmd#*=}"
|
||||
;;
|
||||
@@ -57,14 +65,6 @@ while [[ $# > 0 ]]; do
|
||||
abort "Reverse applying patches not supported yet with this patch tool."
|
||||
;;
|
||||
|
||||
-v)
|
||||
verbose=1
|
||||
;;
|
||||
|
||||
--nogit)
|
||||
nogit=1
|
||||
;;
|
||||
|
||||
--help)
|
||||
usage
|
||||
exit 0
|
||||
@@ -333,8 +333,8 @@ while IFS= read -r line; do
|
||||
sha="0000000000000000000000000000000000000000"
|
||||
fi
|
||||
if [ "$patch_oldsha1" != "$sha" ]; then
|
||||
echo "$lineno: Expected $patch_oldsha1"
|
||||
echo "$lineno: Got $sha"
|
||||
echo "$lineno: Expected $patch_oldsha1" >&2
|
||||
echo "$lineno: Got $sha" >&2
|
||||
abort "Unable to continue because of sha1 mismatch of original file."
|
||||
fi
|
||||
fi
|
||||
@@ -434,8 +434,8 @@ while IFS= read -r line; do
|
||||
# Check shasum if its not a patch creating a new file
|
||||
sha=$(echo -en "blob $(du -b "$patch_tmpfile" | cut -f1)\x00" | cat - "$patch_tmpfile" | sha1sum | cut -d' ' -f1)
|
||||
if [ "$patch_newsha1" != "$sha" ]; then
|
||||
echo "$lineno: Expected $patch_newsha1"
|
||||
echo "$lineno: Got $sha"
|
||||
echo "$lineno: Expected $patch_newsha1" >&2
|
||||
echo "$lineno: Got $sha" >&2
|
||||
abort "Unable to continue because of sha1 mismatch after applying the patch."
|
||||
fi
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
From 4ae376bebffe60ef378e08528d50c1e5723be739 Mon Sep 17 00:00:00 2001
|
||||
From a424efd08ebe4a247b4a3b874137faadb7f59266 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Fri, 18 Apr 2014 15:34:47 -0600
|
||||
Subject: server: Store file security attributes with extended file
|
||||
@@ -6,11 +6,11 @@ Subject: server: Store file security attributes with extended file
|
||||
|
||||
---
|
||||
configure.ac | 12 ++++++++++++
|
||||
server/file.c | 31 +++++++++++++++++++++++++++++++
|
||||
2 files changed, 43 insertions(+)
|
||||
server/file.c | 39 +++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 51 insertions(+)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 46602d6..99fcb9b 100644
|
||||
index c913f9f..2d5d5ee 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -73,6 +73,7 @@ AC_ARG_WITH(pthread, AS_HELP_STRING([--without-pthread],[do not use the pthrea
|
||||
@@ -27,7 +27,7 @@ index 46602d6..99fcb9b 100644
|
||||
|
||||
+if test "x$with_xattr" != "xno"
|
||||
+then
|
||||
+ AC_CHECK_HEADERS(attr/xattr.h,HAVE_XATTR=1)
|
||||
+ AC_CHECK_HEADERS(attr/xattr.h sys/extattr.h,HAVE_XATTR=1)
|
||||
+fi
|
||||
+if test "x$with_xattr" == "xyes"
|
||||
+then
|
||||
@@ -40,7 +40,7 @@ index 46602d6..99fcb9b 100644
|
||||
|
||||
AC_SUBST(dlldir,"\${libdir}/wine")
|
||||
diff --git a/server/file.c b/server/file.c
|
||||
index 1f008ea..ceb57be 100644
|
||||
index 1f008ea..951e25b 100644
|
||||
--- a/server/file.c
|
||||
+++ b/server/file.c
|
||||
@@ -32,6 +32,7 @@
|
||||
@@ -51,23 +51,27 @@ index 1f008ea..ceb57be 100644
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_UTIME_H
|
||||
#include <utime.h>
|
||||
@@ -39,6 +40,9 @@
|
||||
@@ -39,6 +40,13 @@
|
||||
#ifdef HAVE_POLL_H
|
||||
#include <poll.h>
|
||||
#endif
|
||||
+#ifdef HAVE_ATTR_XATTR_H
|
||||
+#include <attr/xattr.h>
|
||||
+#endif
|
||||
+#ifdef HAVE_SYS_EXTATTR_H
|
||||
+#include <sys/extattr.h>
|
||||
+#define XATTR_SIZE_MAX 65536
|
||||
+#endif
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
@@ -178,6 +182,30 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_
|
||||
@@ -178,6 +186,34 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_
|
||||
return &file->obj;
|
||||
}
|
||||
|
||||
+void set_xattr_sd( int fd, const struct security_descriptor *sd )
|
||||
+{
|
||||
+#ifdef HAVE_ATTR_XATTR_H
|
||||
+#if defined(HAVE_ATTR_XATTR_H) || defined(HAVE_SYS_EXTATTR_H)
|
||||
+ char buffer[XATTR_SIZE_MAX];
|
||||
+ int present, len;
|
||||
+ const ACL *dacl;
|
||||
@@ -85,14 +89,18 @@ index 1f008ea..ceb57be 100644
|
||||
+ buffer[0] = SECURITY_DESCRIPTOR_REVISION;
|
||||
+ buffer[1] = 0;
|
||||
+ memcpy( &buffer[2], sd, len - 2 );
|
||||
+#if defined(HAVE_ATTR_XATTR_H)
|
||||
+ fsetxattr( fd, "user.wine.sd", buffer, len, 0 );
|
||||
+#else
|
||||
+ extattr_set_fd( fd, EXTATTR_NAMESPACE_USER, "wine.sd", buffer, len );
|
||||
+#endif
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
static struct object *create_file( struct fd *root, const char *nameptr, data_size_t len,
|
||||
unsigned int access, unsigned int sharing, int create,
|
||||
unsigned int options, unsigned int attrs,
|
||||
@@ -239,6 +267,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
|
||||
@@ -239,6 +275,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
|
||||
/* FIXME: should set error to STATUS_OBJECT_NAME_COLLISION if file existed before */
|
||||
fd = open_fd( root, name, flags | O_NONBLOCK | O_LARGEFILE, &mode, access, sharing, options );
|
||||
if (!fd) goto done;
|
||||
@@ -100,7 +108,7 @@ index 1f008ea..ceb57be 100644
|
||||
|
||||
if (S_ISDIR(mode))
|
||||
obj = create_dir_obj( fd, access, mode );
|
||||
@@ -580,6 +609,8 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
|
||||
@@ -580,6 +617,8 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
|
||||
mode = st.st_mode & (S_ISUID|S_ISGID|S_ISVTX);
|
||||
mode |= sd_to_mode( sd, owner );
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
From ea0c98e71750a0a55273c8cfb4a9c8931d3cf510 Mon Sep 17 00:00:00 2001
|
||||
From 9b59ad02610a11d39ee8338404fd26021e0458c6 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Fri, 18 Apr 2014 15:35:24 -0600
|
||||
Subject: server: Store user and group inside stored extended file attribute
|
||||
@@ -9,17 +9,17 @@ Subject: server: Store user and group inside stored extended file attribute
|
||||
1 file changed, 70 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/server/file.c b/server/file.c
|
||||
index ceb57be..b9106a8 100644
|
||||
index 951e25b..6981fca 100644
|
||||
--- a/server/file.c
|
||||
+++ b/server/file.c
|
||||
@@ -182,11 +182,12 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_
|
||||
@@ -186,11 +186,12 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_
|
||||
return &file->obj;
|
||||
}
|
||||
|
||||
-void set_xattr_sd( int fd, const struct security_descriptor *sd )
|
||||
+void set_xattr_sd( int fd, const struct security_descriptor *sd, const SID *user, const SID *group )
|
||||
{
|
||||
#ifdef HAVE_ATTR_XATTR_H
|
||||
#if defined(HAVE_ATTR_XATTR_H) || defined(HAVE_SYS_EXTATTR_H)
|
||||
- char buffer[XATTR_SIZE_MAX];
|
||||
- int present, len;
|
||||
+ char buffer[XATTR_SIZE_MAX], *dst_ptr = &buffer[2], *src_ptr = (char *)sd;
|
||||
@@ -28,7 +28,7 @@ index ceb57be..b9106a8 100644
|
||||
const ACL *dacl;
|
||||
|
||||
/* there's no point in storing the security descriptor if there's no DACL */
|
||||
@@ -194,14 +195,52 @@ void set_xattr_sd( int fd, const struct security_descriptor *sd )
|
||||
@@ -198,14 +199,52 @@ void set_xattr_sd( int fd, const struct security_descriptor *sd )
|
||||
dacl = sd_get_dacl( sd, &present );
|
||||
if (!present || !dacl) return;
|
||||
|
||||
@@ -80,10 +80,10 @@ index ceb57be..b9106a8 100644
|
||||
+ memcpy( dst_ptr, src_ptr, sd->dacl_len );
|
||||
+ src_ptr += sd->dacl_len;
|
||||
+ dst_ptr += sd->dacl_len;
|
||||
#if defined(HAVE_ATTR_XATTR_H)
|
||||
fsetxattr( fd, "user.wine.sd", buffer, len, 0 );
|
||||
#endif
|
||||
}
|
||||
@@ -211,6 +250,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
|
||||
#else
|
||||
@@ -219,6 +258,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
|
||||
unsigned int options, unsigned int attrs,
|
||||
const struct security_descriptor *sd )
|
||||
{
|
||||
@@ -91,7 +91,7 @@ index ceb57be..b9106a8 100644
|
||||
struct object *obj = NULL;
|
||||
struct fd *fd;
|
||||
int flags;
|
||||
@@ -241,9 +281,12 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
|
||||
@@ -249,9 +289,12 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
|
||||
|
||||
if (sd)
|
||||
{
|
||||
@@ -105,7 +105,7 @@ index ceb57be..b9106a8 100644
|
||||
mode = sd_to_mode( sd, owner );
|
||||
}
|
||||
else if (options & FILE_DIRECTORY_FILE)
|
||||
@@ -267,7 +310,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
|
||||
@@ -275,7 +318,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
|
||||
/* FIXME: should set error to STATUS_OBJECT_NAME_COLLISION if file existed before */
|
||||
fd = open_fd( root, name, flags | O_NONBLOCK | O_LARGEFILE, &mode, access, sharing, options );
|
||||
if (!fd) goto done;
|
||||
@@ -114,7 +114,7 @@ index ceb57be..b9106a8 100644
|
||||
|
||||
if (S_ISDIR(mode))
|
||||
obj = create_dir_obj( fd, access, mode );
|
||||
@@ -577,7 +620,7 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
|
||||
@@ -585,7 +628,7 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
|
||||
unsigned int set_info )
|
||||
{
|
||||
int unix_fd = get_unix_fd( fd );
|
||||
@@ -123,7 +123,7 @@ index ceb57be..b9106a8 100644
|
||||
struct stat st;
|
||||
mode_t mode;
|
||||
|
||||
@@ -601,6 +644,24 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
|
||||
@@ -609,6 +652,24 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
|
||||
else
|
||||
owner = token_get_user( current->process->token );
|
||||
|
||||
@@ -148,7 +148,7 @@ index ceb57be..b9106a8 100644
|
||||
/* group and sacl not supported */
|
||||
|
||||
if (set_info & DACL_SECURITY_INFORMATION)
|
||||
@@ -609,7 +670,7 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
|
||||
@@ -617,7 +678,7 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
|
||||
mode = st.st_mode & (S_ISUID|S_ISGID|S_ISVTX);
|
||||
mode |= sd_to_mode( sd, owner );
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
From 4498c57f61bf85fca6eb17afd21c0c7051534f75 Mon Sep 17 00:00:00 2001
|
||||
From 0fea62714c3bdf5384f2f47c1985c21470710cfd Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Fri, 18 Apr 2014 14:01:35 -0600
|
||||
Subject: server: Retrieve file security attributes with extended file
|
||||
@@ -7,14 +7,14 @@ Subject: server: Retrieve file security attributes with extended file
|
||||
---
|
||||
dlls/advapi32/tests/security.c | 49 ++++++++++++++++++++--------------------
|
||||
server/change.c | 2 +-
|
||||
server/file.c | 28 ++++++++++++++++++++---
|
||||
3 files changed, 50 insertions(+), 29 deletions(-)
|
||||
server/file.c | 38 ++++++++++++++++++++++++++++---
|
||||
3 files changed, 60 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
|
||||
index a0574c4..26cde37 100644
|
||||
index f3ccc8e..4352ba6 100644
|
||||
--- a/dlls/advapi32/tests/security.c
|
||||
+++ b/dlls/advapi32/tests/security.c
|
||||
@@ -3105,24 +3105,24 @@ static void test_CreateDirectoryA(void)
|
||||
@@ -3131,24 +3131,24 @@ static void test_CreateDirectoryA(void)
|
||||
bret = pGetAce(pDacl, 0, (VOID **)&ace);
|
||||
ok(bret, "Failed to get Current User ACE.\n");
|
||||
bret = EqualSid(&ace->SidStart, user_sid);
|
||||
@@ -51,7 +51,7 @@ index a0574c4..26cde37 100644
|
||||
}
|
||||
LocalFree(pSD);
|
||||
|
||||
@@ -3297,23 +3297,22 @@ static void test_GetNamedSecurityInfoA(void)
|
||||
@@ -3323,23 +3323,22 @@ static void test_GetNamedSecurityInfoA(void)
|
||||
bret = pGetAce(pDacl, 0, (VOID **)&ace);
|
||||
ok(bret, "Failed to get Current User ACE.\n");
|
||||
bret = EqualSid(&ace->SidStart, user_sid);
|
||||
@@ -81,7 +81,7 @@ index a0574c4..26cde37 100644
|
||||
}
|
||||
LocalFree(pSD);
|
||||
HeapFree(GetProcessHeap(), 0, user);
|
||||
@@ -3963,22 +3962,22 @@ static void test_GetSecurityInfo(void)
|
||||
@@ -3989,22 +3988,22 @@ static void test_GetSecurityInfo(void)
|
||||
bret = pGetAce(pDacl, 0, (VOID **)&ace);
|
||||
ok(bret, "Failed to get Current User ACE.\n");
|
||||
bret = EqualSid(&ace->SidStart, user_sid);
|
||||
@@ -111,10 +111,10 @@ index a0574c4..26cde37 100644
|
||||
LocalFree(pSD);
|
||||
CloseHandle(obj);
|
||||
diff --git a/server/change.c b/server/change.c
|
||||
index c391180..77c01bb 100644
|
||||
index c673c48..27dbe25 100644
|
||||
--- a/server/change.c
|
||||
+++ b/server/change.c
|
||||
@@ -287,7 +287,7 @@ static struct security_descriptor *dir_get_sd( struct object *obj )
|
||||
@@ -290,7 +290,7 @@ static struct security_descriptor *dir_get_sd( struct object *obj )
|
||||
assert( obj->ops == &dir_ops );
|
||||
|
||||
fd = dir_get_fd( obj );
|
||||
@@ -124,27 +124,37 @@ index c391180..77c01bb 100644
|
||||
return sd;
|
||||
}
|
||||
diff --git a/server/file.c b/server/file.c
|
||||
index b9106a8..c4706b6 100644
|
||||
index 6981fca..26962df 100644
|
||||
--- a/server/file.c
|
||||
+++ b/server/file.c
|
||||
@@ -496,12 +496,33 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
|
||||
@@ -504,12 +504,43 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
|
||||
return sd;
|
||||
}
|
||||
|
||||
+struct security_descriptor *get_xattr_sd( int fd )
|
||||
+{
|
||||
+#ifdef HAVE_ATTR_XATTR_H
|
||||
+#if defined(HAVE_ATTR_XATTR_H) || defined(HAVE_SYS_EXTATTR_H)
|
||||
+ struct security_descriptor *sd;
|
||||
+ char buffer[XATTR_SIZE_MAX];
|
||||
+ int n;
|
||||
+
|
||||
+#if defined(HAVE_ATTR_XATTR_H)
|
||||
+ n = fgetxattr( fd, "user.wine.sd", buffer, sizeof(buffer) );
|
||||
+ if (n == -1) return NULL;
|
||||
+#else
|
||||
+ n = extattr_get_fd( fd, EXTATTR_NAMESPACE_USER, "wine.sd", buffer, sizeof(buffer) );
|
||||
+#endif
|
||||
+ if (n == -1 || n < 2 + sizeof(struct security_descriptor)) return NULL;
|
||||
+
|
||||
+ /* validate that we can handle the descriptor */
|
||||
+ if (buffer[0] != SECURITY_DESCRIPTOR_REVISION || buffer[1] != 0) return NULL;
|
||||
+
|
||||
+ sd = (struct security_descriptor *)&buffer[2];
|
||||
+ if (n < 2 + sizeof(struct security_descriptor) + sd->owner_len
|
||||
+ + sd->group_len + sd->sacl_len + sd->dacl_len)
|
||||
+ return NULL;
|
||||
+
|
||||
+ sd = mem_alloc( n - 2 );
|
||||
+ memcpy( sd, &buffer[2], n - 2 );
|
||||
+ if (sd) memcpy( sd, &buffer[2], n - 2 );
|
||||
+ return sd;
|
||||
+#else
|
||||
+ return NULL;
|
||||
@@ -161,7 +171,7 @@ index b9106a8..c4706b6 100644
|
||||
|
||||
if (unix_fd == -1 || fstat( unix_fd, &st ) == -1)
|
||||
return obj->sd;
|
||||
@@ -511,9 +532,10 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
|
||||
@@ -519,9 +550,10 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
|
||||
(st.st_uid == *uid))
|
||||
return obj->sd;
|
||||
|
||||
|
@@ -1,38 +0,0 @@
|
||||
From 8abcd1aac3f65585dfb2e761dd737c0609cd5f93 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sun, 1 Jun 2014 23:46:09 +0200
|
||||
Subject: server: Add additional checks in get_xattr_sd to prevent crashes
|
||||
caused by invalid attributes.
|
||||
|
||||
---
|
||||
server/file.c | 10 ++++++++--
|
||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/server/file.c b/server/file.c
|
||||
index 08231a7..11522c3 100644
|
||||
--- a/server/file.c
|
||||
+++ b/server/file.c
|
||||
@@ -738,12 +738,18 @@ struct security_descriptor *get_xattr_sd( int fd )
|
||||
int n;
|
||||
|
||||
n = fgetxattr( fd, "user.wine.sd", buffer, sizeof(buffer) );
|
||||
- if (n == -1) return NULL;
|
||||
+ if (n == -1 || n < 2 + sizeof(struct security_descriptor)) return NULL;
|
||||
+
|
||||
/* validate that we can handle the descriptor */
|
||||
if (buffer[0] != SECURITY_DESCRIPTOR_REVISION || buffer[1] != 0) return NULL;
|
||||
|
||||
+ sd = (struct security_descriptor *)&buffer[2];
|
||||
+ if (n < 2 + sizeof(struct security_descriptor) + sd->owner_len
|
||||
+ + sd->group_len + sd->sacl_len + sd->dacl_len)
|
||||
+ return NULL;
|
||||
+
|
||||
sd = mem_alloc( n - 2 );
|
||||
- memcpy( sd, &buffer[2], n - 2 );
|
||||
+ if (sd) memcpy( sd, &buffer[2], n - 2 );
|
||||
return sd;
|
||||
#else
|
||||
return NULL;
|
||||
--
|
||||
1.7.9.5
|
||||
|
@@ -1,80 +0,0 @@
|
||||
From 682e63875f4ae2f58da1677ff44cf1adea35e7d8 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Sun, 1 Jun 2014 22:06:35 +0200
|
||||
Subject: server: Add support for ACLs/xattr on FreeBSD
|
||||
|
||||
---
|
||||
configure.ac | 2 +-
|
||||
server/file.c | 16 ++++++++++++++--
|
||||
2 files changed, 15 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 0663893..c1ea0c9 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -668,7 +668,7 @@ AC_CHECK_HEADERS([libprocstat.h],,,
|
||||
|
||||
if test "x$with_xattr" != "xno"
|
||||
then
|
||||
- AC_CHECK_HEADERS(attr/xattr.h,HAVE_XATTR=1)
|
||||
+ AC_CHECK_HEADERS(attr/xattr.h sys/extattr.h,HAVE_XATTR=1)
|
||||
fi
|
||||
if test "x$with_xattr" == "xyes"
|
||||
then
|
||||
diff --git a/server/file.c b/server/file.c
|
||||
index d5d5ad4..5a4d2f4 100644
|
||||
--- a/server/file.c
|
||||
+++ b/server/file.c
|
||||
@@ -43,6 +43,10 @@
|
||||
#ifdef HAVE_ATTR_XATTR_H
|
||||
#include <attr/xattr.h>
|
||||
#endif
|
||||
+#ifdef HAVE_SYS_EXTATTR_H
|
||||
+#include <sys/extattr.h>
|
||||
+#define XATTR_SIZE_MAX 65536
|
||||
+#endif
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
@@ -184,7 +188,7 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_
|
||||
|
||||
void set_xattr_sd( int fd, const struct security_descriptor *sd, const SID *user, const SID *group )
|
||||
{
|
||||
-#ifdef HAVE_ATTR_XATTR_H
|
||||
+#if defined(HAVE_ATTR_XATTR_H) || defined(HAVE_SYS_EXTATTR_H)
|
||||
char buffer[XATTR_SIZE_MAX], *dst_ptr = &buffer[2], *src_ptr = (char *)sd;
|
||||
int present, len, owner_len, group_len;
|
||||
struct security_descriptor *dst_sd;
|
||||
@@ -241,7 +245,11 @@ void set_xattr_sd( int fd, const struct security_descriptor *sd, const SID *user
|
||||
memcpy( dst_ptr, src_ptr, sd->dacl_len );
|
||||
src_ptr += sd->dacl_len;
|
||||
dst_ptr += sd->dacl_len;
|
||||
+#if defined(HAVE_ATTR_XATTR_H)
|
||||
fsetxattr( fd, "user.wine.sd", buffer, len, 0 );
|
||||
+#else
|
||||
+ extattr_set_fd( fd, EXTATTR_NAMESPACE_USER, "wine.sd", buffer, len );
|
||||
+#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -732,12 +740,16 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
|
||||
|
||||
struct security_descriptor *get_xattr_sd( int fd )
|
||||
{
|
||||
-#ifdef HAVE_ATTR_XATTR_H
|
||||
+#if defined(HAVE_ATTR_XATTR_H) || defined(HAVE_SYS_EXTATTR_H)
|
||||
struct security_descriptor *sd;
|
||||
char buffer[XATTR_SIZE_MAX];
|
||||
int n;
|
||||
|
||||
+#if defined(HAVE_ATTR_XATTR_H)
|
||||
n = fgetxattr( fd, "user.wine.sd", buffer, sizeof(buffer) );
|
||||
+#else
|
||||
+ n = extattr_get_fd( fd, EXTATTR_NAMESPACE_USER, "wine.sd", buffer, sizeof(buffer) );
|
||||
+#endif
|
||||
if (n == -1 || n < 2 + sizeof(struct security_descriptor)) return NULL;
|
||||
|
||||
/* validate that we can handle the descriptor */
|
||||
--
|
||||
1.7.9.5
|
||||
|
@@ -1,17 +1,17 @@
|
||||
From ccfec2389d48a56f0bfdf54b5f1fde6ead00e345 Mon Sep 17 00:00:00 2001
|
||||
From 977d05dff239899b548e170055e2a38ee16d5fd6 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Tue, 13 May 2014 16:49:31 -0600
|
||||
Date: Wed, 25 Jun 2014 11:49:12 -0600
|
||||
Subject: server: Add default security descriptor ownership for processes.
|
||||
|
||||
---
|
||||
dlls/advapi32/tests/security.c | 34 ++++++++++++++++++++++++++++++++++
|
||||
dlls/advapi32/tests/security.c | 35 +++++++++++++++++++++++++++++++++++
|
||||
server/process.c | 26 +++++++++++++++++++++++++-
|
||||
server/security.h | 1 +
|
||||
server/token.c | 8 ++++++++
|
||||
4 files changed, 68 insertions(+), 1 deletion(-)
|
||||
4 files changed, 69 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
|
||||
index 05da0ae..2cf18e0 100644
|
||||
index 05da0ae..2fb57c4 100644
|
||||
--- a/dlls/advapi32/tests/security.c
|
||||
+++ b/dlls/advapi32/tests/security.c
|
||||
@@ -3853,11 +3853,15 @@ static void test_acls(void)
|
||||
@@ -30,10 +30,12 @@ index 05da0ae..2cf18e0 100644
|
||||
ACL_SIZE_INFORMATION acl_size;
|
||||
PSECURITY_DESCRIPTOR pSD;
|
||||
ACCESS_ALLOWED_ACE *ace;
|
||||
@@ -3887,6 +3891,18 @@ static void test_GetSecurityInfo(void)
|
||||
CloseHandle( token );
|
||||
user_sid = ((TOKEN_USER *)b)->User.Sid;
|
||||
|
||||
@@ -3982,6 +3986,37 @@ static void test_GetSecurityInfo(void)
|
||||
}
|
||||
LocalFree(pSD);
|
||||
CloseHandle(obj);
|
||||
+
|
||||
+ /* Obtain the "domain users" SID from the user SID */
|
||||
+ if (!AllocateAndInitializeSid(&sia, 4, *GetSidSubAuthority(user_sid, 0),
|
||||
+ *GetSidSubAuthority(user_sid, 1),
|
||||
+ *GetSidSubAuthority(user_sid, 2),
|
||||
@@ -45,14 +47,6 @@ index 05da0ae..2cf18e0 100644
|
||||
+ sid_size = sizeof(domain_users_ptr);
|
||||
+ pCreateWellKnownSid(WinAccountDomainUsersSid, domain_sid, domain_users_sid, &sid_size);
|
||||
+ FreeSid(domain_sid);
|
||||
+
|
||||
/* Create something. Files have lots of associated security info. */
|
||||
obj = CreateFileA(myARGV[0], GENERIC_READ|WRITE_DAC, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
@@ -3982,6 +3998,24 @@ static void test_GetSecurityInfo(void)
|
||||
}
|
||||
LocalFree(pSD);
|
||||
CloseHandle(obj);
|
||||
+
|
||||
+ /* Test querying the ownership of a process */
|
||||
+ ret = pGetSecurityInfo(GetCurrentProcess(), SE_KERNEL_OBJECT,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
From 83880f60c7b647123815acb945c090bec17bab47 Mon Sep 17 00:00:00 2001
|
||||
From 7e00c939d05fbb097fa22a60fed2e920587f8de6 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Wed, 14 May 2014 08:14:46 -0600
|
||||
Date: Wed, 25 Jun 2014 11:51:05 -0600
|
||||
Subject: server: Add default security descriptor DACL for processes.
|
||||
|
||||
---
|
||||
@@ -9,7 +9,7 @@ Subject: server: Add default security descriptor DACL for processes.
|
||||
2 files changed, 76 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
|
||||
index 2cf18e0..f767512 100644
|
||||
index 2fb57c4..900c3ff 100644
|
||||
--- a/dlls/advapi32/tests/security.c
|
||||
+++ b/dlls/advapi32/tests/security.c
|
||||
@@ -3858,10 +3858,12 @@ static void test_GetSecurityInfo(void)
|
||||
@@ -33,7 +33,7 @@ index 2cf18e0..f767512 100644
|
||||
DWORD ret;
|
||||
|
||||
if (!pGetSecurityInfo || !pSetSecurityInfo)
|
||||
@@ -4016,6 +4019,53 @@ static void test_GetSecurityInfo(void)
|
||||
@@ -4017,6 +4020,53 @@ static void test_GetSecurityInfo(void)
|
||||
ok(group != NULL, "group should not be NULL\n");
|
||||
ok(EqualSid(group, domain_users_sid), "Process group SID != Domain Users SID.\n");
|
||||
LocalFree(pSD);
|
||||
|
@@ -0,0 +1,142 @@
|
||||
From 828665a6803984db12958dfe7e9c735c192ae257 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sun, 22 Jun 2014 19:04:38 +0200
|
||||
Subject: wtsapi32: Partial implementation of WTSEnumerateProcessesW.
|
||||
|
||||
---
|
||||
dlls/wtsapi32/tests/wtsapi.c | 1 -
|
||||
dlls/wtsapi32/wtsapi32.c | 82 ++++++++++++++++++++++++++++++++++++++----
|
||||
2 files changed, 75 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/dlls/wtsapi32/tests/wtsapi.c b/dlls/wtsapi32/tests/wtsapi.c
|
||||
index e8dced7..a317e5f 100644
|
||||
--- a/dlls/wtsapi32/tests/wtsapi.c
|
||||
+++ b/dlls/wtsapi32/tests/wtsapi.c
|
||||
@@ -85,7 +85,6 @@ static void test_WTSEnumerateProcessesW(void)
|
||||
{
|
||||
found = found || !lstrcmpW(pname, info[i].pProcessName);
|
||||
}
|
||||
- todo_wine
|
||||
ok(found || broken(!ret), "process name %s not found\n", wine_dbgstr_w(pname));
|
||||
if (info) WTSFreeMemory(info);
|
||||
}
|
||||
diff --git a/dlls/wtsapi32/wtsapi32.c b/dlls/wtsapi32/wtsapi32.c
|
||||
index 79d5a7f..9457143 100644
|
||||
--- a/dlls/wtsapi32/wtsapi32.c
|
||||
+++ b/dlls/wtsapi32/wtsapi32.c
|
||||
@@ -18,8 +18,11 @@
|
||||
#include "config.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
+#include "ntstatus.h"
|
||||
+#define WIN32_NO_STATUS
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
+#include "winternl.h"
|
||||
#include "wtsapi32.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
@@ -84,8 +87,13 @@ BOOL WINAPI WTSEnumerateProcessesA(HANDLE hServer, DWORD Reserved, DWORD Version
|
||||
BOOL WINAPI WTSEnumerateProcessesW(HANDLE hServer, DWORD Reserved, DWORD Version,
|
||||
PWTS_PROCESS_INFOW* ppProcessInfo, DWORD* pCount)
|
||||
{
|
||||
- FIXME("Stub %p 0x%08x 0x%08x %p %p\n", hServer, Reserved, Version,
|
||||
- ppProcessInfo, pCount);
|
||||
+ WTS_PROCESS_INFOW *processInfo;
|
||||
+ SYSTEM_PROCESS_INFORMATION *spi;
|
||||
+ ULONG size = 0x4000;
|
||||
+ void *buf = NULL;
|
||||
+ NTSTATUS status;
|
||||
+ DWORD count;
|
||||
+ WCHAR *name;
|
||||
|
||||
if (!ppProcessInfo || !pCount || Reserved != 0 || Version != 1)
|
||||
{
|
||||
@@ -93,9 +101,71 @@ BOOL WINAPI WTSEnumerateProcessesW(HANDLE hServer, DWORD Reserved, DWORD Version
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
- *pCount = 0;
|
||||
- *ppProcessInfo = NULL;
|
||||
+ if (hServer != WTS_CURRENT_SERVER_HANDLE)
|
||||
+ {
|
||||
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ do
|
||||
+ {
|
||||
+ size *= 2;
|
||||
+ HeapFree(GetProcessHeap(), 0, buf);
|
||||
+ buf = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
+ if (!buf)
|
||||
+ {
|
||||
+ SetLastError(ERROR_OUTOFMEMORY);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ status = NtQuerySystemInformation(SystemProcessInformation, buf, size, NULL);
|
||||
+ }
|
||||
+ while (status == STATUS_INFO_LENGTH_MISMATCH);
|
||||
+
|
||||
+ if (status != STATUS_SUCCESS)
|
||||
+ {
|
||||
+ HeapFree(GetProcessHeap(), 0, buf);
|
||||
+ SetLastError(RtlNtStatusToDosError(status));
|
||||
+ return FALSE;
|
||||
+ }
|
||||
|
||||
+ spi = buf;
|
||||
+ count = size = 0;
|
||||
+ for (;;)
|
||||
+ {
|
||||
+ size += sizeof(WTS_PROCESS_INFOW) + spi->ProcessName.Length + sizeof(WCHAR);
|
||||
+ count++;
|
||||
+ if (spi->NextEntryOffset == 0) break;
|
||||
+ spi = (SYSTEM_PROCESS_INFORMATION *)(((PCHAR)spi) + spi->NextEntryOffset);
|
||||
+ }
|
||||
+
|
||||
+ processInfo = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
+ if (!processInfo)
|
||||
+ {
|
||||
+ HeapFree(GetProcessHeap(), 0, buf);
|
||||
+ SetLastError(ERROR_OUTOFMEMORY);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ name = (WCHAR *)&processInfo[count];
|
||||
+
|
||||
+ *ppProcessInfo = processInfo;
|
||||
+ *pCount = count;
|
||||
+
|
||||
+ spi = buf;
|
||||
+ while (count--)
|
||||
+ {
|
||||
+ processInfo->SessionId = 0;
|
||||
+ processInfo->ProcessId = HandleToUlong(spi->UniqueProcessId);
|
||||
+ processInfo->pProcessName = name;
|
||||
+ processInfo->pUserSid = NULL;
|
||||
+ memcpy( name, spi->ProcessName.Buffer, spi->ProcessName.Length );
|
||||
+ name[ spi->ProcessName.Length/sizeof(WCHAR) ] = 0;
|
||||
+
|
||||
+ processInfo++;
|
||||
+ name += (spi->ProcessName.Length + sizeof(WCHAR))/sizeof(WCHAR);
|
||||
+ spi = (SYSTEM_PROCESS_INFORMATION *)(((PCHAR)spi) + spi->NextEntryOffset);
|
||||
+ }
|
||||
+
|
||||
+ HeapFree(GetProcessHeap(), 0, buf);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -159,9 +229,7 @@ BOOL WINAPI WTSEnumerateSessionsW(HANDLE hServer, DWORD Reserved, DWORD Version,
|
||||
*/
|
||||
void WINAPI WTSFreeMemory(PVOID pMemory)
|
||||
{
|
||||
- static int once;
|
||||
-
|
||||
- if (!once++) FIXME("Stub %p\n", pMemory);
|
||||
+ HeapFree(GetProcessHeap(), 0, pMemory);
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
--
|
||||
1.7.9.5
|
||||
|
@@ -0,0 +1,3 @@
|
||||
Revision: 1
|
||||
Author: Sebastian Lackner
|
||||
Title: Partial implementation of WTSEnumerateProcessesW.
|
@@ -0,0 +1,103 @@
|
||||
From 91fb6970f6b7f5a5c93d066c143e96398fba294e Mon Sep 17 00:00:00 2001
|
||||
From: Joris van der Wel <joris@jorisvanderwel.com>
|
||||
Date: Wed, 9 Jul 2014 00:58:10 +0200
|
||||
Subject: server: A new function "set_sd_defaults_from_token" (try 3)
|
||||
|
||||
server: A new function "set_sd_defaults_from_token" that sets the
|
||||
security descriptor along with a token that will be used to gather
|
||||
defaults, instead of always using the primary token.
|
||||
|
||||
Some objects take their defaults not from a primary token but from a
|
||||
different one
|
||||
(such as from the impersonation token or the process token).
|
||||
This function can be used to create the various set_sd implementations
|
||||
for the objects that need it.
|
||||
As a bonus, a NULL token will skip setting any defaults, this is
|
||||
useful for object implementations that would like to set their
|
||||
defaults _only_ upon creation.
|
||||
---
|
||||
server/object.c | 23 +++++++++++++++--------
|
||||
server/object.h | 2 ++
|
||||
2 files changed, 17 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/server/object.c b/server/object.c
|
||||
index 11ef0ce..6389409 100644
|
||||
--- a/server/object.c
|
||||
+++ b/server/object.c
|
||||
@@ -423,8 +423,8 @@ struct security_descriptor *default_get_sd( struct object *obj )
|
||||
return obj->sd;
|
||||
}
|
||||
|
||||
-int default_set_sd( struct object *obj, const struct security_descriptor *sd,
|
||||
- unsigned int set_info )
|
||||
+int set_sd_defaults_from_token( struct object *obj, const struct security_descriptor *sd,
|
||||
+ unsigned int set_info, struct token *token )
|
||||
{
|
||||
struct security_descriptor new_sd, *new_sd_ptr;
|
||||
int present;
|
||||
@@ -446,9 +446,9 @@ int default_set_sd( struct object *obj, const struct security_descriptor *sd,
|
||||
owner = sd_get_owner( obj->sd );
|
||||
new_sd.owner_len = obj->sd->owner_len;
|
||||
}
|
||||
- else
|
||||
+ else if (token)
|
||||
{
|
||||
- owner = token_get_user( current->process->token );
|
||||
+ owner = token_get_user( token );
|
||||
new_sd.owner_len = security_sid_len( owner );
|
||||
}
|
||||
|
||||
@@ -462,9 +462,9 @@ int default_set_sd( struct object *obj, const struct security_descriptor *sd,
|
||||
group = sd_get_group( obj->sd );
|
||||
new_sd.group_len = obj->sd->group_len;
|
||||
}
|
||||
- else
|
||||
+ else if (token)
|
||||
{
|
||||
- group = token_get_primary_group( current->process->token );
|
||||
+ group = token_get_primary_group( token );
|
||||
new_sd.group_len = security_sid_len( group );
|
||||
}
|
||||
|
||||
@@ -494,9 +494,9 @@ int default_set_sd( struct object *obj, const struct security_descriptor *sd,
|
||||
|
||||
if (obj->sd && present)
|
||||
new_sd.dacl_len = obj->sd->dacl_len;
|
||||
- else
|
||||
+ else if (token)
|
||||
{
|
||||
- dacl = token_get_default_dacl( current->process->token );
|
||||
+ dacl = token_get_default_dacl( token );
|
||||
new_sd.dacl_len = dacl->AclSize;
|
||||
}
|
||||
}
|
||||
@@ -521,6 +521,13 @@ int default_set_sd( struct object *obj, const struct security_descriptor *sd,
|
||||
return 1;
|
||||
}
|
||||
|
||||
+/** Set the security descriptor using the current primary token for defaults. */
|
||||
+int default_set_sd( struct object *obj, const struct security_descriptor *sd,
|
||||
+ unsigned int set_info )
|
||||
+{
|
||||
+ return set_sd_defaults_from_token( obj, sd, set_info, current->process->token );
|
||||
+}
|
||||
+
|
||||
struct object *no_lookup_name( struct object *obj, struct unicode_str *name,
|
||||
unsigned int attr )
|
||||
{
|
||||
diff --git a/server/object.h b/server/object.h
|
||||
index bb3ff21..7201ff9 100644
|
||||
--- a/server/object.h
|
||||
+++ b/server/object.h
|
||||
@@ -139,6 +139,8 @@ extern struct fd *no_get_fd( struct object *obj );
|
||||
extern unsigned int no_map_access( struct object *obj, unsigned int access );
|
||||
extern struct security_descriptor *default_get_sd( struct object *obj );
|
||||
extern int default_set_sd( struct object *obj, const struct security_descriptor *sd, unsigned int set_info );
|
||||
+extern int set_sd_defaults_from_token( struct object *obj, const struct security_descriptor *sd,
|
||||
+ unsigned int set_info, struct token *token );
|
||||
extern struct object *no_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attributes );
|
||||
extern struct object *no_open_file( struct object *obj, unsigned int access, unsigned int sharing,
|
||||
unsigned int options );
|
||||
--
|
||||
1.7.9.5
|
||||
|
@@ -0,0 +1,176 @@
|
||||
From fe16cbc2062778bef273ac84eca992dcc45653e6 Mon Sep 17 00:00:00 2001
|
||||
From: Joris van der Wel <joris@jorisvanderwel.com>
|
||||
Date: Wed, 9 Jul 2014 00:58:47 +0200
|
||||
Subject: server: Support sending process and thread security descriptors for
|
||||
the "new_process" request in the protocol.
|
||||
|
||||
server: Support sending process and thread security descriptors for
|
||||
the "new_process" request in the protocol.
|
||||
---
|
||||
dlls/kernel32/process.c | 30 +++++++++++++++++-------------
|
||||
server/process.c | 33 ++++++++++++++++++++-------------
|
||||
server/protocol.def | 41 +++++++++++++++++++++++------------------
|
||||
3 files changed, 60 insertions(+), 44 deletions(-)
|
||||
|
||||
diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
|
||||
index 2566ac4..8bf1934 100644
|
||||
--- a/dlls/kernel32/process.c
|
||||
+++ b/dlls/kernel32/process.c
|
||||
@@ -2025,19 +2025,23 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
|
||||
|
||||
SERVER_START_REQ( new_process )
|
||||
{
|
||||
- req->inherit_all = inherit;
|
||||
- req->create_flags = flags;
|
||||
- req->socket_fd = socketfd[1];
|
||||
- req->exe_file = wine_server_obj_handle( hFile );
|
||||
- req->process_access = PROCESS_ALL_ACCESS;
|
||||
- req->process_attr = (psa && (psa->nLength >= sizeof(*psa)) && psa->bInheritHandle) ? OBJ_INHERIT : 0;
|
||||
- req->thread_access = THREAD_ALL_ACCESS;
|
||||
- req->thread_attr = (tsa && (tsa->nLength >= sizeof(*tsa)) && tsa->bInheritHandle) ? OBJ_INHERIT : 0;
|
||||
- req->cpu = cpu;
|
||||
- req->info_size = startup_info_size;
|
||||
-
|
||||
- wine_server_add_data( req, startup_info, startup_info_size );
|
||||
- wine_server_add_data( req, env, (env_end - env) * sizeof(WCHAR) );
|
||||
+ req->inherit_all = inherit;
|
||||
+ req->create_flags = flags;
|
||||
+ req->socket_fd = socketfd[1];
|
||||
+ req->exe_file = wine_server_obj_handle( hFile );
|
||||
+ req->process_access = PROCESS_ALL_ACCESS;
|
||||
+ req->process_attr = (psa && (psa->nLength >= sizeof(*psa)) && psa->bInheritHandle) ? OBJ_INHERIT : 0;
|
||||
+ req->thread_access = THREAD_ALL_ACCESS;
|
||||
+ req->thread_attr = (tsa && (tsa->nLength >= sizeof(*tsa)) && tsa->bInheritHandle) ? OBJ_INHERIT : 0;
|
||||
+ req->cpu = cpu;
|
||||
+ req->process_sd_size = 0;
|
||||
+ req->thread_sd_size = 0;
|
||||
+ req->info_size = startup_info_size;
|
||||
+ req->env_size = (env_end - env) * sizeof(WCHAR);
|
||||
+
|
||||
+ wine_server_add_data( req, startup_info, req->info_size );
|
||||
+ wine_server_add_data( req, env , req->env_size );
|
||||
+
|
||||
if (!(status = wine_server_call( req )))
|
||||
{
|
||||
info->dwProcessId = (DWORD)reply->pid;
|
||||
diff --git a/server/process.c b/server/process.c
|
||||
index 7b9a3b2..9942eb3 100644
|
||||
--- a/server/process.c
|
||||
+++ b/server/process.c
|
||||
@@ -880,6 +880,9 @@ DECL_HANDLER(new_process)
|
||||
struct process *process;
|
||||
struct process *parent = current->process;
|
||||
int socket_fd = thread_get_inflight_fd( current, req->socket_fd );
|
||||
+ const startup_info_t *req_info;
|
||||
+ data_size_t req_info_size;
|
||||
+ const WCHAR *req_env;
|
||||
|
||||
if (socket_fd == -1)
|
||||
{
|
||||
@@ -903,6 +906,12 @@ DECL_HANDLER(new_process)
|
||||
close( socket_fd );
|
||||
return;
|
||||
}
|
||||
+
|
||||
+ req_info = (const startup_info_t *)
|
||||
+ ((char*)get_req_data() + req->process_sd_size + req->thread_sd_size);
|
||||
+
|
||||
+ req_env = (const WCHAR *)
|
||||
+ ((char*)get_req_data() + req->process_sd_size + req->thread_sd_size + req->info_size);
|
||||
|
||||
if (!req->info_size) /* create an orphaned process */
|
||||
{
|
||||
@@ -920,27 +929,25 @@ DECL_HANDLER(new_process)
|
||||
!(info->exe_file = get_file_obj( current->process, req->exe_file, FILE_READ_DATA )))
|
||||
goto done;
|
||||
|
||||
- info->data_size = get_req_data_size();
|
||||
- info->info_size = min( req->info_size, info->data_size );
|
||||
-
|
||||
if (req->info_size < sizeof(*info->data))
|
||||
{
|
||||
/* make sure we have a full startup_info_t structure */
|
||||
- data_size_t env_size = info->data_size - info->info_size;
|
||||
- data_size_t info_size = min( req->info_size, FIELD_OFFSET( startup_info_t, curdir_len ));
|
||||
-
|
||||
- if (!(info->data = mem_alloc( sizeof(*info->data) + env_size ))) goto done;
|
||||
- memcpy( info->data, get_req_data(), info_size );
|
||||
- memset( (char *)info->data + info_size, 0, sizeof(*info->data) - info_size );
|
||||
- memcpy( info->data + 1, (const char *)get_req_data() + req->info_size, env_size );
|
||||
- info->info_size = sizeof(startup_info_t);
|
||||
- info->data_size = info->info_size + env_size;
|
||||
+ info->info_size = sizeof(*info->data);
|
||||
+ info->data_size = sizeof(*info->data) + req->env_size;
|
||||
+
|
||||
+ req_info_size = min( req->info_size, FIELD_OFFSET( startup_info_t, curdir_len ));
|
||||
+ if (!(info->data = mem_alloc( info->data_size ))) goto done;
|
||||
+ memset( info->data, 0, info->data_size );
|
||||
+ memcpy( info->data, req_info, req_info_size );
|
||||
+ memcpy( info->data + 1, req_env, req->env_size );
|
||||
}
|
||||
else
|
||||
{
|
||||
data_size_t pos = sizeof(*info->data);
|
||||
+ info->info_size = req->info_size;
|
||||
+ info->data_size = req->info_size + req->env_size;
|
||||
|
||||
- if (!(info->data = memdup( get_req_data(), info->data_size ))) goto done;
|
||||
+ if (!(info->data = memdup( req_info, info->data_size ))) goto done;
|
||||
#define FIXUP_LEN(len) do { (len) = min( (len), info->info_size - pos ); pos += (len); } while(0)
|
||||
FIXUP_LEN( info->data->curdir_len );
|
||||
FIXUP_LEN( info->data->dllpath_len );
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index a8c1fb9..7b0b769 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -661,24 +661,29 @@ struct rawinput_device
|
||||
|
||||
/* Create a new process from the context of the parent */
|
||||
@REQ(new_process)
|
||||
- int inherit_all; /* inherit all handles from parent */
|
||||
- unsigned int create_flags; /* creation flags */
|
||||
- int socket_fd; /* file descriptor for process socket */
|
||||
- obj_handle_t exe_file; /* file handle for main exe */
|
||||
- unsigned int process_access; /* access rights for process object */
|
||||
- unsigned int process_attr; /* attributes for process object */
|
||||
- unsigned int thread_access; /* access rights for thread object */
|
||||
- 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 */
|
||||
- VARARG(info,startup_info,info_size); /* startup information */
|
||||
- VARARG(env,unicode_str); /* environment for new process */
|
||||
-@REPLY
|
||||
- obj_handle_t info; /* new process info handle */
|
||||
- process_id_t pid; /* process id */
|
||||
- obj_handle_t phandle; /* process handle (in the current process) */
|
||||
- thread_id_t tid; /* thread id */
|
||||
- obj_handle_t thandle; /* thread handle (in the current process) */
|
||||
+ int inherit_all; /* inherit all handles from parent */
|
||||
+ unsigned int create_flags; /* creation flags */
|
||||
+ int socket_fd; /* file descriptor for process socket */
|
||||
+ obj_handle_t exe_file; /* file handle for main exe */
|
||||
+ unsigned int process_access; /* access rights for process object */
|
||||
+ unsigned int process_attr; /* attributes for process object */
|
||||
+ unsigned int thread_access; /* access rights for thread object */
|
||||
+ unsigned int thread_attr; /* attributes for thread object */
|
||||
+ cpu_type_t cpu; /* CPU that the new process will use */
|
||||
+ data_size_t process_sd_size; /* size of the process security descriptor */
|
||||
+ data_size_t thread_sd_size; /* size of the thread security descriptor */
|
||||
+ data_size_t info_size; /* size of startup info */
|
||||
+ data_size_t env_size; /* size of the environment */
|
||||
+ VARARG(process_sd,security_descriptor,process_sd_size); /* security descriptor to set on the process */
|
||||
+ VARARG(thread_sd,security_descriptor,thread_sd_size); /* security descriptor to set on the thread */
|
||||
+ VARARG(info,startup_info,info_size); /* startup information */
|
||||
+ VARARG(env,unicode_str,env_size); /* environment for new process */
|
||||
+@REPLY
|
||||
+ obj_handle_t info; /* new process info handle */
|
||||
+ process_id_t pid; /* process id */
|
||||
+ obj_handle_t phandle; /* process handle (in the current process) */
|
||||
+ thread_id_t tid; /* thread id */
|
||||
+ obj_handle_t thandle; /* thread handle (in the current process) */
|
||||
@END
|
||||
|
||||
|
||||
--
|
||||
1.7.9.5
|
||||
|
@@ -0,0 +1,242 @@
|
||||
From d565d8b72c9f57d5553f72dfd7d18e2e05033c0c Mon Sep 17 00:00:00 2001
|
||||
From: Joris van der Wel <joris@jorisvanderwel.com>
|
||||
Date: Wed, 9 Jul 2014 00:59:30 +0200
|
||||
Subject: server: implement passing a process security descriptor to
|
||||
CreateProcess.
|
||||
|
||||
server: implement passing a process security descriptor to CreateProcess.
|
||||
|
||||
For now the function "NTDLL_create_struct_sd" has been duplicated in
|
||||
kernel32.
|
||||
This is needed because kernel32 makes the server call. kernel32 currently
|
||||
makes the server call because NtCreateProcess(Ex) has not been implemented in
|
||||
ntdll. When NtCreateProcessEx (and NtCreateThreadEx) gets implemented, the
|
||||
server call will be made from within ntdll instead, and this extra function
|
||||
in kernel32 will no longer be needed.
|
||||
---
|
||||
dlls/advapi32/tests/security.c | 3 --
|
||||
dlls/kernel32/process.c | 85 +++++++++++++++++++++++++++++++++++++++-
|
||||
server/process.c | 24 ++++++++++++
|
||||
3 files changed, 108 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
|
||||
index b44496a..b1b35aa 100644
|
||||
--- a/dlls/advapi32/tests/security.c
|
||||
+++ b/dlls/advapi32/tests/security.c
|
||||
@@ -2696,7 +2696,6 @@ static void test_process_security_child(void)
|
||||
ret = DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(),
|
||||
&handle1, PROCESS_ALL_ACCESS, TRUE, 0 );
|
||||
err = GetLastError();
|
||||
- todo_wine
|
||||
ok(!ret && err == ERROR_ACCESS_DENIED, "duplicating handle should have failed "
|
||||
"with STATUS_ACCESS_DENIED, instead of err:%d\n", err);
|
||||
|
||||
@@ -2704,10 +2703,8 @@ static void test_process_security_child(void)
|
||||
|
||||
/* These two should fail - they are denied by ACL */
|
||||
handle = OpenProcess( PROCESS_VM_READ, FALSE, GetCurrentProcessId() );
|
||||
- todo_wine
|
||||
ok(handle == NULL, "OpenProcess(PROCESS_VM_READ) should have failed\n");
|
||||
handle = OpenProcess( PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId() );
|
||||
- todo_wine
|
||||
ok(handle == NULL, "OpenProcess(PROCESS_ALL_ACCESS) should have failed\n");
|
||||
|
||||
/* Documented privilege elevation */
|
||||
diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
|
||||
index 8bf1934..5f6c2e5 100644
|
||||
--- a/dlls/kernel32/process.c
|
||||
+++ b/dlls/kernel32/process.c
|
||||
@@ -1916,6 +1916,70 @@ static pid_t exec_loader( LPCWSTR cmd_line, unsigned int flags, int socketfd,
|
||||
return pid;
|
||||
}
|
||||
|
||||
+/* creates a struct security_descriptor and contained information in one contiguous piece of memory */
|
||||
+static NTSTATUS create_struct_sd(PSECURITY_DESCRIPTOR nt_sd, struct security_descriptor **server_sd,
|
||||
+ data_size_t *server_sd_len)
|
||||
+{
|
||||
+ unsigned int len;
|
||||
+ PSID owner, group;
|
||||
+ ACL *dacl, *sacl;
|
||||
+ BOOLEAN owner_present, group_present, dacl_present, sacl_present;
|
||||
+ BOOLEAN defaulted;
|
||||
+ NTSTATUS status;
|
||||
+ unsigned char *ptr;
|
||||
+
|
||||
+ if (!nt_sd)
|
||||
+ {
|
||||
+ *server_sd = NULL;
|
||||
+ *server_sd_len = 0;
|
||||
+ return STATUS_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ len = sizeof(struct security_descriptor);
|
||||
+
|
||||
+ status = RtlGetOwnerSecurityDescriptor(nt_sd, &owner, &owner_present);
|
||||
+ if (status != STATUS_SUCCESS) return status;
|
||||
+ status = RtlGetGroupSecurityDescriptor(nt_sd, &group, &group_present);
|
||||
+ if (status != STATUS_SUCCESS) return status;
|
||||
+ status = RtlGetSaclSecurityDescriptor(nt_sd, &sacl_present, &sacl, &defaulted);
|
||||
+ if (status != STATUS_SUCCESS) return status;
|
||||
+ status = RtlGetDaclSecurityDescriptor(nt_sd, &dacl_present, &dacl, &defaulted);
|
||||
+ if (status != STATUS_SUCCESS) return status;
|
||||
+
|
||||
+ if (owner_present)
|
||||
+ len += RtlLengthSid(owner);
|
||||
+ if (group_present)
|
||||
+ len += RtlLengthSid(group);
|
||||
+ if (sacl_present && sacl)
|
||||
+ len += sacl->AclSize;
|
||||
+ if (dacl_present && dacl)
|
||||
+ len += dacl->AclSize;
|
||||
+
|
||||
+ /* fix alignment for the Unicode name that follows the structure */
|
||||
+ len = (len + sizeof(WCHAR) - 1) & ~(sizeof(WCHAR) - 1);
|
||||
+ *server_sd = RtlAllocateHeap(GetProcessHeap(), 0, len);
|
||||
+ if (!*server_sd) return STATUS_NO_MEMORY;
|
||||
+
|
||||
+ (*server_sd)->control = ((SECURITY_DESCRIPTOR *)nt_sd)->Control & ~SE_SELF_RELATIVE;
|
||||
+ (*server_sd)->owner_len = owner_present ? RtlLengthSid(owner) : 0;
|
||||
+ (*server_sd)->group_len = group_present ? RtlLengthSid(group) : 0;
|
||||
+ (*server_sd)->sacl_len = (sacl_present && sacl) ? sacl->AclSize : 0;
|
||||
+ (*server_sd)->dacl_len = (dacl_present && dacl) ? dacl->AclSize : 0;
|
||||
+
|
||||
+ ptr = (unsigned char *)(*server_sd + 1);
|
||||
+ memcpy(ptr, owner, (*server_sd)->owner_len);
|
||||
+ ptr += (*server_sd)->owner_len;
|
||||
+ memcpy(ptr, group, (*server_sd)->group_len);
|
||||
+ ptr += (*server_sd)->group_len;
|
||||
+ memcpy(ptr, sacl, (*server_sd)->sacl_len);
|
||||
+ ptr += (*server_sd)->sacl_len;
|
||||
+ memcpy(ptr, dacl, (*server_sd)->dacl_len);
|
||||
+
|
||||
+ *server_sd_len = len;
|
||||
+
|
||||
+ return STATUS_SUCCESS;
|
||||
+}
|
||||
+
|
||||
/***********************************************************************
|
||||
* create_process
|
||||
*
|
||||
@@ -1939,17 +2003,31 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
|
||||
int socketfd[2], stdin_fd = -1, stdout_fd = -1;
|
||||
pid_t pid;
|
||||
int err, cpu;
|
||||
+ struct security_descriptor *psd = NULL;
|
||||
+ data_size_t psd_len = 0;
|
||||
|
||||
if ((cpu = get_process_cpu( filename, binary_info )) == -1)
|
||||
{
|
||||
SetLastError( ERROR_BAD_EXE_FORMAT );
|
||||
return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (psa && (psa->nLength >= sizeof(*psa)) && psa->lpSecurityDescriptor)
|
||||
+ {
|
||||
+ status = create_struct_sd( psa->lpSecurityDescriptor, &psd, &psd_len );
|
||||
+ if (status != STATUS_SUCCESS)
|
||||
+ {
|
||||
+ WARN("Invalid process security descriptor with status %x\n", status);
|
||||
+ SetLastError( RtlNtStatusToDosError(status) );
|
||||
+ return FALSE;
|
||||
+ }
|
||||
}
|
||||
|
||||
/* create the socket for the new process */
|
||||
|
||||
if (socketpair( PF_UNIX, SOCK_STREAM, 0, socketfd ) == -1)
|
||||
{
|
||||
+ RtlFreeHeap(GetProcessHeap(), 0, psd);
|
||||
SetLastError( ERROR_TOO_MANY_OPEN_FILES );
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1989,6 +2067,7 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
|
||||
winedebug, binary_info, TRUE );
|
||||
}
|
||||
close( socketfd[0] );
|
||||
+ RtlFreeHeap(GetProcessHeap(), 0, psd);
|
||||
SetLastError( RtlNtStatusToDosError( status ));
|
||||
return FALSE;
|
||||
}
|
||||
@@ -2001,6 +2080,7 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
|
||||
RtlReleasePebLock();
|
||||
close( socketfd[0] );
|
||||
close( socketfd[1] );
|
||||
+ RtlFreeHeap(GetProcessHeap(), 0, psd);
|
||||
return FALSE;
|
||||
}
|
||||
if (!env) env = NtCurrentTeb()->Peb->ProcessParameters->Environment;
|
||||
@@ -2034,11 +2114,12 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
|
||||
req->thread_access = THREAD_ALL_ACCESS;
|
||||
req->thread_attr = (tsa && (tsa->nLength >= sizeof(*tsa)) && tsa->bInheritHandle) ? OBJ_INHERIT : 0;
|
||||
req->cpu = cpu;
|
||||
- req->process_sd_size = 0;
|
||||
+ req->process_sd_size = psd_len;
|
||||
req->thread_sd_size = 0;
|
||||
req->info_size = startup_info_size;
|
||||
req->env_size = (env_end - env) * sizeof(WCHAR);
|
||||
|
||||
+ wine_server_add_data( req, psd , req->process_sd_size );
|
||||
wine_server_add_data( req, startup_info, req->info_size );
|
||||
wine_server_add_data( req, env , req->env_size );
|
||||
|
||||
@@ -2053,6 +2134,8 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
+ RtlFreeHeap(GetProcessHeap(), 0, psd);
|
||||
+
|
||||
RtlReleasePebLock();
|
||||
if (status)
|
||||
{
|
||||
diff --git a/server/process.c b/server/process.c
|
||||
index 9942eb3..1fba134 100644
|
||||
--- a/server/process.c
|
||||
+++ b/server/process.c
|
||||
@@ -883,6 +883,7 @@ DECL_HANDLER(new_process)
|
||||
const startup_info_t *req_info;
|
||||
data_size_t req_info_size;
|
||||
const WCHAR *req_env;
|
||||
+ const struct security_descriptor *req_psd = NULL;
|
||||
|
||||
if (socket_fd == -1)
|
||||
{
|
||||
@@ -907,6 +908,17 @@ DECL_HANDLER(new_process)
|
||||
return;
|
||||
}
|
||||
|
||||
+ if (req->process_sd_size)
|
||||
+ {
|
||||
+ req_psd = get_req_data();
|
||||
+
|
||||
+ if (!sd_is_valid( req_psd, req->process_sd_size ))
|
||||
+ {
|
||||
+ set_error( STATUS_INVALID_SECURITY_DESCR );
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
req_info = (const startup_info_t *)
|
||||
((char*)get_req_data() + req->process_sd_size + req->thread_sd_size);
|
||||
|
||||
@@ -1011,6 +1023,18 @@ 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 );
|
||||
|
||||
+ /* note: alloc_handle might fail with access denied
|
||||
+ * if the security descriptor is set before that call */
|
||||
+
|
||||
+ if (req_psd)
|
||||
+ {
|
||||
+ default_set_sd( &process->obj,
|
||||
+ req_psd,
|
||||
+ OWNER_SECURITY_INFORMATION|
|
||||
+ GROUP_SECURITY_INFORMATION|
|
||||
+ DACL_SECURITY_INFORMATION|
|
||||
+ SACL_SECURITY_INFORMATION );
|
||||
+ }
|
||||
done:
|
||||
release_object( info );
|
||||
}
|
||||
--
|
||||
1.7.9.5
|
||||
|
@@ -0,0 +1,234 @@
|
||||
From e924e19cc72127f16b64bef300e394a7f641dba1 Mon Sep 17 00:00:00 2001
|
||||
From: Joris van der Wel <joris@jorisvanderwel.com>
|
||||
Date: Wed, 9 Jul 2014 01:00:02 +0200
|
||||
Subject: server: implement passing a thread security descriptor to
|
||||
CreateProcess
|
||||
|
||||
server: implement passing a thread security descriptor to CreateProcess
|
||||
---
|
||||
dlls/advapi32/tests/security.c | 45 ++++++++++++++++++++++++++++++++++++----
|
||||
dlls/kernel32/process.c | 24 ++++++++++++++++++---
|
||||
server/process.c | 28 ++++++++++++++++++++++++-
|
||||
3 files changed, 89 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
|
||||
index b1b35aa..aab63f3 100644
|
||||
--- a/dlls/advapi32/tests/security.c
|
||||
+++ b/dlls/advapi32/tests/security.c
|
||||
@@ -2532,12 +2532,12 @@ static void test_process_security(void)
|
||||
PTOKEN_OWNER owner;
|
||||
PTOKEN_PRIMARY_GROUP group;
|
||||
PSID AdminSid = NULL, UsersSid = NULL;
|
||||
- PACL Acl = NULL;
|
||||
- SECURITY_DESCRIPTOR *SecurityDescriptor = NULL;
|
||||
+ PACL Acl = NULL, ThreadAcl = NULL;
|
||||
+ SECURITY_DESCRIPTOR *SecurityDescriptor = NULL, *ThreadSecurityDescriptor = NULL;
|
||||
char buffer[MAX_PATH];
|
||||
PROCESS_INFORMATION info;
|
||||
STARTUPINFOA startup;
|
||||
- SECURITY_ATTRIBUTES psa;
|
||||
+ SECURITY_ATTRIBUTES psa, tsa;
|
||||
HANDLE token, event;
|
||||
DWORD size;
|
||||
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY };
|
||||
@@ -2657,12 +2657,38 @@ static void test_process_security(void)
|
||||
psa.nLength = sizeof(psa);
|
||||
psa.lpSecurityDescriptor = SecurityDescriptor;
|
||||
psa.bInheritHandle = TRUE;
|
||||
+
|
||||
+
|
||||
+ ThreadSecurityDescriptor = HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH);
|
||||
+ res = InitializeSecurityDescriptor(ThreadSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
|
||||
+ ok(res, "InitializeSecurityDescriptor failed with error %d\n", GetLastError());
|
||||
+
|
||||
+ ThreadAcl = HeapAlloc(GetProcessHeap(), 0, 256);
|
||||
+ res = InitializeAcl(ThreadAcl, 256, ACL_REVISION);
|
||||
+ ok(res, "InitializeAcl failed with error %d\n", GetLastError());
|
||||
+ res = AddAccessDeniedAce(ThreadAcl, ACL_REVISION, THREAD_SET_THREAD_TOKEN, AdminSid);
|
||||
+ ok(res, "AddAccessDeniedAce failed with error %d\n", GetLastError());
|
||||
+ res = AddAccessAllowedAce(ThreadAcl, ACL_REVISION, THREAD_ALL_ACCESS, AdminSid);
|
||||
+ ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError());
|
||||
+
|
||||
+ res = SetSecurityDescriptorOwner(ThreadSecurityDescriptor, AdminSid, FALSE);
|
||||
+ ok(res, "SetSecurityDescriptorOwner failed with error %d\n", GetLastError());
|
||||
+ res = SetSecurityDescriptorGroup(ThreadSecurityDescriptor, UsersSid, FALSE);
|
||||
+ ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError());
|
||||
+ res = SetSecurityDescriptorDacl(ThreadSecurityDescriptor, TRUE, ThreadAcl, FALSE);
|
||||
+ ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError());
|
||||
+
|
||||
+ tsa.nLength = sizeof(tsa);
|
||||
+ tsa.lpSecurityDescriptor = ThreadSecurityDescriptor;
|
||||
+ tsa.bInheritHandle = TRUE;
|
||||
|
||||
/* Doesn't matter what ACL say we should get full access for ourselves */
|
||||
- res = CreateProcessA( NULL, buffer, &psa, NULL, FALSE, 0, NULL, NULL, &startup, &info );
|
||||
+ res = CreateProcessA( NULL, buffer, &psa, &tsa, FALSE, 0, NULL, NULL, &startup, &info );
|
||||
ok(res, "CreateProcess with err:%d\n", GetLastError());
|
||||
TEST_GRANTED_ACCESS2( info.hProcess, PROCESS_ALL_ACCESS_NT4,
|
||||
STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL );
|
||||
+ TEST_GRANTED_ACCESS2( info.hThread, THREAD_ALL_ACCESS_NT4,
|
||||
+ STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL );
|
||||
winetest_wait_child_process( info.hProcess );
|
||||
|
||||
FreeSid(EveryoneSid);
|
||||
@@ -2673,6 +2699,8 @@ static void test_process_security(void)
|
||||
HeapFree(GetProcessHeap(), 0, owner);
|
||||
HeapFree(GetProcessHeap(), 0, Acl);
|
||||
HeapFree(GetProcessHeap(), 0, SecurityDescriptor);
|
||||
+ HeapFree(GetProcessHeap(), 0, ThreadAcl);
|
||||
+ HeapFree(GetProcessHeap(), 0, ThreadSecurityDescriptor);
|
||||
}
|
||||
|
||||
static void test_process_security_child(void)
|
||||
@@ -2728,6 +2756,15 @@ static void test_process_security_child(void)
|
||||
TEST_GRANTED_ACCESS( handle1, PROCESS_VM_READ );
|
||||
CloseHandle( handle1 );
|
||||
CloseHandle( handle );
|
||||
+
|
||||
+
|
||||
+ handle = OpenThread( THREAD_TERMINATE, FALSE, GetCurrentThreadId() );
|
||||
+ ok(handle != NULL, "OpenThread(THREAD_TERMINATE) with err:%d\n", GetLastError());
|
||||
+ TEST_GRANTED_ACCESS( handle, PROCESS_TERMINATE );
|
||||
+ CloseHandle( handle );
|
||||
+
|
||||
+ handle = OpenThread( THREAD_SET_THREAD_TOKEN, FALSE, GetCurrentThreadId() );
|
||||
+ ok(handle == NULL, "OpenThread(THREAD_SET_THREAD_TOKEN) should have failed\n");
|
||||
}
|
||||
|
||||
static void test_impersonation_level(void)
|
||||
diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
|
||||
index 5f6c2e5..a01e681 100644
|
||||
--- a/dlls/kernel32/process.c
|
||||
+++ b/dlls/kernel32/process.c
|
||||
@@ -2003,8 +2003,8 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
|
||||
int socketfd[2], stdin_fd = -1, stdout_fd = -1;
|
||||
pid_t pid;
|
||||
int err, cpu;
|
||||
- struct security_descriptor *psd = NULL;
|
||||
- data_size_t psd_len = 0;
|
||||
+ struct security_descriptor *psd = NULL, *tsd = NULL;
|
||||
+ data_size_t psd_len = 0, tsd_len = 0;
|
||||
|
||||
if ((cpu = get_process_cpu( filename, binary_info )) == -1)
|
||||
{
|
||||
@@ -2022,12 +2022,26 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ if (tsa && (tsa->nLength >= sizeof(*tsa)) && tsa->lpSecurityDescriptor)
|
||||
+ {
|
||||
+ status = create_struct_sd( tsa->lpSecurityDescriptor, &tsd, &tsd_len );
|
||||
+
|
||||
+ if (status != STATUS_SUCCESS)
|
||||
+ {
|
||||
+ RtlFreeHeap(GetProcessHeap(), 0, psd);
|
||||
+ WARN("Invalid thread security descriptor with status %x\n", status);
|
||||
+ SetLastError( RtlNtStatusToDosError(status) );
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
/* create the socket for the new process */
|
||||
|
||||
if (socketpair( PF_UNIX, SOCK_STREAM, 0, socketfd ) == -1)
|
||||
{
|
||||
RtlFreeHeap(GetProcessHeap(), 0, psd);
|
||||
+ RtlFreeHeap(GetProcessHeap(), 0, tsd);
|
||||
SetLastError( ERROR_TOO_MANY_OPEN_FILES );
|
||||
return FALSE;
|
||||
}
|
||||
@@ -2068,6 +2082,7 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
|
||||
}
|
||||
close( socketfd[0] );
|
||||
RtlFreeHeap(GetProcessHeap(), 0, psd);
|
||||
+ RtlFreeHeap(GetProcessHeap(), 0, tsd);
|
||||
SetLastError( RtlNtStatusToDosError( status ));
|
||||
return FALSE;
|
||||
}
|
||||
@@ -2081,6 +2096,7 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
|
||||
close( socketfd[0] );
|
||||
close( socketfd[1] );
|
||||
RtlFreeHeap(GetProcessHeap(), 0, psd);
|
||||
+ RtlFreeHeap(GetProcessHeap(), 0, tsd);
|
||||
return FALSE;
|
||||
}
|
||||
if (!env) env = NtCurrentTeb()->Peb->ProcessParameters->Environment;
|
||||
@@ -2115,11 +2131,12 @@ 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->process_sd_size = psd_len;
|
||||
- req->thread_sd_size = 0;
|
||||
+ req->thread_sd_size = tsd_len;
|
||||
req->info_size = startup_info_size;
|
||||
req->env_size = (env_end - env) * sizeof(WCHAR);
|
||||
|
||||
wine_server_add_data( req, psd , req->process_sd_size );
|
||||
+ wine_server_add_data( req, tsd , req->thread_sd_size );
|
||||
wine_server_add_data( req, startup_info, req->info_size );
|
||||
wine_server_add_data( req, env , req->env_size );
|
||||
|
||||
@@ -2135,6 +2152,7 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
|
||||
SERVER_END_REQ;
|
||||
|
||||
RtlFreeHeap(GetProcessHeap(), 0, psd);
|
||||
+ RtlFreeHeap(GetProcessHeap(), 0, tsd);
|
||||
|
||||
RtlReleasePebLock();
|
||||
if (status)
|
||||
diff --git a/server/process.c b/server/process.c
|
||||
index 1fba134..f9a4611 100644
|
||||
--- a/server/process.c
|
||||
+++ b/server/process.c
|
||||
@@ -883,7 +883,7 @@ DECL_HANDLER(new_process)
|
||||
const startup_info_t *req_info;
|
||||
data_size_t req_info_size;
|
||||
const WCHAR *req_env;
|
||||
- const struct security_descriptor *req_psd = NULL;
|
||||
+ const struct security_descriptor *req_psd = NULL, *req_tsd = NULL;
|
||||
|
||||
if (socket_fd == -1)
|
||||
{
|
||||
@@ -919,6 +919,18 @@ DECL_HANDLER(new_process)
|
||||
}
|
||||
}
|
||||
|
||||
+ if (req->thread_sd_size)
|
||||
+ {
|
||||
+ req_tsd = (const struct security_descriptor *)
|
||||
+ ((char*)get_req_data() + req->process_sd_size);
|
||||
+
|
||||
+ if (!sd_is_valid( req_tsd, req->thread_sd_size ))
|
||||
+ {
|
||||
+ set_error( STATUS_INVALID_SECURITY_DESCR );
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
req_info = (const startup_info_t *)
|
||||
((char*)get_req_data() + req->process_sd_size + req->thread_sd_size);
|
||||
|
||||
@@ -1035,6 +1047,20 @@ DECL_HANDLER(new_process)
|
||||
DACL_SECURITY_INFORMATION|
|
||||
SACL_SECURITY_INFORMATION );
|
||||
}
|
||||
+
|
||||
+ if (req_tsd)
|
||||
+ {
|
||||
+ /* In CreateProcess the thread defaults come from the process token,
|
||||
+ * (this is not the case during CreateThread however) */
|
||||
+ set_sd_defaults_from_token( &thread->obj,
|
||||
+ req_tsd,
|
||||
+ OWNER_SECURITY_INFORMATION|
|
||||
+ GROUP_SECURITY_INFORMATION|
|
||||
+ DACL_SECURITY_INFORMATION|
|
||||
+ SACL_SECURITY_INFORMATION,
|
||||
+ process->token );
|
||||
+ }
|
||||
+
|
||||
done:
|
||||
release_object( info );
|
||||
}
|
||||
--
|
||||
1.7.9.5
|
||||
|
@@ -0,0 +1,3 @@
|
||||
Revision: 1
|
||||
Author: Joris van der Wel
|
||||
Title: Implement passing ACLs to CreateProcess.
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user