Compare commits

..

108 Commits
v2.12 ... v2.16

Author SHA1 Message Date
Sebastian Lackner
578128d012 Release 2.16. 2017-09-07 06:32:03 +02:00
Sebastian Lackner
51cc8cbe36 dwrite-8bpp_Grayscale_Mode: Update patchset. 2017-09-07 03:26:59 +02:00
Sebastian Lackner
f1b1baf057 Added patch to fix privileged instruction exception code on x86_64. 2017-09-07 02:14:38 +02:00
Sebastian Lackner
467fed6501 Added patch to implement syscall thunks for 64-bit. 2017-09-07 02:11:27 +02:00
Sebastian Lackner
83f27c90a6 Added patch to treat invalid pixel types as PFD_TYPE_RGBA in wglChoosePixelFormat. 2017-09-07 02:04:59 +02:00
Sebastian Lackner
7710cdb8c0 Added patch to use 8bpp bitmaps in grayscale mode. 2017-09-06 03:59:23 +02:00
Sebastian Lackner
141768861c Added patches to implement additional d3d11 deferred context functions. 2017-09-06 03:54:37 +02:00
Sebastian Lackner
a8eca598ce Added patch to revert listbox popup height changes. 2017-09-04 01:45:03 +02:00
Sebastian Lackner
ce7d9b6d08 wined3d-Revert_Surface_Blt: Add reference to bug report. 2017-09-04 01:39:03 +02:00
Sebastian Lackner
a7f42dd60a mfplat-MFStartup: Temporarily disable patchset.
The patch causes a regression because applications start using
other mfplat functions.
2017-09-04 01:38:38 +02:00
Sebastian Lackner
83e5c37f16 Added patch to implement support for indexed vertex blending. 2017-09-02 04:31:04 +02:00
Sebastian Lackner
7ad83e6e14 Rebase against 0b1d7ff7655c5aa7ff073f67400bd4401727183f. 2017-09-02 03:46:01 +02:00
Sebastian Lackner
a7cf8014bb Added patch to revert special case for converted surfaces in wined3d_surface_blt. 2017-09-02 02:29:01 +02:00
Sebastian Lackner
c50463197f Rebase against e06b7693d6f0980b1db2fa3b9920c7a925ceb8be. 2017-09-02 02:24:26 +02:00
Sebastian Lackner
f98abfe0dc Added patch to return S_OK from MFStartup stub. 2017-08-31 01:33:52 +02:00
Sebastian Lackner
5a79bf01f2 Added patch to fix handling of empty string in WS_getaddrinfo. 2017-08-31 01:16:11 +02:00
Sebastian Lackner
330f1cc410 Rebase against 844b57e4d800bfb260c1694ed54a02b9f5ad1f47. 2017-08-30 23:16:18 +02:00
Sebastian Lackner
d076d04ebc Rebase against c579a81a6353dd7c843270561cd5763ff895de40. 2017-08-30 01:14:43 +02:00
Sebastian Lackner
7b687557c3 Rebase against dfa1815c02d1661766c8f3a4a290635e7adb4ccf. 2017-08-29 00:10:33 +02:00
Sebastian Lackner
00540ae7b9 Rebase against 083e61fddf90ade32a119d5b6bf84d27adefc589. 2017-08-26 01:02:52 +02:00
Sebastian Lackner
41562729cd Rebase against cc49c40f05a600327b80711f6f80844608dde366. 2017-08-24 23:16:28 +02:00
Sebastian Lackner
6b9d11ac58 Rebase against 79ebd3f3bf9e5b6607363667d03def04e254f710. 2017-08-24 03:42:23 +02:00
Sebastian Lackner
e53b4e2702 dxgi-GammaRamp: Add reference to bug report. 2017-08-23 19:43:34 +02:00
Sebastian Lackner
eb4587492e Release 2.15. 2017-08-23 03:45:59 +02:00
Sebastian Lackner
b6bab9758e Added patches to fix JPEG decoder and implement support for CMYK to BGR conversion. 2017-08-22 03:20:18 +02:00
Sebastian Lackner
bab383452b Added patch to implement dual source blending in wined3d. 2017-08-22 02:00:27 +02:00
Sebastian Lackner
9fbebe7a46 Added patch to allow arbitrary viewports for d3d11 in wined3d. 2017-08-22 00:17:19 +02:00
Sebastian Lackner
14cfabe8ab Added patch to avoid test failures in reg tests. 2017-08-20 18:37:58 +02:00
Sebastian Lackner
5adb9710aa Added patch to avoid stack protector frame in signal handler functions. 2017-08-20 18:24:41 +02:00
Sebastian Lackner
f09e1db3cc Rebase against 67f6eb327ef78fe8acf45bf6ac6c93424ec89335. 2017-08-20 13:51:27 +02:00
Sebastian Lackner
ea6cb58103 Rebase against d53b711f27f15cdeb9700e86526dab13ddf8d731. 2017-08-18 05:31:27 +02:00
Sebastian Lackner
62f94a1ed2 bcrypt-Improvements: Add missing changes to ncrypt.spec. 2017-08-17 22:21:41 +02:00
Sebastian Lackner
41cf5ea976 user32-Sorted_Listbox: Update patchset. 2017-08-17 22:13:10 +02:00
Sebastian Lackner
be0aab1653 Added patch to implement kernelbase.PathCchCombineEx. 2017-08-17 20:42:40 +02:00
Sebastian Lackner
0e27dc7034 Rebase against 866eec810e7342630d47887f8ad7e1fbb5a0e788. 2017-08-17 20:17:02 +02:00
Sebastian Lackner
f6565eb6af Rebase against ae2d6e836b98440cdc938718226dc89592a64eda. 2017-08-17 15:54:43 +02:00
Sebastian Lackner
2d92c18c9e Added patch to implement support for 192 and 256 bit AES keys in bcrypt. 2017-08-13 21:30:25 +02:00
Sebastian Lackner
96dd810f82 Added patch to implement BCryptImportKey and BCryptExportKey. 2017-08-13 21:24:07 +02:00
Sebastian Lackner
8ca3547a36 advapi32-Token_Integrity_Level: Update specfile. 2017-08-13 19:26:30 +02:00
Sebastian Lackner
4938755f5f Added patch to implement stubs for GetWindowDisplayAffinity and SetWindowDisplayAffinity. 2017-08-13 19:21:57 +02:00
Sebastian Lackner
adb8deeaf2 Rebase against 797a746fc2a1b17d67b7423293e081e3e7171033. 2017-08-12 17:09:40 +02:00
Sebastian Lackner
716ea2cef3 wined3d-UAV_Counters: Remove no longer needed dependencies. 2017-08-09 08:50:28 +02:00
Sebastian Lackner
6edf4d136c Rebase against 52fbaeb2c44e585cacd7f0b57e902dfbcf54d09b. 2017-08-09 08:45:29 +02:00
Sebastian Lackner
51d419bbeb patchupdate.py: Simplify code in generate_ifdefined. 2017-08-08 14:54:24 +02:00
Sebastian Lackner
6b40eb077f Release 2.14. 2017-08-07 23:34:30 +02:00
Sebastian Lackner
ae3f3b8bb7 advapi32-Token_Integrity_Level: Add another Fixes line. 2017-08-07 19:38:41 +02:00
Sebastian Lackner
ed87feaf71 server-Debug_Registers: Comment Fixes line of distabled patch. 2017-08-07 19:13:37 +02:00
Sebastian Lackner
081fbc2ef1 Added patch to return D3DFMT_A8R8G8B8 in D3DXGetImageInfoFromFileInMemory for 32 bpp BMP with alpha. 2017-08-07 17:57:44 +02:00
Sebastian Lackner
4455721443 patchupdate.py: Add a hack to speed up patch checks for configure.ac. 2017-08-07 17:27:38 +02:00
Sebastian Lackner
5559653869 Added patch with basic implementation for token integrity levels and UAC handling. 2017-08-07 16:58:46 +02:00
Sebastian Lackner
8f9cc5e01c Added patch to use an inline version of Rtl{Enter,Leave}CriticalSection in some ntdll functions. 2017-08-06 06:14:42 +02:00
Sebastian Lackner
d364296484 Added patch to implement advapi32.CreateRestrictedToken. 2017-08-06 04:34:06 +02:00
Sebastian Lackner
0892d6d89e Added patch to prefer native version of packager.dll. 2017-08-06 02:55:07 +02:00
Sebastian Lackner
aa23179c36 ntdll-NtQueryVirtualMemory: Update patchset. 2017-08-05 00:05:47 +02:00
Sebastian Lackner
e28edf1951 Rebase against 2d9e894d285937716a4541c7fab9152fdf0b495f. 2017-08-03 13:41:34 +02:00
Sebastian Lackner
5f7efc6b30 wintrust-WinVerifyTrust: Update patchset to use MS_ENH_RSA_AES_PROV instead of default provider. 2017-08-02 15:19:37 +02:00
Sebastian Lackner
71f0cf0aef Rebase against 611c15953e8297ac1762abfb5aeca6665985fc0f. 2017-08-01 05:55:02 +02:00
Sebastian Lackner
ea9d4a0fa1 Added patch to implement stub for GetProcessWorkingSetSizeEx. 2017-07-30 21:14:59 +02:00
Sebastian Lackner
3aabb941ae Added patch to fix a TRACE in NtGetContextThread. 2017-07-29 03:12:55 +02:00
Sebastian Lackner
f64dc8457e nvapi-Stub_DLL: Add NULL pointer check in NvAPI_D3D11_SetDepthBoundsTest. 2017-07-29 02:23:36 +02:00
Sebastian Lackner
ebc9ba4921 nvapi-Stub_DLL: Merge some cleanup changes. 2017-07-29 00:49:46 +02:00
Sebastian Lackner
77a90f1dd0 Added patch to avoid crash when async_terminate destroys async object in free_async_queue. 2017-07-28 02:42:42 +02:00
Sebastian Lackner
c0a61524e1 Rebase against 1744277bee3c3c77ae657f42d8fac466cfac7924. 2017-07-28 00:09:26 +02:00
Sebastian Lackner
9f5d2cab05 Rebase against 976c2aa649a526188afd9c0647869ccc82068341. 2017-07-27 06:59:21 +02:00
Sebastian Lackner
2e99d9e465 Rebase against 4a70f67ffcc57e82c22cc349da01d3aa5db84c71. 2017-07-26 16:56:56 +02:00
Sebastian Lackner
2c12e538dd Rebase against 21763489982177f4db9e5f8cc8ccb751441f5a2e. 2017-07-25 17:24:47 +02:00
Sebastian Lackner
d943e0bd51 Release 2.13. 2017-07-25 05:51:25 +02:00
Sebastian Lackner
67ebee7f44 Fix typo in a patch directory. 2017-07-25 05:50:36 +02:00
Sebastian Lackner
91424695c4 winedevice-Default_Drivers: Synchronize spec file. 2017-07-25 03:54:15 +02:00
Sebastian Lackner
7b07cb08f5 Added patch to reduce the cursor height if it also includes the mask. 2017-07-24 23:55:24 +02:00
Sebastian Lackner
4d2afbf14b Added patch to implement support for indirect drawing / compute shader dispatching. 2017-07-24 20:41:34 +02:00
Sebastian Lackner
f47fa538c5 Added patch to fix context backup window handling. 2017-07-24 18:58:35 +02:00
Sebastian Lackner
e866c7f3e1 server-Debug_Registers: Don't abort thread creation when set_thread_context fails. 2017-07-24 17:41:20 +02:00
Sebastian Lackner
b539f0f369 Added patch to implement copying structure count of UAV. 2017-07-24 16:22:58 +02:00
Sebastian Lackner
f5e96b9a37 Added patch to implement support for all d3d11 color write masks in wined3d. 2017-07-24 00:41:59 +02:00
Sebastian Lackner
7a242b50e4 Added patch with stub implementation for DXGI_PRESENT_TEST. 2017-07-23 21:41:02 +02:00
Sebastian Lackner
9921dc7846 Improve formatting in CONTRIBUTING.md. 2017-07-23 21:35:49 +02:00
Sebastian Lackner
1a4ebb027f wined3d-Copy_Resource_Typeless: Add reference to bug report. 2017-07-23 21:33:18 +02:00
Sebastian Lackner
3bf7fe4763 Added patch to improve heap allocation performance. 2017-07-23 20:49:44 +02:00
Sebastian Lackner
eeb6529b09 d3dx9_36-D3DXOptimizeVertices: Merge some style improvements. 2017-07-23 20:42:10 +02:00
Sebastian Lackner
2cb3198298 Added patch to implement support for conservative depth access in SM4 shaders. 2017-07-23 04:26:33 +02:00
Sebastian Lackner
69e273a07f Added patch to implement stub for several setsockopt options. 2017-07-22 05:25:14 +02:00
Sebastian Lackner
60870e076f Added patch to implement LdrRegisterDllNotification/LdrUnregisterDllNotification. 2017-07-22 05:03:41 +02:00
Sebastian Lackner
c8a8ef48e5 Add a separate CONTRIBUTING.md. 2017-07-22 04:07:01 +02:00
Constantine Kharlamov
be9feb4570 advapi-LsaLookupPrivilegeName: check for pointer in WellKnownPrivNames.
Fixes a crash in Dead Space

