Compare commits

...

72 Commits

Author SHA1 Message Date
Erich E. Hoover
79c4f4391e Update changelog. 2014-02-21 09:00:15 -07:00
Erich E. Hoover
820cc2e861 Fix a typo in the configure check for extended attributes. 2014-02-21 08:58:55 -07:00
Sebastian Lackner
29d69db459 Abort if patching the source files fails. 2014-02-21 04:54:31 +01:00
Erich E. Hoover
7642c422ed Updated the changelog for release 1.7.13. 2014-02-20 18:48:44 -07:00
Erich E. Hoover
d56138d8ec Allow Makefile DESTDIR to contain a relative path. 2014-02-17 10:09:44 -07:00
Erich E. Hoover
b5687dc502 Explicitly run configure with '--with-xattr' when building debian packages. 2014-02-16 09:30:22 -07:00
Erich E. Hoover
7a15599a3a Auto-update the patch list when 'make DESTDIR=dest_dir install' is run. 2014-02-15 18:38:28 -07:00
Erich E. Hoover
7e5038e76c Fail on configure when '--with-xattr' is passed and xattr.h cannot be found. 2014-02-15 18:21:54 -07:00
Erich E. Hoover
30f3d023d5 Further separate the file ACL patches. 2014-02-15 18:18:22 -07:00
compholio
a7a1f83013 Update README.md with pipe access patch removal 2014-02-14 22:35:16 -07:00
Erich E. Hoover
53053927fd Update the SIO_ADDRESS_LIST_CHANGE patch to properly return the number of bytes in WSAIoctl. 2014-02-12 14:58:45 -07:00
Erich E. Hoover
35cab4ef93 Update linguistic casing patches to include tests. 2014-02-12 13:29:06 -07:00
Erich E. Hoover
43b0d84ae9 Remove the named pipe security access patch (accepted upstream). 2014-02-10 20:37:09 -07:00
Erich E. Hoover
825145217c Updated the patch list template to be compatible with 'git am'. 2014-02-07 21:31:59 -07:00
Erich E. Hoover
99c6fe660f Provide a Makefile option to change the patching tool. 2014-02-07 21:31:56 -07:00
Erich E. Hoover
4a69f63a78 Output the progress of the patching process. 2014-02-07 20:51:20 -07:00
Erich E. Hoover
39fa530c33 Add an uninstall rule to the patch Makefile. 2014-02-07 20:43:37 -07:00
Erich E. Hoover
564f8aeafc Move the patching code out of the debian rules into a Makefile. 2014-02-07 20:37:54 -07:00
Erich E. Hoover
e77f05ee52 Add support for inherited file ACLs. 2014-02-07 20:20:32 -07:00
Erich E. Hoover
f352182c20 Fixed PulseAudio driver pthread dependency for upstream Wine 1.7.12. 2014-02-07 17:52:58 -07:00
Sebastian Lackner
7bb4be5d03 Fix pulseaudio patch to be compatible with 'git am'. 2014-02-08 01:14:59 +01:00
Erich E. Hoover
ef956caf59 Fixed PulseAudio driver configure file for upstream Wine 1.7.12. 2014-02-07 16:50:34 -07:00
Erich E. Hoover
8e45d4c99f Updated the changelog for release 1.7.12. 2014-02-07 14:57:59 -07:00
compholio
004109b3bd Update README.md with GetVolumePathName patches 2014-01-25 10:14:04 -07:00
Erich E. Hoover
dd5b1514b2 Implement GetVolumePathName. 2014-01-25 10:08:49 -07:00
Erich E. Hoover
34a6c25071 Remove dh_installdocs from debian rules file. 2014-01-19 20:39:51 -07:00
compholio
6dc4078d74 Update README.md to include a couple more patches 2014-01-18 10:47:43 -07:00
compholio
6fcc7f732d Update README.md to include a list of patches. 2014-01-18 10:41:35 -07:00
Erich E. Hoover
997c04f7f8 Move the TransmitFile test so that the entire series of compholio patches can be applied with git-am. 2014-01-17 12:41:40 -07:00
Erich E. Hoover
658fe4e3ae Updated the changelog for release 1.7.11. 2014-01-17 12:27:54 -07:00
Erich E. Hoover
40aaeb61f8 Support for junction points/reparse points. 2014-01-17 11:52:25 -07:00
Erich E. Hoover
6274002623 SRWLock patch is now included in upstream Wine. 2014-01-17 11:52:13 -07:00
Erich E. Hoover
24af73d1d2 Add patches to support TransmitFile. 2014-01-16 19:29:11 -07:00
Erich E. Hoover
155a364280 Update the wineserver protocol request data when the build farm compiles the package. 2014-01-16 18:33:05 -07:00
Sebastian Lackner
9c1492069b Add SRWLock patches and workarounds for shlwapi url functions. 2014-01-17 01:34:27 +01:00
Sebastian Lackner
c3d5bcab99 Moved pipelight related patches to a separate folder. 2014-01-16 20:37:17 +01:00
Erich E. Hoover
c3052d2e31 Add support for security access parameters for named pipes. 2014-01-16 11:40:00 -07:00
Erich E. Hoover
87fd81b9d8 Fix a path length bug in the ACL inheritance patch. 2014-01-13 18:34:28 -07:00
Sebastian Lackner
062426558b Rebased patch 01-Address_Change_Notification/0003 2014-01-14 01:12:38 +01:00
Sebastian Lackner
1c6aeef3b4 Added patch to add support for WINE_STRICT_DRAW_ORDERING environment variable 2014-01-13 23:41:07 +01:00
Michael MĂĽller
f7de528788 Add SetTimer patch 2014-01-09 03:03:04 +01:00
Sebastian Lackner
8d45dc126d Updated winepulse patches 2014-01-06 01:26:32 +01:00
Erich E. Hoover
1a0d969d12 Updated the changelog for release 1.7.10. 2014-01-03 12:22:22 -07:00
Erich E. Hoover
a926ab3deb Remove the monitor GUID patch (accepted upstream). 2014-01-02 21:50:29 -07:00
Erich E. Hoover
d31a32b073 Update SIO_ADDRESS_LIST_CHANGE patch with latest proposed version. 2014-01-02 21:46:22 -07:00
Michael MĂĽller
c21aa8beb3 Add VMR7 monitor enumeration GUID patch 2013-12-31 03:33:23 +01:00
Erich E. Hoover
67079f94ae Update the changelog for a new release. 2013-12-27 12:04:29 -07:00
Sebastian Lackner
c1dccff70a Added new patch to support linux windowlessmode (required for Qt5 browsers) 2013-12-22 00:38:52 +01:00
Erich E. Hoover
7b41306c4b Update the changelog for a new release. 2013-12-07 10:49:20 -07:00
Erich E. Hoover
2d7390de4b Fix mistake in the rules file causing patches to not be applied. 2013-12-07 10:32:24 -07:00
Erich E. Hoover
28bbb866f2 Add PulseAudio dependency to the debian control file. 2013-12-07 10:31:34 -07:00
Erich E. Hoover
fc5a6b8c45 Updated changelog for release 1.7.8. 2013-12-06 13:26:36 -07:00
Sebastian Lackner
7398e80556 Imported winepulse patches and updated patch-list.patch 2013-12-06 21:09:21 +01:00
Erich E. Hoover
25bf8fbc02 Updated SIO_ADDRESS_LIST_CHANGE patches. 2013-12-05 16:40:00 -07:00
Erich E. Hoover
b741e7191b Use UUIDs and revision codes to identify patches instead of md5sum values. 2013-12-02 16:12:40 -07:00
Erich E. Hoover
aa76a0b8d2 Fix missing continuation in patch application. 2013-12-01 01:46:44 -07:00
Erich E. Hoover
d38c90ec2a Updated XEMBED patch to work with latest upstream Wine. 2013-11-29 18:30:37 -07:00
Erich E. Hoover
44bba738bb Separate out patches into logical subfolders. 2013-11-26 14:23:09 -07:00
Erich E. Hoover
264b4b3cab Allow separating patches into subfolders. 2013-11-26 14:12:52 -07:00
Erich E. Hoover
e63f3b7958 Whoops, remove the LICENSE file that bazaar does not like. 2013-11-23 17:17:21 -07:00
Erich E. Hoover
545aaf4153 Merge branch 'master' of github.com:compholio/wine-compholio-daily 2013-11-23 17:00:31 -07:00
Erich E. Hoover
6eb246a811 Work around bazaar merges not liking conflicts. 2013-11-23 17:00:04 -07:00
Sebastian Lackner
cd9fa06fcb Merge branch 'master' of github.com:compholio/wine-compholio-daily 2013-11-23 05:27:11 +01:00
Sebastian Lackner
33b3e62fc1 Fix patch-list-template.diff compilation error, regenerated patch-list.patch 2013-11-23 05:21:44 +01:00
Sebastian Lackner
5808f78d07 Improved VMRMonitorConfig tests according to suggestions by A. Hentschel 2013-11-23 04:46:08 +01:00
Erich E. Hoover
8fa329cfe2 Update changelog to include the multiple monitor workaround. 2013-11-22 14:25:30 -07:00
Sebastian Lackner
6cc7c450bf generate-patchlist.sh: Don't include files without any author and title, regenerated patchlist 2013-11-22 20:06:28 +01:00
Sebastian Lackner
2aa8fe4524 Merge branch 'master' of github.com:compholio/wine-compholio-daily 2013-11-22 19:55:35 +01:00
Sebastian Lackner
3c0f6ef05f Updated patches 7 and 10, added patch 11 to prevent problems with Silverlight 2013-11-22 19:54:41 +01:00
Erich E. Hoover
5a6af8c89c Advertise new patch listing feature. 2013-11-22 10:47:07 -07:00
Erich E. Hoover
4c9309d05a Add initial patch listing feature resulting patch. 2013-11-22 10:45:45 -07:00
Erich E. Hoover
5583aa9cc7 Update the patch list template to include a querying function in NTDLL. 2013-11-22 10:43:44 -07:00
95 changed files with 10640 additions and 1110 deletions

1
.gitignore vendored
View File

@@ -1 +0,0 @@
*~

View File

