[ADVAPI32]
[reactos.git] / reactos / dll / win32 / advapi32 / misc / logon.c
index 8cd1954..8dce3bf 100644 (file)
@@ -7,8 +7,6 @@
  */
 
 #include <advapi32.h>
-
-#include <wine/debug.h>
 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
 
 
@@ -132,9 +130,18 @@ CreateProcessAsUserW(HANDLE hToken,
 /*
  * @unimplemented
  */
-BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
-    LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
-    LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
+BOOL WINAPI
+CreateProcessWithLogonW(LPCWSTR lpUsername,
+                        LPCWSTR lpDomain,
+                        LPCWSTR lpPassword,
+                        DWORD dwLogonFlags,
+                        LPCWSTR lpApplicationName,
+                        LPWSTR lpCommandLine,
+                        DWORD dwCreationFlags,
+                        LPVOID lpEnvironment,
+                        LPCWSTR lpCurrentDirectory,
+                        LPSTARTUPINFOW lpStartupInfo,
+                        LPPROCESS_INFORMATION lpProcessInformation)
 {
     FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
     debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
@@ -158,34 +165,27 @@ LogonUserA(LPSTR lpszUsername,
     UNICODE_STRING UserName;
     UNICODE_STRING Domain;
     UNICODE_STRING Password;
-    NTSTATUS Status;
     BOOL ret = FALSE;
 
     UserName.Buffer = NULL;
     Domain.Buffer = NULL;
     Password.Buffer = NULL;
 
-    Status = RtlCreateUnicodeStringFromAsciiz(&UserName,
-                                              lpszUsername);
-    if (!NT_SUCCESS(Status))
+    if (!RtlCreateUnicodeStringFromAsciiz(&UserName, lpszUsername))
     {
-        SetLastError(RtlNtStatusToDosError(Status));
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
         goto UsernameDone;
     }
 
-    Status = RtlCreateUnicodeStringFromAsciiz(&Domain,
-                                              lpszDomain);
-    if (!NT_SUCCESS(Status))
+    if (!RtlCreateUnicodeStringFromAsciiz(&Domain, lpszDomain))
     {
-        SetLastError(RtlNtStatusToDosError(Status));
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
         goto DomainDone;
     }
 
-    Status = RtlCreateUnicodeStringFromAsciiz(&Password,
-                                              lpszPassword);
-    if (!NT_SUCCESS(Status))
+    if (!RtlCreateUnicodeStringFromAsciiz(&Password, lpszPassword))
     {
-        SetLastError(RtlNtStatusToDosError(Status));
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
         goto PasswordDone;
     }
 
@@ -213,171 +213,59 @@ UsernameDone:
 
 
 static BOOL WINAPI
-SamGetUserSid(LPCWSTR UserName,
-              PSID *Sid)
+GetAccountDomainSid(PSID *Sid)
 {
+    PPOLICY_ACCOUNT_DOMAIN_INFO Info = NULL;
+    LSA_OBJECT_ATTRIBUTES ObjectAttributes;
+    LSA_HANDLE PolicyHandle;
     PSID lpSid;
-    DWORD dwLength;
-    HKEY hUsersKey;
-    HKEY hUserKey;
-
-    if (Sid != NULL)
-        *Sid = NULL;
-
-    /* Open the Users key */
-    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
-                      L"SAM\\SAM\\Domains\\Account\\Users",
-                      0,
-                      KEY_READ,
-                      &hUsersKey))
-    {
-        ERR("Failed to open Users key! (Error %lu)\n", GetLastError());
-        return FALSE;
-    }
-
-    /* Open the user key */
-    if (RegOpenKeyExW(hUsersKey,
-                      UserName,
-                      0,
-                      KEY_READ,
-                      &hUserKey))
-    {
-        if (GetLastError() == ERROR_FILE_NOT_FOUND)
-        {
-            ERR("Invalid user name!\n");
-            SetLastError(ERROR_NO_SUCH_USER);
-        }
-        else
-        {
-            ERR("Failed to open user key! (Error %lu)\n", GetLastError());
-        }
-
-        RegCloseKey(hUsersKey);
-        return FALSE;
-    }
+    ULONG Length;
+    NTSTATUS Status;
 
-    RegCloseKey (hUsersKey);
+    *Sid = NULL;
 
-    /* Get SID size */
-    dwLength = 0;
-    if (RegQueryValueExW(hUserKey,
-                         L"Sid",
-                         NULL,
-                         NULL,
-                         NULL,
-                         &dwLength))
-    {
-        ERR("Failed to read the SID size! (Error %lu)\n", GetLastError());
-        RegCloseKey(hUserKey);
-        return FALSE;
-    }
+    memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
+    ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
 
-    /* Allocate sid buffer */
-    TRACE("Required SID buffer size: %lu\n", dwLength);
-    lpSid = (PSID)RtlAllocateHeap(RtlGetProcessHeap(),
-                                  0,
-                                  dwLength);
-    if (lpSid == NULL)
-    {
-        ERR("Failed to allocate SID buffer!\n");
-        RegCloseKey(hUserKey);
-        return FALSE;
-    }
-
-    /* Read sid */
-    if (RegQueryValueExW(hUserKey,
-                         L"Sid",
-                         NULL,
-                         NULL,
-                         (LPBYTE)lpSid,
-                         &dwLength))
+    Status = LsaOpenPolicy(NULL,
+                           &ObjectAttributes,
+                           POLICY_VIEW_LOCAL_INFORMATION,
+                           &PolicyHandle);
+    if (!NT_SUCCESS(Status))
     {
-        ERR("Failed to read the SID! (Error %lu)\n", GetLastError());
-        RtlFreeHeap(RtlGetProcessHeap(),
-                    0,
-                    lpSid);
-        RegCloseKey(hUserKey);
+        ERR("LsaOpenPolicy failed (Status: 0x%08lx)\n", Status);
         return FALSE;
     }
 
-    RegCloseKey(hUserKey);
-
-    *Sid = lpSid;
-
-    return TRUE;
-}
-
-
-static BOOL WINAPI
-SamGetDomainSid(PSID *Sid)
-{
-    PSID lpSid;
-    DWORD dwLength;
-    HKEY hDomainKey;
-
-    TRACE("SamGetDomainSid() called\n");
-
-    if (Sid != NULL)
-        *Sid = NULL;
-
-    /* Open the account domain key */
-    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
-                      L"SAM\\SAM\\Domains\\Account",
-                      0,
-                      KEY_READ,
-                      &hDomainKey))
+    Status = LsaQueryInformationPolicy(PolicyHandle,
+                                       PolicyAccountDomainInformation,
+                                       (PVOID *)&Info);
+    if (!NT_SUCCESS(Status))
     {
-        ERR("Failed to open the account domain key! (Error %lu)\n", GetLastError());
+        ERR("LsaQueryInformationPolicy failed (Status: 0x%08lx)\n", Status);
+        LsaClose(PolicyHandle);
         return FALSE;
     }
 
