[WINLOGON] Refactor the security management part

Refactor the security related code of Winlogon and move it to its own dedicated place, security.c. This includes code for preparation of security descriptors for window station and desktop objects when their created, helper functions which give allow access to such objects for the logged in user and whatnot.

==== DO NOTE ====
Currently new desktop security assignment fails because for whatever reason the system thinks the application desktop has no prior security even though a descriptor has been created for it before. See the FIXME comment on code for information.
This commit is contained in:
George Bișoc 2022-04-02 18:16:40 +02:00
parent 65a72fb527
commit f96c39f6b0
No known key found for this signature in database
GPG key ID: 688C4FBE25D7DEF6
5 changed files with 1414 additions and 376 deletions

View file

@ -11,6 +11,7 @@ list(APPEND SOURCE
rpcserver.c rpcserver.c
sas.c sas.c
screensaver.c screensaver.c
security.c
setup.c setup.c
shutdown.c shutdown.c
winlogon.c winlogon.c

View file

@ -428,87 +428,6 @@ PlayLogonSound(
CloseHandle(hThread); CloseHandle(hThread);
} }
static BOOL
AllowWinstaAccess(PWLSESSION Session)
{
BOOL bSuccess = FALSE;
DWORD dwIndex;
DWORD dwLength = 0;
PTOKEN_GROUPS ptg = NULL;
PSID psid;
TOKEN_STATISTICS Stats;
DWORD cbStats;
DWORD ret;
// Get required buffer size and allocate the TOKEN_GROUPS buffer.
if (!GetTokenInformation(Session->UserToken,
TokenGroups,
ptg,
0,
&dwLength))
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return FALSE;
ptg = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength);
if (ptg == NULL)
return FALSE;
}
// Get the token group information from the access token.
if (!GetTokenInformation(Session->UserToken,
TokenGroups,
ptg,
dwLength,
&dwLength))
{
goto Cleanup;
}
// Loop through the groups to find the logon SID.
for (dwIndex = 0; dwIndex < ptg->GroupCount; dwIndex++)
{
if ((ptg->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID)
== SE_GROUP_LOGON_ID)
{
psid = ptg->Groups[dwIndex].Sid;
break;
}
}
dwLength = GetLengthSid(psid);
if (!GetTokenInformation(Session->UserToken,
TokenStatistics,
&Stats,
sizeof(TOKEN_STATISTICS),
&cbStats))
{
WARN("Couldn't get Authentication id from user token!\n");
goto Cleanup;
}
AddAceToWindowStation(Session->InteractiveWindowStation, psid);
ret = SetWindowStationUser(Session->InteractiveWindowStation,
&Stats.AuthenticationId,
psid,
dwLength);
TRACE("SetWindowStationUser returned 0x%x\n", ret);
bSuccess = TRUE;
Cleanup:
// Free the buffer for the token groups.
if (ptg != NULL)
HeapFree(GetProcessHeap(), 0, (LPVOID)ptg);
return bSuccess;
}
static static
VOID VOID
RestoreAllConnections(PWLSESSION Session) RestoreAllConnections(PWLSESSION Session)
@ -633,7 +552,12 @@ HandleLogon(
goto cleanup; goto cleanup;
} }
AllowWinstaAccess(Session); /* Allow winsta and desktop access for this session */
if (!AllowAccessOnSession(Session))
{
WARN("WL: AllowAccessOnSession() failed to give winsta & desktop access for this session\n");
goto cleanup;
}
/* Connect remote resources */ /* Connect remote resources */
RestoreAllConnections(Session); RestoreAllConnections(Session);

File diff suppressed because it is too large Load diff

View file

