*/
#include <advapi32.h>
-
-#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(advapi);
/*
* @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),
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;
}
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;
}
}
+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)
if (!NT_SUCCESS(Status))
return NULL;
- if (!SamGetDomainSid(&DomainSid))
+ if (!GetAccountDomainSid(&DomainSid))
return NULL;
TokenGroups = RtlAllocateHeap(
}
DefaultPrivs[] =
{
- { L"SeUnsolicitedInputPrivilege", 0 },
{ L"SeMachineAccountPrivilege", 0 },
{ L"SeSecurityPrivilege", 0 },
{ L"SeTakeOwnershipPrivilege", 0 },
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;
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;
ExpirationTime.QuadPart = -1;
/* Get the user SID from the registry */
- if (!SamGetUserSid (lpszUsername, &UserSid))
+ if (!GetUserSid (lpszUsername, &UserSid))
{
ERR("SamGetUserSid() failed\n");
return FALSE;
/* 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 */
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;
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,
&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);
}