-    /* Get SID size */
-    dwLength = 0;
-    if (RegQueryValueExW(hDomainKey,
-                         L"Sid",
-                         NULL,
-                         NULL,
-                         NULL,
-                         &dwLength))
-    {
-        ERR("Failed to read the SID size! (Error %lu)\n", GetLastError());
-        RegCloseKey(hDomainKey);
-        return FALSE;
-    }
+    Length = RtlLengthSid(Info->DomainSid);
 
-    /* Allocate sid buffer */
-    TRACE("Required SID buffer size: %lu\n", dwLength);
-    lpSid = (PSID)RtlAllocateHeap(RtlGetProcessHeap(),
-                                  0,
-                                  dwLength);
+    lpSid = RtlAllocateHeap(RtlGetProcessHeap(),
+                            0,
+                            Length);
     if (lpSid == NULL)
     {
         ERR("Failed to allocate SID buffer!\n");
-        RegCloseKey(hDomainKey);
+        LsaFreeMemory(Info);
+        LsaClose(PolicyHandle);
         return FALSE;
     }
 
-    /* Read sid */
-    if (RegQueryValueExW(hDomainKey,
-                         L"Sid",
-                         NULL,
-                         NULL,
-                         (LPBYTE)lpSid,
-                         &dwLength))
-    {
-        ERR("Failed to read the SID! (Error %lu)\n", GetLastError());
-        RtlFreeHeap(RtlGetProcessHeap(),
-                    0,
-                    lpSid);
-        RegCloseKey(hDomainKey);
-        return FALSE;
-    }
-
-    RegCloseKey(hDomainKey);
+    memcpy(lpSid, Info->DomainSid, Length);
 
     *Sid = lpSid;
 
