Compare commits

...

95 Commits

Author SHA1 Message Date
Michael MĂĽller
4df6fee769 Add font symlink patch. 2014-07-23 01:20:57 +02:00
Erich E. Hoover
6b2cc4c58f Return correct IMediaSeeking stream positions in quartz. 2014-07-22 08:38:10 -06:00
Michael MĂĽller
a3d2b4b9e0 Fix fuzz in patches. 2014-07-20 22:36:08 +02:00
Erich E. Hoover
95bee0aa1e Fix race condition between EndOfStream and Pause. 2014-07-18 10:58:54 -06:00
Erich E. Hoover
bc6f854478 Fix possible race conditions in strmbase/quartz. 2014-07-17 10:54:33 -06:00
Erich E. Hoover
4b95841bdb Release 1.7.22. 2014-07-11 13:00:13 -06:00
Erich E. Hoover
180fa60a17 Implement passing ACLs to CreateProcess. 2014-07-11 12:57:10 -06:00
Sebastian Lackner
9d3369d7a6 gitapply.sh: Make sure that all error output is redirected to stderr, sort commandline options. 2014-07-11 00:31:33 +02:00
Sebastian Lackner
2bb1b96f06 Removed several patches (accepted upstream). 2014-07-09 21:47:48 +02:00
Erich E. Hoover
2bfe73c2b7 Updated main extended attributes patch to include BSD support. 2014-07-08 14:32:58 -06:00
Erich E. Hoover
8e2ab550d8 Updated main extended attributes patch to include additional data checks. 2014-07-08 14:32:06 -06:00
Erich E. Hoover
7f5e6044ee Reformat the display of the Wine bug number in the README. 2014-07-08 13:19:19 -06:00
Erich E. Hoover
db0464c6f2 Update repository name and description in README. 2014-07-08 12:39:31 -06:00
Sebastian Lackner
80455f2b22 Rebase patch to silence resource_check_usage FIXME. 2014-07-08 01:03:49 +02:00
Sebastian Lackner
ce40587ef4 Return NULL-terminated list of arguments in CommandLineToArgvW. 2014-07-07 23:43:30 +02:00
Sebastian Lackner
4ad4f948c3 Fix incorrect scaling for DECIMAL values in VarDecAdd. 2014-07-07 22:19:53 +02:00
Sebastian Lackner
1fbebd0a1a Add patch for implementation of wtsapi32.WTSEnumerateProcessesW. 2014-07-06 23:55:09 +02:00
Sebastian Lackner
1761c9534e Move UrlCombineW patches in a separate directory. 2014-07-06 23:47:00 +02:00
Sebastian Lackner
b500367ff7 Remove patch '0001-quartz-tests-Add-tests-for-IVMRMonitorConfig-and-IVMRM.patch'. 2014-07-06 23:40:17 +02:00
Erich E. Hoover
5721ee15c9 Removed RegSetKeySecurity patch (accepted upstream). 2014-07-04 13:18:59 -06:00
Erich E. Hoover
56264645ad Updated RegSetKeySecurity patch to work with special root keys. 2014-07-04 10:14:57 -06:00
Erich E. Hoover
113b554090 Retitle RegSetKeySecurity component (advapi -> advapi32). 2014-07-01 20:34:44 -06:00
Erich E. Hoover
24c6b554c9 Implement RegSetKeySecurity on top of NtSetSecurityObject. 2014-07-01 19:26:01 -06:00
Erich E. Hoover
b861c5731d Added NT4 support to the process ACL tests. 2014-07-01 18:32:31 -06:00
Erich E. Hoover
5d354c9b2a Release 1.7.21 2014-06-27 23:09:39 -06:00
Sebastian Lackner
e8fee88c50 Remove several patches (accepted upstream). 2014-06-22 20:40:51 +02:00
Sebastian Lackner
c2e8167d6d Release 1.7.20. 2014-06-14 19:46:09 +02:00
Sebastian Lackner
907d56238e Fix warning during compilation for unused variable. 2014-06-14 10:37:54 +02:00
Sebastian Lackner
674b998176 Add patch to fix issues with Obsidium copy protection (add missing exception in OutputDebugStringA). 2014-06-14 09:45:49 +02:00
Erich E. Hoover
882b560d0d Added patches for default security descriptor ownership and DACLs for processes. 2014-06-13 15:29:17 -06:00
Erich E. Hoover
8df335170a Updated changelog with recent changes. 2014-06-13 15:29:16 -06:00
Sebastian Lackner
2241ffdf4b Disable gstreamer (broken with glib >= 2.32.0).
See http://bugs.winehq.org/show_bug.cgi?id=30557 for more details.
2014-06-13 23:22:54 +02:00
Sebastian Lackner
dff7b6b562 Update winepulse patches to latest revision (extracted from 1.7.19). 2014-06-13 22:47:13 +02:00
Sebastian Lackner
cdb00a9e7a Update README.md. 2014-06-13 22:02:13 +02:00
Sebastian Lackner
f7541123b5 Add patch to avoid race-condition when unloading modules while hook is active. 2014-06-13 21:49:49 +02:00
Sebastian Lackner
6578707ac2 Remove several patches (accepted upstream). 2014-06-13 20:07:34 +02:00
Michael MĂĽller
719c65ebb0 Fix recommendation for odbc and add libgsm1. 2014-06-07 14:55:29 +02:00
Erich E. Hoover
ddefcb372a Force autoreconf even when timestamp seems to indicate that it is not necessary. 2014-06-05 15:38:43 -06:00
Michael MĂĽller
c594bca17a Error out in git apply script on *BSD. 2014-06-05 21:20:54 +02:00
Sebastian Lackner
3c33a592f6 Make generate-patchlist.sh compatible with FreeBSD. 2014-06-05 22:17:55 +02:00
Sebastian Lackner
4476d8af38 Update changelog for release 1.7.19-1. 2014-06-02 23:55:55 +02:00
Sebastian Lackner
b216cdce2c Update FD cache patch to allow complication with -DNDEBUG. 2014-06-02 20:57:19 +02:00
Sebastian Lackner
fc086bb2bc Add additional check to ensure wineserver doesn't crash if mem_alloc fails. 2014-06-02 01:42:23 +02:00
Sebastian Lackner
772dfd9f5a Work around compiler signed <-> unsigned casting issues. 2014-06-02 01:38:40 +02:00
Michael MĂĽller
b4d53a7344 Add support for xattr/ACLs on FreeBSD 2014-06-01 22:10:22 +02:00
Sebastian Lackner
e5c7fe8c18 Merge branch 'master' of github.com:compholio/wine-compholio-daily 2014-06-01 23:48:40 +02:00
Sebastian Lackner
fdc24226bf 02-ACL_Extended_Attributes: Add additional patch to prevent crashes in case of invalid extended attributes. 2014-06-01 23:47:53 +02:00
Michael MĂĽller
3886ee9fae Add patch to detect direct rendering in Wine applications. 2014-06-01 22:55:11 +02:00
Sebastian Lackner
229eb9bba5 Update fd cache patches (use slightly slower interlocked commands, which should also work well on less usual processor architectures). 2014-05-31 22:10:09 +02:00
Sebastian Lackner
1800d1f853 Fixed possible race-condition in FD cache patches. 2014-05-31 18:38:40 +02:00
Sebastian Lackner
24d682fd91 Add patch to fix exception test failures on x86_64. 2014-05-31 14:12:22 +02:00
Sebastian Lackner
979900f060 Add lockfree implementation for get_cached_fd to ntdll. 2014-05-31 04:02:40 +02:00
Michael MĂĽller
d094743650 Fix patchlist. 2014-05-31 03:46:10 +02:00
Michael MĂĽller
2c9d2d8f64 Merge branch 'master' of https://github.com/compholio/wine-compholio-daily 2014-05-31 03:42:29 +02:00
Michael MĂĽller
457c0bf7e1 Add patches to fix current Unity3D webplayer. 2014-05-31 03:42:21 +02:00
Sebastian Lackner
d2209c6ee0 Add additional patch for --check-libs commandline option. 2014-05-30 01:26:10 +02:00
Sebastian Lackner
84997e39ab Separate patchlist into patch-list.patch (containing the autogenerated list) and 00-Commandline for the commandline option changes. 2014-05-30 01:04:27 +02:00
Michael MĂĽller
01be545e92 Replace strict draw ordering patch with a different approach. 2014-05-27 03:03:03 +02:00
Erich E. Hoover
bfb7d535af Updated SIO_ADDRESS_LIST_CHANGE patches. 2014-05-16 13:32:52 -06:00
Sebastian Lackner
94813ecf3c Update changelog for release 1.7.18-1. 2014-05-13 20:49:41 +02:00
Sebastian Lackner
b09ed0f3d2 Rebase 02-ACL_Extended_Attributes patches. 2014-05-04 01:32:57 +02:00
Sebastian Lackner
807da03757 Add additional patch to silence repeated wined3d_swapchain_present FIXMEs. 2014-05-04 00:55:43 +02:00
Sebastian Lackner
af447c6cfd Simplify patch to silence repeated resource_check_usage FIXMEs. 2014-05-04 00:43:52 +02:00
Sebastian Lackner
aac5a0da53 Add additional patch to silence repeated CompareStringEx FIXME messages. 2014-05-04 00:29:57 +02:00
Michael Mueller
7fede3cd56 Fix gitapply on BSD systems 2014-05-03 02:31:56 +02:00
Michael Mueller
43b781b453 Fix problem with CURDIR on BSD systems 2014-05-03 02:19:22 +02:00
Erich E. Hoover
d989770f24 Update changelog for release 1.7.18. 2014-05-02 13:05:45 -06:00
Michael MĂĽller
036250b6da Update timer patch 2014-05-02 20:50:58 +02:00
Erich E. Hoover
d787be6d20 Update changelog for release 1.7.17. 2014-04-18 16:04:47 -06:00
Erich E. Hoover
c35db80eae Split the storage of the ownership information into a separate patch. 2014-04-18 15:48:33 -06:00
Erich E. Hoover
4328f2e964 Update ACL patches to store user/group data instead of replacing it on the retrieval side. 2014-04-18 15:29:56 -06:00
Erich E. Hoover
eecf7c4a68 ACL data is now stored in binary instead of converting it to ASCII. 2014-04-17 16:53:10 -06:00
compholio
4d01de8fcd Update README.md with linguistic casing removal 2014-04-17 13:03:11 -06:00
Erich E. Hoover
f5ef032c89 Removed linguistic casing patches (accepted upstream). 2014-04-17 12:56:29 -06:00
Erich E. Hoover
f9eebd5599 Removed dynamic unwind patches (accepted upstream). 2014-04-16 16:52:37 -06:00
Erich E. Hoover
48bbae3fb7 Fix strndup move not being properly rebased. 2014-04-15 15:30:37 -06:00
Michael MĂĽller
fdbc47e09e Merge branch 'master' of https://github.com/compholio/wine-compholio-daily 2014-04-15 23:19:39 +02:00
Michael MĂĽller
2b4093a0ea Remove recommendation for gettext and libgif 2014-04-15 23:18:52 +02:00
Erich E. Hoover
580ff7c1c5 Move strndup call inside of file_get_parent_sd. 2014-04-15 15:14:15 -06:00
Erich E. Hoover
454c09ddbe Remove old test code for adding extra ACLs. 2014-04-15 15:08:23 -06:00
Erich E. Hoover
810202432b Ensure ACL buffers are NULL terminated for all string processing. 2014-04-15 15:05:36 -06:00
Erich E. Hoover
737eb1005a Add bounds checking on SubAuthorityCount. 2014-04-15 14:56:44 -06:00
Erich E. Hoover
58eeb19b3e Rebase security attribute retrieval patch. 2014-04-15 14:32:21 -06:00
Erich E. Hoover
c8be20f3cf Remove unnecessary check for INHERIT_ONLY_ACE. 2014-04-15 14:28:42 -06:00
Erich E. Hoover
b6d34ea7d2 Do not unnecessarily move 'struct stat st;'. 2014-04-15 14:20:06 -06:00
slackner
f6d14c47ec Merge pull request #3 from anish/patch-1
Update gitapply.sh (Turn off whitespace warnings)
2014-04-10 04:08:07 +02:00
Anish Bhatt
78d6102645 Update gitapply.sh
Turn off whitespace warnings
2014-04-09 19:03:06 -07:00
Erich E. Hoover
b862f600f5 Start putting changelog entries in prior to releases. 2014-04-05 17:46:37 -06:00
Erich E. Hoover
e0b037b82a Update the linguistic casing patches to print a FIXME that the flags are not fully supported. 2014-04-05 14:28:26 -06:00
Erich E. Hoover
69b0f7ebd7 Split Arial replacement into two patches. 2014-04-05 13:29:29 -06:00
Erich E. Hoover
7c95fad661 Dropped liblcms2-dev dependency for old Ubuntu versions. 2014-04-04 19:52:26 -06:00
Sebastian Lackner
67cc61ffca Update changelog. 2014-04-05 03:49:35 +02:00
Sebastian Lackner
0df720506a Fix build failure caused by dynamic unwind patches on 32-bit. 2014-04-05 03:47:22 +02:00
Sebastian Lackner
68c91b3113 Merge branch 'master' of github.com:compholio/wine-compholio-daily 2014-04-05 02:03:52 +02:00
Sebastian Lackner
ac36f88de1 11-Dynamic_Unwind: Add forward from kernel32 to ntdll. 2014-04-05 02:03:07 +02:00
113 changed files with 75318 additions and 43326 deletions