@ -320,6 +320,41 @@ InitializeScreenSaver(IN OUT PWLSESSION Session);
VOID VOID
StartScreenSaver(IN PWLSESSION Session); StartScreenSaver(IN PWLSESSION Session);
/* security.c */
PSECURITY_DESCRIPTOR
ConvertToSelfRelative(
_In_ PSECURITY_DESCRIPTOR AbsoluteSd);
BOOL
CreateWinstaSecurity(
_Out_ PSECURITY_DESCRIPTOR *WinstaSd);
BOOL
CreateApplicationDesktopSecurity(
_Out_ PSECURITY_DESCRIPTOR *ApplicationDesktopSd);
BOOL
CreateWinlogonDesktopSecurity(
_Out_ PSECURITY_DESCRIPTOR *WinlogonDesktopSd);
BOOL
CreateScreenSaverSecurity(
_Out_ PSECURITY_DESCRIPTOR *ScreenSaverDesktopSd);
BOOL
AllowWinstaAccessToUser(
_In_ HWINSTA WinSta,
_In_ PSID LogonSid);
BOOL
AllowDesktopAccessToUser(
_In_ HDESK Desktop,
_In_ PSID LogonSid);
BOOL
AllowAccessOnSession(
_In_ PWLSESSION Session);
/* setup.c */ /* setup.c */
DWORD DWORD
GetSetupType(VOID); GetSetupType(VOID);
@ -364,12 +399,8 @@ BOOL
GinaInit(IN OUT PWLSESSION Session); GinaInit(IN OUT PWLSESSION Session);
BOOL BOOL
AddAceToWindowStation( CreateWindowStationAndDesktops(
IN HWINSTA WinSta, _Inout_ PWLSESSION Session);
IN PSID Sid);
BOOL
CreateWindowStationAndDesktops(IN OUT PWLSESSION Session);
VOID WINAPI WlxUseCtrlAltDel(HANDLE hWlx); VOID WINAPI WlxUseCtrlAltDel(HANDLE hWlx);

View file