@@ -2,3 +2,17 @@ wine-compholio-daily
====================
Daily updates for the Wine "Compholio" Edition.
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 GetVolumePathName
* Allow CompareStringEx flag NORM_LINGUISTIC_CASING (http://bugs.winehq.org/show_bug.cgi?id=34269)
* Workaround for TransactNamedPipe not being supported (http://bugs.winehq.org/show_bug.cgi?id=17273)
* XEMBED support for embedding Wine windows inside Linux applications
* Reduced SetTimer minimum value from 15 ms to 5 ms (improves Silverlight framerates)
* Workaround for shlwapi URLs with relative paths
* Support for PulseAudio backend for audio

63
debian/changelog vendored
View File

@@ -1,8 +1,69 @@
wine-compholio (1.7.13-1) unstable; urgency=low
* Fixed a typo in the configure check for extended attributes.
-- Erich E. Hoover <erich.e.hoover@gmail.com> Fri, 21 Feb 2014 09:00:00 -0700
wine-compholio (1.7.13) unstable; urgency=low
* Added support for inherited file ACLs.
* Further separated the file ACL patches.
* Updated linguistic casing patches to include tests.
* Updated the patch list template to be compatible with 'git am'.
* Moved the patching code out of the debian rules into a Makefile.
* Removed the named pipe security access patch (accepted upstream).
* Explicitly run configure with '--with-xattr' when building debian packages.
* Will now fail on configure when '--with-xattr' is passed and xattr.h cannot be found.
-- Erich E. Hoover <erich.e.hoover@gmail.com> Thu, 20 Feb 2014 18:48:03 -0700
wine-compholio (1.7.12-1) unstable; urgency=low
* Fixed PulseAudio patches to apply with 'git am'.
* Fixed PulseAudio driver configure file for upstream Wine 1.7.12.
* Fixed PulseAudio driver pthread dependency for upstream Wine 1.7.12.
-- Erich E. Hoover <erich.e.hoover@gmail.com> Fri, 07 Feb 2014 17:52:32 -0700
wine-compholio (1.7.12) unstable; urgency=low
* Added new patches to support GetVolumePathName.
-- Erich E. Hoover <erich.e.hoover@gmail.com> Fri, 07 Feb 2014 14:57:33 -0700
wine-compholio (1.7.11) unstable; urgency=low
* Added SRWLock patch.
* Added new patches to support TransmitFile.
* Added new patches to support Junction Points.
* Moved pipelight-specific patches to a separate folder.
* Removed SRWLock patch included in upstream Wine 1.7.11.
* Reduced SetTimer minimum limitation from 15 ms to 5 ms.
* Added support for security access parameters for named pipes.
* Added WINE_STRICT_DRAW_ORDERING command line environment variable.
* Fixed a path length bug in the ACL inheritance patch (assumed DOS limitation).
* Added some workarounds for shlwapi url functions not handling relative paths well.
-- Erich E. Hoover <erich.e.hoover@gmail.com> Fri, 17 Jan 2014 12:27:32 -0700
wine-compholio (1.7.10) unstable; urgency=low
* Removed monitor enumeration patch included in upstream Wine 1.7.10.
* Updated SIO_ADDRESS_LIST_CHANGE patch with latest proposed version.
* Added new patch to support linux windowlessmode (required for Qt5 browsers).
-- Erich E. Hoover <erich.e.hoover@gmail.com> Fri, 03 Jan 2014 12:19:14 -0700
wine-compholio (1.7.9) unstable; urgency=low
* Added a new patch for windowless mode for Qt5 browsers.
-- Erich E. Hoover <erich.e.hoover@gmail.com> Fri, 27 Dec 2013 12:03:22 -0700
wine-compholio (1.7.8-1) unstable; urgency=low
* Fixed several build problems.
-- Erich E. Hoover <erich.e.hoover@gmail.com> Sat, 07 Dec 2013 10:49:03 -0700
wine-compholio (1.7.8) unstable; urgency=low
* Added PulseAudio support patches.
* Updated SIO_ADDRESS_LIST_CHANGE patches.
* Separated out patches into logical subfolders.
* Updated XEMBED patch to work with latest upstream Wine.
-- Erich E. Hoover <erich.e.hoover@gmail.com> Fri, 06 Dec 2013 13:26:24 -0700
wine-compholio (1.7.7) unstable; urgency=low
* Remove patches included in upstream Wine 1.7.7.
* Rebase ACL extended attribute patches against upstream Wine 1.7.7.
* Rebase SIO_ADDRESS_LIST_CHANGE patches against upstream Wine 1.7.7.
-- Erich E. Hoover <erich.e.hoover@gmail.com> Fri, 22 Nov 2013 10:35:07 -0700
* Added the ability to return the list of patches with "wine --patches".
* Added a patch to workaround a Silverlight issue with multiple monitors.
-- Erich E. Hoover <erich.e.hoover@gmail.com> Fri, 22 Nov 2013 14:24:53 -0700
wine-compholio (1.7.6-1) unstable; urgency=low
* Work around a build problem with Wine 1.7.6.

1
debian/control vendored
View File

@@ -50,6 +50,7 @@ Build-Depends: autotools-dev,
libncurses5-dev [i386] | libncurses-dev [i386],
libopenal-dev (>= 1:1.12) | ubuntu-desktop (<< 1.207),
libpng12-dev,
libpulse-dev,
libssl-dev,
libstdc++6-4.5-dev | libstdc++-dev,
libtiff4-dev,

15
debian/rules vendored
View File

@@ -63,18 +63,11 @@ ifneq "$(wildcard /usr/share/misc/config.guess)" ""
cp -f /usr/share/misc/config.guess config.guess
endif
# Apply our patches to Wine
for FILE in `ls $(CURDIR)/patches`; do \
patch -N -p0 --strip=1 < $(CURDIR)/patches/$$FILE || exit 1; \
done
# Update the configure script
autoreconf
# Apply our patches, reconfigure, and update the wineserver protocol request data
make -C "$(CURDIR)/patches/" DESTDIR="$(CURDIR)" install
# Configure
CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/opt/wine-compholio --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info $(CONFFLAGS)
CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/opt/wine-compholio --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info --with-xattr $(CONFFLAGS)
build: build-stamp
@@ -117,7 +110,7 @@ binary-arch: build install
dh_testdir
dh_testroot
# dh_installchangelogs ChangeLog
dh_installdocs
# dh_installdocs
dh_installexamples
# dh_install
# dh_installmenu

View File

@@ -1,15 +1,19 @@
#!/bin/sh
PATCH_DATA="";
for FILE in patches/*.patch; do
MD5SUM=$(md5sum "${FILE}" | sed 's| .*||g');
AUTHOR=$(cat "${FILE}" | sed -n 's|From: \([^<]*\).*|\1|p' | sed -e 's|"||g' -e 's| $||g');
TITLE=$(cat "${FILE}" | sed -n '1!N; s|Subject: \(.*\)\n|\1|p');
for FILE in patches/*/*.def; do
UUID=$(echo "${FILE}" | sed -e 's|^.*/||g' -e 's|\.def$||g');
REVISION=$(cat "${FILE}" | sed -n 's|Revision: \(.*\)|\1|p');
AUTHOR=$(cat "${FILE}" | sed -n 's|Author: \(.*\)|\1|p');
TITLE=$(cat "${FILE}" | sed -n 's|Title: \(.*\)|\1|p');
if [ "${AUTHOR}" = "" ] && [ "${TITLE}" = "" ]; then
continue;
fi
if [ "${PATCH_DATA}" != "" ]; then
PATCH_DATA="${PATCH_DATA}
";
fi
PATCH_DATA="${PATCH_DATA}+ { \"${MD5SUM}\", \"${AUTHOR}\", \"${TITLE}\" },";
PATCH_DATA="${PATCH_DATA}+ { \"${UUID}:${REVISION}\", \"${AUTHOR}\", \"${TITLE}\" },";
done
PATCH_LINES=$(echo "${PATCH_DATA}" | grep -c '\n');
PATCH_LINES=$((${PATCH_LINES}+20));

View File

@@ -1,5 +1,40 @@
From: "FDS-Team" <webmaster@fds-team.de>
Subject: Autogenerated patch list.
---
diff --git a/dlls/ntdll/misc.c b/dlls/ntdll/misc.c
index 8bd4eb7..4b4c318 100644
--- a/dlls/ntdll/misc.c
+++ b/dlls/ntdll/misc.c
@@ -60,6 +60,14 @@ const char * CDECL NTDLL_wine_get_version(void)
}
/*********************************************************************
+ * wine_get_patches (NTDLL.@)
+ */
+const void * CDECL NTDLL_wine_get_patches(void)
+{
+ return wine_get_patches();
+}
+
+/*********************************************************************
* wine_get_build_id (NTDLL.@)
*/
const char * CDECL NTDLL_wine_get_build_id(void)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 70bf94f..42eddcf 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -1410,6 +1410,7 @@
# Version
@ cdecl wine_get_version() NTDLL_wine_get_version
+@ cdecl wine_get_patches() NTDLL_wine_get_patches
@ cdecl wine_get_build_id() NTDLL_wine_get_build_id
@ cdecl wine_get_host_version(ptr ptr) NTDLL_wine_get_host_version
diff --git a/libs/wine/config.c b/libs/wine/config.c
index a273502..751a9e7 100644
index a273502..5fa0cd5 100644
--- a/libs/wine/config.c
+++ b/libs/wine/config.c
@@ -478,6 +478,##PATCH_LINES## @@ const char *wine_get_version(void)
@@ -16,7 +51,7 @@ index a273502..751a9e7 100644
+};
+
+/* return the applied non-standard patches */
+const struct wine_patch * wine_get_patches(void)
+const void * wine_get_patches(void)
+{
+ return &wine_patch_data[0];
+}
@@ -52,7 +87,7 @@ diff --git a/loader/main.c b/loader/main.c
index ac67290..516fd82 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -79,6 +79,13 @@ static inline void reserve_area( void *addr, size_t size )
@@ -79,6 +79,12 @@ static inline void reserve_area( void *addr, size_t size )
#endif /* __APPLE__ */
@@ -61,7 +96,6 @@ index ac67290..516fd82 100644
+ const char *author;
+ const char *title;
+};
+extern void * CDECL wine_get_patches(void);
+
/***********************************************************************
* check_command_line
@@ -82,7 +116,7 @@ index ac67290..516fd82 100644
}
+ if (!strcmp( argv[1], "--patches" ))
+ {
+ struct wine_patch *wine_patch_data = wine_get_patches();
+ const struct wine_patch *wine_patch_data = wine_get_patches();
+ for(; wine_patch_data->hash != NULL; wine_patch_data++)
+ {
+ printf( "%s :: %s :: %s\n", wine_patch_data->hash, wine_patch_data->author,
@@ -93,3 +127,15 @@ index ac67290..516fd82 100644
}
diff --git a/include/wine/library.h b/include/wine/library.h
index 242bb69..aa9e585 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -43,6 +43,7 @@ extern const char *wine_get_data_dir(void);
extern const char *wine_get_server_dir(void);
extern const char *wine_get_user_name(void);
extern const char *wine_get_version(void);
+extern const void *wine_get_patches(void);
extern const char *wine_get_build_id(void);
extern void wine_init_argv0_path( const char *argv0 );
extern void wine_exec_wine_binary( const char *name, char **argv, const char *env_var );

View File

@@ -1,499 +0,0 @@
From 78a5ebb94f3717bedd77f7c096e8fce1e9a640d1 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Mon, 18 Nov 2013 18:12:05 -0700
Subject: server: Store and return security attributes with extended file
attributes.
---
configure.ac | 6 ++
dlls/advapi32/tests/security.c | 25 +++---
server/change.c | 11 ++-
server/fd.c | 68 +++++++++++++++-
server/file.c | 176 +++++++++++++++++++++++++++++++++++++++-
server/file.h | 5 +-
6 files changed, 269 insertions(+), 22 deletions(-)
diff --git a/configure.ac b/configure.ac
index 98a73f2..bb03667 100644
--- a/configure.ac
+++ b/configure.ac
@@ -71,6 +71,7 @@ AC_ARG_WITH(pthread, AS_HELP_STRING([--without-pthread],[do not use the pthrea
AC_ARG_WITH(sane, AS_HELP_STRING([--without-sane],[do not use SANE (scanner support)]))
AC_ARG_WITH(tiff, AS_HELP_STRING([--without-tiff],[do not use TIFF]))
AC_ARG_WITH(v4l, AS_HELP_STRING([--without-v4l],[do not use v4l1 (v4l support)]))
+AC_ARG_WITH(xattr, AS_HELP_STRING([--without-xattr],[do not use xattr (security attributes support)]))
AC_ARG_WITH(xcomposite,AS_HELP_STRING([--without-xcomposite],[do not use the Xcomposite extension]),
[if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_Xcomposite_h=no; fi])
AC_ARG_WITH(xcursor, AS_HELP_STRING([--without-xcursor],[do not use the Xcursor extension]),
@@ -666,6 +667,11 @@ AC_CHECK_HEADERS([libprocstat.h],,,
#include <sys/socket.h>
#endif])
+if test "x$with_xattr" != "xno"
+then
+ AC_CHECK_HEADERS(attr/xattr.h)
+fi
+
dnl **** Check for working dll ****
AC_SUBST(dlldir,"\${libdir}/wine")
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index fe31b5c..7d28c05 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -3088,10 +3088,10 @@ 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);
- todo_wine ok(bret, "Current User ACE != Current User SID.\n");
- todo_wine ok(((ACE_HEADER *)ace)->AceFlags == (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE),
- "Current User ACE has unexpected flags (0x%x != 0x03)\n",
- ((ACE_HEADER *)ace)->AceFlags);
+ ok(bret, "Current User ACE != Current User SID.\n");
+ ok(((ACE_HEADER *)ace)->AceFlags == (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE),
+ "Current User ACE has unexpected flags (0x%x != 0x03)\n",
+ ((ACE_HEADER *)ace)->AceFlags);
ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n",
ace->Mask);
}
@@ -3100,10 +3100,10 @@ static void test_CreateDirectoryA(void)
bret = pGetAce(pDacl, 1, (VOID **)&ace);
ok(bret, "Failed to get Administators Group ACE.\n");
bret = EqualSid(&ace->SidStart, admin_sid);
- todo_wine ok(bret, "Administators Group ACE != Administators Group SID.\n");
- todo_wine ok(((ACE_HEADER *)ace)->AceFlags == (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE),
- "Administators Group ACE has unexpected flags (0x%x != 0x03)\n",
- ((ACE_HEADER *)ace)->AceFlags);
+ ok(bret, "Administators Group ACE != Administators Group SID.\n");
+ ok(((ACE_HEADER *)ace)->AceFlags == (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE),
+ "Administators Group ACE has unexpected flags (0x%x != 0x03)\n",
+ ((ACE_HEADER *)ace)->AceFlags);
ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n",
ace->Mask);
}
@@ -3277,7 +3277,7 @@ 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);
- todo_wine ok(bret, "Current User ACE != Current User SID.\n");
+ ok(bret, "Current User ACE != Current User SID.\n");
ok(((ACE_HEADER *)ace)->AceFlags == 0,
"Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n",
@@ -3288,8 +3288,7 @@ static void test_GetNamedSecurityInfoA(void)
bret = pGetAce(pDacl, 1, (VOID **)&ace);
ok(bret, "Failed to get Administators Group ACE.\n");
bret = EqualSid(&ace->SidStart, admin_sid);
- todo_wine ok(bret || broken(!bret) /* win2k */,
- "Administators Group ACE != Administators Group SID.\n");
+ ok(bret || broken(!bret) /* win2k */, "Administators Group ACE != Administators Group SID.\n");
ok(((ACE_HEADER *)ace)->AceFlags == 0,
"Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
ok(ace->Mask == 0x1f01ff || broken(ace->Mask == GENERIC_ALL) /* win2k */,
@@ -3943,7 +3942,7 @@ 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);
- todo_wine ok(bret, "Current User ACE != Current User SID.\n");
+ ok(bret, "Current User ACE != Current User SID.\n");
ok(((ACE_HEADER *)ace)->AceFlags == 0,
"Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n",
@@ -3954,7 +3953,7 @@ static void test_GetSecurityInfo(void)
bret = pGetAce(pDacl, 1, (VOID **)&ace);
ok(bret, "Failed to get Administators Group ACE.\n");
bret = EqualSid(&ace->SidStart, admin_sid);
- todo_wine ok(bret, "Administators Group ACE != Administators Group SID.\n");
+ ok(bret, "Administators Group ACE != Administators Group SID.\n");
ok(((ACE_HEADER *)ace)->AceFlags == 0,
"Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n",
diff --git a/server/change.c b/server/change.c
index f6d56b0..022c780 100644
--- a/server/change.c
+++ b/server/change.c
@@ -286,6 +286,7 @@ static int get_dir_unix_fd( struct dir *dir )
static struct security_descriptor *dir_get_sd( struct object *obj )
{
struct dir *dir = (struct dir *)obj;
+ const SID *user, *group;
int unix_fd;
struct stat st;
struct security_descriptor *sd;
@@ -302,9 +303,11 @@ static struct security_descriptor *dir_get_sd( struct object *obj )
(st.st_uid == dir->uid))
return obj->sd;
- sd = mode_to_sd( st.st_mode,
- security_unix_uid_to_sid( st.st_uid ),
- token_get_primary_group( current->process->token ));
+ user = security_unix_uid_to_sid( st.st_uid );
+ group = token_get_primary_group( current->process->token );
+ sd = get_file_acls( unix_fd, user, group );
+ if (!sd)
+ sd = mode_to_sd( st.st_mode, user, group );
if (!sd) return obj->sd;
dir->mode = st.st_mode;
@@ -353,6 +356,8 @@ static int dir_set_sd( struct object *obj, const struct security_descriptor *sd,
mode = st.st_mode & (S_ISUID|S_ISGID|S_ISVTX);
mode |= sd_to_mode( sd, owner );
+ set_file_acls( unix_fd, sd );
+
if (((st.st_mode ^ mode) & (S_IRWXU|S_IRWXG|S_IRWXO)) && fchmod( unix_fd, mode ) == -1)
{
file_set_error();
diff --git a/server/fd.c b/server/fd.c
index fa8874c..98e3eca 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -91,6 +91,9 @@
#ifdef HAVE_SYS_SYSCALL_H
#include <sys/syscall.h>
#endif
+#ifdef HAVE_ATTR_XATTR_H
+#include <attr/xattr.h>
+#endif
#include "ntstatus.h"
#define WIN32_NO_STATUS
@@ -99,6 +102,7 @@
#include "handle.h"
#include "process.h"
#include "request.h"
+#include "security.h"
#include "winternl.h"
#include "winioctl.h"
@@ -1726,9 +1730,69 @@ static char *dup_fd_name( struct fd *root, const char *name )
return ret;
}
+void set_file_acls( int fd, const struct security_descriptor *sd )
+{
+#ifdef HAVE_ATTR_XATTR_H
+ char buffer[XATTR_SIZE_MAX], *p = buffer;
+ const ACE_HEADER *ace;
+ int present, i, j, n;
+ const ACL *dacl;
+
+ if (!sd) return;
+ dacl = sd_get_dacl( sd, &present );
+ if (!present || !dacl) return;
+ ace = (const ACE_HEADER *)(dacl + 1);
+
+ for (i = 0; i < dacl->AceCount; i++, ace = ace_next( ace ))
+ {
+ BYTE type = ace->AceType, flags;
+ const ACCESS_ALLOWED_ACE *aaa;
+ const ACCESS_DENIED_ACE *ada;
+ char sidtxt[100], *s;
+ const SID *sid;
+ DWORD mask;
+
+ if (type & INHERIT_ONLY_ACE) continue;
+
+ switch (type)
+ {
+ case ACCESS_DENIED_ACE_TYPE:
+ ada = (const ACCESS_DENIED_ACE *)ace;
+ flags = ada->Header.AceFlags;
+ mask = ada->Mask;
+ sid = (const SID *)&ada->SidStart;
+ break;
+ case ACCESS_ALLOWED_ACE_TYPE:
+ aaa = (const ACCESS_ALLOWED_ACE *)ace;
+ flags = aaa->Header.AceFlags;
+ mask = aaa->Mask;
+ sid = (const SID *)&aaa->SidStart;
+ break;
+ default:
+ continue;
+ }
+ n = sprintf( sidtxt, "S-%u-%d", sid->Revision,
+ MAKELONG(
+ MAKEWORD( sid->IdentifierAuthority.Value[5],
+ sid->IdentifierAuthority.Value[4] ),
+ MAKEWORD( sid->IdentifierAuthority.Value[3],
+ sid->IdentifierAuthority.Value[2] )
+ ) );
+ s = sidtxt + n;
+ for( j=0; j<sid->SubAuthorityCount; j++ )
+ s += sprintf( s, "-%u", sid->SubAuthority[j] );
+
+ p += snprintf( p, XATTR_SIZE_MAX-(p-buffer), "%s%x,%x,%x,%s",
+ (p != buffer ? ";" : ""), type, flags, mask, sidtxt );
+ }
+
+ fsetxattr( fd, "user.wine.acl", buffer, p-buffer, 0 );
+#endif
+}
+
/* open() wrapper that returns a struct fd with no fd user set */
struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode, unsigned int access,
- unsigned int sharing, unsigned int options )
+ unsigned int sharing, unsigned int options, const struct security_descriptor *sd )
{
struct stat st;
struct closed_fd *closed_fd;
@@ -1804,6 +1868,8 @@ struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode,
}
}
+ set_file_acls( fd->unix_fd, sd );
+
closed_fd->unix_fd = fd->unix_fd;
closed_fd->unlink[0] = 0;
fstat( fd->unix_fd, &st );
diff --git a/server/file.c b/server/file.c
index cceb8ad..9ac9188 100644
--- a/server/file.c
+++ b/server/file.c
@@ -32,6 +32,7 @@
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
+#include <limits.h>
#include <unistd.h>
#ifdef HAVE_UTIME_H
#include <utime.h>
@@ -39,6 +40,9 @@
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
+#ifdef HAVE_ATTR_XATTR_H
+#include <attr/xattr.h>
+#endif
#include "ntstatus.h"
#define WIN32_NO_STATUS
@@ -237,7 +241,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
access = generic_file_map_access( access );
/* 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 );
+ fd = open_fd( root, name, flags | O_NONBLOCK | O_LARGEFILE, &mode, access, sharing, options, sd );
if (!fd) goto done;
if (S_ISDIR(mode))
@@ -424,9 +428,169 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
return sd;
}
+struct security_descriptor *get_file_acls( int fd, const SID *user, const SID *group )
+{
+#ifdef HAVE_ATTR_XATTR_H
+ int ace_count = 0, dacl_size = sizeof(ACL), i, n;
+ char buffer[XATTR_SIZE_MAX], *p = buffer, *pn;
+ struct security_descriptor *sd;
+ ACE_HEADER *current_ace;
+ ACCESS_ALLOWED_ACE *aaa;
+ ACCESS_DENIED_ACE *ada;
+ int type, flags, mask;
+ ACL *dacl;
+ char *ptr;
+
+ n = fgetxattr( fd, "user.wine.acl", buffer, sizeof(buffer) );
+ if (n == -1) return NULL;
+ buffer[n] = 0;
+
+ do
+ {
+ int sub_authority_count = 0;
+
+ pn = strchr(p, ';');
+ if (pn) pn++;
+ sscanf(p, "%x", &type);
+ do
+ {
+ p = strchr(p, '-');
+ if (p) p++;
+ sub_authority_count++;
+ }
+ while(p && (!pn || p < pn));
+ sub_authority_count -= 3; /* Revision and IdentifierAuthority don't count */
+
+ switch (type)
+ {
+ case ACCESS_DENIED_ACE_TYPE:
+ dacl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) +
+ FIELD_OFFSET(SID, SubAuthority[sub_authority_count]);
+ break;
+ case ACCESS_ALLOWED_ACE_TYPE:
+ dacl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) +
+ FIELD_OFFSET(SID, SubAuthority[sub_authority_count]);
+ break;
+ default:
+ continue;
+ }
+ ace_count++;
+ p = pn;
+ }
+ while(p);
+
+ sd = mem_alloc( sizeof(struct security_descriptor) +
+ FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]) +
+ FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]) +
+ dacl_size );
+
+ sd->control = SE_DACL_PRESENT;
+ sd->owner_len = FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]);
+ sd->group_len = FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]);
+ sd->sacl_len = 0;
+ sd->dacl_len = dacl_size;
+
+ ptr = (char *)(sd + 1);
+ memcpy( ptr, user, sd->owner_len );
+ ptr += sd->owner_len;
+ memcpy( ptr, group, sd->group_len );
+ ptr += sd->group_len;
+
+ dacl = (ACL *)ptr;
+ dacl->AclRevision = ACL_REVISION;
+ dacl->Sbz1 = 0;
+ dacl->AclSize = dacl_size;
+ dacl->AceCount = ace_count;
+ dacl->Sbz2 = 0;
+ aaa = (ACCESS_ALLOWED_ACE *)(dacl + 1);
+ current_ace = &aaa->Header;
+
+ p = buffer;
+ for(i=0; i<ace_count; i++)
+ {
+ char b[sizeof(SID) + sizeof(ULONG) * SID_MAX_SUB_AUTHORITIES];
+ int sub_authority_count = 0;
+ SID *sid = (SID *)&b[0];
+ char sidtxt[100];
+ int rev, ia, sa;
+
+ if (i != 0)
+ {
+ aaa = (ACCESS_ALLOWED_ACE *)ace_next( current_ace );
+ current_ace = &aaa->Header;
+ }
+ pn = strchr(p, ';');
+ if (pn) pn++;
+ sscanf(p, "%x,%x,%x,%[^;]", &type, &flags, &mask, sidtxt);
+ sscanf(sidtxt, "S-%u-%d", &rev, &ia);
+ sid->Revision = rev;
+ sid->IdentifierAuthority.Value[0] = 0;
+ sid->IdentifierAuthority.Value[1] = 0;
+ sid->IdentifierAuthority.Value[2] = HIBYTE(HIWORD(ia));
+ sid->IdentifierAuthority.Value[3] = LOBYTE(HIWORD(ia));
+ sid->IdentifierAuthority.Value[4] = HIBYTE(LOWORD(ia));
+ sid->IdentifierAuthority.Value[5] = LOBYTE(LOWORD(ia));
+ p = strchr(sidtxt, '-')+1;
+ p = strchr(p, '-')+1; /* Revision doesn't count */
+ p = strchr(p, '-')+1; /* IdentifierAuthority doesn't count */
+ do
+ {
+ sscanf(p, "%u", &sa);
+ sid->SubAuthority[sub_authority_count] = sa;
+ p = strchr(p, '-');
+ if (p) p++;
+ sub_authority_count++;
+ }
+ while(p);
+ sid->SubAuthorityCount = sub_authority_count;
+
+ /* Convert generic rights into standard access rights */
+ if (mask & GENERIC_ALL)
+ mask |= WRITE_DAC | WRITE_OWNER | DELETE | FILE_DELETE_CHILD;
+ if (mask & (GENERIC_ALL|GENERIC_READ))
+ mask |= FILE_GENERIC_READ;
+ if (mask & (GENERIC_ALL|GENERIC_WRITE))
+ mask |= FILE_GENERIC_WRITE;
+ if (mask & (GENERIC_ALL|GENERIC_EXECUTE))
+ mask |= FILE_GENERIC_EXECUTE;
+ mask &= 0x0FFFFFFF;
+
+ /* Handle the specific ACE */
+ switch (type)
+ {
+ case ACCESS_DENIED_ACE_TYPE:
+ ada = (ACCESS_DENIED_ACE *)aaa;
+ ada->Header.AceType = type;
+ ada->Header.AceFlags = flags;
+ ada->Header.AceSize = FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) +
+ FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]);
+ ada->Mask = mask;
+ memcpy( &ada->SidStart, sid, FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]) );
+ break;
+ case ACCESS_ALLOWED_ACE_TYPE:
+ aaa->Header.AceType = type;
+ aaa->Header.AceFlags = flags;
+ aaa->Header.AceSize = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) +
+ FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]);
+ aaa->Mask = mask;
+ memcpy( &aaa->SidStart, sid, FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]) );
+ break;
+ default:
+ continue;
+ }
+ p = pn;
+ }
+
+ return sd;
+#else
+ return NULL;
+#endif
+}
+
static struct security_descriptor *file_get_sd( struct object *obj )
{
struct file *file = (struct file *)obj;
+ const SID *user, *group;
struct stat st;
int unix_fd;
struct security_descriptor *sd;
@@ -443,9 +607,11 @@ static struct security_descriptor *file_get_sd( struct object *obj )
(st.st_uid == file->uid))
return obj->sd;
- sd = mode_to_sd( st.st_mode,
- security_unix_uid_to_sid( st.st_uid ),
- token_get_primary_group( current->process->token ));
+ user = security_unix_uid_to_sid( st.st_uid );
+ group = token_get_primary_group( current->process->token );
+ sd = get_file_acls( unix_fd, user, group );
+ if (!sd)
+ sd = mode_to_sd( st.st_mode, user, group);
if (!sd) return obj->sd;
file->mode = st.st_mode;
@@ -575,6 +741,8 @@ static int file_set_sd( struct object *obj, const struct security_descriptor *sd
mode = st.st_mode & (S_ISUID|S_ISGID|S_ISVTX);
mode |= sd_to_mode( sd, owner );
+ set_file_acls( unix_fd, sd );
+
if (((st.st_mode ^ mode) & (S_IRWXU|S_IRWXG|S_IRWXO)) && fchmod( unix_fd, mode ) == -1)
{
file_set_error();
diff --git a/server/file.h b/server/file.h
index 493d30b..721c087 100644
--- a/server/file.h
+++ b/server/file.h
@@ -56,7 +56,8 @@ extern struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct obje
unsigned int options );
extern void set_no_fd_status( struct fd *fd, unsigned int status );
extern struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode,
- unsigned int access, unsigned int sharing, unsigned int options );
+ unsigned int access, unsigned int sharing, unsigned int options,
+ const struct security_descriptor *sd );
extern struct fd *create_anonymous_fd( const struct fd_ops *fd_user_ops,
int unix_fd, struct object *user, unsigned int options );
extern struct fd *dup_fd_object( struct fd *orig, unsigned int access, unsigned int sharing,
@@ -122,6 +123,8 @@ extern struct file *create_file_for_fd_obj( struct fd *fd, unsigned int access,
extern void file_set_error(void);
extern struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID *group );
extern mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner );
+extern void set_file_acls( int fd, const struct security_descriptor *sd );
+extern struct security_descriptor *get_file_acls( int fd, const SID *user, const SID *group );
/* file mapping functions */
--
1.7.9.5