View File

@@ -1,19 +1,23 @@
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)
* 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)
* 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)
* Workaround for shlwapi URLs with relative paths
* Support for PulseAudio backend for audio
* Other Pipelight specific enhancements

73
debian/changelog vendored
View File

@@ -1,3 +1,76 @@
wine-compholio (1.7.23) UNRELEASED; urgency=low
* Fix possible race conditions in strmbase/quartz.
* Fix race condition between EndOfStream and Pause.
* Return correct IMediaSeeking stream positions in quartz.
-- Erich E. Hoover <erich.e.hoover@gmail.com> Tue, 22 Jul 2014 08:37:27 -0600
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
wine-compholio (1.7.20) unstable; urgency=low
* Remove several patches (accepted upstream).
* Fix recommendation for odbc and add libgsm1.
* Disabled gstreamer (broken with glib >= 2.32.0).
* Updated scripts to be compatible with BSD systems.
* Update winepulse patches to latest revision (extracted from 1.7.19).
* Force autoreconf even when timestamp seems to indicate that it is not necessary.
* Added patches for default security descriptor ownership and DACLs for processes.
* Added a patch to avoid a race-condition when unloading modules while a hook is active.
* Add patch to fix issues with Obsidium copy protection.
-- Erich E. Hoover <erich.e.hoover@gmail.com> Sat, 14 Jun 2014 18:15:12 +0200
wine-compholio (1.7.19-1) unstable; urgency=low
* Added a patch to fix return value for FSCTL_PIPE_WAIT (required for Unity3D).
* Added a patch to stub TokenAppContainerSid in NtQueryInformationToken (required for Unity3D).
* Added a patch to optimize the file descriptor cache by using lockfree algorithms.
* Add additional checks in XATTR patch to ensure wineserver doesn't crash if data is corrupted.
* Add support for extended attributes on FreeBSD systems.
* Added a patch to fix ntdll/exception test failures on x86_64.
* Allow to change 'strict draw ordering' at runtime.
* Add ability to test if all dynamic libraries are installed with "wine --check-libs".
* Added a patch to query if direct rendering is enabled via GLX extension.
-- Sebastian Lackner <sebastian@fds-team.de> Mon, 02 Jun 2014 23:50:23 +0200
wine-compholio (1.7.19) unstable; urgency=low
* Updated SIO_ADDRESS_LIST_CHANGE patches.
-- Erich E. Hoover <erich.e.hoover@gmail.com> Tue, 06 May 2014 15:42:32 -0600
wine-compholio (1.7.18-1) unstable; urgency=low
* Fix some issues on BSD systems.
* Add additional patches to silence a few FIXMEs.
* Rebase 02-ACL_Extended_Attributes patches.
-- Sebastian Lackner <sebastian@fds-team.de> Tue, 13 May 2014 20:47:23 +0200
wine-compholio (1.7.18) unstable; urgency=low
* Updated SetTimer patch (10 ms accepted upstream).
-- Erich E. Hoover <erich.e.hoover@gmail.com> Fri, 02 May 2014 13:05:13 -0600
wine-compholio (1.7.17) unstable; urgency=low
* Split Arial replacement into two patches.
* Removed dynamic unwind patches (accepted upstream).
* Removed linguistic casing patches (accepted upstream).
* ACL data is now stored in binary instead of converting it to ASCII.
-- Erich E. Hoover <erich.e.hoover@gmail.com> Fri, 18 Apr 2014 16:03:57 -0600
wine-compholio (1.7.16-1) unstable; urgency=low
* Fix build failure caused by dynamic unwind functions.
* Dropped liblcms2-dev dependency for old Ubuntu versions.
-- Sebastian Lackner <sebastian@fds-team.de> Sat, 05 Apr 2014 03:48:25 +0200
wine-compholio (1.7.16) unstable; urgency=low
* Add stub for RtlInstallFunctionTableCallback.
* Further split out the SIO_ADDRESS_LIST_CHANGE patches.

19
debian/control vendored
View File

@@ -27,17 +27,14 @@ Build-Depends: autotools-dev,
libesd0-dev,
libfontconfig1-dev | libfontconfig-dev,
libfreetype6-dev,
libgif-dev | libungif4-dev,
libgl1-mesa-dev | nvidia-glx-dev | fglrx-driver-dev | libgl-dev,
libglu1-mesa-dev | libglu-dev,
libgnutls-dev,
libgphoto2-dev | libgphoto2-6-dev | libgphoto2-2-dev (>= 2.4.6),
libgsm1-dev,
libgstreamer-plugins-base0.10-dev,
libgstreamer0.10-dev,
libice-dev,
libjpeg-dev,
liblcms2-dev,
liblcms2-dev | ubuntu-desktop (<< 1.267),
libldap2-dev, libldap-dev,
libmpg123-dev,
libncurses5-dev | libncurses-dev,
@@ -77,13 +74,11 @@ Pre-Depends: dpkg (>= 1.14.12ubuntu3), ${misc:Pre-Depends}
Depends: ${shlibs:Depends},
libasound2-plugins,
libncurses5
Recommends: gettext,
libcapi20-3,
Recommends: libcapi20-3,
libcups2,
libdbus-1-3,
libfontconfig1 | libfontconfig,
libfreetype6,
libgif4,
libgnutls26,
libgphoto2-6 | libgphoto2-2 (>= 2.4.6),
libgphoto2-port10 | libgphoto2-port0 (>= 2.4.6),
@@ -105,7 +100,8 @@ Recommends: gettext,
libxslt1.1,
libxt6,
libxxf86vm1,
unixodbc
libodbc1,
libgsm1
Section: otherosfs
Priority: optional
Replaces: wine-compholio (<< 1.7.15-1~)
@@ -136,13 +132,11 @@ Pre-Depends: dpkg (>= 1.14.12ubuntu3), ${misc:Pre-Depends}
Depends: ${shlibs:Depends},
libasound2-plugins,
libncurses5
Recommends: gettext,
libcapi20-3,
Recommends: libcapi20-3,
libcups2,
libdbus-1-3,
libfontconfig1 | libfontconfig,
libfreetype6,
libgif4,
libgnutls26,
libgphoto2-6 | libgphoto2-2 (>= 2.4.6),
libgphoto2-port10 | libgphoto2-port0 (>= 2.4.6),
@@ -164,7 +158,8 @@ Recommends: gettext,
libxslt1.1,
libxt6,
libxxf86vm1,
unixodbc
libodbc1,
libgsm1
Section: otherosfs
Priority: optional
Replaces: wine-compholio (<< 1.7.15-1~)