@ -12,20 +12,6 @@
#include "winlogon.h" #include "winlogon.h"
#define DESKTOP_ALL (DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW | \
DESKTOP_CREATEMENU | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALRECORD | \
DESKTOP_JOURNALPLAYBACK | DESKTOP_ENUMERATE | DESKTOP_WRITEOBJECTS | \
DESKTOP_SWITCHDESKTOP | STANDARD_RIGHTS_REQUIRED)
#define WINSTA_ALL (WINSTA_ENUMDESKTOPS | WINSTA_READATTRIBUTES | \
WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | \
WINSTA_WRITEATTRIBUTES | WINSTA_ACCESSGLOBALATOMS | \
WINSTA_EXITWINDOWS | WINSTA_ENUMERATE | WINSTA_READSCREEN | \
STANDARD_RIGHTS_REQUIRED)
#define GENERIC_ACCESS (GENERIC_READ | GENERIC_WRITE | \
GENERIC_EXECUTE | GENERIC_ALL)
typedef struct _DIALOG_LIST_ENTRY typedef struct _DIALOG_LIST_ENTRY
{ {
LIST_ENTRY Entry; LIST_ENTRY Entry;
@ -938,293 +924,59 @@ GinaInit(
&Session->Gina.Context); &Session->Gina.Context);
} }
BOOL
AddAceToWindowStation(
IN HWINSTA WinSta,
IN PSID Sid)
{
DWORD AclSize;
SECURITY_INFORMATION SecurityInformation;
PACL pDefaultAcl = NULL;
PSECURITY_DESCRIPTOR WinstaSd = NULL;
PACCESS_ALLOWED_ACE Ace = NULL;
BOOL Ret = FALSE;
/* Allocate space for an ACL */
AclSize = sizeof(ACL)
+ 2 * (FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(Sid));
pDefaultAcl = HeapAlloc(GetProcessHeap(), 0, AclSize);
if (!pDefaultAcl)
{
ERR("WL: HeapAlloc() failed\n");
goto cleanup;
}
/* Initialize it */
if (!InitializeAcl(pDefaultAcl, AclSize, ACL_REVISION))
{
ERR("WL: InitializeAcl() failed (error %lu)\n", GetLastError());
goto cleanup;
}
/* Initialize new security descriptor */
WinstaSd = HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH);
if (!InitializeSecurityDescriptor(WinstaSd, SECURITY_DESCRIPTOR_REVISION))
{
ERR("WL: InitializeSecurityDescriptor() failed (error %lu)\n", GetLastError());
goto cleanup;
}
/* Allocate memory for access allowed ACE */
Ace = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ACCESS_ALLOWED_ACE)+
GetLengthSid(Sid) - sizeof(DWORD));
/* Create the first ACE for the window station */
Ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
Ace->Header.AceFlags = CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE;
Ace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(Sid) - sizeof(DWORD);
Ace->Mask = GENERIC_ACCESS;
/* Copy the sid */
if (!CopySid(GetLengthSid(Sid), &Ace->SidStart, Sid))
{
ERR("WL: CopySid() failed (error %lu)\n", GetLastError());
goto cleanup;
}
/* Add the first ACE */
if (!AddAce(pDefaultAcl, ACL_REVISION, MAXDWORD, (LPVOID)Ace, Ace->Header.AceSize))
{
ERR("WL: AddAce() failed (error %lu)\n", GetLastError());
goto cleanup;
}
/* Add the second ACE to the end of ACL */
Ace->Header.AceFlags = NO_PROPAGATE_INHERIT_ACE;
Ace->Mask = WINSTA_ALL;
if (!AddAce(pDefaultAcl, ACL_REVISION, MAXDWORD, (LPVOID)Ace, Ace->Header.AceSize))
{
ERR("WL: AddAce() failed (error %lu)\n", GetLastError());
goto cleanup;
}
/* Add ACL to winsta's security descriptor */
if (!SetSecurityDescriptorDacl(WinstaSd, TRUE, pDefaultAcl, FALSE))
{
ERR("WL: SetSecurityDescriptorDacl() failed (error %lu)\n", GetLastError());
goto cleanup;
}
/* Apply security to the window station */
SecurityInformation = DACL_SECURITY_INFORMATION;
if (!SetUserObjectSecurity(WinSta, &SecurityInformation, WinstaSd))
{
ERR("WL: SetUserObjectSecurity() failed (error %lu)\n", GetLastError());
goto cleanup;
}
/* Indicate success */
Ret = TRUE;
cleanup:
/* Free allocated stuff */
if (pDefaultAcl) HeapFree(GetProcessHeap(), 0, pDefaultAcl);
if (WinstaSd) HeapFree(GetProcessHeap(), 0, WinstaSd);
if (Ace) HeapFree(GetProcessHeap(), 0, Ace);
return Ret;
}
BOOL
AddAceToDesktop(
IN HDESK Desktop,
IN PSID WinlogonSid,
IN PSID UserSid)
{
DWORD AclSize;
SECURITY_INFORMATION SecurityInformation;
PACL Acl = NULL;
PSECURITY_DESCRIPTOR DesktopSd = NULL;
BOOL Ret = FALSE;
/* Allocate ACL */
AclSize = sizeof(ACL)
+ FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(WinlogonSid);
/* Take user's sid into account */
if (UserSid)
AclSize += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(UserSid);
Acl = HeapAlloc(GetProcessHeap(), 0, AclSize);
if (!Acl)
{
ERR("WL: HeapAlloc() failed\n");
goto cleanup;
}
/* Initialize ACL */
if (!InitializeAcl(Acl, AclSize, ACL_REVISION))
{
ERR("WL: InitializeAcl() failed (error %lu)\n", GetLastError());
goto cleanup;
}
/* Add full desktop access ACE for winlogon */
if (!AddAccessAllowedAce(Acl, ACL_REVISION, DESKTOP_ALL, WinlogonSid))
{
ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError());
goto cleanup;
}
/* Add full desktop access ACE for a user (if provided) */
if (UserSid && !AddAccessAllowedAce(Acl, ACL_REVISION, DESKTOP_ALL, UserSid))
{
ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError());
goto cleanup;
}
/* Initialize new security descriptor */
DesktopSd = HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH);
if (!InitializeSecurityDescriptor(DesktopSd, SECURITY_DESCRIPTOR_REVISION))
{
ERR("WL: InitializeSecurityDescriptor() failed (error %lu)\n", GetLastError());
goto cleanup;
}
/* Add ACL to the security descriptor */
if (!SetSecurityDescriptorDacl(DesktopSd, TRUE, Acl, FALSE))
{
ERR("WL: SetSecurityDescriptorDacl() failed (error %lu)\n", GetLastError());
goto cleanup;
}
/* Apply security to the window station */
SecurityInformation = DACL_SECURITY_INFORMATION;
if (!SetUserObjectSecurity(Desktop, &SecurityInformation, DesktopSd))
{
ERR("WL: SetUserObjectSecurity() failed (error %lu)\n", GetLastError());
goto cleanup;
}
/* Indicate success */
Ret = TRUE;
cleanup:
/* Free allocated stuff */
if (Acl) HeapFree(GetProcessHeap(), 0, Acl);
if (DesktopSd) HeapFree(GetProcessHeap(), 0, DesktopSd);
return Ret;
}
BOOL BOOL
CreateWindowStationAndDesktops( CreateWindowStationAndDesktops(
IN OUT PWLSESSION Session) _Inout_ PWLSESSION Session)
{ {
BYTE LocalSystemBuffer[SECURITY_MAX_SID_SIZE]; SECURITY_ATTRIBUTES WinstaSecurity;
BYTE InteractiveBuffer[SECURITY_MAX_SID_SIZE]; SECURITY_ATTRIBUTES ApplicationDesktopSecurity;
PSID pLocalSystemSid = (PSID)&LocalSystemBuffer; SECURITY_ATTRIBUTES WinlogonDesktopSecurity;
PSID pInteractiveSid = (PSID)InteractiveBuffer; SECURITY_ATTRIBUTES ScreenSaverDesktopSecurity;
DWORD SidSize, AclSize; PSECURITY_DESCRIPTOR WlWinstaSecurityDescriptor;
PACL pDefaultAcl = NULL; PSECURITY_DESCRIPTOR WlApplicationDesktopSecurityDescriptor;
PACL pUserDesktopAcl = NULL; PSECURITY_DESCRIPTOR WlWinlogonDesktopSecurityDescriptor;
SECURITY_DESCRIPTOR DefaultSecurityDescriptor; PSECURITY_DESCRIPTOR WlScreenSaverDesktopSecurityDescriptor;
SECURITY_ATTRIBUTES DefaultSecurity;
SECURITY_DESCRIPTOR UserDesktopSecurityDescriptor;
SECURITY_ATTRIBUTES UserDesktopSecurity;
BOOL ret = FALSE; BOOL ret = FALSE;
/* if (!CreateWinstaSecurity(&WlWinstaSecurityDescriptor))
* Prepare information for ACLs we will apply
*/
SidSize = SECURITY_MAX_SID_SIZE;
if (!CreateWellKnownSid(WinLocalSystemSid, NULL, pLocalSystemSid, &SidSize))
{ {
ERR("WL: CreateWellKnownSid() failed (error %lu)\n", GetLastError()); ERR("WL: Failed to create winsta security!\n");
goto cleanup; return ret;
} }
SidSize = SECURITY_MAX_SID_SIZE;
if (!CreateWellKnownSid(WinInteractiveSid, NULL, pInteractiveSid, &SidSize)) WinstaSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
WinstaSecurity.lpSecurityDescriptor = WlWinstaSecurityDescriptor;
WinstaSecurity.bInheritHandle = TRUE;
if (!CreateApplicationDesktopSecurity(&WlApplicationDesktopSecurityDescriptor))
{ {
ERR("WL: CreateWellKnownSid() failed (error %lu)\n", GetLastError()); ERR("WL: Failed to create application desktop security!\n");
goto cleanup; goto cleanup;
} }
AclSize = sizeof(ACL) ApplicationDesktopSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
+ FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(pLocalSystemSid) ApplicationDesktopSecurity.lpSecurityDescriptor = WlApplicationDesktopSecurityDescriptor;
+ FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(pInteractiveSid); ApplicationDesktopSecurity.bInheritHandle = TRUE;
pDefaultAcl = HeapAlloc(GetProcessHeap(), 0, AclSize);
pUserDesktopAcl = HeapAlloc(GetProcessHeap(), 0, AclSize); if (!CreateWinlogonDesktopSecurity(&WlWinlogonDesktopSecurityDescriptor))
if (!pDefaultAcl || !pUserDesktopAcl)
{ {
ERR("WL: HeapAlloc() failed\n"); ERR("WL: Failed to create winlogon desktop security!\n");
goto cleanup; goto cleanup;
} }
if (!InitializeAcl(pDefaultAcl, AclSize, ACL_REVISION) WinlogonDesktopSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
|| !InitializeAcl(pUserDesktopAcl, AclSize, ACL_REVISION)) WinlogonDesktopSecurity.lpSecurityDescriptor = WlWinlogonDesktopSecurityDescriptor;
WinlogonDesktopSecurity.bInheritHandle = FALSE;
if (!CreateScreenSaverSecurity(&WlScreenSaverDesktopSecurityDescriptor))
{ {
ERR("WL: InitializeAcl() failed (error %lu)\n", GetLastError()); ERR("WL: Failed to create winlogon desktop security!\n");
goto cleanup; goto cleanup;
} }
/* ScreenSaverDesktopSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
* Create default ACL (window station, winlogon desktop, screen saver desktop) ScreenSaverDesktopSecurity.lpSecurityDescriptor = WlScreenSaverDesktopSecurityDescriptor;
*/ ScreenSaverDesktopSecurity.bInheritHandle = TRUE;
if (!AddAccessAllowedAce(pDefaultAcl, ACL_REVISION, GENERIC_ALL, pLocalSystemSid)
|| !AddAccessAllowedAce(pDefaultAcl, ACL_REVISION, GENERIC_READ, pInteractiveSid))
{
ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError());
goto cleanup;
}
/*
* Create the default security descriptor
*/
if (!InitializeSecurityDescriptor(&DefaultSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION))
{
ERR("WL: InitializeSecurityDescriptor() failed (error %lu)\n", GetLastError());
goto cleanup;
}
if (!SetSecurityDescriptorDacl(&DefaultSecurityDescriptor, TRUE, pDefaultAcl, FALSE))
{
ERR("WL: SetSecurityDescriptorDacl() failed (error %lu)\n", GetLastError());
goto cleanup;
}
DefaultSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
DefaultSecurity.lpSecurityDescriptor = &DefaultSecurityDescriptor;
DefaultSecurity.bInheritHandle = TRUE;
/*
* Create user desktop ACL
*/
if (!AddAccessAllowedAce(pUserDesktopAcl, ACL_REVISION, GENERIC_ALL, pLocalSystemSid)
|| !AddAccessAllowedAce(pUserDesktopAcl, ACL_REVISION, GENERIC_ALL, pInteractiveSid))
{
ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError());
goto cleanup;
}
/*
* Create the user desktop security descriptor
*/
if (!InitializeSecurityDescriptor(&UserDesktopSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION))
{
ERR("WL: InitializeSecurityDescriptor() failed (error %lu)\n", GetLastError());
goto cleanup;
}
if (!SetSecurityDescriptorDacl(&UserDesktopSecurityDescriptor, TRUE, pUserDesktopAcl, FALSE))
{
ERR("WL: SetSecurityDescriptorDacl() failed (error %lu)\n", GetLastError());
goto cleanup;
}
UserDesktopSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
UserDesktopSecurity.lpSecurityDescriptor = &UserDesktopSecurityDescriptor;
UserDesktopSecurity.bInheritHandle = TRUE;
/* /*
* Create the interactive window station * Create the interactive window station
@ -1234,12 +986,13 @@ CreateWindowStationAndDesktops(
Session->InteractiveWindowStationName, Session->InteractiveWindowStationName,
0, 0,
MAXIMUM_ALLOWED, MAXIMUM_ALLOWED,
&DefaultSecurity); &WinstaSecurity);
if (!Session->InteractiveWindowStation) if (!Session->InteractiveWindowStation)
{ {
ERR("WL: Failed to create window station (%lu)\n", GetLastError()); ERR("WL: Failed to create window station (%lu)\n", GetLastError());
goto cleanup; goto cleanup;
} }
if (!SetProcessWindowStation(Session->InteractiveWindowStation)) if (!SetProcessWindowStation(Session->InteractiveWindowStation))
{ {
ERR("WL: SetProcessWindowStation() failed (error %lu)\n", GetLastError()); ERR("WL: SetProcessWindowStation() failed (error %lu)\n", GetLastError());
@ -1255,7 +1008,7 @@ CreateWindowStationAndDesktops(
NULL, NULL,
0, /* FIXME: Add DF_ALLOWOTHERACCOUNTHOOK flag? */ 0, /* FIXME: Add DF_ALLOWOTHERACCOUNTHOOK flag? */
MAXIMUM_ALLOWED, MAXIMUM_ALLOWED,
&UserDesktopSecurity); &ApplicationDesktopSecurity);
if (!Session->ApplicationDesktop) if (!Session->ApplicationDesktop)
{ {
ERR("WL: Failed to create Default desktop (%lu)\n", GetLastError()); ERR("WL: Failed to create Default desktop (%lu)\n", GetLastError());
@ -1271,7 +1024,7 @@ CreateWindowStationAndDesktops(
NULL, NULL,
0, 0,
MAXIMUM_ALLOWED, MAXIMUM_ALLOWED,
&DefaultSecurity); // FIXME: Must use restricted Winlogon-only security!! &WinlogonDesktopSecurity);
if (!Session->WinlogonDesktop) if (!Session->WinlogonDesktop)
{ {
ERR("WL: Failed to create Winlogon desktop (%lu)\n", GetLastError()); ERR("WL: Failed to create Winlogon desktop (%lu)\n", GetLastError());
@ -1287,7 +1040,7 @@ CreateWindowStationAndDesktops(
NULL, NULL,
0, 0,
MAXIMUM_ALLOWED, MAXIMUM_ALLOWED,
&DefaultSecurity); &ScreenSaverDesktopSecurity);
if(!Session->ScreenSaverDesktop) if(!Session->ScreenSaverDesktop)
{ {
ERR("WL: Failed to create Screen-Saver desktop (%lu)\n", GetLastError()); ERR("WL: Failed to create Screen-Saver desktop (%lu)\n", GetLastError());
@ -1332,8 +1085,23 @@ cleanup:
CloseWindowStation(Session->InteractiveWindowStation); CloseWindowStation(Session->InteractiveWindowStation);
Session->InteractiveWindowStation = NULL; Session->InteractiveWindowStation = NULL;
} }
if (WlWinstaSecurityDescriptor)
{
RtlFreeHeap(RtlGetProcessHeap(), 0, WlWinstaSecurityDescriptor);
}
if (WlApplicationDesktopSecurityDescriptor)
{
RtlFreeHeap(RtlGetProcessHeap(), 0, WlApplicationDesktopSecurityDescriptor);
}
if (WlWinlogonDesktopSecurityDescriptor)
{
RtlFreeHeap(RtlGetProcessHeap(), 0, WlWinlogonDesktopSecurityDescriptor);
}
if (WlScreenSaverDesktopSecurityDescriptor)
{
RtlFreeHeap(RtlGetProcessHeap(), 0, WlScreenSaverDesktopSecurityDescriptor);
}
} }
HeapFree(GetProcessHeap(), 0, pDefaultAcl);
HeapFree(GetProcessHeap(), 0, pUserDesktopAcl);
return ret; return ret;
} }