-    TRACE("SamGetDomainSid() done\n");
+    LsaFreeMemory(Info);
+    LsaClose(PolicyHandle);
 
     return TRUE;
 }
@@ -418,6 +306,79 @@ AppendRidToSid(PSID SrcSid,
 }
 
 
+static BOOL WINAPI
+GetUserSid(LPCWSTR UserName,
+           PSID *Sid)
+{
+    PSID SidBuffer = NULL;
+    PWSTR DomainBuffer = NULL;
+    DWORD cbSidSize = 0;
+    DWORD cchDomSize = 0;
+    SID_NAME_USE Use;
+    BOOL res = TRUE;
+
+    *Sid = NULL;
+
+    LookupAccountNameW(NULL,
+                       UserName,
+                       NULL,
+                       &cbSidSize,
+                       NULL,
+                       &cchDomSize,
+                       &Use);
+
+    if (cbSidSize == 0 || cchDomSize == 0)
+        return FALSE;
+
+    SidBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
+                                HEAP_ZERO_MEMORY,
+                                cbSidSize);
+    if (SidBuffer == NULL)
+        return FALSE;
+
+    DomainBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
+                                   HEAP_ZERO_MEMORY,
+                                   cchDomSize * sizeof(WCHAR));
+    if (DomainBuffer == NULL)
+    {
+        res = FALSE;
+        goto done;
+    }
+
+    if (!LookupAccountNameW(NULL,
+                            UserName,
+                            SidBuffer,
+                            &cbSidSize,
+                            DomainBuffer,
+                            &cchDomSize,
+                            &Use))
+    {
+        res = FALSE;
+        goto done;
+    }
+
+    if (Use != SidTypeUser)
+    {
+        res = FALSE;
+        goto done;
+    }
+
+    *Sid = SidBuffer;
+
+done:
+    if (DomainBuffer != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, DomainBuffer);
+
+    if (res == FALSE)
+    {
+        if (SidBuffer != NULL)
+            RtlFreeHeap(RtlGetProcessHeap(), 0, SidBuffer);
+    }
+
+    return res;
+}
+
+
 static PTOKEN_GROUPS
 AllocateGroupSids(OUT PSID *PrimaryGroupSid,
                   OUT PSID *OwnerSid)