4
debian/rules vendored
View File

@@ -16,9 +16,9 @@ override_dh_auto_configure:
make -C "$(CURDIR)/patches/" DESTDIR="$(CURDIR)" install
ifeq ($(DEB_BUILD_ARCH), amd64)
./configure --prefix=/opt/wine-compholio --libdir=\$${prefix}/lib64 --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info --enable-win64 --with-xattr $(CONFFLAGS)
./configure --prefix=/opt/wine-compholio --libdir=\$${prefix}/lib64 --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info --enable-win64 --without-gstreamer --with-xattr $(CONFFLAGS)
else
./configure --prefix=/opt/wine-compholio --libdir=\$${prefix}/lib --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info --with-xattr $(CONFFLAGS)
./configure --prefix=/opt/wine-compholio --libdir=\$${prefix}/lib --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info --without-gstreamer --with-xattr $(CONFFLAGS)
endif
override_dh_auto_test:

View File

@@ -18,50 +18,17 @@ done
PATCH_LINES=$(echo "${PATCH_DATA}" | wc -l);
PATCH_LINES=$((${PATCH_LINES}+20));
PATCH_DATA=$(echo "${PATCH_DATA}" | sed ':a;N;$!ba;s/\n/\\n/g');
cat <<EOF | sed -e "s|##PATCH_LINES##|${PATCH_LINES}|" \
-e "s|##PATCH_DATA##|${PATCH_DATA}|"
cat <<EOF
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..5fa0cd5 100644
--- a/libs/wine/config.c
+++ b/libs/wine/config.c
@@ -478,6 +478,##PATCH_LINES## @@ const char *wine_get_version(void)
@@ -478,6 +478,${PATCH_LINES} @@ const char *wine_get_version(void)
return PACKAGE_VERSION;
}
@@ -70,7 +37,7 @@ index a273502..5fa0cd5 100644
+ const char *author;
+ const char *title;
+} wine_patch_data[] = {
##PATCH_DATA##
${PATCH_DATA}
+ { NULL, NULL, NULL }
+};
+
@@ -107,50 +74,6 @@ index 2159fac..7cb2918 100644
wine_init;
wine_init_argv0_path;
wine_is_dbcs_leadbyte;
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,12 @@ static inline void reserve_area( void *addr, size_t size )
#endif /* __APPLE__ */
+struct wine_patch {
+ const char *hash;
+ const char *author;
+ const char *title;
+};
+
/***********************************************************************
* check_command_line
*
@@ -89,7 +96,8 @@ static void check_command_line( int argc, char *argv[] )
static const char usage[] =
"Usage: wine PROGRAM [ARGUMENTS...] Run the specified program\n"
" wine --help Display this help and exit\n"
- " wine --version Output version information and exit";
+ " wine --version Output version information and exit\n"
+ " wine --patches Output patch information and exit";
if (argc <= 1)
{
@@ -106,6 +114,16 @@ static void check_command_line( int argc, char *argv[] )
printf( "%s\n", wine_get_build_id() );
exit(0);
}
+ if (!strcmp( argv[1], "--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,
+ wine_patch_data->title );
+ }
+ exit(0);
+ }
}
diff --git a/include/wine/library.h b/include/wine/library.h
index 242bb69..aa9e585 100644
--- a/include/wine/library.h

View File

@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# Setup parser variables
nogit=0
@@ -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
@@ -78,10 +78,16 @@ done
# Redirect to git apply if available
if [ "$nogit" -eq 0 ] && command -v git >/dev/null 2>&1; then
exec git apply "$@"
exec git apply --whitespace=nowarn "$@"
exit 1
fi
if gzip -V 2>&1 | grep "BSD" &> /dev/null; then
echo "This script is not compatible with *BSD utilities." >&2
echo "Please install git, which provides the same functionality and will be used instead." >&2
exit 1;
fi
# Decode base85 git data, prepend with a gzip header
awk_b85='
BEGIN{
@@ -327,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
@@ -428,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

View File

@@ -0,0 +1,89 @@
From d88eb32e40bff9b8279f57b13a5f2cc09a9273ea Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Thu, 29 May 2014 23:43:45 +0200
Subject: loader: Add commandline option --patches to show the patch list.
---
dlls/ntdll/misc.c | 8 ++++++++
dlls/ntdll/ntdll.spec | 1 +
loader/main.c | 19 ++++++++++++++++++-
3 files changed, 27 insertions(+), 1 deletion(-)
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 5bac269..ab50882 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -1419,6 +1419,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/loader/main.c b/loader/main.c
index ac67290..71e5055 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -79,6 +79,12 @@ static inline void reserve_area( void *addr, size_t size )
#endif /* __APPLE__ */
+struct wine_patch {
+ const char *hash;
+ const char *author;
+ const char *title;
+};
+
/***********************************************************************
* check_command_line
*
@@ -89,7 +95,8 @@ static void check_command_line( int argc, char *argv[] )
static const char usage[] =
"Usage: wine PROGRAM [ARGUMENTS...] Run the specified program\n"
" wine --help Display this help and exit\n"
- " wine --version Output version information and exit";
+ " wine --version Output version information and exit\n"
+ " wine --patches Output patch information and exit";
if (argc <= 1)
{
@@ -106,6 +113,16 @@ static void check_command_line( int argc, char *argv[] )
printf( "%s\n", wine_get_build_id() );
exit(0);
}
+ if (!strcmp( argv[1], "--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,
+ wine_patch_data->title );
+ }
+ exit(0);
+ }
}
--
1.7.9.5

View File

@@ -0,0 +1,301 @@
From eb9657a39d222aa59140f6b0aff657ae86d1824d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Wed, 28 May 2014 19:50:51 +0200
Subject: loader: Add commandline option --check-libs.
---
include/wine/library.h | 2 ++
libs/wine/config.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++
libs/wine/loader.c | 36 +++++++++++++++++++
libs/wine/wine.def | 2 ++
libs/wine/wine.map | 2 ++
loader/main.c | 50 +++++++++++++++++++++++++-
6 files changed, 182 insertions(+), 1 deletion(-)
diff --git a/include/wine/library.h b/include/wine/library.h
index fae73fe..7395a11 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -40,6 +40,7 @@ extern "C" {
extern const char *wine_get_build_dir(void);
extern const char *wine_get_config_dir(void);
extern const char *wine_get_data_dir(void);
+extern const char **wine_get_libs(void);
extern const char *wine_get_server_dir(void);
extern const char *wine_get_user_name(void);
extern const char *wine_get_version(void);
@@ -52,6 +53,7 @@ extern void wine_exec_wine_binary( const char *name, char **argv, const char *en
typedef void (*load_dll_callback_t)( void *, const char * );
+extern int wine_dladdr( void *addr, void *info, char *error, size_t errorsize );
extern void *wine_dlopen( const char *filename, int flag, char *error, size_t errorsize );
extern void *wine_dlsym( void *handle, const char *symbol, char *error, size_t errorsize );
extern int wine_dlclose( void *handle, char *error, size_t errorsize );
diff --git a/libs/wine/config.c b/libs/wine/config.c
index 954035d..3fb7327 100644
--- a/libs/wine/config.c
+++ b/libs/wine/config.c
@@ -444,6 +444,97 @@ const char *wine_get_build_dir(void)
return build_dir;
}
+const char *wine_libs[] = {
+#ifdef SONAME_LIBCAPI20
+ SONAME_LIBCAPI20,
+#endif
+#ifdef SONAME_LIBCUPS
+ SONAME_LIBCUPS,
+#endif
+#ifdef SONAME_LIBCURSES
+ SONAME_LIBCURSES,
+#endif
+#ifdef SONAME_LIBDBUS_1
+ SONAME_LIBDBUS_1,
+#endif
+#ifdef SONAME_LIBFONTCONFIG
+ SONAME_LIBFONTCONFIG,
+#endif
+#ifdef SONAME_LIBGL
+ SONAME_LIBGL,
+#endif
+#ifdef SONAME_LIBGNUTLS
+ SONAME_LIBGNUTLS,
+#endif
+#ifdef SONAME_LIBGSM
+ SONAME_LIBGSM,
+#endif
+#ifdef SONAME_LIBHAL
+ SONAME_LIBHAL,
+#endif
+#ifdef SONAME_LIBJPEG
+ SONAME_LIBJPEG,
+#endif
+#ifdef SONAME_LIBNCURSES
+ SONAME_LIBNCURSES,
+#endif
+#ifdef SONAME_LIBNETAPI
+ SONAME_LIBNETAPI,
+#endif
+#ifdef SONAME_LIBODBC
+ SONAME_LIBODBC,
+#endif
+#ifdef SONAME_LIBOSMESA
+ SONAME_LIBOSMESA,
+#endif
+#ifdef SONAME_LIBPNG
+ SONAME_LIBPNG,
+#endif
+#ifdef SONAME_LIBSANE
+ SONAME_LIBSANE,
+#endif
+#ifdef SONAME_LIBTIFF
+ SONAME_LIBTIFF,
+#endif
+#ifdef SONAME_LIBV4L1
+ SONAME_LIBV4L1,
+#endif
+#ifdef SONAME_LIBXCOMPOSITE
+ SONAME_LIBXCOMPOSITE,
+#endif
+#ifdef SONAME_LIBXCURSOR
+ SONAME_LIBXCURSOR,
+#endif
+#ifdef SONAME_LIBXEXT
+ SONAME_LIBXEXT,
+#endif
+#ifdef SONAME_LIBXI
+ SONAME_LIBXI,
+#endif
+#ifdef SONAME_LIBXINERAMA
+ SONAME_LIBXINERAMA,
+#endif
+#ifdef SONAME_LIBXRANDR
+ SONAME_LIBXRANDR,
+#endif
+#ifdef SONAME_LIBXRENDER
+ SONAME_LIBXRENDER,
+#endif
+#ifdef SONAME_LIBXSLT
+ SONAME_LIBXSLT,
+#endif
+#ifdef SONAME_LIBXXF86VM
+ SONAME_LIBXXF86VM,
+#endif
+ NULL
+};
+
+/* return the list of shared libs used by wine */
+const char **wine_get_libs(void)
+{
+ return &wine_libs[0];
+}
+
/* return the full name of the server directory (the one containing the socket) */
const char *wine_get_server_dir(void)
{
diff --git a/libs/wine/loader.c b/libs/wine/loader.c
index 5c0192d..91a4428 100644
--- a/libs/wine/loader.c
+++ b/libs/wine/loader.c
@@ -1054,6 +1054,42 @@ void *wine_dlopen( const char *filename, int flag, char *error, size_t errorsize
}
/***********************************************************************
+ * wine_dladdr
+ */
+int wine_dladdr( void *addr, void *info, char *error, size_t errorsize )
+{
+#ifdef HAVE_DLADDR
+ int ret;
+ const char *s;
+ dlerror(); dlerror();
+ ret = dladdr( addr, (Dl_info *)info );
+ s = dlerror();
+ if (error && errorsize)
+ {
+ if (s)
+ {
+ size_t len = strlen(s);
+ if (len >= errorsize) len = errorsize - 1;
+ memcpy( error, s, len );
+ error[len] = 0;
+ }
+ else error[0] = 0;
+ }
+ dlerror();
+ return ret;
+#else
+ if (error)
+ {
+ static const char msg[] = "dladdr interface not detected by configure";
+ size_t len = min( errorsize, sizeof(msg) );
+ memcpy( error, msg, len );
+ error[len - 1] = 0;
+ }
+ return 0;
+#endif
+}
+
+/***********************************************************************
* wine_dlsym
*/
void *wine_dlsym( void *handle, const char *symbol, char *error, size_t errorsize )
diff --git a/libs/wine/wine.def b/libs/wine/wine.def
index 5b42029..6acf329 100644
--- a/libs/wine/wine.def
+++ b/libs/wine/wine.def
@@ -64,6 +64,7 @@ EXPORTS
wine_dbg_sprintf
wine_dbgstr_an
wine_dbgstr_wn
+ wine_dladdr
wine_dlclose
wine_dll_enum_load_path
wine_dll_get_owner
@@ -79,6 +80,7 @@ EXPORTS
wine_get_build_id
wine_get_config_dir
wine_get_data_dir
+ wine_get_libs
wine_get_server_dir
wine_get_sortkey
wine_get_user_name
diff --git a/libs/wine/wine.map b/libs/wine/wine.map
index 7cb2918..72ffed8 100644
--- a/libs/wine/wine.map
+++ b/libs/wine/wine.map
@@ -65,6 +65,7 @@ WINE_1.0
wine_dbg_sprintf;
wine_dbgstr_an;
wine_dbgstr_wn;
+ wine_dladdr;
wine_dlclose;
wine_dll_enum_load_path;
wine_dll_get_owner;
@@ -85,6 +86,7 @@ WINE_1.0
wine_get_es;
wine_get_fs;
wine_get_gs;
+ wine_get_libs;
wine_get_server_dir;
wine_get_sortkey;
wine_get_ss;
diff --git a/loader/main.c b/loader/main.c
index 71e5055..131ac2f 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -36,6 +36,12 @@
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
+#ifdef HAVE_DLADDR
+# include <dlfcn.h>
+#endif
+#ifdef HAVE_LINK_H
+# include <link.h>
+#endif
#include <pthread.h>
#include "wine/library.h"
@@ -96,7 +102,8 @@ static void check_command_line( int argc, char *argv[] )
"Usage: wine PROGRAM [ARGUMENTS...] Run the specified program\n"
" wine --help Display this help and exit\n"
" wine --version Output version information and exit\n"
- " wine --patches Output patch information and exit";
+ " wine --patches Output patch information and exit\n"
+ " wine --check-libs Checks if shared libs are installed";
if (argc <= 1)
{
@@ -123,6 +130,47 @@ static void check_command_line( int argc, char *argv[] )
}
exit(0);
}
+ if (!strcmp( argv[1], "--check-libs" ))
+ {
+ void* lib_handle;
+ int ret = 0;
+ const char **wine_libs = wine_get_libs();
+
+ for(; *wine_libs; wine_libs++)
+ {
+ lib_handle = wine_dlopen( *wine_libs, RTLD_NOW, NULL, 0 );
+ if (lib_handle)
+ {
+ #ifdef HAVE_DLADDR
+ Dl_info libinfo;
+ void* symbol;
+
+ #ifdef HAVE_LINK_H
+ struct link_map *lm = (struct link_map *)lib_handle;
+ symbol = (void *)lm->l_addr;
+ #else
+ symbol = wine_dlsym( lib_handle, "_init", NULL, 0 );
+ #endif
+ if (symbol && wine_dladdr( symbol, &libinfo, NULL, 0 ))
+ {
+ printf( "%s: %s\n", *wine_libs, libinfo.dli_fname );
+ }
+ else
+ #endif
+ {
+ printf( "%s: found\n", *wine_libs );
+ }
+ wine_dlclose( lib_handle, NULL, 0 );
+ }
+ else
+ {
+ printf( "%s: missing\n", *wine_libs );
+ ret = 1;
+ }
+ }
+
+ exit(ret);
+ }
}
--
1.7.9.5

