diff --git a/win32ss/CMakeLists.txt b/win32ss/CMakeLists.txt index a5efa7f9f16..0a7dd1492de 100644 --- a/win32ss/CMakeLists.txt +++ b/win32ss/CMakeLists.txt @@ -144,6 +144,7 @@ list(APPEND SOURCE user/ntuser/prop.c user/ntuser/scrollbar.c user/ntuser/scrollex.c + user/ntuser/security.c user/ntuser/session.c user/ntuser/shutdown.c user/ntuser/simplecall.c diff --git a/win32ss/gdi/ntgdi/gdidbg.c b/win32ss/gdi/ntgdi/gdidbg.c index 51de52670b8..2dbe30e69d5 100644 --- a/win32ss/gdi/ntgdi/gdidbg.c +++ b/win32ss/gdi/ntgdi/gdidbg.c @@ -87,6 +87,7 @@ DBG_CHANNEL DbgChannels[DbgChCount] = { {L"UserProcess", DbgChUserProcess}, {L"UserProp", DbgChUserProp}, {L"UserScrollbar", DbgChUserScrollbar}, + {L"UserSecurity", DbgChUserSecurity}, {L"UserShutdown", DbgChUserShutdown}, {L"UserSysparams", DbgChUserSysparams}, {L"UserTimer", DbgChUserTimer}, diff --git a/win32ss/pch.h b/win32ss/pch.h index 40fd8a7f861..60bdb37a8d6 100644 --- a/win32ss/pch.h +++ b/win32ss/pch.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/win32ss/user/ntuser/desktop.c b/win32ss/user/ntuser/desktop.c index 4b82da31ce9..fb8d6ed96cd 100644 --- a/win32ss/user/ntuser/desktop.c +++ b/win32ss/user/ntuser/desktop.c @@ -555,6 +555,7 @@ IntResolveDesktop( LUID ProcessLuid; USHORT StrSize; SIZE_T MemSize; + PSECURITY_DESCRIPTOR ServiceSD = NULL; POBJECT_ATTRIBUTES ObjectAttributes = NULL; PUNICODE_STRING ObjectName; UNICODE_STRING WinStaName, DesktopName; @@ -1012,16 +1013,29 @@ IntResolveDesktop( } ObjectName->Length = (USHORT)(wcslen(ObjectName->Buffer) * sizeof(WCHAR)); + /* + * Set up a security descriptor for the service. + * A service is generally based upon a desktop + * and a window station. The newly created window + * station and desktop will get this security descriptor + * if such objects weren't created before. + */ + Status = IntCreateServiceSecurity(&ServiceSD); + if (!NT_SUCCESS(Status)) + { + ERR("Failed to create a security descriptor for default window station, Status 0x%08lx\n", Status); + goto Quit; + } + /* * Create or open the non-interactive window station. * NOTE: The non-interactive window station handle is never inheritable. */ - // FIXME: Set security! InitializeObjectAttributes(ObjectAttributes, ObjectName, OBJ_CASE_INSENSITIVE | OBJ_OPENIF, NULL, - NULL); + ServiceSD); Status = IntCreateWindowStation(&hWinSta, ObjectAttributes, @@ -1054,8 +1068,11 @@ IntResolveDesktop( } ObjectName->Length = (USHORT)(wcslen(ObjectName->Buffer) * sizeof(WCHAR)); - /* NOTE: The non-interactive desktop handle is never inheritable. */ - // FIXME: Set security! + /* + * NOTE: The non-interactive desktop handle is never inheritable. + * The security descriptor is inherited from the newly created + * window station for the desktop. + */ InitializeObjectAttributes(ObjectAttributes, ObjectName, OBJ_CASE_INSENSITIVE | OBJ_OPENIF, @@ -1175,6 +1192,8 @@ Quit: { *phWinSta = hWinSta; *phDesktop = hDesktop; + + IntFreeSecurityBuffer(ServiceSD); return STATUS_SUCCESS; } else @@ -1191,6 +1210,9 @@ Quit: if (hWinSta) ObCloseHandle(hWinSta, UserMode); + if (ServiceSD) + IntFreeSecurityBuffer(ServiceSD); + SetLastNtError(Status); return Status; } diff --git a/win32ss/user/ntuser/desktop.h b/win32ss/user/ntuser/desktop.h index 5a7f4bca500..169cca1819e 100644 --- a/win32ss/user/ntuser/desktop.h +++ b/win32ss/user/ntuser/desktop.h @@ -55,32 +55,6 @@ typedef struct _DESKTOP #define DT_GWL_PROCESSID 0 #define DT_GWL_THREADID 4 -#define DESKTOP_READ STANDARD_RIGHTS_READ | \ - DESKTOP_ENUMERATE | \ - DESKTOP_READOBJECTS - -#define DESKTOP_WRITE STANDARD_RIGHTS_WRITE | \ - DESKTOP_CREATEMENU | \ - DESKTOP_CREATEWINDOW | \ - DESKTOP_HOOKCONTROL | \ - DESKTOP_JOURNALPLAYBACK | \ - DESKTOP_JOURNALRECORD | \ - DESKTOP_WRITEOBJECTS - -#define DESKTOP_EXECUTE STANDARD_RIGHTS_EXECUTE | \ - DESKTOP_SWITCHDESKTOP - -#define DESKTOP_ALL_ACCESS STANDARD_RIGHTS_REQUIRED | \ - DESKTOP_CREATEMENU | \ - DESKTOP_CREATEWINDOW | \ - DESKTOP_ENUMERATE | \ - DESKTOP_HOOKCONTROL | \ - DESKTOP_JOURNALPLAYBACK | \ - DESKTOP_JOURNALRECORD | \ - DESKTOP_READOBJECTS | \ - DESKTOP_SWITCHDESKTOP | \ - DESKTOP_WRITEOBJECTS - extern PDESKTOP gpdeskInputDesktop; extern PCLS DesktopWindowClass; extern HDC ScreenDeviceContext; diff --git a/win32ss/user/ntuser/security.c b/win32ss/user/ntuser/security.c new file mode 100644 index 00000000000..0286a76f5e3 --- /dev/null +++ b/win32ss/user/ntuser/security.c @@ -0,0 +1,493 @@ +/* + * PROJECT: ReactOS Win32k subsystem + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Security infrastructure of NTUSER component of Win32k + * COPYRIGHT: Copyright 2022 George Bișoc + */ + +/* INCLUDES ******************************************************************/ + +#include +DBG_DEFAULT_CHANNEL(UserSecurity); + +/* FUNCTIONS *****************************************************************/ + +/** + * @brief + * Opens an access token that represents the effective security + * context of the caller. The purpose of this function is to query + * the authenticated user that is associated with the security + * context. + * + * @return + * Returns a handle to an opened access token that represents the + * security context of the authenticated user, otherwise NULL. + */ +HANDLE +IntGetCurrentAccessToken(VOID) +{ + NTSTATUS Status; + HANDLE TokenHandle; + + /* + * Try acquiring the security context by opening + * the current thread (or so called impersonation) + * token. Such token represents the effective caller. + * Otherwise if the current thread does not have a + * token (hence no impersonation occurs) then open + * the token of main calling process instead. + */ + Status = ZwOpenThreadToken(ZwCurrentThread(), + TOKEN_QUERY, + FALSE, + &TokenHandle); + if (!NT_SUCCESS(Status)) + { + /* + * We might likely fail to open the thread + * token if the process isn't impersonating + * a client. In scenarios where the server + * isn't impersonating, open the main process + * token. + */ + if (Status == STATUS_NO_TOKEN) + { + TRACE("IntGetCurrentAccessToken(): The thread doesn't have a token, trying to open the process one...\n"); + Status = ZwOpenProcessToken(ZwCurrentProcess(), + TOKEN_QUERY, + &TokenHandle); + if (!NT_SUCCESS(Status)) + { + /* We failed opening process token as well, bail out... */ + ERR("IntGetCurrentAccessToken(): Failed to capture security context, couldn't open the process token (Status 0x%08lx)\n", Status); + return NULL; + } + + /* Return the opened token handle */ + return TokenHandle; + } + + /* There's a thread token but we couldn't open it so bail out */ + ERR("IntGetCurrentAccessToken(): Failed to capture security context, couldn't open the thread token (Status 0x%08lx)\n", Status); + return NULL; + } + + /* Return the opened token handle */ + return TokenHandle; +} + +/** + * @brief + * Allocates a buffer within UM (user mode) address + * space area. Such buffer is reserved for security + * purposes, such as allocating a buffer for a DACL + * or a security descriptor. + * + * @param[in] Length + * The length of the buffer that has to be allocated, + * in bytes. + * + * @return + * Returns a pointer to an allocated buffer whose + * contents are arbitrary. If the function fails, + * it means no pages are available to reserve for + * memory allocation for this buffer. + */ +PVOID +IntAllocateSecurityBuffer( + _In_ SIZE_T Length) +{ + NTSTATUS Status; + PVOID Buffer = NULL; + + /* Allocate the buffer in UM memory space */ + Status = ZwAllocateVirtualMemory(ZwCurrentProcess(), + &Buffer, + 0, + &Length, + MEM_COMMIT, + PAGE_READWRITE); + if (!NT_SUCCESS(Status)) + { + ERR("IntAllocateSecurityBuffer(): Failed to allocate the buffer (Status 0x%08lx)\n", Status); + return NULL; + } + + return Buffer; +} + +/** + * @brief + * Frees an allocated security buffer from UM + * memory that is been previously allocated by + * IntAllocateSecurityBuffer function. + * + * @param[in] Buffer + * A pointer to a buffer whose contents are + * arbitrary, to be freed from UM memory space. + * + * @return + * Nothing. + */ +VOID +IntFreeSecurityBuffer( + _In_ PVOID Buffer) +{ + SIZE_T Size = 0; + + ZwFreeVirtualMemory(ZwCurrentProcess(), + &Buffer, + &Size, + MEM_RELEASE); +} + +/** + * @brief + * Queries the authenticated user security identifier + * (SID) that is associated with the security context + * of the access token that is being opened. + * + * @param[out] User + * A pointer to the token user that contains the security + * identifier of the authenticated user. + * + * @return + * Returns STATUS_SUCCESS if the function has successfully + * queried the token user. STATUS_UNSUCCESSFUL is returned + * if the effective token of the caller couldn't be opened. + * STATUS_NO_MEMORY is returned if memory allocation for + * token user buffer has failed because of lack of necessary + * pages reserved for such allocation. A failure NTSTATUS + * code is returned otherwise. + * + * @remarks + * !!!WARNING!!! -- THE CALLER WHO QUERIES THE TOKEN USER IS + * RESPONSIBLE TO FREE THE ALLOCATED TOKEN USER BUFFER THAT IS + * BEING GIVEN. + */ +NTSTATUS +IntQueryUserSecurityIdentification( + _Out_ PTOKEN_USER *User) +{ + NTSTATUS Status; + PTOKEN_USER UserToken; + HANDLE Token; + ULONG BufferLength; + + /* Initialize the parameter */ + *User = NULL; + + /* Open the current token of the caller */ + Token = IntGetCurrentAccessToken(); + if (!Token) + { + ERR("IntQueryUserSecurityIdentification(): Couldn't capture the token!\n"); + return STATUS_UNSUCCESSFUL; + } + + /* + * Since we do not know what the length + * of the buffer size should be exactly to + * hold the user data, let the function + * tell us the size. + */ + Status = ZwQueryInformationToken(Token, + TokenUser, + NULL, + 0, + &BufferLength); + if (!NT_SUCCESS(Status) && Status == STATUS_BUFFER_TOO_SMALL) + { + /* + * Allocate some memory for the buffer + * based on the size that the function + * gave us. + */ + UserToken = IntAllocateSecurityBuffer(BufferLength); + if (!UserToken) + { + /* Bail out if we failed */ + ERR("IntQueryUserSecurityIdentification(): Couldn't allocate memory for the token user!\n"); + ZwClose(Token); + return STATUS_NO_MEMORY; + } + } + + /* Query the user now as we have plenty of space to hold it */ + Status = ZwQueryInformationToken(Token, + TokenUser, + UserToken, + BufferLength, + &BufferLength); + if (!NT_SUCCESS(Status)) + { + /* We failed, bail out */ + ERR("IntQueryUserSecurityIdentification(): Failed to query token user (Status 0x%08lx)\n", Status); + IntFreeSecurityBuffer(UserToken); + ZwClose(Token); + return Status; + } + + /* All good, give the buffer to the caller and close the captured token */ + *User = UserToken; + ZwClose(Token); + + return STATUS_SUCCESS; +} + +/** + * @brief + * Creates a security descriptor for the service. + * + * @param[out] ServiceSd + * A pointer to a newly allocated and created security + * descriptor for the service. + * + * @return + * Returns STATUS_SUCCESS if the function has successfully + * queried created the security descriptor. STATUS_NO_MEMORY + * is returned if memory allocation for security buffers because + * of a lack of needed pages to reserve for such allocation. A + * failure NTSTATUS code is returned otherwise. + */ +NTSTATUS +NTAPI +IntCreateServiceSecurity( + _Out_ PSECURITY_DESCRIPTOR *ServiceSd) +{ + NTSTATUS Status; + PACL ServiceDacl; + ULONG DaclSize; + ULONG RelSDSize; + SECURITY_DESCRIPTOR AbsSD; + PSECURITY_DESCRIPTOR RelSD; + PTOKEN_USER TokenUser; + + /* Initialize our local variables */ + RelSDSize = 0; + TokenUser = NULL; + RelSD = NULL; + ServiceDacl = NULL; + + /* Query the logged in user of the current security context (aka token) */ + Status = IntQueryUserSecurityIdentification(&TokenUser); + if (!TokenUser) + { + ERR("IntCreateServiceSecurity(): Failed to query the token user (Status 0x%08lx)\n", Status); + return Status; + } + + /* Initialize the absolute security descriptor */ + Status = RtlCreateSecurityDescriptor(&AbsSD, SECURITY_DESCRIPTOR_REVISION); + if (!NT_SUCCESS(Status)) + { + ERR("IntCreateServiceSecurity(): Failed to initialize absolute SD (Status 0x%08lx)\n", Status); + goto Quit; + } + + /* + * Build up the size of access control + * list (the DACL) necessary to initialize + * our ACL. The first two entry members + * of ACL field are the authenticated user + * that is associated with the security + * context of the token. Then here come + * the last two entries which are admins. + * Why the ACL contains two ACEs of the + * same SID is because of service access + * rights and ACE inheritance. + * + * A service is composed of a default + * desktop and window station upon + * booting the system. On Windows connection + * to such service is being made if no + * default window station and desktop handles + * were created before. The desktop and winsta + * objects grant access on a separate type basis. + * The user is granted full access to the window + * station first and then full access to the desktop. + * After that admins are granted specific rights + * separately, just like the user. Ultimately the + * ACEs that handle desktop rights management are + * inherited to the default desktop object so + * that there's no need to have a separate security + * descriptor for the desktop object alone. + */ + DaclSize = sizeof(ACL) + + sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(TokenUser->User.Sid) + + sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(TokenUser->User.Sid) + + sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(SeExports->SeAliasAdminsSid) + + sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(SeExports->SeAliasAdminsSid); + + /* Allocate memory for service DACL */ + ServiceDacl = IntAllocateSecurityBuffer(DaclSize); + if (!ServiceDacl) + { + ERR("IntCreateServiceSecurity(): Failed to allocate memory for service DACL!\n"); + Status = STATUS_NO_MEMORY; + goto Quit; + } + + /* Now create the DACL */ + Status = RtlCreateAcl(ServiceDacl, + DaclSize, + ACL_REVISION); + if (!NT_SUCCESS(Status)) + { + ERR("IntCreateServiceSecurity(): Failed to create service DACL (Status 0x%08lx)\n", Status); + goto Quit; + } + + /* + * The authenticated user is the ultimate and absolute + * king in charge of the created (or opened, whatever that is) + * window station object. + */ + Status = RtlAddAccessAllowedAceEx(ServiceDacl, + ACL_REVISION, + 0, + WINSTA_ACCESS_ALL, + TokenUser->User.Sid); + if (!NT_SUCCESS(Status)) + { + ERR("IntCreateServiceSecurity(): Failed to set up window station ACE for authenticated user (Status 0x%08lx)\n", Status); + goto Quit; + } + + /* + * The authenticated user also has the ultimate power + * over the desktop object as well. This ACE cannot + * be propagated but inherited. See the comment + * above regarding ACL size for further explanation. + */ + Status = RtlAddAccessAllowedAceEx(ServiceDacl, + ACL_REVISION, + INHERIT_ONLY_ACE | NO_PROPAGATE_INHERIT_ACE | OBJECT_INHERIT_ACE, + DESKTOP_ALL_ACCESS, + TokenUser->User.Sid); + if (!NT_SUCCESS(Status)) + { + ERR("IntCreateServiceSecurity(): Failed to set up desktop ACE for authenticated user (Status 0x%08lx)\n", Status); + goto Quit; + } + + /* + * Administrators can only enumerate window + * stations within a desktop. + */ + Status = RtlAddAccessAllowedAceEx(ServiceDacl, + ACL_REVISION, + 0, + WINSTA_ENUMERATE, + SeExports->SeAliasAdminsSid); + if (!NT_SUCCESS(Status)) + { + ERR("IntCreateServiceSecurity(): Failed to set up window station ACE for admins (Status 0x%08lx)\n", Status); + goto Quit; + } + + /* + * Administrators have some share of power over + * the desktop object. They can enumerate desktops, + * write and read upon the object itself. + */ + Status = RtlAddAccessAllowedAceEx(ServiceDacl, + ACL_REVISION, + INHERIT_ONLY_ACE | NO_PROPAGATE_INHERIT_ACE | OBJECT_INHERIT_ACE, + DESKTOP_ENUMERATE | DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS, + SeExports->SeAliasAdminsSid); + if (!NT_SUCCESS(Status)) + { + ERR("IntCreateServiceSecurity(): Failed to set up desktop ACE for admins (Status 0x%08lx)\n", Status); + goto Quit; + } + + /* Set the DACL to absolute SD */ + Status = RtlSetDaclSecurityDescriptor(&AbsSD, + TRUE, + ServiceDacl, + FALSE); + if (!NT_SUCCESS(Status)) + { + ERR("IntCreateServiceSecurity(): Failed to set up service DACL to absolute SD (Status 0x%08lx)\n", Status); + goto Quit; + } + + /* This descriptor is ownerless */ + Status = RtlSetOwnerSecurityDescriptor(&AbsSD, + NULL, + FALSE); + if (!NT_SUCCESS(Status)) + { + ERR("IntCreateServiceSecurity(): Failed to make the absolute SD as ownerless (Status 0x%08lx)\n", Status); + goto Quit; + } + + /* This descriptor has no primary group */ + Status = RtlSetGroupSecurityDescriptor(&AbsSD, + NULL, + FALSE); + if (!NT_SUCCESS(Status)) + { + ERR("IntCreateServiceSecurity(): Failed to make the absolute SD as having no primary group (Status 0x%08lx)\n", Status); + goto Quit; + } + + /* + * Determine how much size is needed to allocate + * memory space for our relative security descriptor. + */ + Status = RtlAbsoluteToSelfRelativeSD(&AbsSD, + NULL, + &RelSDSize); + if (Status != STATUS_BUFFER_TOO_SMALL) + { + ERR("IntCreateServiceSecurity(): Unexpected status code, must be STATUS_BUFFER_TOO_SMALL (Status 0x%08lx)\n", Status); + goto Quit; + } + + /* Allocate memory for this */ + RelSD = IntAllocateSecurityBuffer(RelSDSize); + if (!RelSD) + { + ERR("IntCreateServiceSecurity(): Failed to allocate memory pool for relative SD!\n"); + Status = STATUS_NO_MEMORY; + goto Quit; + } + + /* Convert the absolute SD into a relative one now */ + Status = RtlAbsoluteToSelfRelativeSD(&AbsSD, + RelSD, + &RelSDSize); + if (!NT_SUCCESS(Status)) + { + ERR("IntCreateServiceSecurity(): Failed to convert absolute SD to a relative one (Status 0x%08lx)\n", Status); + goto Quit; + } + + /* All good, give the SD to the caller */ + *ServiceSd = RelSD; + +Quit: + if (ServiceDacl) + { + IntFreeSecurityBuffer(ServiceDacl); + } + + if (TokenUser) + { + IntFreeSecurityBuffer(TokenUser); + } + + if (!NT_SUCCESS(Status)) + { + if (RelSD) + { + IntFreeSecurityBuffer(RelSD); + } + } + + return Status; +} + +/* EOF */ diff --git a/win32ss/user/ntuser/security.h b/win32ss/user/ntuser/security.h new file mode 100644 index 00000000000..f719beccc8a --- /dev/null +++ b/win32ss/user/ntuser/security.h @@ -0,0 +1,92 @@ +/* + * PROJECT: ReactOS Win32k subsystem + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Security infrastructure of NTUSER component of Win32k + * COPYRIGHT: Copyright 2022 George Bișoc + */ + +#pragma once + +// +// USER objects security rights +// + +/* Desktop access rights */ +#define DESKTOP_READ (STANDARD_RIGHTS_READ | \ + DESKTOP_ENUMERATE | \ + DESKTOP_READOBJECTS) + +#define DESKTOP_WRITE (STANDARD_RIGHTS_WRITE | \ + DESKTOP_CREATEMENU | \ + DESKTOP_CREATEWINDOW | \ + DESKTOP_HOOKCONTROL | \ + DESKTOP_JOURNALPLAYBACK | \ + DESKTOP_JOURNALRECORD | \ + DESKTOP_WRITEOBJECTS) + +#define DESKTOP_EXECUTE (STANDARD_RIGHTS_EXECUTE | \ + DESKTOP_SWITCHDESKTOP) + +#define DESKTOP_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | \ + DESKTOP_CREATEMENU | \ + DESKTOP_CREATEWINDOW | \ + DESKTOP_ENUMERATE | \ + DESKTOP_HOOKCONTROL | \ + DESKTOP_JOURNALPLAYBACK | \ + DESKTOP_JOURNALRECORD | \ + DESKTOP_READOBJECTS | \ + DESKTOP_SWITCHDESKTOP | \ + DESKTOP_WRITEOBJECTS) + +/* Window Station access rights */ +#define WINSTA_READ (STANDARD_RIGHTS_READ | \ + WINSTA_ENUMDESKTOPS | \ + WINSTA_ENUMERATE | \ + WINSTA_READATTRIBUTES | \ + WINSTA_READSCREEN) + +#define WINSTA_WRITE (STANDARD_RIGHTS_WRITE | \ + WINSTA_ACCESSCLIPBOARD | \ + WINSTA_CREATEDESKTOP | \ + WINSTA_WRITEATTRIBUTES) + +#define WINSTA_EXECUTE (STANDARD_RIGHTS_EXECUTE | \ + WINSTA_ACCESSGLOBALATOMS | \ + WINSTA_EXITWINDOWS) + +#define WINSTA_ACCESS_ALL (STANDARD_RIGHTS_REQUIRED | \ + WINSTA_ACCESSCLIPBOARD | \ + WINSTA_ACCESSGLOBALATOMS | \ + WINSTA_CREATEDESKTOP | \ + WINSTA_ENUMDESKTOPS | \ + WINSTA_ENUMERATE | \ + WINSTA_EXITWINDOWS | \ + WINSTA_READATTRIBUTES | \ + WINSTA_READSCREEN | \ + WINSTA_WRITEATTRIBUTES) + +// +// Function prototypes +// + +HANDLE +IntCaptureCurrentAccessToken(VOID); + +PVOID +IntAllocateSecurityBuffer( + _In_ SIZE_T Length); + +VOID +IntFreeSecurityBuffer( + _In_ PVOID Buffer); + +NTSTATUS +IntQueryUserSecurityIdentification( + _Out_ PTOKEN_USER *User); + +NTSTATUS +NTAPI +IntCreateServiceSecurity( + _Out_ PSECURITY_DESCRIPTOR *ServiceSd); + +/* EOF */ diff --git a/win32ss/user/ntuser/win32kdebug.h b/win32ss/user/ntuser/win32kdebug.h index 48175854401..2d9e1a95351 100644 --- a/win32ss/user/ntuser/win32kdebug.h +++ b/win32ss/user/ntuser/win32kdebug.h @@ -108,6 +108,7 @@ DbgChUserProcess, DbgChUserProp, DbgChUserScrollbar, + DbgChUserSecurity, DbgChUserShutdown, DbgChUserSysparams, DbgChUserThread, diff --git a/win32ss/user/ntuser/winsta.h b/win32ss/user/ntuser/winsta.h index 34720ad5093..b36aaa1ce55 100644 --- a/win32ss/user/ntuser/winsta.h +++ b/win32ss/user/ntuser/winsta.h @@ -47,32 +47,6 @@ extern HANDLE gpidLogon; extern HWND hwndSAS; extern UNICODE_STRING gustrWindowStationsDir; -#define WINSTA_READ STANDARD_RIGHTS_READ | \ - WINSTA_ENUMDESKTOPS | \ - WINSTA_ENUMERATE | \ - WINSTA_READATTRIBUTES | \ - WINSTA_READSCREEN - -#define WINSTA_WRITE STANDARD_RIGHTS_WRITE | \ - WINSTA_ACCESSCLIPBOARD | \ - WINSTA_CREATEDESKTOP | \ - WINSTA_WRITEATTRIBUTES - -#define WINSTA_EXECUTE STANDARD_RIGHTS_EXECUTE | \ - WINSTA_ACCESSGLOBALATOMS | \ - WINSTA_EXITWINDOWS - -#define WINSTA_ACCESS_ALL STANDARD_RIGHTS_REQUIRED | \ - WINSTA_ACCESSCLIPBOARD | \ - WINSTA_ACCESSGLOBALATOMS | \ - WINSTA_CREATEDESKTOP | \ - WINSTA_ENUMDESKTOPS | \ - WINSTA_ENUMERATE | \ - WINSTA_EXITWINDOWS | \ - WINSTA_READATTRIBUTES | \ - WINSTA_READSCREEN | \ - WINSTA_WRITEATTRIBUTES - CODE_SEG("INIT") NTSTATUS NTAPI @@ -125,4 +99,5 @@ BOOL FASTCALL UserSetProcessWindowStation(HWINSTA hWindowStation); BOOL FASTCALL co_IntInitializeDesktopGraphics(VOID); VOID FASTCALL IntEndDesktopGraphics(VOID); BOOL FASTCALL CheckWinstaAttributeAccess(ACCESS_MASK); + /* EOF */ diff --git a/win32ss/win32kp.h b/win32ss/win32kp.h index e8f401d35c2..9a6ae760005 100644 --- a/win32ss/win32kp.h +++ b/win32ss/win32kp.h @@ -81,6 +81,7 @@ typedef struct _DC *PDC; #include "user/ntuser/painting.h" #include "user/ntuser/class.h" #include "user/ntuser/window.h" +#include "user/ntuser/security.h" #include "user/ntuser/sysparams.h" #include "user/ntuser/prop.h" #include "user/ntuser/guicheck.h"