Signed-off-by: Constantine Kharlamov <Hi-Angel@yandex.ru>
2017-07-22 02:57:42 +02:00
Sebastian Lackner
62ae507b36 Rebase against 7d3c068c3beeac8691cfa96f0dce6b5583072eaa. 2017-07-22 01:14:10 +02:00
Sebastian Lackner
5ec57827af d3dx9_36-D3DXOptimizeVertices: Add a missing test-only patch. 2017-07-21 04:24:04 +02:00
Sebastian Lackner
d0dccc7b7e Added patch to recognize SM4 nop opcode. 2017-07-21 04:01:19 +02:00
Sebastian Lackner
4e031ef171 Added patch to hold CS while iterating through rpcrt4 protseqs list. 2017-07-21 03:18:46 +02:00
Sebastian Lackner
60d4b6fe21 wined3d-Copy_Resource_Typeless: Add dependency on wined3d-1DTextures. 2017-07-21 02:55:02 +02:00
Sebastian Lackner
8706a334ad Added patch to implement support for start instance in draw_primitive_arrays. 2017-07-20 15:24:23 +02:00
Sebastian Lackner
43f5b05fd5 Rebase against 5a61913e90e3725d08c0e1fd06ccfe936434cbcc. 2017-07-20 03:09:05 +02:00
Sebastian Lackner
a05970ca53 Rebase against 9118512135a1aac6969bf575a0656855ba84ef11. 2017-07-19 13:21:54 +02:00
Sebastian Lackner
d9d149f369 Rebase against a8b5fdda3214e4fd52682aefaa093cd45766580e. 2017-07-18 11:29:09 +02:00
Sebastian Lackner
e2dbf3ab7e Added patch to fix regression related to interface bind handling. 2017-07-18 11:27:34 +02:00
Sebastian Lackner
fe97269c92 Added patch to implement semi-stub for D3DXOptimizeVertices. 2017-07-17 15:24:11 +02:00
Sebastian Lackner
c99cdb85d7 Added patch to prevent a possible nullptr dereference in SHGetFileInfoW. 2017-07-17 15:10:03 +02:00
Sebastian Lackner
020888539d Added patch to use assembly wrapper to call OnVoiceProcessingPassStart callback. 2017-07-15 23:17:29 +02:00
Sebastian Lackner
b8ffc62855 kernel32-UmsStubs: Add a reference to a bug report. 2017-07-15 21:34:07 +02:00
Sebastian Lackner
dc531c457c Added patch to implement FreePhysicalMemory in Win32_OperatingSystem wbemprox class. 2017-07-15 20:38:36 +02:00
Sebastian Lackner
08cd599f17 Added patch to avoid possible deadlock in dinput when CS are acquired in different order. 2017-07-15 20:14:50 +02:00
Sebastian Lackner
bfef128732 Added patch for nvapi d3d11 CreateDevice/CreateDeviceAndSwapChain implementation. 2017-07-14 22:39:13 +02:00
Sebastian Lackner
201e62615e Rebase against ab313dd3beb7e495b36f8320ffc2354b9c854d51. 2017-07-14 08:09:51 +02:00
Sebastian Lackner
c852826507 Rebase against 989a9dc91778c94d0cf0c769709f10dcc92a5ead. 2017-07-13 01:42:44 +02:00
Sebastian Lackner
c1b18bc491 wined3d-Copy_Resource_Typeless: Add reference to bug report. 2017-07-12 22:27:09 +02:00
Sebastian Lackner
edcc6684ad dwmapi-DwmSetIcon: Add reference to bug report. 2017-07-12 22:23:39 +02:00
Sebastian Lackner
96a77f3ae2 Rebase against 437c6674b06663908472d31ed68fcab6e2fdd5f7. 2017-07-12 12:56:45 +02:00
Sebastian Lackner
4c1a8684a0 Rebase against 35f82ba444930b770684f0bd623c505d52c7b58f. 2017-07-12 12:22:15 +02:00
258 changed files with 17739 additions and 4478 deletions