View File

@@ -0,0 +1,3 @@
Revision: 1
Author: Sebastian Lackner
Title: Add commandline option --patches to show the patch list.

View File

@@ -0,0 +1,3 @@
Revision: 1
Author: Michael MĂĽller
Title: Add commandline option --check-libs to test if shared libraries are installed.

View File

@@ -1,15 +1,15 @@
From 69e77bd226057f486d1c076ccbebb963d3b750ee Mon Sep 17 00:00:00 2001
From 864781654bfbb059a351fdcda6773e2857019278 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 3 Apr 2014 09:25:48 -0600
Date: Tue, 6 May 2014 08:39:18 -0600
Subject: server: Add socket-side support for the interface change
notification object.
---
server/sock.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 91 insertions(+), 1 deletion(-)
server/sock.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 86 insertions(+), 1 deletion(-)
diff --git a/server/sock.c b/server/sock.c
index 05fc38b..20d022f 100644
index 3eb1bdf..ad20a69 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -106,12 +106,18 @@ struct sock
@@ -22,26 +22,26 @@ index 05fc38b..20d022f 100644
};
static void sock_dump( struct object *obj, int verbose );
+static int sock_add_ifchange( struct sock *sock, const async_data_t *async_data );
+static void sock_add_ifchange( struct sock *sock, const async_data_t *async_data );
static int sock_signaled( struct object *obj, struct wait_queue_entry *entry );
static struct fd *sock_get_fd( struct object *obj );
static void sock_destroy( struct object *obj );
+static int sock_get_ifchange_q( struct sock *sock, struct async_queue **async_queue );
+static struct async_queue *sock_get_ifchange_q( struct sock *sock );
+static void sock_destroy_ifchange_q( struct sock *sock );
static int sock_get_poll_events( struct fd *fd );
static void sock_poll_event( struct fd *fd, int event );
@@ -539,7 +545,8 @@ obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *a
@@ -529,7 +535,8 @@ obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *a
switch(code)
{
case WS_SIO_ADDRESS_LIST_CHANGE:
- /* intentional fallthrough, not yet supported */
+ error = sock_add_ifchange( sock, async_data );
+ break;
+ sock_add_ifchange( sock, async_data );
+ return 0;
default:
error = STATUS_NOT_SUPPORTED;
break;
@@ -625,6 +632,7 @@ static void sock_destroy( struct object *obj )
set_error( STATUS_NOT_SUPPORTED );
return 0;
@@ -610,6 +617,7 @@ static void sock_destroy( struct object *obj )
free_async_queue( sock->read_q );
free_async_queue( sock->write_q );
@@ -49,7 +49,7 @@ index 05fc38b..20d022f 100644
if (sock->event) release_object( sock->event );
if (sock->fd)
{
@@ -651,6 +659,8 @@ static void init_sock(struct sock *sock)
@@ -636,6 +644,8 @@ static void init_sock(struct sock *sock)
sock->deferred = NULL;
sock->read_q = NULL;
sock->write_q = NULL;
@@ -58,37 +58,37 @@ index 05fc38b..20d022f 100644
memset( sock->errors, 0, sizeof(sock->errors) );
}
@@ -939,6 +949,86 @@ static void sock_set_error(void)
@@ -924,6 +934,81 @@ static void sock_set_error(void)
set_error( sock_get_ntstatus( errno ) );
}
+/* add interface change notification to a socket */
+static int sock_add_ifchange( struct sock *sock, const async_data_t *async_data )
+static void sock_add_ifchange( struct sock *sock, const async_data_t *async_data )
+{
+ struct async_queue *ifchange_q = NULL;
+ struct async *async;
+ int error;
+
+ error = sock_get_ifchange_q( sock, &ifchange_q );
+ if (error != STATUS_PENDING)
+ return error;
+ if (!(ifchange_q = sock_get_ifchange_q( sock )))
+ return;
+
+ if (!(async = create_async( current, ifchange_q, async_data )))
+ {
+ if (!async_queued( ifchange_q ))
+ sock_destroy_ifchange_q( sock );
+
+ return STATUS_NO_MEMORY;
+ set_error( STATUS_NO_MEMORY );
+ return;
+ }
+
+ release_object( async );
+ return error;
+ set_error( STATUS_PENDING );
+}
+
+/* stub ifchange object */
+static int get_ifchange( struct object **obj )
+static struct object *get_ifchange( void )
+{
+ return STATUS_NOT_SUPPORTED;
+ set_error( STATUS_NOT_SUPPORTED );
+ return NULL;
+}
+
+/* stub ifchange add socket to list */
@@ -97,21 +97,16 @@ index 05fc38b..20d022f 100644
+}
+
+/* create a new ifchange queue for a specific socket or, if one already exists, reuse the existing one */
+static int sock_get_ifchange_q( struct sock *sock, struct async_queue **async_queue )
+static struct async_queue *sock_get_ifchange_q( struct sock *sock )
+{
+ struct object *ifchange = NULL;
+ struct fd *fd;
+ int error;
+
+ if (sock->ifchange_q) /* reuse existing ifchange_q for this socket */
+ {
+ *async_queue = sock->ifchange_q;
+ return STATUS_PENDING;
+ }
+ return sock->ifchange_q;
+
+ error = get_ifchange( &ifchange );
+ if (error != STATUS_PENDING)
+ return error;
+ if (!(ifchange = get_ifchange()))
+ return NULL;
+
+ /* create the ifchange notification queue */
+ fd = ifchange->ops->get_fd( ifchange );
@@ -120,14 +115,14 @@ index 05fc38b..20d022f 100644
+ if (!sock->ifchange_q)
+ {
+ release_object( ifchange );
+ return STATUS_NO_MEMORY;
+ set_error( STATUS_NO_MEMORY );
+ return NULL;
+ }
+
+ /* add the socket to the ifchange notification list */
+ ifchange_add_sock( ifchange, sock );
+ sock->ifchange_obj = ifchange;
+ *async_queue = sock->ifchange_q;
+ return error;
+ return sock->ifchange_q;
+}
+
+/* destroy an existing ifchange queue for a specific socket */

