Sync with trunk head
[reactos.git] / base / system / winlogon / wlx.c
index 86065de..04a7ef0 100644 (file)
 
 WINE_DEFAULT_DEBUG_CHANNEL(winlogon);
 
+#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)
+
 /* GLOBALS ******************************************************************/
 
 static DLGPROC PreviousWindowProc;
@@ -23,7 +37,7 @@ static UINT_PTR IdTimer;
 
 /* FUNCTIONS ****************************************************************/
 
-static BOOL CALLBACK
+static INT_PTR CALLBACK
 DefaultWlxWindowProc(
        IN HWND hwndDlg,
        IN UINT uMsg,
@@ -39,7 +53,7 @@ DefaultWlxWindowProc(
        else if (uMsg == WM_INITDIALOG)
        {
                IdTimer = SetTimer(hwndDlg, 0, WLSession->DialogTimeout * 1000, NULL);
-               return PreviousWindowProc(hwndDlg, uMsg, wParam, lParam);;
+               return PreviousWindowProc(hwndDlg, uMsg, wParam, lParam);
        }
        else if (uMsg == WM_NCDESTROY)
        {
@@ -757,6 +771,185 @@ GinaInit(
                &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
 CreateWindowStationAndDesktops(
        IN OUT PWLSESSION Session)