30
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,30 @@
Contributing to Wine Staging
----------------------------
First of all, thank you for taking the time to contribute to this project.
### Reporting bugs
Since WineConf 2015 Wine Staging is an official part of WineHQ, which means you
can report problems directly at [bugs.winehq.org](https://bugs.winehq.org/).
Most of the time bugs found in Wine Staging also turn out to be present in the
development branch, so its recommended to open your bug in the "Wine" product,
unless you are sure its really "Wine Staging" specific. For bugs related to our
binary packages, please open a bug report in the "Packaging" product.
### Submitting patches
**IMPORTANT:** Please use [dev.wine-staging.com](https://dev.wine-staging.com/patches)
for patch submissions, we currently do not accept Pull requests on GitHub.
Wine Staging mainly concentrates on experimental features and patches which are
difficult to get into the development branch. If you have a very simple bug fix
including tests, there is usually no need to send it to Wine Staging. You can
directly contribute it to the
[development branch](http://wiki.winehq.org/SubmittingPatches). However, if you
already tried that without success, or are working on such a complex area that
you do not really think its ready for inclusion, you might want to submit it to
our Staging tree. Please open a patch submission request on
[dev.wine-staging.com](https://dev.wine-staging.com/patches) including the patch.
More information is also available in our
[Wiki](https://wiki.winehq.org/Wine-Staging_Patches).

View File

@@ -24,16 +24,6 @@ other wine-specific programs like `winecfg`. To learn more about how to use
Wine Staging, please take a look at the
[usage instructions](https://github.com/wine-compholio/wine-staging/wiki/Usage).
Reporting bugs
--------------
Since WineConf 2015 Wine Staging is an official part of WineHQ, which means you
can report problems directly at https://bugs.winehq.org/. Most of the time bugs
found in Wine Staging also turn out to be present in the development branch, so
its recommended to open your bug in the "Wine" product, unless you are sure its
really "Wine Staging" specific. For problems with our binary packages, please
also open a bug report there.
Building
--------
@@ -88,14 +78,5 @@ in our [Wiki](https://github.com/wine-compholio/wine-staging/wiki/Packaging).
Contributing
------------
Wine Staging mainly concentrates on experimental features and patches which are
difficult to get into the development branch. If you have a very simple bug fix
including tests, there is usually no need to send it to Wine Staging. You can
directly contribute it to the
[development branch](http://wiki.winehq.org/SubmittingPatches). However, if you
already tried that without success, or are working on such a complex area that
you do not really think its ready for inclusion, you might want to submit it to
our Staging tree. Please open a patch submission request on
[bugs.wine-staging.com](https://bugs.wine-staging.com/) including the patch.
More information is also available in our
[Wiki](https://github.com/wine-compholio/wine-staging/wiki/Contributing).
Please see CONTRIBUTING.md for more information about contributing to Wine
Staging.

View File

@@ -1,25 +0,0 @@
From 33717bde9e702520e23ae014c398bd7076902d43 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sun, 4 Jun 2017 12:56:47 +0200
Subject: shell32: Fix length parameter for ZeroMemory.
---
dlls/shell32/shfldr_fs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/shell32/shfldr_fs.c b/dlls/shell32/shfldr_fs.c
index c7259276d1d..10653f92b52 100644
--- a/dlls/shell32/shfldr_fs.c
+++ b/dlls/shell32/shfldr_fs.c
@@ -1315,7 +1315,7 @@ ISFHelper_fnCopyItems (ISFHelper * iface, IShellFolder * pSFFrom, UINT cidl,
if (SUCCEEDED (IPersistFolder2_GetCurFolder (ppf2, &pidl))) {
SHGetPathFromIDListW (pidl, wszSrcPathRoot);
- ZeroMemory(wszDstPath, MAX_PATH+1);
+ ZeroMemory(wszDstPath, sizeof(wszDstPath));
if (This->sPathTarget)
lstrcpynW(wszDstPath, This->sPathTarget, MAX_PATH);
PathAddBackslashW(wszSrcPathRoot);
--
2.13.0

View File

@@ -1,25 +0,0 @@
From 2b5e9f330770221eee2eda2aab251eba8d370a60 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sun, 4 Jun 2017 13:17:54 +0200
Subject: fusion: Fix length parameter for ZeroMemory.
---
dlls/fusion/tests/asmname.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/fusion/tests/asmname.c b/dlls/fusion/tests/asmname.c
index 5fb14a48291..21cd4874edc 100644
--- a/dlls/fusion/tests/asmname.c
+++ b/dlls/fusion/tests/asmname.c
@@ -358,7 +358,7 @@ static void test_assembly_name_props_line(IAssemblyName *name,
to_widechar(expect, vals[i].val);
size = MAX_PATH;
- ZeroMemory(str, MAX_PATH);
+ ZeroMemory(str, sizeof(str));
hr = IAssemblyName_GetProperty(name, i, str, &size);
to_multibyte(val, str);
--
2.13.0

View File

@@ -1,34 +0,0 @@
From 3e59710a3091a4a61b7cce00606ed23b7b66dfda Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sun, 4 Jun 2017 12:55:31 +0200
Subject: fusion/tests: Avoid compiler warnings with GCC 7.
---
dlls/fusion/tests/asmenum.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/fusion/tests/asmenum.c b/dlls/fusion/tests/asmenum.c
index 1dc34a286e5..8b95f2a6bd5 100644
--- a/dlls/fusion/tests/asmenum.c
+++ b/dlls/fusion/tests/asmenum.c
@@ -223,7 +223,7 @@ typedef struct _tagASMNAME
static BOOL enum_gac_assemblies(struct list *assemblies, int depth, LPSTR path)
{
WIN32_FIND_DATAA ffd;
- CHAR buf[MAX_PATH];
+ CHAR buf[MAX_PATH + 37];
CHAR disp[MAX_PATH];
ASMNAME *name;
HANDLE hfind;
@@ -248,7 +248,7 @@ static BOOL enum_gac_assemblies(struct list *assemblies, int depth, LPSTR path)
else if (depth == 1)
{
char culture[MAX_PATH];
- char dll[MAX_PATH], exe[MAX_PATH];
+ char dll[MAX_PATH + 6], exe[MAX_PATH + 6];
/* Directories with no dll or exe will not be enumerated */
sprintf(dll, "%s\\%s\\%s.dll", path, ffd.cFileName, parent);
--
2.13.0

View File

@@ -1,34 +0,0 @@
From d1eafd34d4c0619f956afd365ddbde79680a18dc Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sun, 4 Jun 2017 12:56:10 +0200
Subject: kernel32/tests: Avoid compiler warnings with GCC 7.
---
dlls/kernel32/tests/heap.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c
index 0acf109dff0..70ba674bc91 100644
--- a/dlls/kernel32/tests/heap.c
+++ b/dlls/kernel32/tests/heap.c
@@ -109,6 +109,9 @@ static void test_heap(void)
}
/* test some border cases of HeapAlloc and HeapReAlloc */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas"
+#pragma GCC diagnostic ignored "-Walloc-size-larger-than="
mem = HeapAlloc(GetProcessHeap(), 0, 0);
ok(mem != NULL, "memory not allocated for size 0\n");
msecond = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, mem, ~(SIZE_T)0 - 7);
@@ -125,6 +128,7 @@ static void test_heap(void)
ok(size == 0 || broken(size == 1) /* some vista and win7 */,
"HeapSize should have returned 0 instead of %lu\n", size);
HeapFree(GetProcessHeap(), 0, msecond);
+#pragma GCC diagnostic pop
/* large blocks must be 16-byte aligned */
mem = HeapAlloc(GetProcessHeap(), 0, 512 * 1024);
--
2.13.1

View File

@@ -1,25 +0,0 @@
From 61ceddca38f26c2df2acc6361c35ced52fe9b098 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sun, 4 Jun 2017 12:58:31 +0200
Subject: rsaenh/tests: Avoid compiler warnings with GCC 7.
---
dlls/rsaenh/rsaenh.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/rsaenh/rsaenh.c b/dlls/rsaenh/rsaenh.c
index 9af770dfc6e..6978c860278 100644
--- a/dlls/rsaenh/rsaenh.c
+++ b/dlls/rsaenh/rsaenh.c
@@ -1097,7 +1097,7 @@ static void store_key_permissions(HCRYPTKEY hCryptKey, HKEY hKey, DWORD dwKeySpe
*/
static BOOL create_container_key(KEYCONTAINER *pKeyContainer, REGSAM sam, HKEY *phKey)
{
- CHAR szRSABase[MAX_PATH];
+ CHAR szRSABase[MAX_PATH + 25];
HKEY hRootKey;
sprintf(szRSABase, RSAENH_REGKEY, pKeyContainer->szName);
--
2.13.0

View File

@@ -1,46 +0,0 @@
From 67ed53ca67214d7dbdea7f342b9f2ff0356a220b Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sun, 4 Jun 2017 12:59:10 +0200
Subject: kernel32: Avoid compiler warnings with GCC 7.
---
dlls/kernel32/oldconfig.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/dlls/kernel32/oldconfig.c b/dlls/kernel32/oldconfig.c
index 6c80dc614f0..3e628757283 100644
--- a/dlls/kernel32/oldconfig.c
+++ b/dlls/kernel32/oldconfig.c
@@ -290,7 +290,8 @@ static void create_hardware_branch(void)
{
if (strncmp(dent->d_name, "hd", 2) == 0)
{
- sprintf(cStr, procname_ide_media, dent->d_name);
+ result = snprintf(cStr, sizeof(cStr), procname_ide_media, dent->d_name);
+ if (result < 0 || result >= sizeof(cStr)) continue;
procfile = fopen(cStr, "r");
if (!procfile)
{
@@ -306,7 +307,8 @@ static void create_hardware_branch(void)
if (nType == DRIVE_UNKNOWN) continue;
}
- sprintf(cStr, procname_ide_model, dent->d_name);
+ result = snprintf(cStr, sizeof(cStr), procname_ide_model, dent->d_name);
+ if (result < 0 || result >= sizeof(cStr)) continue;
procfile = fopen(cStr, "r");
if (!procfile)
{
@@ -322,7 +324,8 @@ static void create_hardware_branch(void)
cDevModel[strlen(cDevModel) - 1] = 0;
}
- sprintf(cUnixDeviceName, "/dev/%s", dent->d_name);
+ result = snprintf(cUnixDeviceName, sizeof(cUnixDeviceName), "/dev/%s", dent->d_name);
+ if (result < 0 || result >= sizeof(cUnixDeviceName)) continue;
scsi_addr.PortNumber = (dent->d_name[2] - 'a') / 2;
scsi_addr.PathId = 0;
scsi_addr.TargetId = (dent->d_name[2] - 'a') % 2;
--
2.13.0

View File

@@ -1,15 +1,14 @@
From b6b1e5da04ed867251253410e37d412109a4cec2 Mon Sep 17 00:00:00 2001
From cd34de81164087b3593d0ec9416e2f157a5df40d Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Fri, 8 Aug 2014 19:33:14 -0600
Subject: Appease the blessed version of gcc (4.5) when -Werror is enabled.
---
dlls/d3d9/tests/visual.c | 2 +-
dlls/netapi32/netapi32.c | 2 +-
dlls/winealsa.drv/mmdevdrv.c | 2 +-
dlls/wined3d/glsl_shader.c | 2 +-
tools/makedep.c | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
dlls/d3d9/tests/visual.c | 2 +-
dlls/netapi32/netapi32.c | 2 +-
dlls/wined3d/glsl_shader.c | 2 +-
tools/makedep.c | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index c8a6a1fa5a8..0261d3708e6 100644
@@ -37,24 +36,11 @@ index 278d4528b01..1c5f110b828 100644
NET_API_STATUS status;
if (servername && !(server = strdup_unixcp( servername ))) return ERROR_OUTOFMEMORY;
diff --git a/dlls/winealsa.drv/mmdevdrv.c b/dlls/winealsa.drv/mmdevdrv.c
index 2ecb111e218..b285705509c 100644
--- a/dlls/winealsa.drv/mmdevdrv.c
+++ b/dlls/winealsa.drv/mmdevdrv.c
@@ -359,7 +359,7 @@ static WCHAR *construct_device_id(EDataFlow flow, const WCHAR *chunk1, const cha
{
WCHAR *ret;
const WCHAR *prefix;
- DWORD len_wchars = 0, chunk1_len, copied = 0, prefix_len;
+ DWORD len_wchars = 0, chunk1_len = 0, copied = 0, prefix_len;
static const WCHAR dashW[] = {' ','-',' ',0};
static const size_t dashW_len = (sizeof(dashW) / sizeof(*dashW)) - 1;
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index ce960853362..f4275d8dd48 100644
index f96f48d97d1..8fe3318cd78 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -9316,7 +9316,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
@@ -9721,7 +9721,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
GLuint ds_id = 0;
GLuint gs_id = 0;
GLuint ps_id = 0;
@@ -64,7 +50,7 @@ index ce960853362..f4275d8dd48 100644
struct wined3d_string_buffer *tmp_name;
diff --git a/tools/makedep.c b/tools/makedep.c
index add722f80a9..24b06bbfcb2 100644
index 296356b0a57..5a2873b56f1 100644
--- a/tools/makedep.c
+++ b/tools/makedep.c
@@ -1608,7 +1608,7 @@ static const char *get_make_variable( const struct makefile *make, const char *n
@@ -77,5 +63,5 @@ index add722f80a9..24b06bbfcb2 100644
var = get_make_variable( make, name );
if (!var) return NULL;
--
2.12.2
2.13.1

View File

@@ -1,4 +1,4 @@
From bee5e0baac722c66ad8c1034a65a2cecfe74716e Mon Sep 17 00:00:00 2001
From fcefc5661656de44d02fed0431b4a61fa618b663 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sun, 5 Mar 2017 23:50:06 +0100
Subject: advapi32: Implement LsaLookupPrivilegeName.
@@ -6,13 +6,13 @@ Subject: advapi32: Implement LsaLookupPrivilegeName.
---
dlls/advapi32/advapi32.spec | 2 +-
dlls/advapi32/advapi32_misc.h | 2 ++
dlls/advapi32/lsa.c | 38 ++++++++++++++++++++++++++++++++++++++
dlls/advapi32/lsa.c | 39 +++++++++++++++++++++++++++++++++++++++
dlls/advapi32/security.c | 27 ++++++++++++++++++---------
include/ntsecapi.h | 1 +
5 files changed, 60 insertions(+), 10 deletions(-)
5 files changed, 61 insertions(+), 10 deletions(-)
diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec
index 078bb8fc25..124f527282 100644
index d5503490a0..709a385967 100644
--- a/dlls/advapi32/advapi32.spec
+++ b/dlls/advapi32/advapi32.spec
@@ -469,7 +469,7 @@
@@ -36,10 +36,10 @@ index d116ecb836..ecb07f635a 100644
+
#endif /* __WINE_ADVAPI32MISC_H */
diff --git a/dlls/advapi32/lsa.c b/dlls/advapi32/lsa.c
index 479201bfc1..ceb3b05c05 100644
index 3da6d19b82..af5f9dd46d 100644
--- a/dlls/advapi32/lsa.c
+++ b/dlls/advapi32/lsa.c
@@ -973,3 +973,41 @@ NTSTATUS WINAPI LsaUnregisterPolicyChangeNotification(
@@ -973,3 +973,42 @@ NTSTATUS WINAPI LsaUnregisterPolicyChangeNotification(
FIXME("(%d,%p) stub\n", class, event);
return STATUS_SUCCESS;
}
@@ -67,7 +67,8 @@ index 479201bfc1..ceb3b05c05 100644
+
+ if (lpLuid->HighPart ||
+ (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
+ lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
+ lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE ||
+ !WellKnownPrivNames[lpLuid->LowPart]))
+ return STATUS_NO_SUCH_PRIVILEGE;
+
+ priv_size = (strlenW(WellKnownPrivNames[lpLuid->LowPart]) + 1) * sizeof(WCHAR);
@@ -158,5 +159,5 @@ index 2bb3d312e4..0bf0eca43e 100644
ULONG WINAPI LsaNtStatusToWinError(NTSTATUS);
NTSTATUS WINAPI LsaOpenPolicy(PLSA_UNICODE_STRING,PLSA_OBJECT_ATTRIBUTES,ACCESS_MASK,PLSA_HANDLE);
--
2.11.0
2.13.1

View File

@@ -0,0 +1,315 @@
From 3f314cc8251f62f592013abe7b1c3b977de0699a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Fri, 4 Aug 2017 02:33:14 +0200
Subject: ntdll: Implement NtFilterToken.
---
dlls/ntdll/nt.c | 59 ++++++++++++++++++++++++++++++++++++
dlls/ntdll/ntdll.spec | 2 +-
include/winnt.h | 5 +++
include/winternl.h | 1 +
server/process.c | 2 +-
server/protocol.def | 10 ++++++
server/security.h | 4 ++-
server/token.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++--
8 files changed, 162 insertions(+), 5 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index 93554e929be..5822dec9b15 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -136,6 +136,65 @@ NTSTATUS WINAPI NtDuplicateToken(
}
/******************************************************************************
+ * NtFilterToken [NTDLL.@]
+ * ZwFilterToken [NTDLL.@]
+ */
+NTSTATUS WINAPI NtFilterToken( HANDLE token, ULONG flags, TOKEN_GROUPS *disable_sids,
+ TOKEN_PRIVILEGES *privileges, TOKEN_GROUPS *restrict_sids,
+ HANDLE *new_token )
+{
+ data_size_t privileges_len = 0;
+ data_size_t sids_len = 0;
+ SID *sids = NULL;
+ NTSTATUS status;
+
+ TRACE( "(%p, 0x%08x, %p, %p, %p, %p)\n", token, flags, disable_sids, privileges,
+ restrict_sids, new_token );
+
+ if (flags)
+ FIXME( "flags %x unsupported\n", flags );
+
+ if (restrict_sids)
+ FIXME( "support for restricting sids not yet implemented\n" );
+
+ if (privileges)
+ privileges_len = privileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
+
+ if (disable_sids)
+ {
+ DWORD len, i;
+ BYTE *tmp;
+
+ for (i = 0; i < disable_sids->GroupCount; i++)
+ sids_len += RtlLengthSid( disable_sids->Groups[i].Sid );
+
+ sids = RtlAllocateHeap( GetProcessHeap(), 0, sids_len );
+ if (!sids) return STATUS_NO_MEMORY;
+
+ for (i = 0, tmp = (BYTE *)sids; i < disable_sids->GroupCount; i++, tmp += len)
+ {
+ len = RtlLengthSid( disable_sids->Groups[i].Sid );
+ memcpy( tmp, disable_sids->Groups[i].Sid, len );
+ }
+ }
+
+ SERVER_START_REQ( filter_token )
+ {
+ req->handle = wine_server_obj_handle( token );
+ req->flags = flags;
+ req->privileges_size = privileges_len;
+ wine_server_add_data( req, privileges->Privileges, privileges_len );
+ wine_server_add_data( req, sids, sids_len );
+ status = wine_server_call( req );
+ if (!status) *new_token = wine_server_ptr_handle( reply->new_handle );
+ }
+ SERVER_END_REQ;
+
+ RtlFreeHeap( GetProcessHeap(), 0, sids );
+ return status;
+}
+
+/******************************************************************************
* NtOpenProcessToken [NTDLL.@]
* ZwOpenProcessToken [NTDLL.@]
*/
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 4f7ee496437..275fda57970 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -179,7 +179,7 @@
# @ stub NtEnumerateSystemEnvironmentValuesEx
@ stdcall NtEnumerateValueKey(long long long ptr long ptr)
@ stub NtExtendSection
-# @ stub NtFilterToken
+@ stdcall NtFilterToken(long long ptr ptr ptr ptr)
@ stdcall NtFindAtom(ptr long ptr)
@ stdcall NtFlushBuffersFile(long ptr)
@ stdcall NtFlushInstructionCache(long ptr long)
diff --git a/include/winnt.h b/include/winnt.h
index f91f81eb559..891c9b6d4bb 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -3844,6 +3844,11 @@ typedef enum _TOKEN_INFORMATION_CLASS {
TOKEN_ADJUST_SESSIONID | \
TOKEN_ADJUST_DEFAULT )
+#define DISABLE_MAX_PRIVILEGE 0x1
+#define SANDBOX_INERT 0x2
+#define LUA_TOKEN 0x4
+#define WRITE_RESTRICTED 0x8
+
#ifndef _SECURITY_DEFINED
#define _SECURITY_DEFINED
diff --git a/include/winternl.h b/include/winternl.h
index 140669b0105..899e8324d67 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -2348,6 +2348,7 @@ NTSYSAPI NTSTATUS WINAPI NtDuplicateToken(HANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES
NTSYSAPI NTSTATUS WINAPI NtEnumerateKey(HANDLE,ULONG,KEY_INFORMATION_CLASS,void *,DWORD,DWORD *);
NTSYSAPI NTSTATUS WINAPI NtEnumerateValueKey(HANDLE,ULONG,KEY_VALUE_INFORMATION_CLASS,PVOID,ULONG,PULONG);
NTSYSAPI NTSTATUS WINAPI NtExtendSection(HANDLE,PLARGE_INTEGER);
+NTSYSAPI NTSTATUS WINAPI NtFilterToken(HANDLE,ULONG,TOKEN_GROUPS*,TOKEN_PRIVILEGES*,TOKEN_GROUPS*,HANDLE*);
NTSYSAPI NTSTATUS WINAPI NtFindAtom(const WCHAR*,ULONG,RTL_ATOM*);
NTSYSAPI NTSTATUS WINAPI NtFlushBuffersFile(HANDLE,IO_STATUS_BLOCK*);
NTSYSAPI NTSTATUS WINAPI NtFlushInstructionCache(HANDLE,LPCVOID,SIZE_T);
diff --git a/server/process.c b/server/process.c
index cbe726afe81..f0f60edcd3f 100644
--- a/server/process.c
+++ b/server/process.c
@@ -571,7 +571,7 @@ struct thread *create_process( int fd, struct thread *parent_thread, int inherit
: alloc_handle_table( process, 0 );
/* Note: for security reasons, starting a new process does not attempt
* to use the current impersonation token for the new process */
- process->token = token_duplicate( parent->token, TRUE, 0, NULL );
+ process->token = token_duplicate( parent->token, TRUE, 0, NULL, NULL, 0, NULL, 0 );
process->affinity = parent->affinity;
}
if (!process->handles || !process->token) goto error;
diff --git a/server/protocol.def b/server/protocol.def
index fc6e343af52..b3dce66eb9c 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3391,6 +3391,16 @@ enum caret_state
obj_handle_t new_handle; /* duplicated handle */
@END
+@REQ(filter_token)
+ obj_handle_t handle; /* handle to the token to duplicate */
+ unsigned int flags; /* flags */
+ data_size_t privileges_size; /* size of privileges */
+ VARARG(privileges,LUID_AND_ATTRIBUTES,privileges_size); /* privileges to remove from new token */
+ VARARG(disable_sids,SID); /* array of groups to remove from new token */
+@REPLY
+ obj_handle_t new_handle; /* filtered handle */
+@END
+
@REQ(access_check)
obj_handle_t handle; /* handle to the token */
unsigned int desired_access; /* desired access to the object */
diff --git a/server/security.h b/server/security.h
index 606dbb2ab2c..6c337143c3d 100644
--- a/server/security.h
+++ b/server/security.h
@@ -56,7 +56,9 @@ extern const PSID security_high_label_sid;
extern struct token *token_create_admin(void);
extern int token_assign_label( struct token *token, PSID label );
extern struct token *token_duplicate( struct token *src_token, unsigned primary,
- int impersonation_level, const struct security_descriptor *sd );
+ int impersonation_level, const struct security_descriptor *sd,
+ const LUID_AND_ATTRIBUTES *filter_privileges, unsigned int priv_count,
+ const SID *filter_groups, unsigned int group_count );
extern int token_check_privileges( struct token *token, int all_required,
const LUID_AND_ATTRIBUTES *reqprivs,
unsigned int count, LUID_AND_ATTRIBUTES *usedprivs);
diff --git a/server/token.c b/server/token.c
index 74db66e1e24..acd7a4dedb5 100644
--- a/server/token.c
+++ b/server/token.c
@@ -299,6 +299,19 @@ static int acl_is_valid( const ACL *acl, data_size_t size )
return TRUE;
}
+static unsigned int get_sid_count( const SID *sid, data_size_t size )
+{
+ unsigned int count;
+
+ for (count = 0; size >= sizeof(SID) && security_sid_len( sid ) <= size; count++)
+ {
+ size -= security_sid_len( sid );
+ sid = (const SID *)((char *)sid + security_sid_len( sid ));
+ }
+
+ return count;
+}
+
/* checks whether all members of a security descriptor fit inside the size
* of memory specified */
int sd_is_valid( const struct security_descriptor *sd, data_size_t size )
@@ -639,8 +652,36 @@ static struct token *create_token( unsigned primary, const SID *user,
return token;
}
+static int filter_group( struct group *group, const SID *filter, unsigned int count )
+{
+ unsigned int i;
+
+ for (i = 0; i < count; i++)
+ {
+ if (security_equal_sid( &group->sid, filter )) return 1;
+ filter = (const SID *)((char *)filter + security_sid_len( filter ));
+ }
+
+ return 0;
+}
+
+static int filter_privilege( struct privilege *privilege, const LUID_AND_ATTRIBUTES *filter, unsigned int count )
+{
+ unsigned int i;
+
+ for (i = 0; i < count; i++)
+ {
+ if (!memcmp( &privilege->luid, &filter[i].Luid, sizeof(LUID) ))
+ return 1;
+ }
+
+ return 0;
+}
+
struct token *token_duplicate( struct token *src_token, unsigned primary,
- int impersonation_level, const struct security_descriptor *sd )
+ int impersonation_level, const struct security_descriptor *sd,
+ const LUID_AND_ATTRIBUTES *filter_privileges, unsigned int priv_count,
+ const SID *filter_groups, unsigned int group_count)
{
const luid_t *modified_id =
primary || (impersonation_level == src_token->impersonation_level) ?
@@ -676,6 +717,12 @@ struct token *token_duplicate( struct token *src_token, unsigned primary,
return NULL;
}
memcpy( newgroup, group, size );
+ if (filter_group( group, filter_groups, group_count ))
+ {
+ newgroup->enabled = 0;
+ newgroup->def = 0;
+ newgroup->deny_only = 1;
+ }
list_add_tail( &token->groups, &newgroup->entry );
if (src_token->primary_group == &group->sid)
token->primary_group = &newgroup->sid;
@@ -684,11 +731,14 @@ struct token *token_duplicate( struct token *src_token, unsigned primary,
/* copy privileges */
LIST_FOR_EACH_ENTRY( privilege, &src_token->privileges, struct privilege, entry )
+ {
+ if (filter_privilege( privilege, filter_privileges, priv_count )) continue;
if (!privilege_add( token, &privilege->luid, privilege->enabled ))
{
release_object( token );
return NULL;
}
+ }
if (sd) default_set_sd( &token->obj, sd, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION );
@@ -1322,7 +1372,7 @@ DECL_HANDLER(duplicate_token)
TOKEN_DUPLICATE,
&token_ops )))
{
- struct token *token = token_duplicate( src_token, req->primary, req->impersonation_level, sd );
+ struct token *token = token_duplicate( src_token, req->primary, req->impersonation_level, sd, NULL, 0, NULL, 0 );
if (token)
{
reply->new_handle = alloc_handle_no_access_check( current->process, token, req->access, objattr->attributes );
@@ -1332,6 +1382,36 @@ DECL_HANDLER(duplicate_token)
}
}
+/* creates a restricted version of a token */
+DECL_HANDLER(filter_token)
+{
+ struct token *src_token;
+
+ if ((src_token = (struct token *)get_handle_obj( current->process, req->handle,
+ TOKEN_DUPLICATE,
+ &token_ops )))
+ {
+ const LUID_AND_ATTRIBUTES *filter_privileges = get_req_data();
+ unsigned int priv_count, group_count;
+ const SID *filter_groups;
+ struct token *token;
+
+ priv_count = min( req->privileges_size, get_req_data_size() ) / sizeof(LUID_AND_ATTRIBUTES);
+ filter_groups = (const SID *)((char *)filter_privileges + priv_count * sizeof(LUID_AND_ATTRIBUTES));
+ group_count = get_sid_count( filter_groups, get_req_data_size() - priv_count * sizeof(LUID_AND_ATTRIBUTES) );
+
+ token = token_duplicate( src_token, src_token->primary, src_token->impersonation_level, NULL,
+ filter_privileges, priv_count, filter_groups, group_count );
+ if (token)
+ {
+ unsigned int access = get_handle_access( current->process, req->handle );
+ reply->new_handle = alloc_handle_no_access_check( current->process, token, access, 0 );
+ release_object( token );
+ }
+ release_object( src_token );
+ }
+}
+
/* checks the specified privileges are held by the token */
DECL_HANDLER(check_token_privileges)
{
--
2.13.1

View File

@@ -0,0 +1,271 @@
From 2a1064c5f90beac2bd709ab5d1c454c90a16189b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Fri, 4 Aug 2017 02:51:57 +0200
Subject: advapi32: Implement CreateRestrictedToken.
---
dlls/advapi32/security.c | 88 +++++++++++++++++++++++++++++++++++-------
dlls/advapi32/tests/security.c | 88 +++++++++++++++++++++++++++++++++++++++---
2 files changed, 157 insertions(+), 19 deletions(-)
diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c
index 82bb6689d43..c531e45c9a0 100644
--- a/dlls/advapi32/security.c
+++ b/dlls/advapi32/security.c
@@ -840,6 +840,60 @@ BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
ThreadImpersonationToken, &token, sizeof token ));
}
+static BOOL allocate_groups(TOKEN_GROUPS **groups_ret, SID_AND_ATTRIBUTES *sids, DWORD count)
+{
+ TOKEN_GROUPS *groups;
+ DWORD i;
+
+ if (!count)
+ {
+ *groups_ret = NULL;
+ return TRUE;
+ }
+
+ groups = (TOKEN_GROUPS *)heap_alloc(FIELD_OFFSET(TOKEN_GROUPS, Groups) +
+ count * sizeof(SID_AND_ATTRIBUTES));
+ if (!groups)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return FALSE;
+ }
+
+ groups->GroupCount = count;
+ for (i = 0; i < count; i++)
+ groups->Groups[i] = sids[i];
+
+ *groups_ret = groups;
+ return TRUE;
+}
+
+static BOOL allocate_privileges(TOKEN_PRIVILEGES **privileges_ret, LUID_AND_ATTRIBUTES *privs, DWORD count)
+{
+ TOKEN_PRIVILEGES *privileges;
+ DWORD i;
+
+ if (!count)
+ {
+ *privileges_ret = NULL;
+ return TRUE;
+ }
+
+ privileges = (TOKEN_PRIVILEGES *)heap_alloc(FIELD_OFFSET(TOKEN_PRIVILEGES, Privileges) +
+ count * sizeof(LUID_AND_ATTRIBUTES));
+ if (!privileges)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return FALSE;
+ }
+
+ privileges->PrivilegeCount = count;
+ for (i = 0; i < count; i++)
+ privileges->Privileges[i] = privs[i];
+
+ *privileges_ret = privileges;
+ return TRUE;
+}
+
/*************************************************************************
* CreateRestrictedToken [ADVAPI32.@]
*
@@ -871,25 +925,33 @@ BOOL WINAPI CreateRestrictedToken(
PSID_AND_ATTRIBUTES restrictSids,
PHANDLE newToken)
{
- TOKEN_TYPE type;
- SECURITY_IMPERSONATION_LEVEL level = SecurityAnonymous;
- DWORD size;
+ TOKEN_PRIVILEGES *delete_privs = NULL;
+ TOKEN_GROUPS *disable_groups = NULL;
+ TOKEN_GROUPS *restrict_sids = NULL;
+ BOOL ret = FALSE;
- FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
+ TRACE("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p)\n",
baseToken, flags, nDisableSids, disableSids,
nDeletePrivs, deletePrivs,
nRestrictSids, restrictSids,
newToken);
- size = sizeof(type);
- if (!GetTokenInformation( baseToken, TokenType, &type, size, &size )) return FALSE;
- if (type == TokenImpersonation)
- {
- size = sizeof(level);
- if (!GetTokenInformation( baseToken, TokenImpersonationLevel, &level, size, &size ))
- return FALSE;
- }
- return DuplicateTokenEx( baseToken, MAXIMUM_ALLOWED, NULL, level, type, newToken );
+ if (!allocate_groups(&disable_groups, disableSids, nDisableSids))
+ goto done;
+
+ if (!allocate_privileges(&delete_privs, deletePrivs, nDeletePrivs))
+ goto done;
+
+ if (!allocate_groups(&restrict_sids, restrictSids, nRestrictSids))
+ goto done;
+
+ ret = set_ntstatus(NtFilterToken(baseToken, flags, disable_groups, delete_privs, restrict_sids, newToken));
+
+done:
+ heap_free(disable_groups);
+ heap_free(delete_privs);
+ heap_free(restrict_sids);
+ return ret;
}
/* ##############################
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index a1ecc409b73..0fd41fe82fa 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -5292,10 +5292,13 @@ static void test_GetUserNameW(void)
static void test_CreateRestrictedToken(void)
{
+ TOKEN_PRIMARY_GROUP *primary_group, *primary_group2;
HANDLE process_token, token, r_token;
PTOKEN_GROUPS token_groups, groups2;
SID_AND_ATTRIBUTES sattr;
SECURITY_IMPERSONATION_LEVEL level;
+ TOKEN_PRIVILEGES *privs;
+ PRIVILEGE_SET privset;
TOKEN_TYPE type;
BOOL is_member;
DWORD size;
@@ -5311,7 +5314,7 @@ static void test_CreateRestrictedToken(void)
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &process_token);
ok(ret, "got error %d\n", GetLastError());
- ret = DuplicateTokenEx(process_token, TOKEN_DUPLICATE|TOKEN_ADJUST_GROUPS|TOKEN_QUERY,
+ ret = DuplicateTokenEx(process_token, TOKEN_DUPLICATE|TOKEN_ADJUST_GROUPS|TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,
NULL, SecurityImpersonation, TokenImpersonation, &token);
ok(ret, "got error %d\n", GetLastError());
@@ -5342,11 +5345,21 @@ static void test_CreateRestrictedToken(void)
ok(ret, "got error %d\n", GetLastError());
ok(is_member, "not a member\n");
- /* disable a SID in new token */
+ privset.PrivilegeCount = 1;
+ privset.Control = PRIVILEGE_SET_ALL_NECESSARY;
+ ret = LookupPrivilegeValueA(NULL, "SeChangeNotifyPrivilege", &privset.Privilege[0].Luid);
+ ok(ret, "got error %d\n", GetLastError());
+
+ is_member = FALSE;
+ ret = PrivilegeCheck(token, &privset, &is_member);
+ ok(ret, "got error %d\n", GetLastError());
+ ok(is_member, "Expected SeChangeNotifyPrivilege to be enabled\n");
+
+ /* disable a SID and a privilege in new token */
sattr.Sid = token_groups->Groups[i].Sid;
sattr.Attributes = 0;
r_token = NULL;
- ret = pCreateRestrictedToken(token, 0, 1, &sattr, 0, NULL, 0, NULL, &r_token);
+ ret = pCreateRestrictedToken(token, 0, 1, &sattr, 1, &privset.Privilege[0], 0, NULL, &r_token);
ok(ret, "got error %d\n", GetLastError());
if (ret)
@@ -5355,7 +5368,7 @@ static void test_CreateRestrictedToken(void)
is_member = TRUE;
ret = pCheckTokenMembership(r_token, token_groups->Groups[i].Sid, &is_member);
ok(ret, "got error %d\n", GetLastError());
- todo_wine ok(!is_member, "not a member\n");
+ ok(!is_member, "not a member\n");
ret = GetTokenInformation(r_token, TokenGroups, NULL, 0, &size);
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d with error %d\n",
@@ -5370,9 +5383,9 @@ static void test_CreateRestrictedToken(void)
break;
}
- todo_wine ok(groups2->Groups[j].Attributes & SE_GROUP_USE_FOR_DENY_ONLY,
+ ok(groups2->Groups[j].Attributes & SE_GROUP_USE_FOR_DENY_ONLY,
"got wrong attributes\n");
- todo_wine ok((groups2->Groups[j].Attributes & SE_GROUP_ENABLED) == 0,
+ ok((groups2->Groups[j].Attributes & SE_GROUP_ENABLED) == 0,
"got wrong attributes\n");
HeapFree(GetProcessHeap(), 0, groups2);
@@ -5386,10 +5399,73 @@ static void test_CreateRestrictedToken(void)
ret = GetTokenInformation(r_token, TokenImpersonationLevel, &level, size, &size);
ok(ret, "got error %d\n", GetLastError());
ok(level == SecurityImpersonation, "got level %u\n", type);
+
+ is_member = TRUE;
+ ret = PrivilegeCheck(r_token, &privset, &is_member);
+ ok(ret, "got error %d\n", GetLastError());
+ ok(!is_member, "Expected SeChangeNotifyPrivilege not to be enabled\n");
+
+ ret = GetTokenInformation(r_token, TokenPrivileges, NULL, 0, &size);
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d with error %d\n",
+ ret, GetLastError());
+ privs = HeapAlloc(GetProcessHeap(), 0, size);
+ ret = GetTokenInformation(r_token, TokenPrivileges, privs, size, &size);
+ ok(ret, "got error %d\n", GetLastError());
+
+ is_member = FALSE;
+ for (j = 0; j < privs->PrivilegeCount; j++)
+ {
+ if (RtlEqualLuid(&privs->Privileges[j].Luid, &privset.Privilege[0].Luid))
+ {
+ is_member = TRUE;
+ break;
+ }
+ }
+
+ ok(!is_member, "Expected not to find privilege\n");
+ HeapFree(GetProcessHeap(), 0, privs);
}
HeapFree(GetProcessHeap(), 0, token_groups);
CloseHandle(r_token);
+
+ ret = GetTokenInformation(token, TokenPrimaryGroup, NULL, 0, &size);
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d with error %d\n",
+ ret, GetLastError());
+ primary_group = HeapAlloc(GetProcessHeap(), 0, size);
+ ret = GetTokenInformation(token, TokenPrimaryGroup, primary_group, size, &size);
+ ok(ret, "got error %d\n", GetLastError());
+
+ /* disable primary group */
+ sattr.Sid = primary_group->PrimaryGroup;
+ sattr.Attributes = 0;
+ r_token = NULL;
+ ret = pCreateRestrictedToken(token, 0, 1, &sattr, 0, NULL, 0, NULL, &r_token);
+ ok(ret, "got error %d\n", GetLastError());
+
+ if (ret)
+ {
+ is_member = TRUE;
+ ret = pCheckTokenMembership(r_token, primary_group->PrimaryGroup, &is_member);
+ ok(ret, "got error %d\n", GetLastError());
+ ok(!is_member, "not a member\n");
+
+ ret = GetTokenInformation(r_token, TokenPrimaryGroup, NULL, 0, &size);
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d with error %d\n",
+ ret, GetLastError());
+ primary_group2 = HeapAlloc(GetProcessHeap(), 0, size);
+ ret = GetTokenInformation(r_token, TokenPrimaryGroup, primary_group2, size, &size);
+ ok(ret, "got error %d\n", GetLastError());
+
+ ok(EqualSid(primary_group2->PrimaryGroup, primary_group->PrimaryGroup),
+ "Expected same primary group\n");
+
+ HeapFree(GetProcessHeap(), 0, primary_group2);
+ }
+
+ HeapFree(GetProcessHeap(), 0, primary_group);
+ CloseHandle(r_token);
+
CloseHandle(token);
CloseHandle(process_token);
}
--
2.13.1

View File

@@ -0,0 +1,36 @@
From 22a49dfa50cda9b1f5a5c64eabed2d17b0033896 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Fri, 4 Aug 2017 02:52:50 +0200
Subject: server: Correctly validate SID length in sd_is_valid.
---
server/token.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/server/token.c b/server/token.c
index acd7a4dedb5..7ab0f634c05 100644
--- a/server/token.c
+++ b/server/token.c
@@ -332,8 +332,7 @@ int sd_is_valid( const struct security_descriptor *sd, data_size_t size )
owner = sd_get_owner( sd );
if (owner)
{
- size_t needed_size = security_sid_len( owner );
- if ((sd->owner_len < sizeof(SID)) || (needed_size > sd->owner_len))
+ if ((sd->owner_len < sizeof(SID)) || (security_sid_len( owner ) > sd->owner_len))
return FALSE;
}
offset += sd->owner_len;
@@ -344,8 +343,7 @@ int sd_is_valid( const struct security_descriptor *sd, data_size_t size )
group = sd_get_group( sd );
if (group)
{
- size_t needed_size = security_sid_len( group );
- if ((sd->group_len < sizeof(SID)) || (needed_size > sd->group_len))
+ if ((sd->group_len < sizeof(SID)) || (security_sid_len( group ) > sd->group_len))
return FALSE;
}
offset += sd->group_len;
--
2.13.1

View File

@@ -0,0 +1 @@
Fixes: Implement advapi32.CreateRestrictedToken

View File

@@ -0,0 +1,456 @@
From ba50fc98ee4690e62899d48efc856c2bc910536c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Mon, 7 Aug 2017 01:25:02 +0200
Subject: advapi32/tests: Extend security label / token integrity tests.
---
dlls/advapi32/tests/Makefile.in | 2 +-
dlls/advapi32/tests/security.c | 389 +++++++++++++++++++++++++++++++++++++++-
2 files changed, 387 insertions(+), 4 deletions(-)
diff --git a/dlls/advapi32/tests/Makefile.in b/dlls/advapi32/tests/Makefile.in
index 36ce031ef62..4437e6e5de7 100644
--- a/dlls/advapi32/tests/Makefile.in
+++ b/dlls/advapi32/tests/Makefile.in
@@ -1,5 +1,5 @@
TESTDLL = advapi32.dll
-IMPORTS = ole32 advapi32
+IMPORTS = ole32 user32 advapi32
C_SRCS = \
cred.c \
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index 0fd41fe82fa..4a03db27e69 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -7191,13 +7191,19 @@ static void test_token_security_descriptor(void)
{
static SID low_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
{SECURITY_MANDATORY_LOW_RID}};
+ static SID medium_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
+ {SECURITY_MANDATORY_MEDIUM_RID}};
+ static SID high_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
+ {SECURITY_MANDATORY_HIGH_RID}};
char buffer_sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
- SECURITY_DESCRIPTOR *sd = (SECURITY_DESCRIPTOR *)&buffer_sd, *sd2;
+ SECURITY_DESCRIPTOR *sd = (SECURITY_DESCRIPTOR *)&buffer_sd, *sd2, *sd3;
char buffer_acl[256], buffer[MAX_PATH];
- ACL *acl = (ACL *)&buffer_acl, *acl2, *acl_child;
+ ACL *acl = (ACL *)&buffer_acl, *acl2, *acl_child, *sacl;
BOOL defaulted, present, ret, found;
- HANDLE token, token2, token3;
+ HANDLE token, token2, token3, token4, token5, token6;
EXPLICIT_ACCESSW exp_access;
+ TOKEN_MANDATORY_LABEL *tml;
+ BYTE buffer_integrity[64];
PROCESS_INFORMATION info;
DWORD size, index, retd;
ACCESS_ALLOWED_ACE *ace;
@@ -7347,6 +7353,185 @@ static void test_token_security_descriptor(void)
/* The security label is also not inherited */
if (pAddMandatoryAce)
{
+ memset(buffer_integrity, 0, sizeof(buffer_integrity));
+ ret = GetTokenInformation(token, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size);
+ ok(ret, "GetTokenInformation failed with error %u\n", GetLastError());
+ tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity;
+ ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level),
+ "Expected medium or high integrity level\n");
+
+ if (EqualSid(tml->Label.Sid, &high_level))
+ {
+ DWORD process_id;
+ HANDLE process;
+ HWND shell;
+
+ /* This test tries to get a medium token and then impersonates this token. The
+ * idea is to check whether the sd label of a newly created token depends on the
+ * current active token or the integrity level of the newly created token. */
+
+ /* Steal process token of the explorer.exe process */
+ shell = GetShellWindow();
+ todo_wine ok(shell != NULL, "Failed to get shell window\n");
+ if (!shell) shell = GetDesktopWindow(); /* FIXME: Workaround for Wine */
+ ok(GetWindowThreadProcessId(shell, &process_id),
+ "Failed to get process id of shell window: %u\n", GetLastError());
+ process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, process_id);
+ ok(process != NULL, "Failed to open process: %u\n", GetLastError());
+ ok(OpenProcessToken(process, TOKEN_ALL_ACCESS, &token4),
+ "Failed to open process token: %u\n", GetLastError());
+ CloseHandle(process);
+
+ /* Check TokenIntegrityLevel and LABEL_SECURITY_INFORMATION of explorer.exe token */
+ memset(buffer_integrity, 0, sizeof(buffer_integrity));
+ ret = GetTokenInformation(token4, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size);
+ ok(ret, "GetTokenInformation failed with error %u\n", GetLastError());
+ tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity;
+ todo_wine ok(EqualSid(tml->Label.Sid, &medium_level), "Expected medium integrity level\n");
+
+ size = 0;
+ ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError());
+
+ sd3 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
+ ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, sd3, size, &size);
+ ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
+
+ sacl = NULL;
+ ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted);
+ ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
+ ok(present, "No SACL in the security descriptor\n");
+ ok(sacl != NULL, "NULL SACL in the security descriptor\n");
+
+ if (sacl)
+ {
+ ret = pGetAce(sacl, 0, (void **)&ace);
+ ok(ret, "GetAce failed with error %u\n", GetLastError());
+ ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE,
+ "Unexpected ACE type %#x\n", ace->Header.AceType);
+ todo_wine ok(EqualSid(&ace->SidStart, &medium_level),
+ "Expected medium integrity level\n");
+ }
+
+ HeapFree(GetProcessHeap(), 0, sd3);
+
+ /* Start child process with the explorer.exe token */
+ memset(&startup, 0, sizeof(startup));
+ startup.cb = sizeof(startup);
+ startup.dwFlags = STARTF_USESHOWWINDOW;
+ startup.wShowWindow = SW_SHOWNORMAL;
+
+ sprintf(buffer, "%s tests/security.c test_token_sd_medium", myARGV[0]);
+ ret = CreateProcessAsUserA(token4, NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info);
+ ok(ret || GetLastError() == ERROR_PRIVILEGE_NOT_HELD,
+ "CreateProcess failed with error %u\n", GetLastError());
+ if (ret)
+ {
+ winetest_wait_child_process(info.hProcess);
+ CloseHandle(info.hProcess);
+ CloseHandle(info.hThread);
+ }
+ else
+ win_skip("Skipping test for creating process with medium level token\n");
+
+ ret = DuplicateTokenEx(token4, 0, NULL, SecurityImpersonation, TokenImpersonation, &token5);
+ ok(ret, "DuplicateTokenEx failed with error %u\n", GetLastError());
+ ret = SetThreadToken(NULL, token5);
+ todo_wine ok(ret, "SetThreadToken failed with error %u\n", GetLastError());
+ CloseHandle(token4);
+
+ /* Restrict current process token while impersonating a medium integrity token */
+ ret = CreateRestrictedToken(token, 0, 0, NULL, 0, NULL, 0, NULL, &token6);
+ ok(ret, "CreateRestrictedToken failed with error %u\n", GetLastError());
+
+ memset(buffer_integrity, 0, sizeof(buffer_integrity));
+ ret = GetTokenInformation(token6, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size);
+ ok(ret, "GetTokenInformation failed with error %u\n", GetLastError());
+ tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity;
+ ok(EqualSid(tml->Label.Sid, &high_level), "Expected high integrity level\n");
+
+ size = 0;
+ ret = GetKernelObjectSecurity(token6, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError());
+
+ sd3 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
+ ret = GetKernelObjectSecurity(token6, LABEL_SECURITY_INFORMATION, sd3, size, &size);
+ ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
+
+ sacl = NULL;
+ ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted);
+ ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
+ todo_wine ok(present, "No SACL in the security descriptor\n");
+ todo_wine ok(sacl != NULL, "NULL SACL in the security descriptor\n");
+
+ if (sacl)
+ {
+ ret = pGetAce(sacl, 0, (void **)&ace);
+ ok(ret, "GetAce failed with error %u\n", GetLastError());
+ ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE,
+ "Unexpected ACE type %#x\n", ace->Header.AceType);
+ ok(EqualSid(&ace->SidStart, &medium_level),
+ "Expected medium integrity level\n");
+ }
+
+ HeapFree(GetProcessHeap(), 0, sd3);
+ RevertToSelf();
+ CloseHandle(token5);
+
+ /* Start child process with the restricted token */
+ sprintf(buffer, "%s tests/security.c test_token_sd_restricted", myARGV[0]);
+ ret = CreateProcessAsUserA(token6, NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info);
+ ok(ret, "CreateProcess failed with error %u\n", GetLastError());
+ winetest_wait_child_process(info.hProcess);
+ CloseHandle(info.hProcess);
+ CloseHandle(info.hThread);
+ CloseHandle(token6);
+
+ /* DuplicateTokenEx should assign security label even when SA points to empty SD */
+ memset(sd, 0, sizeof(buffer_sd));
+ ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
+ ok(ret, "InitializeSecurityDescriptor failed with error %u\n", GetLastError());
+
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ sa.lpSecurityDescriptor = sd;
+ sa.bInheritHandle = FALSE;
+
+ ret = DuplicateTokenEx(token, 0, &sa, 0, TokenPrimary, &token6);
+ ok(ret, "DuplicateTokenEx failed with error %u\n", GetLastError());
+
+ size = 0;
+ ret = GetKernelObjectSecurity(token6, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
+ todo_wine ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError());
+
+ sd3 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
+ ret = GetKernelObjectSecurity(token6, LABEL_SECURITY_INFORMATION, sd3, size, &size);
+ todo_wine ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
+
+ sacl = NULL;
+ ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted);
+ todo_wine ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
+ todo_wine ok(present, "No SACL in the security descriptor\n");
+ todo_wine ok(sacl != NULL, "NULL SACL in the security descriptor\n");
+
+ if (sacl)
+ {
+ ret = pGetAce(sacl, 0, (void **)&ace);
+ ok(ret, "GetAce failed with error %u\n", GetLastError());
+ ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE,
+ "Unexpected ACE type %#x\n", ace->Header.AceType);
+ ok(EqualSid(&ace->SidStart, &high_level),
+ "Expected high integrity level\n");
+ }
+
+ HeapFree(GetProcessHeap(), 0, sd3);
+ CloseHandle(token6);
+ }
+ else
+ skip("Skipping test, running without admin rights\n");
+
ret = InitializeAcl(acl, 256, ACL_REVISION);
ok(ret, "InitializeAcl failed with error %u\n", GetLastError());
@@ -7362,6 +7547,90 @@ static void test_token_security_descriptor(void)
ret = SetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd);
ok(ret, "SetKernelObjectSecurity failed with error %u\n", GetLastError());
+
+ /* changing the label of the security descriptor does not change the integrity level of the token itself */
+ memset(buffer_integrity, 0, sizeof(buffer_integrity));
+ ret = GetTokenInformation(token, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size);
+ ok(ret, "GetTokenInformation failed with error %u\n", GetLastError());
+ tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity;
+ ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level),
+ "Expected medium or high integrity level\n");
+
+ /* restricting / duplicating a token resets the mandatory sd label */
+ ret = CreateRestrictedToken(token, 0, 0, NULL, 0, NULL, 0, NULL, &token4);
+ ok(ret, "CreateRestrictedToken failed with error %u\n", GetLastError());
+
+ memset(buffer_integrity, 0, sizeof(buffer_integrity));
+ ret = GetTokenInformation(token4, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size);
+ ok(ret, "GetTokenInformation failed with error %u\n", GetLastError());
+ tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity;
+ ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level),
+ "Expected medium or high integrity level\n");
+
+ size = 0;
+ ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError());
+
+ sd3 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
+ ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, sd3, size, &size);
+ ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
+
+ ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted);
+ ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
+ todo_wine ok(present, "No SACL in the security descriptor\n");
+ todo_wine ok(sacl != NULL, "NULL SACL in the security descriptor\n");
+
+ if (sacl)
+ {
+ ret = pGetAce(sacl, 0, (void **)&ace);
+ ok(ret, "GetAce failed with error %u\n", GetLastError());
+ ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE,
+ "Unexpected ACE type %#x\n", ace->Header.AceType);
+ ok(EqualSid(&ace->SidStart, &medium_level) || EqualSid(&ace->SidStart, &high_level),
+ "Low integrity level should not have been inherited\n");
+ }
+
+ HeapFree(GetProcessHeap(), 0, sd3);
+ CloseHandle(token4);
+
+ ret = DuplicateTokenEx(token, 0, NULL, 0, TokenPrimary, &token4);
+ ok(ret, "DuplicateTokenEx failed with error %u\n", GetLastError());
+
+ memset(buffer_integrity, 0, sizeof(buffer_integrity));
+ ret = GetTokenInformation(token4, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size);
+ ok(ret, "GetTokenInformation failed with error %u\n", GetLastError());
+ tml = (TOKEN_MANDATORY_LABEL*) buffer_integrity;
+ ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level),
+ "Expected medium or high integrity level\n");
+
+ size = 0;
+ ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
+ todo_wine ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError());
+
+ sd3 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
+ ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, sd3, size, &size);
+ todo_wine ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
+
+ sacl = NULL;
+ ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted);
+ todo_wine ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
+ todo_wine ok(present, "No SACL in the security descriptor\n");
+ todo_wine ok(sacl != NULL, "NULL SACL in the security descriptor\n");
+
+ if (sacl)
+ {
+ ret = pGetAce(sacl, 0, (void **)&ace);
+ ok(ret, "GetAce failed with error %u\n", GetLastError());
+ ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE,
+ "Unexpected ACE type %#x\n", ace->Header.AceType);
+ ok(EqualSid(&ace->SidStart, &medium_level) || EqualSid(&ace->SidStart, &high_level),
+ "Low integrity level should not have been inherited\n");
+ }
+
+ HeapFree(GetProcessHeap(), 0, sd3);
+ CloseHandle(token4);
}
else
win_skip("SYSTEM_MANDATORY_LABEL not supported\n");
@@ -7467,6 +7736,116 @@ static void test_child_token_sd(void)
HeapFree(GetProcessHeap(), 0, sd);
}
+static void test_child_token_sd_restricted(void)
+{
+ static SID high_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
+ {SECURITY_MANDATORY_HIGH_RID}};
+ SYSTEM_MANDATORY_LABEL_ACE *ace_label;
+ BOOL ret, present, defaulted;
+ TOKEN_MANDATORY_LABEL *tml;
+ BYTE buffer_integrity[64];
+ SECURITY_DESCRIPTOR *sd;
+ HANDLE token;
+ DWORD size;
+ ACL *acl;
+
+ if (!pAddMandatoryAce)
+ {
+ win_skip("SYSTEM_MANDATORY_LABEL not supported\n");
+ return;
+ }
+
+ ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token);
+ ok(ret, "OpenProcessToken failed with error %u\n", GetLastError());
+
+ ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError());
+
+ sd = HeapAlloc(GetProcessHeap(), 0, size);
+ ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd, size, &size);
+ ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
+
+ acl = NULL;
+ present = FALSE;
+ defaulted = TRUE;
+ ret = GetSecurityDescriptorSacl(sd, &present, &acl, &defaulted);
+ ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
+ ok(present, "SACL not present\n");
+ ok(acl && acl != (void *)0xdeadbeef, "Got invalid SACL\n");
+ ok(!defaulted, "SACL defaulted\n");
+ ok(acl->AceCount == 1, "Expected exactly one ACE\n");
+ ret = pGetAce(acl, 0, (void **)&ace_label);
+ ok(ret, "GetAce failed with error %u\n", GetLastError());
+ ok(ace_label->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE,
+ "Unexpected ACE type %#x\n", ace_label->Header.AceType);
+ ok(EqualSid(&ace_label->SidStart, &high_level),
+ "Expected high integrity level\n");
+
+ memset(buffer_integrity, 0, sizeof(buffer_integrity));
+ ret = GetTokenInformation(token, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size);
+ ok(ret, "GetTokenInformation failed with error %u\n", GetLastError());
+ tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity;
+ ok(EqualSid(tml->Label.Sid, &high_level), "Expected high integrity level\n");
+
+ HeapFree(GetProcessHeap(), 0, sd);
+}
+
+static void test_child_token_sd_medium(void)
+{
+ static SID medium_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
+ {SECURITY_MANDATORY_MEDIUM_RID}};
+ SYSTEM_MANDATORY_LABEL_ACE *ace_label;
+ BOOL ret, present, defaulted;
+ TOKEN_MANDATORY_LABEL *tml;
+ BYTE buffer_integrity[64];
+ SECURITY_DESCRIPTOR *sd;
+ HANDLE token;
+ DWORD size;
+ ACL *acl;
+
+ if (!pAddMandatoryAce)
+ {
+ win_skip("SYSTEM_MANDATORY_LABEL not supported\n");
+ return;
+ }
+
+ ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token);
+ ok(ret, "OpenProcessToken failed with error %u\n", GetLastError());
+
+ ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError());
+
+ sd = HeapAlloc(GetProcessHeap(), 0, size);
+ ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd, size, &size);
+ ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
+
+ acl = NULL;
+ present = FALSE;
+ defaulted = TRUE;
+ ret = GetSecurityDescriptorSacl(sd, &present, &acl, &defaulted);
+ ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
+ ok(present, "SACL not present\n");
+ ok(acl && acl != (void *)0xdeadbeef, "Got invalid SACL\n");
+ ok(!defaulted, "SACL defaulted\n");
+ ok(acl->AceCount == 1, "Expected exactly one ACE\n");
+ ret = pGetAce(acl, 0, (void **)&ace_label);
+ ok(ret, "GetAce failed with error %u\n", GetLastError());
+ ok(ace_label->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE,
+ "Unexpected ACE type %#x\n", ace_label->Header.AceType);
+ todo_wine ok(EqualSid(&ace_label->SidStart, &medium_level),
+ "Expected medium integrity level\n");
+
+ memset(buffer_integrity, 0, sizeof(buffer_integrity));
+ ret = GetTokenInformation(token, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size);
+ ok(ret, "GetTokenInformation failed with error %u\n", GetLastError());
+ tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity;
+ todo_wine ok(EqualSid(tml->Label.Sid, &medium_level), "Expected medium integrity level\n");
+
+ HeapFree(GetProcessHeap(), 0, sd);
+}
+
static void test_GetExplicitEntriesFromAclW(void)
{
static const WCHAR wszCurrentUser[] = { 'C','U','R','R','E','N','T','_','U','S','E','R','\0'};
@@ -7653,6 +8032,10 @@ START_TEST(security)
{
if (!strcmp(myARGV[2], "test_token_sd"))
test_child_token_sd();
+ else if (!strcmp(myARGV[2], "test_token_sd_restricted"))
+ test_child_token_sd_restricted();
+ else if (!strcmp(myARGV[2], "test_token_sd_medium"))
+ test_child_token_sd_medium();
else
test_process_security_child();
return;
--
2.13.1

View File

@@ -0,0 +1,136 @@
From 4b428e09733605affb987d369f56ec09d2525858 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 5 Aug 2017 00:26:03 +0200
Subject: server: Implement token elevation information.
---
dlls/ntdll/nt.c | 16 ++++++++++++----
server/protocol.def | 8 ++++++++
server/token.c | 22 +++++++++++++++++++---
3 files changed, 39 insertions(+), 7 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index 5822dec9b15..dda6cabe1cf 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -597,18 +597,26 @@ NTSTATUS WINAPI NtQueryInformationToken(
SERVER_END_REQ;
break;
case TokenElevationType:
+ SERVER_START_REQ( get_token_elevation_type )
{
TOKEN_ELEVATION_TYPE *elevation_type = tokeninfo;
- FIXME("QueryInformationToken( ..., TokenElevationType, ...) semi-stub\n");
- *elevation_type = TokenElevationTypeFull;
+ req->handle = wine_server_obj_handle( token );
+ status = wine_server_call( req );
+ if (status == STATUS_SUCCESS)
+ *elevation_type = reply->elevation;
}
+ SERVER_END_REQ;
break;
case TokenElevation:
+ SERVER_START_REQ( get_token_elevation_type )
{
TOKEN_ELEVATION *elevation = tokeninfo;
- FIXME("QueryInformationToken( ..., TokenElevation, ...) semi-stub\n");
- elevation->TokenIsElevated = TRUE;
+ req->handle = wine_server_obj_handle( token );
+ status = wine_server_call( req );
+ if (status == STATUS_SUCCESS)
+ elevation->TokenIsElevated = (reply->elevation == TokenElevationTypeFull);
}
+ SERVER_END_REQ;
break;
case TokenSessionId:
{
diff --git a/server/protocol.def b/server/protocol.def
index b3dce66eb9c..33f1d5f0ab8 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3673,6 +3673,14 @@ struct handle_info
@END
+/* Get elevation level of token */
+@REQ(get_token_elevation_type)
+ obj_handle_t handle; /* handle to the object */
+@REPLY
+ unsigned int elevation; /* elevation level */
+@END
+
+
/* Create I/O completion port */
@REQ(create_completion)
unsigned int access; /* desired access to a port */
diff --git a/server/token.c b/server/token.c
index 7ab0f634c05..6a1085bae12 100644
--- a/server/token.c
+++ b/server/token.c
@@ -126,6 +126,7 @@ struct token
ACL *default_dacl; /* the default DACL to assign to objects created by this user */
TOKEN_SOURCE source; /* source of the token */
int impersonation_level; /* impersonation level this token is capable of if non-primary token */
+ TOKEN_ELEVATION_TYPE elevation; /* elevation level */
};
struct privilege
@@ -566,7 +567,7 @@ static struct token *create_token( unsigned primary, const SID *user,
const LUID_AND_ATTRIBUTES *privs, unsigned int priv_count,
const ACL *default_dacl, TOKEN_SOURCE source,
const luid_t *modified_id,
- int impersonation_level )
+ int impersonation_level, TOKEN_ELEVATION_TYPE elevation )
{
struct token *token = alloc_object( &token_ops );
if (token)
@@ -588,6 +589,7 @@ static struct token *create_token( unsigned primary, const SID *user,
token->impersonation_level = impersonation_level;
token->default_dacl = NULL;
token->primary_group = NULL;
+ token->elevation = elevation;
/* copy user */
token->user = memdup( user, security_sid_len( user ));
@@ -700,7 +702,8 @@ struct token *token_duplicate( struct token *src_token, unsigned primary,
token = create_token( primary, src_token->user, NULL, 0,
NULL, 0, src_token->default_dacl,
src_token->source, modified_id,
- impersonation_level );
+ impersonation_level,
+ src_token->elevation );
if (!token) return token;
/* copy groups */
@@ -904,7 +907,7 @@ struct token *token_create_admin( void )
static const TOKEN_SOURCE admin_source = {"SeMgr", {0, 0}};
token = create_token( TRUE, user_sid, admin_groups, sizeof(admin_groups)/sizeof(admin_groups[0]),
admin_privs, sizeof(admin_privs)/sizeof(admin_privs[0]), default_dacl,
- admin_source, NULL, -1 );
+ admin_source, NULL, -1, TokenElevationTypeFull );
/* we really need a primary group */
assert( token->primary_group );
}
@@ -1652,6 +1655,19 @@ DECL_HANDLER(get_token_statistics)
}
}
+DECL_HANDLER(get_token_elevation_type)
+{
+ struct token *token;
+
+ if ((token = (struct token *)get_handle_obj( current->process, req->handle,
+ TOKEN_QUERY,
+ &token_ops )))
+ {
+ reply->elevation = token->elevation;
+ release_object( token );
+ }
+}
+
DECL_HANDLER(get_token_default_dacl)
{
struct token *token;
--
2.13.1

View File

@@ -0,0 +1,81 @@
From 7e73f449d158f0d6a6b6b421d073dbaf1741e1c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Mon, 7 Aug 2017 02:22:11 +0200
Subject: server: Correctly treat zero access mask in duplicate_token
wineserver call.
---
dlls/advapi32/tests/security.c | 14 +++++++-------
server/token.c | 3 ++-
2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index 4a03db27e69..f1a64e29dea 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -7438,7 +7438,7 @@ static void test_token_security_descriptor(void)
ret = DuplicateTokenEx(token4, 0, NULL, SecurityImpersonation, TokenImpersonation, &token5);
ok(ret, "DuplicateTokenEx failed with error %u\n", GetLastError());
ret = SetThreadToken(NULL, token5);
- todo_wine ok(ret, "SetThreadToken failed with error %u\n", GetLastError());
+ ok(ret, "SetThreadToken failed with error %u\n", GetLastError());
CloseHandle(token4);
/* Restrict current process token while impersonating a medium integrity token */
@@ -7503,16 +7503,16 @@ static void test_token_security_descriptor(void)
size = 0;
ret = GetKernelObjectSecurity(token6, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
- todo_wine ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
"Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError());
sd3 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
ret = GetKernelObjectSecurity(token6, LABEL_SECURITY_INFORMATION, sd3, size, &size);
- todo_wine ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
+ ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
sacl = NULL;
ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted);
- todo_wine ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
+ ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
todo_wine ok(present, "No SACL in the security descriptor\n");
todo_wine ok(sacl != NULL, "NULL SACL in the security descriptor\n");
@@ -7606,16 +7606,16 @@ static void test_token_security_descriptor(void)
size = 0;
ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
- todo_wine ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
"Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError());
sd3 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, sd3, size, &size);
- todo_wine ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
+ ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
sacl = NULL;
ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted);
- todo_wine ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
+ ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
todo_wine ok(present, "No SACL in the security descriptor\n");
todo_wine ok(sacl != NULL, "NULL SACL in the security descriptor\n");
diff --git a/server/token.c b/server/token.c
index 6a1085bae12..292e1df80fd 100644
--- a/server/token.c
+++ b/server/token.c
@@ -1376,7 +1376,8 @@ DECL_HANDLER(duplicate_token)
struct token *token = token_duplicate( src_token, req->primary, req->impersonation_level, sd, NULL, 0, NULL, 0 );
if (token)
{
- reply->new_handle = alloc_handle_no_access_check( current->process, token, req->access, objattr->attributes );
+ unsigned int access = req->access ? req->access : get_handle_access( current->process, req->handle );
+ reply->new_handle = alloc_handle_no_access_check( current->process, token, access, objattr->attributes );
release_object( token );
}
release_object( src_token );
--
2.13.1