View File

@@ -1,14 +1,14 @@
From 45dfbd2ddb5ca2c64fcfd56392be9c55513abc4b Mon Sep 17 00:00:00 2001
From c93a05ca0114b76c542f251de60b8c009e4a72b0 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 3 Apr 2014 09:23:02 -0600
Subject: server: Add delayed processing for socket-specific ioctl().
Date: Tue, 6 May 2014 08:44:59 -0600
Subject: server: Add blocked support for SIO_ADDRESS_LIST_CHANGE ioctl().
---
server/event.c | 13 +++++++++++++
server/named_pipe.c | 13 -------------
server/object.h | 1 +
server/sock.c | 19 +++++++++++++++++--
4 files changed, 31 insertions(+), 15 deletions(-)
server/sock.c | 26 ++++++++++++++++++++------
4 files changed, 34 insertions(+), 19 deletions(-)
diff --git a/server/event.c b/server/event.c
index 4d3c562..0daa5b2 100644
@@ -71,44 +71,78 @@ index bb3ff21..bad162f 100644
extern struct keyed_event *get_keyed_event_obj( struct process *process, obj_handle_t handle, unsigned int access );
extern void pulse_event( struct event *event );
diff --git a/server/sock.c b/server/sock.c
index 3eb1bdf..05fc38b 100644
index ad20a69..a8a5ac3 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -523,17 +523,32 @@ obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *a
@@ -112,7 +112,7 @@ struct sock
};
static void sock_dump( struct object *obj, int verbose );
-static void sock_add_ifchange( struct sock *sock, const async_data_t *async_data );
+static int sock_add_ifchange( struct sock *sock, const async_data_t *async_data );
static int sock_signaled( struct object *obj, struct wait_queue_entry *entry );
static struct fd *sock_get_fd( struct object *obj );
static void sock_destroy( struct object *obj );
@@ -529,14 +529,27 @@ obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *a
int blocking, const void *data, data_size_t size )
{
struct sock *sock = get_fd_user( fd );
+ obj_handle_t wait_handle = 0;
+ async_data_t new_data;
+ int error;
assert( sock->obj.ops == &sock_ops );
+ if (blocking)
+ {
+ if (!(wait_handle = alloc_wait_event( current->process ))) return 0;
+ new_data = *async_data;
+ new_data.event = wait_handle;
+ async_data = &new_data;
+ }
switch(code)
{
case WS_SIO_ADDRESS_LIST_CHANGE:
/* intentional fallthrough, not yet supported */
default:
- set_error( STATUS_NOT_SUPPORTED );
- sock_add_ifchange( sock, async_data );
- return 0;
+ error = STATUS_NOT_SUPPORTED;
+ break;
}
+ set_error( error );
+ if (error == STATUS_PENDING)
+ if (blocking)
+ {
+ if (!(wait_handle = alloc_wait_event( current->process ))) return 0;
+ new_data = *async_data;
+ new_data.event = wait_handle;
+ async_data = &new_data;
+ }
+ if (!sock_add_ifchange( sock, async_data ) && wait_handle)
+ {
+ close_handle( current->process, wait_handle );
+ return 0;
+ }
+ return wait_handle;
+ close_handle( current->process, wait_handle );
+ return 0;
default:
set_error( STATUS_NOT_SUPPORTED );
return 0;
@@ -935,13 +948,13 @@ static void sock_set_error(void)
}
static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, int count )
/* add interface change notification to a socket */
-static void sock_add_ifchange( struct sock *sock, const async_data_t *async_data )
+static int sock_add_ifchange( struct sock *sock, const async_data_t *async_data )
{
struct async_queue *ifchange_q = NULL;
struct async *async;
if (!(ifchange_q = sock_get_ifchange_q( sock )))
- return;
+ return FALSE;
if (!(async = create_async( current, ifchange_q, async_data )))
{
@@ -949,11 +962,12 @@ static void sock_add_ifchange( struct sock *sock, const async_data_t *async_data
sock_destroy_ifchange_q( sock );
set_error( STATUS_NO_MEMORY );
- return;
+ return FALSE;
}
release_object( async );
set_error( STATUS_PENDING );
+ return TRUE;
}
/* stub ifchange object */
--
1.7.9.5

View File

@@ -1,14 +1,14 @@
From 85d0475a493be336c340f25cab9895846e202f26 Mon Sep 17 00:00:00 2001
From 55c83dc866e2d0e2cdc15b976b6d818a03ef4b89 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 3 Apr 2014 09:26:34 -0600
Date: Tue, 6 May 2014 08:49:52 -0600
Subject: server: Implement the interface change notification object.
---
server/sock.c | 200 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 198 insertions(+), 2 deletions(-)
server/sock.c | 206 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 203 insertions(+), 3 deletions(-)
diff --git a/server/sock.c b/server/sock.c
index 20d022f..82464f2 100644
index a8a5ac3..2af9acc 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -43,6 +43,10 @@
@@ -22,11 +22,12 @@ index 20d022f..82464f2 100644
#include "ntstatus.h"
#define WIN32_NO_STATUS
@@ -972,15 +976,207 @@ static int sock_add_ifchange( struct sock *sock, const async_data_t *async_data
return error;
@@ -970,16 +974,212 @@ static int sock_add_ifchange( struct sock *sock, const async_data_t *async_data
return TRUE;
}
-/* stub ifchange object */
-static struct object *get_ifchange( void )
+#ifdef HAVE_LINUX_RTNETLINK_H
+
+/* only keep one ifchange object around, all sockets waiting for wakeups will look to it */
@@ -162,7 +163,7 @@ index 20d022f..82464f2 100644
+}
+
+static void ifchange_reselect_async( struct fd *fd, struct async_queue *queue )
+{
{
+ /* do nothing, this object is about to disappear */
+}
+
@@ -170,8 +171,8 @@ index 20d022f..82464f2 100644
+
+/* we only need one of these interface notification objects, all of the sockets dependent upon
+ * it will wake up when a notification event occurs */
static int get_ifchange( struct object **obj )
{
+ static struct object *get_ifchange( void )
+ {
+#ifdef HAVE_LINUX_RTNETLINK_H
+ struct ifchange *ifchange;
+ struct sockaddr_nl addr;
@@ -180,14 +181,16 @@ index 20d022f..82464f2 100644
+ if (ifchange_object)
+ {
+ /* increment the refcount for each socket that uses the ifchange object */
+ *obj = grab_object( ifchange_object );
+ return STATUS_PENDING;
+ return grab_object( ifchange_object );
+ }
+
+ /* create the socket we need for processing interface change notifications */
+ unix_fd = socket( PF_NETLINK, SOCK_RAW, NETLINK_ROUTE );
+ if (unix_fd == -1)
+ return sock_get_ntstatus( errno );
+ {
+ sock_set_error();
+ return NULL;
+ }
+ fcntl( unix_fd, F_SETFL, O_NONBLOCK ); /* make socket nonblocking */
+ memset( &addr, 0, sizeof(addr) );
+ addr.nl_family = AF_NETLINK;
@@ -196,27 +199,30 @@ index 20d022f..82464f2 100644
+ if (bind( unix_fd, (struct sockaddr *)&addr, sizeof(addr) ) == -1)
+ {
+ close( unix_fd );
+ return sock_get_ntstatus( errno );
+ sock_set_error();
+ return NULL;
+ }
+ if (!(ifchange = alloc_object( &ifchange_ops )))
+ {
+ close( unix_fd );
+ return STATUS_NO_MEMORY;
+ set_error( STATUS_NO_MEMORY );
+ return NULL;
+ }
+ list_init( &ifchange->sockets );
+ if (!(ifchange->fd = create_anonymous_fd( &ifchange_fd_ops, unix_fd, &ifchange->obj, 0 )))
+ {
+ release_object( ifchange );
+ return STATUS_NO_MEMORY;
+ set_error( STATUS_NO_MEMORY );
+ return NULL;
+ }
+ set_fd_events( ifchange->fd, POLLIN ); /* enable read wakeup on the file descriptor */
+
+ /* the ifchange object is now successfully configured */
+ ifchange_object = &ifchange->obj;
+ *obj = &ifchange->obj;
+ return STATUS_PENDING;
+ return &ifchange->obj;
+#else
return STATUS_NOT_SUPPORTED;
set_error( STATUS_NOT_SUPPORTED );
return NULL;
+#endif
}

View File

@@ -1,6 +1,6 @@
From ee79e1be71635431d0d05841c7f9cea720411ba6 Mon Sep 17 00:00:00 2001
From 379e01b2aea67fa305d2ccd08b589d2d31cd0da0 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
Date: Thu, 17 Apr 2014 16:07:46 -0600
Subject: server: Unify the storage of security attributes for files and
directories.
@@ -11,7 +11,7 @@ Subject: server: Unify the storage of security attributes for files and
3 files changed, 25 insertions(+), 48 deletions(-)
diff --git a/server/change.c b/server/change.c
index f6d56b0..76fc9f7 100644
index f6d56b0..7cea06b 100644
--- a/server/change.c
+++ b/server/change.c
@@ -317,49 +317,15 @@ static struct security_descriptor *dir_get_sd( struct object *obj )
@@ -64,14 +64,14 @@ index f6d56b0..76fc9f7 100644
- }
- return 1;
+ fd = dir_get_fd( obj );
+ ret = file_set_acls( obj, fd, sd, set_info );
+ ret = set_file_sd( 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
index cceb8ad..fb89272 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 )
@@ -80,8 +80,8 @@ index cceb8ad..13ebaf9 100644
-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 )
+int set_file_sd( 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 );
@@ -109,7 +109,7 @@ index cceb8ad..13ebaf9 100644
+ assert( obj->ops == &file_ops );
+
+ fd = file_get_fd( obj );
+ ret = file_set_acls( obj, fd, sd, set_info );
+ ret = set_file_sd( obj, fd, sd, set_info );
+ release_object( fd );
+ return ret;
+}
@@ -118,15 +118,15 @@ index cceb8ad..13ebaf9 100644
{
struct file *file = (struct file *)obj;
diff --git a/server/file.h b/server/file.h
index 493d30b..11c3220 100644
index 493d30b..76cb383 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 );
+extern int set_file_sd( struct object *obj, struct fd *fd, const struct security_descriptor *sd,
+ unsigned int set_info );
/* file mapping functions */