View File

@@ -1,180 +0,0 @@
From 5e49f53a4bd591e67c9b7c4fdaf46933e319f9aa Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Mon, 18 Nov 2013 18:15:20 -0700
Subject: ntdll: Inherit security attributes from parent directories.
---
dlls/advapi32/tests/security.c | 40 ++++++++++++++++++-
dlls/ntdll/file.c | 85 +++++++++++++++++++++++++++++++++++++++-
2 files changed, 123 insertions(+), 2 deletions(-)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index 7d28c05..a8d136b 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -3013,10 +3013,11 @@ static void test_CreateDirectoryA(void)
ACL_SIZE_INFORMATION acl_size;
ACCESS_ALLOWED_ACE *ace;
SECURITY_ATTRIBUTES sa;
+ char tmpfile[MAX_PATH];
char tmpdir[MAX_PATH];
+ HANDLE token, hTemp;
struct _SID *owner;
BOOL bret = TRUE;
- HANDLE token;
DWORD error;
PACL pDacl;
@@ -3108,6 +3109,43 @@ static void test_CreateDirectoryA(void)
ace->Mask);
}
+ /* Test inheritance of ACLs */
+ strcpy(tmpfile, tmpdir);
+ lstrcatA(tmpfile, "/tmpfile");
+ hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW,
+ FILE_FLAG_DELETE_ON_CLOSE, NULL);
+ error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
+ OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, (PSID*)&owner,
+ NULL, &pDacl, NULL, &pSD);
+ ok(error == ERROR_SUCCESS, "Failed to get permissions on file.\n");
+ bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
+ ok(bret, "GetAclInformation failed\n");
+ ok(acl_size.AceCount == 2, "GetAclInformation returned unexpected entry count (%d != 2).\n",
+ acl_size.AceCount);
+ if (acl_size.AceCount > 0)
+ {
+ bret = pGetAce(pDacl, 0, (VOID **)&ace);
+ ok(bret, "Inherited Failed to get Current User ACE.\n");
+ bret = EqualSid(&ace->SidStart, user_sid);
+ ok(bret, "Inherited Current User ACE != Current User SID.\n");
+ ok(((ACE_HEADER *)ace)->AceFlags == INHERITED_ACE,
+ "Inherited Current User ACE has unexpected flags (0x%x != 0x10)\n", ((ACE_HEADER *)ace)->AceFlags);
+ ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n",
+ ace->Mask);
+ }
+ if (acl_size.AceCount > 1)
+ {
+ bret = pGetAce(pDacl, 1, (VOID **)&ace);
+ ok(bret, "Inherited Failed to get Administators Group ACE.\n");
+ bret = EqualSid(&ace->SidStart, admin_sid);
+ ok(bret, "Inherited Administators Group ACE != Administators Group SID.\n");
+ ok(((ACE_HEADER *)ace)->AceFlags == INHERITED_ACE,
+ "Inherited Administators Group ACE has unexpected flags (0x%x != 0x10)\n", ((ACE_HEADER *)ace)->AceFlags);
+ ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n",
+ ace->Mask);
+ }
+ CloseHandle(hTemp);
+
done:
HeapFree(GetProcessHeap(), 0, user);
bret = RemoveDirectoryA(tmpdir);
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 1de2c61..8948bb7 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -103,6 +103,81 @@ mode_t FILE_umask = 0;
static const WCHAR ntfsW[] = {'N','T','F','S'};
+static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIBUTES attr,
+ PIO_STATUS_BLOCK io, PLARGE_INTEGER alloc_size,
+ ULONG attributes, ULONG sharing, ULONG disposition,
+ ULONG options, PVOID ea_buffer, ULONG ea_length );
+
+struct security_descriptor *FILE_get_parent_sd(UNICODE_STRING *filenameW)
+{
+ SECURITY_INFORMATION info = OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION
+ |DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION;
+ PSECURITY_DESCRIPTOR parentsd = NULL;
+ ACL_SIZE_INFORMATION acl_size;
+ BOOLEAN present, defaulted;
+ WCHAR *p, parent[MAX_PATH];
+ OBJECT_ATTRIBUTES pattr;
+ UNICODE_STRING parentW;
+ IO_STATUS_BLOCK io;
+ NTSTATUS status;
+ HANDLE hparent;
+ ULONG n1, n2;
+ PACL pDacl;
+ int i;
+
+ parentW.Buffer = parent;
+ parentW.Length = filenameW->Length;
+ memcpy(parentW.Buffer, filenameW->Buffer, filenameW->Length);
+ if ((p = strrchrW(parent, '\\')) != NULL)
+ {
+ p[0] = 0;
+ parentW.Length = (p-parent)*sizeof(WCHAR);
+ }
+ memset(&pattr, 0x0, sizeof(pattr));
+ pattr.Length = sizeof(pattr);
+ pattr.Attributes = OBJ_CASE_INSENSITIVE;
+ pattr.ObjectName = &parentW;
+ status = FILE_CreateFile( &hparent, READ_CONTROL|ACCESS_SYSTEM_SECURITY, &pattr, &io, NULL,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
+ FILE_OPEN_FOR_BACKUP_INTENT, NULL, 0 );
+ if (status == STATUS_SUCCESS)
+ status = NtQuerySecurityObject( hparent, info, NULL, 0, &n1 );
+ if (status == STATUS_BUFFER_TOO_SMALL && (parentsd = RtlAllocateHeap( GetProcessHeap(), 0, n1 )) != NULL)
+ status = NtQuerySecurityObject( hparent, info, parentsd, n1, &n2 );
+ if (status == STATUS_SUCCESS)
+ status = NtQuerySecurityObject( hparent, info, parentsd, n1, &n2 );
+ if (hparent != INVALID_HANDLE_VALUE)
+ NtClose( hparent );
+ if (status != STATUS_SUCCESS) return NULL;
+ status = RtlGetDaclSecurityDescriptor(parentsd, &present, &pDacl, &defaulted);
+ if (status != STATUS_SUCCESS || !present) return NULL;
+ status = RtlQueryInformationAcl(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
+ if (status != STATUS_SUCCESS) return NULL;
+
+ for (i=acl_size.AceCount-1; i>=0; i--)
+ {
+ DWORD inheritance_mask = INHERIT_ONLY_ACE|OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE;
+ ACE_HEADER *ace;
+
+ status = RtlGetAce(pDacl, i, (VOID **)&ace);
+ if (status != STATUS_SUCCESS || !(ace->AceFlags & inheritance_mask))
+ {
+ RtlDeleteAce(pDacl, i);
+ acl_size.AceCount--;
+ }
+ else
+ ace->AceFlags = (ace->AceFlags & ~inheritance_mask) | INHERITED_ACE;
+ }
+
+ if (!acl_size.AceCount)
+ {
+ return NULL;
+ }
+ return parentsd;
+}
+
+
/**************************************************************************
* FILE_CreateFile (internal)
* Open a file.
@@ -161,10 +236,18 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT
{
struct security_descriptor *sd;
struct object_attributes objattr;
+ PSECURITY_DESCRIPTOR parentsd = NULL, psd;
objattr.rootdir = wine_server_obj_handle( attr->RootDirectory );
objattr.name_len = 0;
- io->u.Status = NTDLL_create_struct_sd( attr->SecurityDescriptor, &sd, &objattr.sd_len );
+ psd = attr->SecurityDescriptor;
+ if (!psd && (disposition == FILE_CREATE||disposition == FILE_OVERWRITE_IF))
+ parentsd = FILE_get_parent_sd( attr->ObjectName );
+ if (parentsd)
+ psd = parentsd;
+ io->u.Status = NTDLL_create_struct_sd( psd, &sd, &objattr.sd_len );
+ if (parentsd)
+ RtlFreeHeap( GetProcessHeap(), 0, parentsd );
if (io->u.Status != STATUS_SUCCESS)
{
RtlFreeAnsiString( &unix_name );
--
1.7.9.5

View File

@@ -1,25 +0,0 @@
From d027a6891aa48f2614b606892bc54e25e147eee2 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Sun, 11 Aug 2013 17:45:19 -0600
Subject: kernel32: Allow string comparison with linguistic casing.
---
dlls/kernel32/locale.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c
index 9ddf078..d635364 100644
--- a/dlls/kernel32/locale.c
+++ b/dlls/kernel32/locale.c
@@ -2934,7 +2934,7 @@ INT WINAPI CompareStringEx(LPCWSTR locale, DWORD flags, LPCWSTR str1, INT len1,
return 0;
}
- if( flags & ~(NORM_IGNORECASE|NORM_IGNORENONSPACE|NORM_IGNORESYMBOLS|
+ if( flags & ~(NORM_IGNORECASE|NORM_IGNORENONSPACE|NORM_IGNORESYMBOLS|NORM_LINGUISTIC_CASING|
SORT_STRINGSORT|NORM_IGNOREKANATYPE|NORM_IGNOREWIDTH|LOCALE_USE_CP_ACP|0x10000000) )
{
SetLastError(ERROR_INVALID_FLAGS);
--
1.7.9.5

View File

@@ -1,163 +0,0 @@
From 4c261ca7ce6d73f0820106804797dcc7f0912b62 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Mon, 11 Nov 2013 00:18:31 +0100
Subject: quartz/tests: Add tests for IVMRMonitorConfig
---
dlls/quartz/tests/Makefile.in | 1 +
dlls/quartz/tests/monitorconfig.c | 131 +++++++++++++++++++++++++++++++++++++
2 files changed, 132 insertions(+)
create mode 100644 dlls/quartz/tests/monitorconfig.c
diff --git a/dlls/quartz/tests/Makefile.in b/dlls/quartz/tests/Makefile.in
index ae5fbac..94b2f44 100644
--- a/dlls/quartz/tests/Makefile.in
+++ b/dlls/quartz/tests/Makefile.in
@@ -8,6 +8,7 @@ C_SRCS = \
filtermapper.c \
memallocator.c \
misc.c \
+ monitorconfig.c \
referenceclock.c \
videorenderer.c
diff --git a/dlls/quartz/tests/monitorconfig.c b/dlls/quartz/tests/monitorconfig.c
new file mode 100644
index 0000000..3a18460
--- /dev/null
+++ b/dlls/quartz/tests/monitorconfig.c
@@ -0,0 +1,131 @@
+/*
+ * MonitorConfig unit tests for Quartz
+ *
+ * Copyright (C) 2013 Sebastian Lackner
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define COBJMACROS
+
+#include "wine/test.h"
+#include "dshow.h"
+
+static void test_monitorconfig_setmonitor(void)
+{
+ HRESULT hr;
+ IUnknown *pVMR = NULL;
+ IVMRMonitorConfig *pMonitorConfig = NULL;
+ VMRGUID guid;
+
+ hr = CoCreateInstance(&CLSID_VideoMixingRenderer, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IUnknown, (LPVOID*)&pVMR);
+ ok(hr == S_OK, "CoCreateInstance failed with %x.\n", hr);
+ ok(pVMR != NULL, "pVMR is NULL.\n");
+ if (!pVMR) goto out;
+
+ hr = IUnknown_QueryInterface(pVMR, &IID_IVMRMonitorConfig, (LPVOID*)&pMonitorConfig);
+ ok(hr == S_OK, "IUnknown_QueryInterface returned %x.\n", hr);
+ ok(pMonitorConfig != NULL, "pMonitorConfig is NULL.\n");
+ if (!pMonitorConfig) goto out;
+
+ memset(&guid, 0, sizeof(guid));
+ guid.pGUID = NULL; /* default DirectDraw device */
+ hr = IVMRMonitorConfig_SetMonitor(pMonitorConfig, &guid);
+ ok(hr == S_OK, "SetMonitor failed with %x.\n", hr);
+
+ memset(&guid, 255, sizeof(guid));
+ hr = IVMRMonitorConfig_GetMonitor(pMonitorConfig, &guid);
+ ok(hr == S_OK, "GetMonitor failed with %x.\n", hr);
+ ok(guid.pGUID == NULL, "GetMonitor returned guid.pGUID = %p, expected NULL.\n", guid.pGUID);
+
+ memset(&guid, 0, sizeof(guid));
+ guid.pGUID = NULL; /* default DirectDraw device */
+ hr = IVMRMonitorConfig_SetDefaultMonitor(pMonitorConfig, &guid);
+ ok(hr == S_OK, "SetDefaultMonitor failed with %x.\n", hr);
+
+ memset(&guid, 255, sizeof(guid));
+ hr = IVMRMonitorConfig_GetDefaultMonitor(pMonitorConfig, &guid);
+ ok(hr == S_OK, "GetDefaultMonitor failed with %x.\n", hr);
+ ok(guid.pGUID == NULL, "GetDefaultMonitor returned guid.pGUID = %p, expected NULL.\n", guid.pGUID);
+
+out:
+ if (pMonitorConfig) IVMRMonitorConfig_Release(pMonitorConfig);
+ if (pVMR) IUnknown_Release(pVMR);
+}
+
+static void test_monitorconfig_getavailablemonitors(void)
+{
+ HRESULT hr;
+ IUnknown *pVMR = NULL;
+ IVMRMonitorConfig *pMonitorConfig = NULL;
+ VMRMONITORINFO info[8];
+ DWORD numdev_total, numdev;
+
+ hr = CoCreateInstance(&CLSID_VideoMixingRenderer, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IUnknown, (LPVOID*)&pVMR);
+ ok(hr == S_OK, "CoCreateInstance failed with %x.\n", hr);
+ ok(pVMR != NULL, "pVMR is NULL.\n");
+ if (!pVMR) goto out;
+
+ hr = IUnknown_QueryInterface(pVMR, &IID_IVMRMonitorConfig, (LPVOID*)&pMonitorConfig);
+ ok(hr == S_OK, "IUnknown_QueryInterface returned %x.\n", hr);
+ ok(pMonitorConfig != NULL, "pMonitorConfig is NULL.\n");
+ if (!pMonitorConfig) goto out;
+
+ /* call without any arguments */
+ hr = IVMRMonitorConfig_GetAvailableMonitors(pMonitorConfig, NULL, 0, NULL);
+ ok(hr == E_POINTER, "GetAvailableMonitors returned %x, expected E_POINTER.\n", hr);
+
+ hr = IVMRMonitorConfig_GetAvailableMonitors(pMonitorConfig, info, 0, &numdev_total);
+ ok(hr == E_INVALIDARG, "GetAvailableMonitors returned %x, expected E_INVALIDARG.\n", hr);
+
+ numdev_total = 0;
+ hr = IVMRMonitorConfig_GetAvailableMonitors(pMonitorConfig, NULL, 0, &numdev_total);
+ ok(hr == S_OK, "GetAvailableMonitors failed with %x.\n", hr);
+ ok(numdev_total > 0, "GetAvailableMonitors returned numdev_total = %d, expected > 0.\n", numdev_total);
+
+ if (numdev_total > 1)
+ {
+ /* return just the first monitor */
+ hr = IVMRMonitorConfig_GetAvailableMonitors(pMonitorConfig, info, 1, &numdev);
+ ok(hr == S_OK, "GetAvailableMonitors failed with %x.\n", hr);
+ ok(numdev == 1, "GetAvailableMonitors returned numdev = %d, expected 1.\n", numdev);
+ }
+
+ /* don't request information for more monitors than memory available */
+ if (numdev_total > sizeof(info)/sizeof(VMRMONITORINFO))
+ numdev_total = sizeof(info)/sizeof(VMRMONITORINFO);
+
+ hr = IVMRMonitorConfig_GetAvailableMonitors(pMonitorConfig, info, numdev_total, &numdev);
+ ok(hr == S_OK, "GetAvailableMonitors failed with %x.\n", hr);
+ ok(numdev == numdev_total, "GetAvailableMonitors returned numdev = %d, expected %d.\n", numdev, numdev_total);
+
+ /* TODO: Add test for content of info */
+
+out:
+ if (pMonitorConfig) IVMRMonitorConfig_Release(pMonitorConfig);
+ if (pVMR) IUnknown_Release(pVMR);
+}
+
+START_TEST(monitorconfig)
+{
+ CoInitialize(NULL);
+
+ test_monitorconfig_setmonitor();
+ test_monitorconfig_getavailablemonitors();
+
+ CoUninitialize();
+}
--
1.7.9.5