View File

@@ -0,0 +1,153 @@
From 3092c9de3ac89e77a139db97a33b8b15f9a12eac Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Mon, 7 Aug 2017 02:28:35 +0200
Subject: server: Implement token integrity level.
---
dlls/ntdll/nt.c | 23 ++++++++++++++---------
server/protocol.def | 7 +++++++
server/token.c | 30 +++++++++++++++++++++++++++---
3 files changed, 48 insertions(+), 12 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index dda6cabe1cf..6f2b24e6ba4 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -372,7 +372,7 @@ NTSTATUS WINAPI NtQueryInformationToken(
0, /* TokenAccessInformation */
0, /* TokenVirtualizationAllowed */
0, /* TokenVirtualizationEnabled */
- sizeof(TOKEN_MANDATORY_LABEL) + sizeof(SID), /* TokenIntegrityLevel [sizeof(SID) includes one SubAuthority] */
+ 0, /* TokenIntegrityLevel */
0, /* TokenUIAccess */
0, /* TokenMandatoryPolicy */
sizeof(TOKEN_GROUPS) + sizeof(logon_sid), /* TokenLogonSid */
@@ -625,18 +625,23 @@ NTSTATUS WINAPI NtQueryInformationToken(
}
break;
case TokenIntegrityLevel:
+ SERVER_START_REQ( get_token_integrity )
{
- /* report always "S-1-16-12288" (high mandatory level) for now */
- static const SID high_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
- {SECURITY_MANDATORY_HIGH_RID}};
-
TOKEN_MANDATORY_LABEL *tml = tokeninfo;
- PSID psid = tml + 1;
+ PSID sid = tml + 1;
+ DWORD sid_len = tokeninfolength < sizeof(*tml) ? 0 : tokeninfolength - sizeof(*tml);
- tml->Label.Sid = psid;
- tml->Label.Attributes = SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED;
- memcpy(psid, &high_level, sizeof(SID));
+ req->handle = wine_server_obj_handle( token );
+ wine_server_set_reply( req, sid, sid_len );
+ status = wine_server_call( req );
+ if (retlen) *retlen = reply->sid_len + sizeof(*tml);
+ if (status == STATUS_SUCCESS)
+ {
+ tml->Label.Sid = sid;
+ tml->Label.Attributes = SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED;
+ }
}
+ SERVER_END_REQ;
break;
case TokenAppContainerSid:
{
diff --git a/server/protocol.def b/server/protocol.def
index 33f1d5f0ab8..ac2e2242511 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3424,6 +3424,13 @@ enum caret_state
VARARG(sid,SID); /* the sid specified by which_sid from the token */
@END
+@REQ(get_token_integrity)
+ obj_handle_t handle; /* handle to the token */
+@REPLY
+ data_size_t sid_len; /* length needed to store sid */
+ VARARG(sid,SID); /* the integrity sid */
+@END
+
@REQ(get_token_groups)
obj_handle_t handle; /* handle to the token */
@REPLY
diff --git a/server/token.c b/server/token.c
index 292e1df80fd..8d2de6ab58e 100644
--- a/server/token.c
+++ b/server/token.c
@@ -127,6 +127,7 @@ struct token
TOKEN_SOURCE source; /* source of the token */
int impersonation_level; /* impersonation level this token is capable of if non-primary token */
TOKEN_ELEVATION_TYPE elevation; /* elevation level */
+ const SID *integrity; /* token integrity */
};
struct privilege
@@ -567,7 +568,8 @@ static struct token *create_token( unsigned primary, const SID *user,
const LUID_AND_ATTRIBUTES *privs, unsigned int priv_count,
const ACL *default_dacl, TOKEN_SOURCE source,
const luid_t *modified_id,
- int impersonation_level, TOKEN_ELEVATION_TYPE elevation )
+ int impersonation_level, TOKEN_ELEVATION_TYPE elevation,
+ const SID *integrity )
{
struct token *token = alloc_object( &token_ops );
if (token)
@@ -648,6 +650,7 @@ static struct token *create_token( unsigned primary, const SID *user,
}
token->source = source;
+ token->integrity = integrity;
}
return token;
}
@@ -703,7 +706,8 @@ struct token *token_duplicate( struct token *src_token, unsigned primary,
NULL, 0, src_token->default_dacl,
src_token->source, modified_id,
impersonation_level,
- src_token->elevation );
+ src_token->elevation,
+ src_token->integrity );
if (!token) return token;
/* copy groups */
@@ -907,7 +911,7 @@ struct token *token_create_admin( void )
static const TOKEN_SOURCE admin_source = {"SeMgr", {0, 0}};
token = create_token( TRUE, user_sid, admin_groups, sizeof(admin_groups)/sizeof(admin_groups[0]),
admin_privs, sizeof(admin_privs)/sizeof(admin_privs[0]), default_dacl,
- admin_source, NULL, -1, TokenElevationTypeFull );
+ admin_source, NULL, -1, TokenElevationTypeFull, &high_label_sid );
/* we really need a primary group */
assert( token->primary_group );
}
@@ -1550,6 +1554,26 @@ DECL_HANDLER(get_token_sid)
}
}
+/* retrieves the integrity sid */
+DECL_HANDLER(get_token_integrity)
+{
+ struct token *token;
+
+ reply->sid_len = 0;
+
+ if ((token = (struct token *)get_handle_obj( current->process, req->handle,
+ TOKEN_QUERY,
+ &token_ops )))
+ {
+ reply->sid_len = security_sid_len( token->integrity );
+ if (reply->sid_len <= get_reply_max_size())
+ set_reply_data( token->integrity, reply->sid_len );
+ else
+ set_error( STATUS_BUFFER_TOO_SMALL );
+ release_object( token );
+ }
+}
+
/* retrieves the groups that the user represented by the token belongs to */
DECL_HANDLER(get_token_groups)
{
--
2.13.1

View File

@@ -0,0 +1,46 @@
From 77c9e6c6f408a2b59a79f3773a379a43b6994f2c Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sun, 6 Aug 2017 15:16:33 +0200
Subject: server: Use all group attributes in create_token.
---
server/token.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/server/token.c b/server/token.c
index 8d2de6ab58e..e61fe97bfa0 100644
--- a/server/token.c
+++ b/server/token.c
@@ -613,13 +613,13 @@ static struct token *create_token( unsigned primary, const SID *user,
return NULL;
}
memcpy( &group->sid, groups[i].Sid, security_sid_len( groups[i].Sid ));
- group->enabled = TRUE;
- group->def = TRUE;
- group->logon = (groups[i].Attributes & SE_GROUP_LOGON_ID) != 0;
group->mandatory = (groups[i].Attributes & SE_GROUP_MANDATORY) != 0;
- group->owner = (groups[i].Attributes & SE_GROUP_OWNER) != 0;
- group->resource = FALSE;
- group->deny_only = FALSE;
+ group->def = (groups[i].Attributes & SE_GROUP_ENABLED_BY_DEFAULT) != 0;
+ group->enabled = (groups[i].Attributes & SE_GROUP_ENABLED) != 0;
+ group->owner = (groups[i].Attributes & SE_GROUP_OWNER) != 0;
+ group->deny_only = (groups[i].Attributes & SE_GROUP_USE_FOR_DENY_ONLY) != 0;
+ group->logon = (groups[i].Attributes & SE_GROUP_LOGON_ID) != 0;
+ group->resource = (groups[i].Attributes & SE_GROUP_RESOURCE) != 0;
list_add_tail( &token->groups, &group->entry );
/* Use first owner capable group as an owner */
if (!token->primary_group && group->owner)
@@ -1628,8 +1628,8 @@ DECL_HANDLER(get_token_groups)
if (group->enabled) *attr_ptr |= SE_GROUP_ENABLED;
if (group->owner) *attr_ptr |= SE_GROUP_OWNER;
if (group->deny_only) *attr_ptr |= SE_GROUP_USE_FOR_DENY_ONLY;
- if (group->resource) *attr_ptr |= SE_GROUP_RESOURCE;
if (group->logon) *attr_ptr |= SE_GROUP_LOGON_ID;
+ if (group->resource) *attr_ptr |= SE_GROUP_RESOURCE;
memcpy(sid_ptr, &group->sid, security_sid_len( &group->sid ));
--
2.13.1

View File

@@ -0,0 +1,218 @@
From fcceb1b0f1aee4ca4fe7362a4e87c4c94456f2ec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 5 Aug 2017 01:45:29 +0200
Subject: ntdll: Add function to create new tokens for elevation purposes.
---
dlls/ntdll/ntdll.spec | 3 ++
dlls/ntdll/ntdll_misc.h | 3 ++
dlls/ntdll/process.c | 18 +++++++++++
server/protocol.def | 8 +++++
server/security.h | 1 +
server/token.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 117 insertions(+)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 275fda57970..8f5357b944c 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -1487,6 +1487,9 @@
@ cdecl wine_server_send_fd(long)
@ cdecl __wine_make_process_system()
+# Token
+@ cdecl __wine_create_default_token(long)
+
# Version
@ cdecl wine_get_version() NTDLL_wine_get_version
@ cdecl wine_get_patches() NTDLL_wine_get_patches
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index c6c60090d10..e64cb9e75a3 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -82,6 +82,9 @@ extern void fill_cpu_info(void) DECLSPEC_HIDDEN;
extern void *grow_virtual_heap( HANDLE handle, SIZE_T *size ) DECLSPEC_HIDDEN;
extern void heap_set_debug_flags( HANDLE handle ) DECLSPEC_HIDDEN;
+/* token */
+extern HANDLE CDECL __wine_create_default_token(BOOL admin);
+
/* server support */
extern timeout_t server_start_time DECLSPEC_HIDDEN;
extern unsigned int server_cpus DECLSPEC_HIDDEN;
diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c
index f2eb09c142f..ba4613e87b3 100644
--- a/dlls/ntdll/process.c
+++ b/dlls/ntdll/process.c
@@ -99,6 +99,24 @@ HANDLE CDECL __wine_make_process_system(void)
return ret;
}
+/***********************************************************************
+ * __wine_create_default_token (NTDLL.@)
+ *
+ * Creates a default limited or admin token.
+ */
+HANDLE CDECL __wine_create_default_token( BOOL admin )
+{
+ HANDLE ret = NULL;
+ SERVER_START_REQ( create_token )
+ {
+ req->admin = admin;
+ if (!wine_server_call( req ))
+ ret = wine_server_ptr_handle( reply->token );
+ }
+ SERVER_END_REQ;
+ return ret;
+}
+
static UINT process_error_mode;
#define UNIMPLEMENTED_INFO_CLASS(c) \
diff --git a/server/protocol.def b/server/protocol.def
index ac2e2242511..300f23fb9b6 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3688,6 +3688,14 @@ struct handle_info
@END
+/* Create a new token */
+@REQ(create_token)
+ unsigned int admin; /* admin or limited token */
+@REPLY
+ obj_handle_t token; /* handle for new token */
+@END
+
+
/* Create I/O completion port */
@REQ(create_completion)
unsigned int access; /* desired access to a port */
diff --git a/server/security.h b/server/security.h
index 6c337143c3d..21e90ccf23f 100644
--- a/server/security.h
+++ b/server/security.h
@@ -49,6 +49,7 @@ extern const PSID security_builtin_users_sid;
extern const PSID security_builtin_admins_sid;
extern const PSID security_domain_users_sid;
extern const PSID security_high_label_sid;
+extern const PSID security_medium_label_sid;
/* token functions */
diff --git a/server/token.c b/server/token.c
index e61fe97bfa0..c9d36a5b4f3 100644
--- a/server/token.c
+++ b/server/token.c
@@ -71,6 +71,7 @@ static const SID anonymous_logon_sid = { SID_REVISION, 1, { SECURITY_NT_AUTHORIT
static const SID authenticated_user_sid = { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } };
static const SID local_system_sid = { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } };
static const SID high_label_sid = { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY }, { SECURITY_MANDATORY_HIGH_RID } };
+static const SID medium_label_sid = { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY }, { SECURITY_MANDATORY_MEDIUM_RID } };
static const struct /* same fields as struct SID */
{
BYTE Revision;
@@ -110,6 +111,7 @@ const PSID security_builtin_admins_sid = (PSID)&builtin_admins_sid;
const PSID security_builtin_users_sid = (PSID)&builtin_users_sid;
const PSID security_domain_users_sid = (PSID)&domain_users_sid;
const PSID security_high_label_sid = (PSID)&high_label_sid;
+const PSID security_medium_label_sid = (PSID)&medium_label_sid;
static luid_t prev_luid_value = { 1000, 0 };
@@ -924,6 +926,64 @@ struct token *token_create_admin( void )
return token;
}
+static struct token *token_create_limited( void )
+{
+ struct token *token = NULL;
+ static const SID_IDENTIFIER_AUTHORITY nt_authority = { SECURITY_NT_AUTHORITY };
+ static const unsigned int alias_admins_subauth[] = { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS };
+ static const unsigned int alias_users_subauth[] = { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS };
+ /* on Windows, this value changes every time the user logs on */
+ static const unsigned int logon_subauth[] = { SECURITY_LOGON_IDS_RID, 0, 1 /* FIXME: should be randomly generated when tokens are inherited by new processes */ };
+ PSID alias_admins_sid;
+ PSID alias_users_sid;
+ PSID logon_sid;
+ const SID *user_sid = security_unix_uid_to_sid( getuid() );
+ ACL *default_dacl = create_default_dacl( user_sid );
+
+ alias_admins_sid = security_sid_alloc( &nt_authority, sizeof(alias_admins_subauth)/sizeof(alias_admins_subauth[0]),
+ alias_admins_subauth );
+ alias_users_sid = security_sid_alloc( &nt_authority, sizeof(alias_users_subauth)/sizeof(alias_users_subauth[0]),
+ alias_users_subauth );
+ logon_sid = security_sid_alloc( &nt_authority, sizeof(logon_subauth)/sizeof(logon_subauth[0]),
+ logon_subauth );
+
+ if (alias_admins_sid && alias_users_sid && logon_sid && default_dacl)
+ {
+ const LUID_AND_ATTRIBUTES user_privs[] =
+ {
+ { SeChangeNotifyPrivilege , SE_PRIVILEGE_ENABLED },
+ { SeShutdownPrivilege , 0 },
+ { SeUndockPrivilege , 0 },
+ };
+ /* note: we don't include non-builtin groups here for the user -
+ * telling us these is the job of a client-side program */
+ const SID_AND_ATTRIBUTES user_groups[] =
+ {
+ { security_world_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY },
+ { security_local_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY },
+ { security_interactive_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY },
+ { security_authenticated_user_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY },
+ { security_domain_users_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY|SE_GROUP_OWNER },
+ { alias_admins_sid, SE_GROUP_USE_FOR_DENY_ONLY },
+ { alias_users_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY },
+ { logon_sid, SE_GROUP_ENABLED|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_MANDATORY|SE_GROUP_LOGON_ID },
+ };
+ static const TOKEN_SOURCE admin_source = {"SeMgr", {0, 0}};
+ token = create_token( TRUE, user_sid, user_groups, sizeof(user_groups)/sizeof(user_groups[0]),
+ user_privs, sizeof(user_privs)/sizeof(user_privs[0]), default_dacl,
+ admin_source, NULL, -1, TokenElevationTypeLimited, &medium_label_sid );
+ /* we really need a primary group */
+ assert( token->primary_group );
+ }
+
+ free( logon_sid );
+ free( alias_admins_sid );
+ free( alias_users_sid );
+ free( default_dacl );
+
+ return token;
+}
+
static struct privilege *token_find_privilege( struct token *token, const LUID *luid, int enabled_only )
{
struct privilege *privilege;
@@ -1738,3 +1798,27 @@ DECL_HANDLER(set_token_default_dacl)
release_object( token );
}
}
+
+DECL_HANDLER(create_token)
+{
+ struct token *token;
+ PSID label;
+
+ if (req->admin)
+ {
+ token = token_create_admin();
+ label = security_high_label_sid;
+ }
+ else
+ {
+ token = token_create_limited();
+ label = security_medium_label_sid;
+ }
+
+ if (token)
+ {
+ if (token_assign_label( token, label ))
+ reply->token = alloc_handle( current->process, token, TOKEN_ALL_ACCESS, 0 );
+ release_object( token );
+ }
+}
--
2.13.1

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