View File

@@ -1,17 +1,17 @@
From b83ae7cc77483519ed870ead3a167e83acbf1cff Mon Sep 17 00:00:00 2001
From e20db446df6bb0177f90964cd09dd9a993d120f3 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
Date: Thu, 17 Apr 2014 16:07:50 -0600
Subject: server: Unify the retrieval of security attributes for files and
directories.
---
server/change.c | 32 +++++---------------------------
server/file.c | 34 ++++++++++++++++++++++------------
server/file.c | 32 +++++++++++++++++++++-----------
server/file.h | 2 ++
3 files changed, 29 insertions(+), 39 deletions(-)
3 files changed, 28 insertions(+), 38 deletions(-)
diff --git a/server/change.c b/server/change.c
index 76fc9f7..eb16923 100644
index 7cea06b..c391180 100644
--- a/server/change.c
+++ b/server/change.c
@@ -278,39 +278,17 @@ static struct fd *dir_get_fd( struct object *obj )
@@ -54,13 +54,13 @@ index 76fc9f7..eb16923 100644
- free( obj->sd );
- obj->sd = sd;
+ fd = dir_get_fd( obj );
+ sd = file_get_acls( obj, fd, &dir->mode, &dir->uid );
+ sd = set_file_sd( 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
index fb89272..1f008ea 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
@@ -68,20 +68,19 @@ index 13ebaf9..8baa712 100644
}
-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 security_descriptor *get_file_sd( 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 stat st;
- int unix_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;
@@ -115,7 +114,7 @@ index 13ebaf9..8baa712 100644
+ assert( obj->ops == &file_ops );
+
+ fd = file_get_fd( obj );
+ sd = file_get_acls( obj, fd, &file->mode, &file->uid );
+ sd = get_file_sd( obj, fd, &file->mode, &file->uid );
+ release_object( fd );
+ return sd;
+}
@@ -124,15 +123,15 @@ index 13ebaf9..8baa712 100644
{
mode_t mode = 0;
diff --git a/server/file.h b/server/file.h
index 11c3220..89b5888 100644
index 76cb383..43a234f 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 );
extern int set_file_sd( struct object *obj, struct fd *fd, const struct security_descriptor *sd,
unsigned int set_info );
+extern struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode,
+ uid_t *uid );
/* file mapping functions */

View File