View File

@@ -1,17 +1,17 @@
From c1f305f001257ac6bc215abd34c1577e7d9bf7f2 Mon Sep 17 00:00:00 2001
From a1ad64b059de5325b15ed09a39083f5eb973a2f6 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Fri, 4 Oct 2013 08:10:20 -0600
Date: Wed, 12 Feb 2014 13:46:28 -0700
Subject: ws2_32: Ask the server to process unsupported WSAIoctl operations.
---
dlls/ws2_32/socket.c | 47 ++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 44 insertions(+), 3 deletions(-)
dlls/ws2_32/socket.c | 60 ++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 53 insertions(+), 7 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 679258b..44a9093 100644
index 1c558bf..fe5577c 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -3608,6 +3608,36 @@ static const char *debugstr_wsaioctl(DWORD ioctl)
@@ -3668,6 +3668,40 @@ static const char *debugstr_wsaioctl(DWORD ioctl)
(USHORT)(ioctl & 0xffff));
}
@@ -37,8 +37,12 @@ index 679258b..44a9093 100644
+ status = NtDeviceIoControlFile( handle, event, (PIO_APC_ROUTINE)ws2_async_apc, wsa, io, code,
+ in_buff, in_size, out_buff, out_size );
+ if (status == STATUS_NOT_SUPPORTED)
+ {
+ FIXME("Unsupported ioctl %x (device=%x access=%x func=%x method=%x)\n",
+ code, code >> 16, (code >> 14) & 3, (code >> 2) & 0xfff, code & 3);
+ }
+ else if (status == STATUS_SUCCESS)
+ *ret_size = io->Information; /* "Information" is the size written to the output buffer */
+
+ if (status != STATUS_PENDING) RtlFreeHeap( GetProcessHeap(), 0, wsa );
+
@@ -48,32 +52,45 @@ index 679258b..44a9093 100644
/**********************************************************************
* WSAIoctl (WS2_32.50)
*
@@ -3800,9 +3830,8 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID
@@ -3859,12 +3893,6 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID
break;
}
case WS_SIO_ADDRESS_LIST_CHANGE:
- case WS_SIO_ADDRESS_LIST_CHANGE:
- FIXME("-> SIO_ADDRESS_LIST_CHANGE request: stub\n");
- /* FIXME: error and return code depend on whether socket was created
- * with WSA_FLAG_OVERLAPPED, but there is no easy way to get this */
+ TRACE("-> SIO_ADDRESS_LIST_CHANGE request\n");
+ status = WSAEOPNOTSUPP; /* this operation needs to be handled by the server */
break;
- break;
-
case WS_SIO_ADDRESS_LIST_QUERY:
@@ -4045,6 +4074,18 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID
{
DWORD size;
@@ -4100,11 +4128,29 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID
WSASetLastError(WSAEOPNOTSUPP);
return SOCKET_ERROR;
default:
- FIXME("unsupported WS_IOCTL cmd (%s)\n", debugstr_wsaioctl(code));
status = WSAEOPNOTSUPP;
break;
}
+ if (status == WSAEOPNOTSUPP)
+ {
+ status = server_ioctl_sock(s, code, in_buff, in_size, out_buff, out_size, ret_size,
+ status = server_ioctl_sock(s, code, in_buff, in_size, out_buff, out_size, &total,
+ overlapped, completion);
+ if (status != WSAEOPNOTSUPP)
+ {
+ if (status == 0 || status == WSA_IO_PENDING)
+ TRACE("-> %s request\n", debugstr_wsaioctl(code));
+ else
+ ERR("-> %s request failed with status 0x%x\n", debugstr_wsaioctl(code), status);
+
+ /* overlapped and completion operations will be handled by the server */
+ completion = NULL;
+ overlapped = NULL;
+ }
+ else
+ FIXME("unsupported WS_IOCTL cmd (%s)\n", debugstr_wsaioctl(code));
+ }
+
if (completion)

View File

@@ -8,10 +8,10 @@ Subject: ws2_32: Add an interactive test for interface change notifications.
1 file changed, 68 insertions(+)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index ac6ee10..b6da0e7 100644
index 0abf732..4703e59 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -6225,6 +6225,73 @@ static void test_sioRoutingInterfaceQuery(void)
@@ -6487,6 +6487,73 @@ static void test_sioRoutingInterfaceQuery(void)
closesocket(sock);
}
@@ -85,14 +85,14 @@ index ac6ee10..b6da0e7 100644
static void test_synchronous_WSAIoctl(void)
{
HANDLE previous_port, io_port;
@@ -7101,6 +7168,7 @@ START_TEST( sock )
@@ -7570,6 +7637,7 @@ START_TEST( sock )
test_ConnectEx();
test_sioRoutingInterfaceQuery();
+ test_sioAddressListChange();
test_WSAAsyncGetServByPort();
test_WSAAsyncGetServByName();
test_WSALookupService();
--
1.7.9.5

View File

@@ -0,0 +1,3 @@
Revision: 1
Author: Erich E. Hoover
Title: Implement SIO_ADDRESS_LIST_CHANGE.

View File

@@ -0,0 +1,135 @@
From ee79e1be71635431d0d05841c7f9cea720411ba6 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 13 Feb 2014 15:45:41 -0700
Subject: server: Unify the storage of security attributes for files and
directories.
---
server/change.c | 46 ++++++----------------------------------------
server/file.c | 25 +++++++++++++++++--------
server/file.h | 2 ++
3 files changed, 25 insertions(+), 48 deletions(-)
diff --git a/server/change.c b/server/change.c
index f6d56b0..76fc9f7 100644
--- a/server/change.c
+++ b/server/change.c
@@ -317,49 +317,15 @@ static struct security_descriptor *dir_get_sd( struct object *obj )
static int dir_set_sd( struct object *obj, const struct security_descriptor *sd,
unsigned int set_info )
{
- struct dir *dir = (struct dir *)obj;
- const SID *owner;
- struct stat st;
- mode_t mode;
- int unix_fd;
+ struct fd *fd;
+ int ret;
assert( obj->ops == &dir_ops );
- unix_fd = get_dir_unix_fd( dir );
-
- if (unix_fd == -1 || fstat( unix_fd, &st ) == -1) return 1;
-
- if (set_info & OWNER_SECURITY_INFORMATION)
- {
- owner = sd_get_owner( sd );
- if (!owner)
- {
- set_error( STATUS_INVALID_SECURITY_DESCR );
- return 0;
- }
- if (!obj->sd || !security_equal_sid( owner, sd_get_owner( obj->sd ) ))
- {
- /* FIXME: get Unix uid and call fchown */
- }
- }
- else if (obj->sd)
- owner = sd_get_owner( obj->sd );
- else
- owner = token_get_user( current->process->token );
-
- if (set_info & DACL_SECURITY_INFORMATION)
- {
- /* keep the bits that we don't map to access rights in the ACL */
- mode = st.st_mode & (S_ISUID|S_ISGID|S_ISVTX);
- mode |= sd_to_mode( sd, owner );
-
- if (((st.st_mode ^ mode) & (S_IRWXU|S_IRWXG|S_IRWXO)) && fchmod( unix_fd, mode ) == -1)
- {
- file_set_error();
- return 0;
- }
- }
- return 1;
+ fd = dir_get_fd( obj );
+ ret = file_set_acls( obj, fd, sd, set_info );
+ release_object( fd );
+ return ret;
}
static struct change_record *get_first_change_record( struct dir *dir )
diff --git a/server/file.c b/server/file.c
index cceb8ad..13ebaf9 100644
--- a/server/file.c
+++ b/server/file.c
@@ -534,18 +534,13 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner )
return new_mode & ~denied_mode;
}
-static int file_set_sd( struct object *obj, const struct security_descriptor *sd,
- unsigned int set_info )
+int file_set_acls( struct object *obj, struct fd *fd, const struct security_descriptor *sd,
+ unsigned int set_info )
{
- struct file *file = (struct file *)obj;
+ int unix_fd = get_unix_fd( fd );
const SID *owner;
struct stat st;
mode_t mode;
- int unix_fd;
-
- assert( obj->ops == &file_ops );
-
- unix_fd = get_file_unix_fd( file );
if (unix_fd == -1 || fstat( unix_fd, &st ) == -1) return 1;
@@ -584,6 +579,20 @@ static int file_set_sd( struct object *obj, const struct security_descriptor *sd
return 1;
}
+static int file_set_sd( struct object *obj, const struct security_descriptor *sd,
+ unsigned int set_info )
+{
+ struct fd *fd;
+ int ret;
+
+ assert( obj->ops == &file_ops );
+
+ fd = file_get_fd( obj );
+ ret = file_set_acls( obj, fd, sd, set_info );
+ release_object( fd );
+ return ret;
+}
+
static void file_destroy( struct object *obj )
{
struct file *file = (struct file *)obj;
diff --git a/server/file.h b/server/file.h
index 493d30b..11c3220 100644
--- a/server/file.h
+++ b/server/file.h
@@ -122,6 +122,8 @@ extern struct file *create_file_for_fd_obj( struct fd *fd, unsigned int access,
extern void file_set_error(void);
extern struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID *group );
extern mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner );
+extern int file_set_acls( struct object *obj, struct fd *fd, const struct security_descriptor *sd,
+ unsigned int set_info );
/* file mapping functions */
--
1.7.9.5

View File

@@ -0,0 +1,133 @@
From bfad7f20bef7f8ef39e6354d0b47c0c349eac967 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 13 Feb 2014 15:45:48 -0700
Subject: server: Unify the retrieval of security attributes for files and
directories.
---
server/change.c | 27 +++++----------------------
server/file.c | 34 ++++++++++++++++++++++------------
server/file.h | 2 ++
3 files changed, 29 insertions(+), 34 deletions(-)
diff --git a/server/change.c b/server/change.c
index 76fc9f7..0b7b979 100644
--- a/server/change.c
+++ b/server/change.c
@@ -286,31 +286,14 @@ static int get_dir_unix_fd( struct dir *dir )
static struct security_descriptor *dir_get_sd( struct object *obj )
{
struct dir *dir = (struct dir *)obj;
- int unix_fd;
- struct stat st;
struct security_descriptor *sd;
- assert( obj->ops == &dir_ops );
-
- unix_fd = get_dir_unix_fd( dir );
-
- if (unix_fd == -1 || fstat( unix_fd, &st ) == -1)
- return obj->sd;
-
- /* mode and uid the same? if so, no need to re-generate security descriptor */
- if (obj->sd &&
- (st.st_mode & (S_IRWXU|S_IRWXO)) == (dir->mode & (S_IRWXU|S_IRWXO)) &&
- (st.st_uid == dir->uid))
- return obj->sd;
+ struct fd *fd;
- sd = mode_to_sd( st.st_mode,
- security_unix_uid_to_sid( st.st_uid ),
- token_get_primary_group( current->process->token ));
- if (!sd) return obj->sd;
+ assert( obj->ops == &dir_ops );
- dir->mode = st.st_mode;
- dir->uid = st.st_uid;
- free( obj->sd );
- obj->sd = sd;
+ fd = dir_get_fd( obj );
+ sd = file_get_acls( obj, fd, &dir->mode, &dir->uid );
+ release_object( fd );
return sd;
}
diff --git a/server/file.c b/server/file.c
index 13ebaf9..8baa712 100644
--- a/server/file.c
+++ b/server/file.c
@@ -424,23 +424,19 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
return sd;
}
-static struct security_descriptor *file_get_sd( struct object *obj )
+struct security_descriptor *file_get_acls( struct object *obj, struct fd *fd, mode_t *mode,
+ uid_t *uid )
{
- struct file *file = (struct file *)obj;
- struct stat st;
- int unix_fd;
+ int unix_fd = get_unix_fd( fd );
struct security_descriptor *sd;
-
- assert( obj->ops == &file_ops );
-
- unix_fd = get_file_unix_fd( file );
+ struct stat st;
if (unix_fd == -1 || fstat( unix_fd, &st ) == -1)
return obj->sd;
/* mode and uid the same? if so, no need to re-generate security descriptor */
- if (obj->sd && (st.st_mode & (S_IRWXU|S_IRWXO)) == (file->mode & (S_IRWXU|S_IRWXO)) &&
- (st.st_uid == file->uid))
+ if (obj->sd && (st.st_mode & (S_IRWXU|S_IRWXO)) == (*mode & (S_IRWXU|S_IRWXO)) &&
+ (st.st_uid == *uid))
return obj->sd;
sd = mode_to_sd( st.st_mode,
@@ -448,13 +444,27 @@ static struct security_descriptor *file_get_sd( struct object *obj )
token_get_primary_group( current->process->token ));
if (!sd) return obj->sd;
- file->mode = st.st_mode;
- file->uid = st.st_uid;
+ *mode = st.st_mode;
+ *uid = st.st_uid;
free( obj->sd );
obj->sd = sd;
return sd;
}
+static struct security_descriptor *file_get_sd( struct object *obj )
+{
+ struct file *file = (struct file *)obj;
+ struct security_descriptor *sd;
+ struct fd *fd;
+
+ assert( obj->ops == &file_ops );
+
+ fd = file_get_fd( obj );
+ sd = file_get_acls( obj, fd, &file->mode, &file->uid );
+ release_object( fd );
+ return sd;
+}
+
static mode_t file_access_to_mode( unsigned int access )
{
mode_t mode = 0;
diff --git a/server/file.h b/server/file.h
index 11c3220..89b5888 100644
--- a/server/file.h
+++ b/server/file.h
@@ -124,6 +124,8 @@ extern struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, con
extern mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner );
extern int file_set_acls( struct object *obj, struct fd *fd, const struct security_descriptor *sd,
unsigned int set_info );
+extern struct security_descriptor *file_get_acls( struct object *obj, struct fd *fd, mode_t *mode,
+ uid_t *uid );
/* file mapping functions */
--
1.7.9.5