@@ -437,7 +398,7 @@ AllocateGroupSids(OUT PSID *PrimaryGroupSid,
     if (!NT_SUCCESS(Status))
         return NULL;
 
-    if (!SamGetDomainSid(&DomainSid))
+    if (!GetAccountDomainSid(&DomainSid))
         return NULL;
 
     TokenGroups = RtlAllocateHeap(
@@ -625,7 +586,6 @@ LogonUserW(LPWSTR lpszUsername,
     }
     DefaultPrivs[] =
     {
-      { L"SeUnsolicitedInputPrivilege", 0 },
       { L"SeMachineAccountPrivilege", 0 },
       { L"SeSecurityPrivilege", 0 },
       { L"SeTakeOwnershipPrivilege", 0 },
@@ -652,8 +612,8 @@ LogonUserW(LPWSTR lpszUsername,
     TOKEN_USER TokenUser;
     TOKEN_OWNER TokenOwner;
     TOKEN_PRIMARY_GROUP TokenPrimaryGroup;
-    PTOKEN_GROUPS TokenGroups;
-    PTOKEN_PRIVILEGES TokenPrivileges;
+    PTOKEN_GROUPS TokenGroups = NULL;
+    PTOKEN_PRIVILEGES TokenPrivileges = NULL;
     TOKEN_DEFAULT_DACL TokenDefaultDacl;
     LARGE_INTEGER ExpirationTime;
     LUID AuthenticationId;
@@ -662,10 +622,10 @@ LogonUserW(LPWSTR lpszUsername,
     PSID PrimaryGroupSid = NULL;
     PSID OwnerSid = NULL;
     PSID LocalSystemSid;
-    PACL Dacl;
-    NTSTATUS Status;
+    PACL Dacl = NULL;
     SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY};
     unsigned i;
+    NTSTATUS Status = STATUS_SUCCESS;
 
     Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
     Qos.ImpersonationLevel = SecurityAnonymous;
@@ -688,7 +648,7 @@ LogonUserW(LPWSTR lpszUsername,
     ExpirationTime.QuadPart = -1;
 
     /* Get the user SID from the registry */
-    if (!SamGetUserSid (lpszUsername, &UserSid))
+    if (!GetUserSid (lpszUsername, &UserSid))
     {
         ERR("SamGetUserSid() failed\n");
         return FALSE;
@@ -700,11 +660,10 @@ LogonUserW(LPWSTR lpszUsername,
     /* Allocate and initialize token groups */
     TokenGroups = AllocateGroupSids(&PrimaryGroupSid,
                                     &OwnerSid);
-    if (NULL == TokenGroups)
+    if (TokenGroups == NULL)
     {
-        RtlFreeSid(UserSid);
-        SetLastError(ERROR_OUTOFMEMORY);
-        return FALSE;
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto done;
     }
 
     /* Allocate and initialize token privileges */
@@ -712,12 +671,10 @@ LogonUserW(LPWSTR lpszUsername,
                                       sizeof(TOKEN_PRIVILEGES)
                                     + sizeof(DefaultPrivs) / sizeof(DefaultPrivs[0])
                                       * sizeof(LUID_AND_ATTRIBUTES));
-    if (NULL == TokenPrivileges)
+    if (TokenPrivileges == NULL)
     {
-        FreeGroupSids(TokenGroups);
-        RtlFreeSid(UserSid);
-        SetLastError(ERROR_OUTOFMEMORY);
-        return FALSE;
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto done;
     }
 
     TokenPrivileges->PrivilegeCount = 0;
@@ -742,21 +699,13 @@ LogonUserW(LPWSTR lpszUsername,
     Dacl = RtlAllocateHeap(GetProcessHeap(), 0, 1024);
     if (Dacl == NULL)
     {
-        FreeGroupSids(TokenGroups);
-        RtlFreeSid(UserSid);
-        SetLastError(ERROR_OUTOFMEMORY);
-        return FALSE;
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto done;
     }
 
     Status = RtlCreateAcl(Dacl, 1024, ACL_REVISION);
     if (!NT_SUCCESS(Status))
-    {
-        RtlFreeHeap(GetProcessHeap(), 0, Dacl);
-        FreeGroupSids(TokenGroups);
-        RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges);
-        RtlFreeSid(UserSid);
-        return FALSE;
-    }
+        goto done;
 
     RtlAddAccessAllowedAce(Dacl,
                            ACL_REVISION,
@@ -813,10 +762,18 @@ LogonUserW(LPWSTR lpszUsername,
                            &TokenDefaultDacl,
                            &TokenSource);
 
-    RtlFreeHeap(GetProcessHeap(), 0, Dacl);
-    FreeGroupSids(TokenGroups);
-    RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges);
-    RtlFreeSid(UserSid);
+done:
+    if (Dacl != NULL)
+        RtlFreeHeap(GetProcessHeap(), 0, Dacl);
+
+    if (TokenGroups != NULL)
+        FreeGroupSids(TokenGroups);
+
+    if (TokenPrivileges != NULL)
+        RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges);
+
+    if (UserSid != NULL)
+        RtlFreeHeap(GetProcessHeap(), 0, UserSid);
 
     return NT_SUCCESS(Status);
 }