@@ -1,16 +1,16 @@
From 96470b6ee4c0e91700ac197e77784feb42d9a961 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: Sat, 15 Feb 2014 18:20:49 -0700
Date: Fri, 18 Apr 2014 15:34:47 -0600
Subject: server: Store file security attributes with extended file
attributes.
---
configure.ac | 12 +++++++++++
server/file.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 79 insertions(+)
configure.ac | 12 ++++++++++++
server/file.c | 39 +++++++++++++++++++++++++++++++++++++++
2 files changed, 51 insertions(+)
diff --git a/configure.ac b/configure.ac
index 32730f3..96d796a 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
@@ -21,13 +21,13 @@ index 32730f3..96d796a 100644
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],,,
@@ -664,6 +665,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)
+ 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 32730f3..96d796a 100644
AC_SUBST(dlldir,"\${libdir}/wine")
diff --git a/server/file.c b/server/file.c
index 8baa712..c375c72 100644
index 1f008ea..951e25b 100644
--- a/server/file.c
+++ b/server/file.c
@@ -32,6 +32,7 @@
@@ -51,96 +51,68 @@ index 8baa712..c375c72 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,66 @@ 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_acls( int fd, const struct security_descriptor *sd )
+void set_xattr_sd( 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;
+#if defined(HAVE_ATTR_XATTR_H) || defined(HAVE_SYS_EXTATTR_H)
+ char buffer[XATTR_SIZE_MAX];
+ int present, len;
+ const ACL *dacl;
+
+ /* there's no point in storing the security descriptor if there's no 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;
+ len = 2 + sizeof(struct security_descriptor) + sd->owner_len + sd->group_len + sd->sacl_len
+ + sd->dacl_len;
+ if (len > XATTR_SIZE_MAX) return;
+
+ 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 );
+ /* include the descriptor revision and resource manager control bits */
+ 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 +303,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;
+ set_xattr_acls( get_unix_fd( fd ), sd );
+ set_xattr_sd( 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
@@ -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 );
+ set_xattr_acls( unix_fd, sd );
+ set_xattr_sd( unix_fd, sd );
+
if (((st.st_mode ^ mode) & (S_IRWXU|S_IRWXG|S_IRWXO)) && fchmod( unix_fd, mode ) == -1)
{

View File

@@ -0,0 +1,162 @@
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
information.
---
server/file.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 70 insertions(+), 9 deletions(-)
diff --git a/server/file.c b/server/file.c
index 951e25b..6981fca 100644
--- a/server/file.c
+++ b/server/file.c
@@ -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 )
{
#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;
+ int present, len, owner_len, group_len;
+ struct security_descriptor *dst_sd;
const ACL *dacl;
/* there's no point in storing the security descriptor if there's no DACL */
@@ -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;
- len = 2 + sizeof(struct security_descriptor) + sd->owner_len + sd->group_len + sd->sacl_len
+ /* make sure that we always store the ownership information */
+ if (!sd->owner_len)
+ owner_len = FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]);
+ else
+ owner_len = sd->owner_len;
+ if (!sd->group_len)
+ group_len = FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]);
+ else
+ group_len = sd->group_len;
+ len = 2 + sizeof(struct security_descriptor) + owner_len + group_len + sd->sacl_len
+ sd->dacl_len;
if (len > XATTR_SIZE_MAX) return;
/* include the descriptor revision and resource manager control bits */
buffer[0] = SECURITY_DESCRIPTOR_REVISION;
buffer[1] = 0;
- memcpy( &buffer[2], sd, len - 2 );
+ memcpy( dst_ptr, sd, sizeof(struct security_descriptor) );
+ dst_sd = (struct security_descriptor *)dst_ptr;
+ src_ptr += sizeof(struct security_descriptor);
+ dst_ptr += sizeof(struct security_descriptor);
+ dst_sd->owner_len = owner_len;
+ dst_sd->group_len = group_len;
+ /* copy the appropriate ownership information (explicit or inferred) */
+ if (sd->owner_len)
+ {
+ memcpy( dst_ptr, src_ptr, sd->owner_len );
+ src_ptr += sd->owner_len;
+ }
+ else
+ memcpy( dst_ptr, user, owner_len );
+ dst_ptr += owner_len;
+ if (sd->group_len)
+ {
+ memcpy( dst_ptr, src_ptr, sd->group_len );
+ src_ptr += sd->group_len;
+ }
+ else
+ memcpy( dst_ptr, group, group_len );
+ dst_ptr += group_len;
+ /* copy the ACL information (explicit only) */
+ memcpy( dst_ptr, src_ptr, sd->sacl_len );
+ src_ptr += sd->sacl_len;
+ dst_ptr += sd->sacl_len;
+ 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
@@ -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 )
{
+ const SID *owner = NULL, *group = NULL;
struct object *obj = NULL;
struct fd *fd;
int flags;
@@ -249,9 +289,12 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
if (sd)
{
- const SID *owner = sd_get_owner( sd );
+ owner = sd_get_owner( sd );
if (!owner)
owner = token_get_user( current->process->token );
+ group = sd_get_group( sd );
+ if (!group)
+ group = token_get_primary_group( current->process->token );
mode = sd_to_mode( sd, owner );
}
else if (options & FILE_DIRECTORY_FILE)
@@ -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;
- set_xattr_sd( get_unix_fd( fd ), sd );
+ set_xattr_sd( get_unix_fd( fd ), sd, owner, group );
if (S_ISDIR(mode))
obj = create_dir_obj( fd, access, mode );
@@ -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 );
- const SID *owner;
+ const SID *owner, *group;
struct stat st;
mode_t mode;
@@ -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 );
+ if (set_info & GROUP_SECURITY_INFORMATION)
+ {
+ group = sd_get_group( sd );
+ if (!group)
+ {
+ set_error( STATUS_INVALID_SECURITY_DESCR );
+ return 0;
+ }
+ if (!obj->sd || !security_equal_sid( group, sd_get_group( obj->sd ) ))
+ {
+ /* FIXME: get Unix uid and call fchown */
+ }
+ }
+ else if (obj->sd)
+ group = sd_get_group( obj->sd );
+ else
+ group = token_get_primary_group( current->process->token );
+
/* group and sacl not supported */
if (set_info & DACL_SECURITY_INFORMATION)
@@ -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 );
- set_xattr_sd( unix_fd, sd );
+ set_xattr_sd( unix_fd, sd, owner, group );
if (((st.st_mode ^ mode) & (S_IRWXU|S_IRWXG|S_IRWXO)) && fchmod( unix_fd, mode ) == -1)
{
--
1.7.9.5

View File

@@ -1,19 +1,20 @@
From 66583f9f848becaa12d84270a2ebe7a79ac34724 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: Thu, 13 Feb 2014 16:04:57 -0700
Date: Fri, 18 Apr 2014 14:01:35 -0600
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(-)
dlls/advapi32/tests/security.c | 49 ++++++++++++++++++++--------------------
server/change.c | 2 +-
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 e2e9cd5..f107abc 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);
@@ -48,9 +49,9 @@ index e2e9cd5..f107abc 100644
+ todo_wine ok(ace->Mask == 0x1f01ff,
+ "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
}
LocalFree(pSD);
done:
@@ -3294,23 +3294,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);
@@ -80,7 +81,7 @@ index e2e9cd5..f107abc 100644
}
LocalFree(pSD);
HeapFree(GetProcessHeap(), 0, user);
@@ -3960,22 +3959,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);
@@ -107,174 +108,70 @@ index e2e9cd5..f107abc 100644
+ todo_wine ok(ace->Mask == 0x1f01ff,
+ "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
}
LocalFree(pSD);
CloseHandle(obj);
diff --git a/server/change.c b/server/change.c
index c673c48..27dbe25 100644
--- a/server/change.c
+++ b/server/change.c
@@ -290,7 +290,7 @@ static struct security_descriptor *dir_get_sd( struct object *obj )
assert( obj->ops == &dir_ops );
fd = dir_get_fd( obj );
- sd = set_file_sd( obj, fd, &dir->mode, &dir->uid );
+ sd = get_file_sd( obj, fd, &dir->mode, &dir->uid );
release_object( fd );
return sd;
}
diff --git a/server/file.c b/server/file.c
index c375c72..b9135b9 100644
index 6981fca..26962df 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
@@ -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_acls( int fd, const SID *user, const SID *group )
+struct security_descriptor *get_xattr_sd( int fd )
+{
+#ifdef HAVE_ATTR_XATTR_H
+ int ace_count = 0, dacl_size = sizeof(ACL), i, n;
+ char buffer[XATTR_SIZE_MAX], *p = buffer, *pn;
+#if defined(HAVE_ATTR_XATTR_H) || defined(HAVE_SYS_EXTATTR_H)
+ struct security_descriptor *sd;
+ ACE_HEADER *current_ace;
+ ACCESS_ALLOWED_ACE *aaa;
+ ACCESS_DENIED_ACE *ada;
+ int type, flags, mask;
+ ACL *dacl;
+ char *ptr;
+ char buffer[XATTR_SIZE_MAX];
+ int n;
+
+ n = fgetxattr( fd, "user.wine.acl", buffer, sizeof(buffer) );
+ if (n == -1) return NULL;
+ buffer[n] = 0;
+#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;
+
+ do
+ {
+ int sub_authority_count = 0;
+ /* validate that we can handle the descriptor */
+ if (buffer[0] != SECURITY_DESCRIPTOR_REVISION || buffer[1] != 0) return NULL;
+
+ 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;
+ }
+ 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 );
+ if (sd) memcpy( sd, &buffer[2], n - 2 );
+ return sd;
+#else
+ return NULL;
+#endif
+}
+
struct security_descriptor *file_get_acls( struct object *obj, struct fd *fd, mode_t *mode,
uid_t *uid )
struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode,
uid_t *uid )
{
int unix_fd = get_unix_fd( fd );
struct stat st;
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
return obj->sd;
@@ -519,9 +550,10 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
(st.st_uid == *uid))
return obj->sd;
@@ -283,7 +180,7 @@ index c375c72..b9135b9 100644
- 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 );
+ sd = get_xattr_sd( unix_fd );
+ if (!sd) sd = mode_to_sd( st.st_mode, user, group);
if (!sd) return obj->sd;

View File