View File

@@ -0,0 +1,150 @@
From 96470b6ee4c0e91700ac197e77784feb42d9a961 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Sat, 15 Feb 2014 18:20:49 -0700
Subject: server: Store file security attributes with extended file
attributes.
---
configure.ac | 12 +++++++++++
server/file.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 79 insertions(+)
diff --git a/configure.ac b/configure.ac
index 32730f3..96d796a 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
AC_ARG_WITH(sane, AS_HELP_STRING([--without-sane],[do not use SANE (scanner support)]))
AC_ARG_WITH(tiff, AS_HELP_STRING([--without-tiff],[do not use TIFF]))
AC_ARG_WITH(v4l, AS_HELP_STRING([--without-v4l],[do not use v4l1 (v4l support)]))
+AC_ARG_WITH(xattr, AS_HELP_STRING([--without-xattr],[do not use xattr (security attributes support)]))
AC_ARG_WITH(xcomposite,AS_HELP_STRING([--without-xcomposite],[do not use the Xcomposite extension]),
[if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_Xcomposite_h=no; fi])
AC_ARG_WITH(xcursor, AS_HELP_STRING([--without-xcursor],[do not use the Xcursor extension]),
@@ -661,6 +662,17 @@ AC_CHECK_HEADERS([libprocstat.h],,,
#include <sys/socket.h>
#endif])
+if test "x$with_xattr" != "xno"
+then
+ AC_CHECK_HEADERS(attr/xattr.h,HAVE_XATTR=1)
+fi
+if test "x$with_xattr" == "xyes"
+then
+ WINE_ERROR_WITH(xattr,[test "x$HAVE_XATTR" = "x"],[xattr ${notice_platform}development files not \
+found. Wine will be built without extended attribute support, which probably isn't what you want. \
+You will need to install ${notice_platform}development packages of libacl at the very least.])
+fi
+
dnl **** Check for working dll ****
AC_SUBST(dlldir,"\${libdir}/wine")
diff --git a/server/file.c b/server/file.c
index 8baa712..c375c72 100644
--- a/server/file.c
+++ b/server/file.c
@@ -32,6 +32,7 @@
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
+#include <limits.h>
#include <unistd.h>
#ifdef HAVE_UTIME_H
#include <utime.h>
@@ -39,6 +40,9 @@
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
+#ifdef HAVE_ATTR_XATTR_H
+#include <attr/xattr.h>
+#endif
#include "ntstatus.h"
#define WIN32_NO_STATUS
@@ -178,6 +182,66 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_
return &file->obj;
}
+void set_xattr_acls( int fd, const struct security_descriptor *sd )
+{
+#ifdef HAVE_ATTR_XATTR_H
+ char buffer[XATTR_SIZE_MAX], *p = buffer;
+ const ACE_HEADER *ace;
+ int present, i, j, n;
+ const ACL *dacl;
+
+ if (!sd) return;
+ dacl = sd_get_dacl( sd, &present );
+ if (!present || !dacl) return;
+ ace = (const ACE_HEADER *)(dacl + 1);
+
+ for (i = 0; i < dacl->AceCount; i++, ace = ace_next( ace ))
+ {
+ BYTE type = ace->AceType, flags;
+ const ACCESS_ALLOWED_ACE *aaa;
+ const ACCESS_DENIED_ACE *ada;
+ char sidtxt[100], *s;
+ const SID *sid;
+ DWORD mask;
+
+ if (type & INHERIT_ONLY_ACE) continue;
+
+ switch (type)
+ {
+ case ACCESS_DENIED_ACE_TYPE:
+ ada = (const ACCESS_DENIED_ACE *)ace;
+ flags = ada->Header.AceFlags;
+ mask = ada->Mask;
+ sid = (const SID *)&ada->SidStart;
+ break;
+ case ACCESS_ALLOWED_ACE_TYPE:
+ aaa = (const ACCESS_ALLOWED_ACE *)ace;
+ flags = aaa->Header.AceFlags;
+ mask = aaa->Mask;
+ sid = (const SID *)&aaa->SidStart;
+ break;
+ default:
+ continue;
+ }
+ n = sprintf( sidtxt, "S-%u-%d", sid->Revision,
+ MAKELONG(
+ MAKEWORD( sid->IdentifierAuthority.Value[5],
+ sid->IdentifierAuthority.Value[4] ),
+ MAKEWORD( sid->IdentifierAuthority.Value[3],
+ sid->IdentifierAuthority.Value[2] )
+ ) );
+ s = sidtxt + n;
+ for( j=0; j<sid->SubAuthorityCount; j++ )
+ s += sprintf( s, "-%u", sid->SubAuthority[j] );
+
+ p += snprintf( p, XATTR_SIZE_MAX-(p-buffer), "%s%x,%x,%x,%s",
+ (p != buffer ? ";" : ""), type, flags, mask, sidtxt );
+ }
+
+ fsetxattr( fd, "user.wine.acl", buffer, p-buffer, 0 );
+#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 +303,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;
+ set_xattr_acls( get_unix_fd( fd ), sd );
if (S_ISDIR(mode))
obj = create_dir_obj( fd, access, mode );
@@ -580,6 +645,8 @@ int file_set_acls( struct object *obj, struct fd *fd, const struct security_desc
mode = st.st_mode & (S_ISUID|S_ISGID|S_ISVTX);
mode |= sd_to_mode( sd, owner );
+ set_xattr_acls( unix_fd, sd );
+
if (((st.st_mode ^ mode) & (S_IRWXU|S_IRWXG|S_IRWXO)) && fchmod( unix_fd, mode ) == -1)
{
file_set_error();
--
1.7.9.5

View File

@@ -0,0 +1,293 @@
From 66583f9f848becaa12d84270a2ebe7a79ac34724 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 13 Feb 2014 16:04:57 -0700
Subject: server: Retrieve file security attributes with extended file
attributes.
---
dlls/advapi32/tests/security.c | 49 +++++++------
server/file.c | 156 +++++++++++++++++++++++++++++++++++++++-
2 files changed, 177 insertions(+), 28 deletions(-)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index e2e9cd5..f107abc 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -3105,24 +3105,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);
- todo_wine ok(bret, "Current User ACE != Current User SID.\n");
- todo_wine ok(((ACE_HEADER *)ace)->AceFlags == (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE),
- "Current User ACE has unexpected flags (0x%x != 0x03)\n",
- ((ACE_HEADER *)ace)->AceFlags);
- ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n",
- ace->Mask);
+ ok(bret, "Current User ACE != Current User SID.\n");
+ ok(((ACE_HEADER *)ace)->AceFlags == (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE),
+ "Current User ACE has unexpected flags (0x%x != 0x03)\n",
+ ((ACE_HEADER *)ace)->AceFlags);
+ todo_wine ok(ace->Mask == 0x1f01ff,
+ "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
}
if (acl_size.AceCount > 1)
{
bret = pGetAce(pDacl, 1, (VOID **)&ace);
ok(bret, "Failed to get Administators Group ACE.\n");
bret = EqualSid(&ace->SidStart, admin_sid);
- todo_wine ok(bret, "Administators Group ACE != Administators Group SID.\n");
- todo_wine ok(((ACE_HEADER *)ace)->AceFlags == (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE),
- "Administators Group ACE has unexpected flags (0x%x != 0x03)\n",
- ((ACE_HEADER *)ace)->AceFlags);
- ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n",
- ace->Mask);
+ ok(bret, "Administators Group ACE != Administators Group SID.\n");
+ ok(((ACE_HEADER *)ace)->AceFlags == (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE),
+ "Administators Group ACE has unexpected flags (0x%x != 0x03)\n",
+ ((ACE_HEADER *)ace)->AceFlags);
+ todo_wine ok(ace->Mask == 0x1f01ff,
+ "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
}
done:
@@ -3294,23 +3294,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);
- todo_wine ok(bret, "Current User ACE != Current User SID.\n");
+ ok(bret, "Current User ACE != Current User SID.\n");
ok(((ACE_HEADER *)ace)->AceFlags == 0,
"Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
- ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n",
- ace->Mask);
+ todo_wine ok(ace->Mask == 0x1f01ff,
+ "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
}
if (acl_size.AceCount > 1)
{
bret = pGetAce(pDacl, 1, (VOID **)&ace);
ok(bret, "Failed to get Administators Group ACE.\n");
bret = EqualSid(&ace->SidStart, admin_sid);
- todo_wine ok(bret || broken(!bret) /* win2k */,
- "Administators Group ACE != Administators Group SID.\n");
+ ok(bret || broken(!bret) /* win2k */, "Administators Group ACE != Administators Group SID.\n");
ok(((ACE_HEADER *)ace)->AceFlags == 0,
"Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
- ok(ace->Mask == 0x1f01ff || broken(ace->Mask == GENERIC_ALL) /* win2k */,
- "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
+ todo_wine ok(ace->Mask == 0x1f01ff || broken(ace->Mask == GENERIC_ALL) /* win2k */,
+ "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
}
LocalFree(pSD);
HeapFree(GetProcessHeap(), 0, user);
@@ -3960,22 +3959,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);
- todo_wine ok(bret, "Current User ACE != Current User SID.\n");
+ ok(bret, "Current User ACE != Current User SID.\n");
ok(((ACE_HEADER *)ace)->AceFlags == 0,
"Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
- ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n",
- ace->Mask);
+ todo_wine ok(ace->Mask == 0x1f01ff,
+ "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
}
if (acl_size.AceCount > 1)
{
bret = pGetAce(pDacl, 1, (VOID **)&ace);
ok(bret, "Failed to get Administators Group ACE.\n");
bret = EqualSid(&ace->SidStart, admin_sid);
- todo_wine ok(bret, "Administators Group ACE != Administators Group SID.\n");
+ ok(bret, "Administators Group ACE != Administators Group SID.\n");
ok(((ACE_HEADER *)ace)->AceFlags == 0,
"Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
- ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n",
- ace->Mask);
+ todo_wine ok(ace->Mask == 0x1f01ff,
+ "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
}
CloseHandle(obj);
}
diff --git a/server/file.c b/server/file.c
index c375c72..b9135b9 100644
--- a/server/file.c
+++ b/server/file.c
@@ -489,11 +489,160 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
return sd;
}
+struct security_descriptor *get_xattr_acls( int fd, const SID *user, const SID *group )
+{
+#ifdef HAVE_ATTR_XATTR_H
+ int ace_count = 0, dacl_size = sizeof(ACL), i, n;
+ char buffer[XATTR_SIZE_MAX], *p = buffer, *pn;
+ struct security_descriptor *sd;
+ ACE_HEADER *current_ace;
+ ACCESS_ALLOWED_ACE *aaa;
+ ACCESS_DENIED_ACE *ada;
+ int type, flags, mask;
+ ACL *dacl;
+ char *ptr;
+
+ n = fgetxattr( fd, "user.wine.acl", buffer, sizeof(buffer) );
+ if (n == -1) return NULL;
+ buffer[n] = 0;
+
+ do
+ {
+ int sub_authority_count = 0;
+
+ pn = strchr(p, ';');
+ if (pn) pn++;
+ sscanf(p, "%x", &type);
+ do
+ {
+ p = strchr(p, '-');
+ if (p) p++;
+ sub_authority_count++;
+ }
+ while(p && (!pn || p < pn));
+ sub_authority_count -= 3; /* Revision and IdentifierAuthority don't count */
+
+ switch (type)
+ {
+ case ACCESS_DENIED_ACE_TYPE:
+ dacl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) +
+ FIELD_OFFSET(SID, SubAuthority[sub_authority_count]);
+ break;
+ case ACCESS_ALLOWED_ACE_TYPE:
+ dacl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) +
+ FIELD_OFFSET(SID, SubAuthority[sub_authority_count]);
+ break;
+ default:
+ continue;
+ }
+ ace_count++;
+ p = pn;
+ }
+ while(p);
+
+ sd = mem_alloc( sizeof(struct security_descriptor) +
+ FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]) +
+ FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]) +
+ dacl_size );
+
+ sd->control = SE_DACL_PRESENT;
+ sd->owner_len = FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]);
+ sd->group_len = FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]);
+ sd->sacl_len = 0;
+ sd->dacl_len = dacl_size;
+
+ ptr = (char *)(sd + 1);
+ memcpy( ptr, user, sd->owner_len );
+ ptr += sd->owner_len;
+ memcpy( ptr, group, sd->group_len );
+ ptr += sd->group_len;
+
+ dacl = (ACL *)ptr;
+ dacl->AclRevision = ACL_REVISION;
+ dacl->Sbz1 = 0;
+ dacl->AclSize = dacl_size;
+ dacl->AceCount = ace_count;
+ dacl->Sbz2 = 0;
+ aaa = (ACCESS_ALLOWED_ACE *)(dacl + 1);
+ current_ace = &aaa->Header;
+
+ p = buffer;
+ for(i=0; i<ace_count; i++)
+ {
+ char b[sizeof(SID) + sizeof(ULONG) * SID_MAX_SUB_AUTHORITIES];
+ int sub_authority_count = 0;
+ SID *sid = (SID *)&b[0];
+ char sidtxt[100];
+ int rev, ia, sa;
+
+ if (i != 0)
+ {
+ aaa = (ACCESS_ALLOWED_ACE *)ace_next( current_ace );
+ current_ace = &aaa->Header;
+ }
+ pn = strchr(p, ';');
+ if (pn) pn++;
+ sscanf(p, "%x,%x,%x,%[^;]", &type, &flags, &mask, sidtxt);
+ sscanf(sidtxt, "S-%u-%d", &rev, &ia);
+ sid->Revision = rev;
+ sid->IdentifierAuthority.Value[0] = 0;
+ sid->IdentifierAuthority.Value[1] = 0;
+ sid->IdentifierAuthority.Value[2] = HIBYTE(HIWORD(ia));
+ sid->IdentifierAuthority.Value[3] = LOBYTE(HIWORD(ia));
+ sid->IdentifierAuthority.Value[4] = HIBYTE(LOWORD(ia));
+ sid->IdentifierAuthority.Value[5] = LOBYTE(LOWORD(ia));
+ p = strchr(sidtxt, '-')+1;
+ p = strchr(p, '-')+1; /* Revision doesn't count */
+ p = strchr(p, '-')+1; /* IdentifierAuthority doesn't count */
+ do
+ {
+ sscanf(p, "%u", &sa);
+ sid->SubAuthority[sub_authority_count] = sa;
+ p = strchr(p, '-');
+ if (p) p++;
+ sub_authority_count++;
+ }
+ while(p);
+ sid->SubAuthorityCount = sub_authority_count;
+
+ /* Handle the specific ACE */
+ switch (type)
+ {
+ case ACCESS_DENIED_ACE_TYPE:
+ ada = (ACCESS_DENIED_ACE *)aaa;
+ ada->Header.AceType = type;
+ ada->Header.AceFlags = flags;
+ ada->Header.AceSize = FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) +
+ FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]);
+ ada->Mask = mask;
+ memcpy( &ada->SidStart, sid, FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]) );
+ break;
+ case ACCESS_ALLOWED_ACE_TYPE:
+ aaa->Header.AceType = type;
+ aaa->Header.AceFlags = flags;
+ aaa->Header.AceSize = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) +
+ FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]);
+ aaa->Mask = mask;
+ memcpy( &aaa->SidStart, sid, FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]) );
+ break;
+ default:
+ continue;
+ }
+ p = pn;
+ }
+
+ return sd;
+#else
+ return NULL;
+#endif
+}
+
struct security_descriptor *file_get_acls( struct object *obj, struct fd *fd, mode_t *mode,
uid_t *uid )
{
int unix_fd = get_unix_fd( fd );
struct security_descriptor *sd;
+ const SID *user, *group;
struct stat st;
if (unix_fd == -1 || fstat( unix_fd, &st ) == -1)
@@ -504,9 +653,10 @@ struct security_descriptor *file_get_acls( struct object *obj, struct fd *fd, mo
(st.st_uid == *uid))
return obj->sd;
- sd = mode_to_sd( st.st_mode,
- security_unix_uid_to_sid( st.st_uid ),
- token_get_primary_group( current->process->token ));
+ user = security_unix_uid_to_sid( st.st_uid );
+ group = token_get_primary_group( current->process->token );
+ sd = get_xattr_acls( unix_fd, user, group );
+ if (!sd) sd = mode_to_sd( st.st_mode, user, group);
if (!sd) return obj->sd;
*mode = st.st_mode;
--
1.7.9.5

Some files were not shown because too many files have changed in this diff Show More