@@ -1,6 +1,6 @@
From e1b3d93adab31966d145ea41a9246d8f498c09d6 Mon Sep 17 00:00:00 2001
From 689b660afba80654cde0a2dd6cf1d647a6e3705c Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 13 Feb 2014 16:06:54 -0700
Date: Fri, 18 Apr 2014 14:05:32 -0600
Subject: server: Convert return of file security masks with generic access
mappings.
@@ -10,7 +10,7 @@ Subject: server: Convert return of file security masks with generic access
2 files changed, 34 insertions(+), 12 deletions(-)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index f107abc..b71bad3 100644
index 26cde37..48a3291 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -3109,8 +3109,8 @@ static void test_CreateDirectoryA(void)
@@ -33,9 +33,9 @@ index f107abc..b71bad3 100644
+ ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n",
+ ace->Mask);
}
LocalFree(pSD);
done:
@@ -3297,8 +3297,8 @@ static void test_GetNamedSecurityInfoA(void)
@@ -3300,8 +3300,8 @@ static void test_GetNamedSecurityInfoA(void)
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);
@@ -46,7 +46,7 @@ index f107abc..b71bad3 100644
}
if (acl_size.AceCount > 1)
{
@@ -3308,8 +3308,8 @@ static void test_GetNamedSecurityInfoA(void)
@@ -3311,8 +3311,8 @@ static void test_GetNamedSecurityInfoA(void)
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);
@@ -57,7 +57,7 @@ index f107abc..b71bad3 100644
}
LocalFree(pSD);
HeapFree(GetProcessHeap(), 0, user);
@@ -3962,8 +3962,8 @@ static void test_GetSecurityInfo(void)
@@ -3965,8 +3965,8 @@ static void test_GetSecurityInfo(void)
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);
@@ -68,7 +68,7 @@ index f107abc..b71bad3 100644
}
if (acl_size.AceCount > 1)
{
@@ -3973,8 +3973,8 @@ static void test_GetSecurityInfo(void)
@@ -3976,8 +3976,8 @@ static void test_GetSecurityInfo(void)
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);
@@ -77,13 +77,13 @@ index f107abc..b71bad3 100644
+ ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n",
+ ace->Mask);
}
LocalFree(pSD);
CloseHandle(obj);
}
diff --git a/server/file.c b/server/file.c
index b9135b9..0df2245 100644
index c4706b6..75f015b 100644
--- a/server/file.c
+++ b/server/file.c
@@ -637,6 +637,27 @@ struct security_descriptor *get_xattr_acls( int fd, const SID *user, const SID *
@@ -516,6 +516,27 @@ struct security_descriptor *get_xattr_sd( int fd )
#endif
}
@@ -108,13 +108,13 @@ index b9135b9..0df2245 100644
+ }
+}
+
struct security_descriptor *file_get_acls( struct object *obj, struct fd *fd, mode_t *mode,
uid_t *uid )
struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode,
uid_t *uid )
{
@@ -656,6 +677,7 @@ struct security_descriptor *file_get_acls( struct object *obj, struct fd *fd, mo
@@ -535,6 +556,7 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
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 );
sd = get_xattr_sd( unix_fd );
+ if (sd) convert_generic_sd( sd );
if (!sd) sd = mode_to_sd( st.st_mode, user, group);
if (!sd) return obj->sd;

View File

@@ -1,300 +0,0 @@
From 81bfee65674a81a826b32629e218e457b5ef6b4b Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 13 Feb 2014 16:07:15 -0700
Subject: server: Inherit security attributes from parent directories on
creation.
---
dlls/advapi32/tests/security.c | 40 ++++++++++-
server/change.c | 2 +-
server/file.c | 146 +++++++++++++++++++++++++++++++++++++++-
server/file.h | 2 +-
4 files changed, 184 insertions(+), 6 deletions(-)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index b71bad3..cad8ca9 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -3030,10 +3030,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;
@@ -3125,6 +3126,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/server/change.c b/server/change.c
index 0b7b979..14f37c3 100644
--- a/server/change.c
+++ b/server/change.c
@@ -292,7 +292,7 @@ static struct security_descriptor *dir_get_sd( struct object *obj )
assert( obj->ops == &dir_ops );
fd = dir_get_fd( obj );
- sd = file_get_acls( obj, fd, &dir->mode, &dir->uid );
+ sd = file_get_acls( obj, fd, &dir->mode, &dir->uid, TRUE );
release_object( fd );
return sd;
}
diff --git a/server/file.c b/server/file.c
index 0df2245..c115ff7 100644
--- a/server/file.c
+++ b/server/file.c
@@ -242,11 +242,141 @@ void set_xattr_acls( int fd, const struct security_descriptor *sd )
#endif
}
+struct security_descriptor *inherit_sd( const struct security_descriptor *parent_sd, int is_dir )
+{
+ DWORD inheritance_mask = INHERIT_ONLY_ACE|OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE;
+ struct security_descriptor *sd = NULL;
+ const ACL *parent_dacl;
+ int present;
+ ACL *dacl;
+
+ parent_dacl = sd_get_dacl( parent_sd, &present );
+ if (present && parent_dacl)
+ {
+ size_t dacl_size = sizeof(ACL), ace_count = 0;
+ const ACE_HEADER *parent_ace;
+ const SID *user, *group;
+ ACE_HEADER *ace;
+ char *ptr;
+ ULONG i;
+
+ /* Calculate the size of the DACL */
+ parent_ace = (const ACE_HEADER *)(parent_dacl + 1);
+ for (i = 0; i < parent_dacl->AceCount; i++, parent_ace = ace_next( parent_ace ))
+ {
+ int multiplier = 1;
+
+ if (!(parent_ace->AceFlags & inheritance_mask)) continue;
+
+ ace_count += multiplier;
+ dacl_size += multiplier * parent_ace->AceSize;
+ }
+ if(!ace_count) return sd; /* No inheritance */
+
+ /* Fill in the security descriptor so that it is compatible with our DACL */
+ user = (const SID *)(parent_sd + 1);
+ group = (const SID *)((char *)(parent_sd + 1) + parent_sd->owner_len);
+ sd = mem_alloc( sizeof(struct security_descriptor) + security_sid_len( user )
+ + security_sid_len( group ) + dacl_size );
+ if (!sd) return sd;
+ sd->control = SE_DACL_PRESENT;
+ sd->owner_len = parent_sd->owner_len;
+ sd->group_len = parent_sd->group_len;
+ 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;
+ ace = (ACE_HEADER *)(dacl + 1);
+
+ /* Build the new DACL, inheriting from the parent's information */
+ parent_ace = (const ACE_HEADER *)(parent_dacl + 1);
+ for (i = 0; i < parent_dacl->AceCount; i++, parent_ace = ace_next( parent_ace ))
+ {
+ DWORD flags = parent_ace->AceFlags;
+
+ if (!(flags & inheritance_mask)) continue;
+
+ ace->AceType = parent_ace->AceType;
+ if(is_dir && (flags & CONTAINER_INHERIT_ACE))
+ flags &= ~INHERIT_ONLY_ACE;
+ else if(!is_dir && (flags & OBJECT_INHERIT_ACE))
+ flags &= ~INHERIT_ONLY_ACE;
+ else if(is_dir && (flags & OBJECT_INHERIT_ACE))
+ flags |= INHERIT_ONLY_ACE;
+ if(is_dir)
+ ace->AceFlags = flags | INHERITED_ACE;
+ else
+ ace->AceFlags = (parent_ace->AceFlags & ~inheritance_mask) | INHERITED_ACE;
+ ace->AceSize = parent_ace->AceSize;
+ memcpy( ace + 1, parent_ace + 1, parent_ace->AceSize - sizeof(ACE_HEADER));
+ ace = (ACE_HEADER *)ace_next( ace );
+ }
+ }
+ return sd;
+}
+
+static struct security_descriptor *file_get_parent_sd( struct fd *root, char *parent_name,
+ int is_dir )
+{
+ struct security_descriptor *sd = NULL;
+ int len = strlen( parent_name );
+ mode_t parent_mode = 0555;
+ struct fd *parent_fd;
+ char *slash;
+
+ /* Even if the file is a directory we need its parent, so skip any terminating slash */
+ if (parent_name[len-1] == '/')
+ parent_name[len-1] = 0;
+ /* Find the last slash in the filename and terminate the name there */
+ slash = strrchr(parent_name, '/');
+ if (slash)
+ slash[0] = 0;
+ else
+ parent_name[0] = 0;
+
+ parent_fd = open_fd( root, parent_name, O_NONBLOCK | O_LARGEFILE, &parent_mode,
+ READ_CONTROL|ACCESS_SYSTEM_SECURITY,
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
+ FILE_OPEN_FOR_BACKUP_INTENT );
+ if(parent_fd)
+ {
+ struct object *obj;
+
+ if ((obj = create_file_obj( parent_fd, READ_CONTROL|ACCESS_SYSTEM_SECURITY, parent_mode )))
+ {
+ struct file *file = (struct file *)obj;
+ struct fd *fd;
+
+ fd = file_get_fd( obj );
+ if (fd)
+ {
+ sd = file_get_acls( obj, fd, &file->mode, &file->uid, FALSE );
+ release_object( fd );
+ }
+ if (sd)
+ sd = inherit_sd( sd, is_dir );
+ release_object( obj );
+ }
+ release_object( parent_fd );
+ }
+ return sd;
+}
+
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,
const struct security_descriptor *sd )
{
+ struct security_descriptor *temp_sd = NULL;
struct object *obj = NULL;
struct fd *fd;
int flags;
@@ -275,6 +405,15 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
default: set_error( STATUS_INVALID_PARAMETER ); goto done;
}
+ if (!sd && (create == FILE_CREATE || create == FILE_OVERWRITE_IF))
+ {
+ /* Note: inheritance of security descriptors only occurs on creation when sd is NULL */
+ char *child_name = strndup( nameptr, len );
+
+ sd = temp_sd = file_get_parent_sd( root, child_name, options & FILE_DIRECTORY_FILE );
+ free(child_name);
+ }
+
if (sd)
{
const SID *owner = sd_get_owner( sd );
@@ -315,6 +454,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
release_object( fd );
done:
+ free( temp_sd );
free( name );
return obj;
}
@@ -659,7 +799,7 @@ void convert_generic_sd( struct security_descriptor *sd )
}
struct security_descriptor *file_get_acls( struct object *obj, struct fd *fd, mode_t *mode,
- uid_t *uid )
+ uid_t *uid, int convert_generic )
{
int unix_fd = get_unix_fd( fd );
struct security_descriptor *sd;
@@ -677,7 +817,7 @@ struct security_descriptor *file_get_acls( struct object *obj, struct fd *fd, mo
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) convert_generic_sd( sd );
+ if (sd && convert_generic) convert_generic_sd( sd );
if (!sd) sd = mode_to_sd( st.st_mode, user, group);
if (!sd) return obj->sd;
@@ -697,7 +837,7 @@ static struct security_descriptor *file_get_sd( struct object *obj )
assert( obj->ops == &file_ops );
fd = file_get_fd( obj );
- sd = file_get_acls( obj, fd, &file->mode, &file->uid );
+ sd = file_get_acls( obj, fd, &file->mode, &file->uid, TRUE );
release_object( fd );
return sd;
}
diff --git a/server/file.h b/server/file.h
index 89b5888..0905fbb 100644
--- a/server/file.h
+++ b/server/file.h
@@ -125,7 +125,7 @@ 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 );
+ uid_t *uid, int convert_generic );
/* file mapping functions */
--
1.7.9.5

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