ReactOS  0.4.15-dev-5459-gb85f005
logon.c File Reference
#include <advapi32.h>
Include dependency graph for logon.c:

Go to the source code of this file.

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (advapi)
 
 C_ASSERT (sizeof(AdvapiTokenSourceName)==RTL_FIELD_SIZE(TOKEN_SOURCE, SourceName)+1)
 
static NTSTATUS OpenLogonLsaHandle (VOID)
 
NTSTATUS CloseLogonLsaHandle (VOID)
 
static BOOL CreateDefaultProcessSecurityCommon (_In_ HANDLE TokenHandle, _Out_ PSECURITY_DESCRIPTOR *Sd)
 Creates a default security descriptor that is going to be used by both the newly created process and thread by a call to CreateProcessAsUserA/W. This descriptor also serves for the newly duplicated token object that is going to be set for the token which acts as the main user. More...
 
static BOOL InsertProcessSecurityCommon (_In_ HANDLE ProcessHandle, _In_ HANDLE ThreadHandle, _In_ PSECURITY_DESCRIPTOR ProcessSecurity, _In_ PSECURITY_DESCRIPTOR ThreadSecurity)
 Changes the object security information of a process and thread that belongs to the process with new security data, basically by replacing the previous security descriptor with a new one. More...
 
static NTSTATUS InsertTokenToProcessCommon (_In_ BOOL ImpersonateAsSelf, _In_ HANDLE ProcessHandle, _In_ HANDLE ThreadHandle, _In_ HANDLE DuplicatedTokenHandle)
 Sets a primary token to the newly created process. The primary token that gets assigned to is a token whose security context is associated with the logged in user. For futher documentation information, see Remarks. More...
 
static BOOL CreateProcessAsUserCommon (_In_opt_ HANDLE hToken, _In_ DWORD dwCreationFlags, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _Inout_ LPPROCESS_INFORMATION lpProcessInformation)
 Internal function that serves as a helper for CreateProcessAsUserW/A routines on creating a process within the context of the logged in user. More...
 
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessAsUserA (_In_opt_ HANDLE hToken, _In_opt_ LPCSTR lpApplicationName, _Inout_opt_ LPSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags, _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCSTR lpCurrentDirectory, _In_ LPSTARTUPINFOA lpStartupInfo, _Out_ LPPROCESS_INFORMATION lpProcessInformation)
 
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessAsUserW (_In_opt_ HANDLE hToken, _In_opt_ LPCWSTR lpApplicationName, _Inout_opt_ LPWSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags, _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCWSTR lpCurrentDirectory, _In_ LPSTARTUPINFOW lpStartupInfo, _Out_ LPPROCESS_INFORMATION lpProcessInformation)
 
BOOL WINAPI LogonUserA (_In_ LPSTR lpszUsername, _In_opt_ LPSTR lpszDomain, _In_opt_ LPSTR lpszPassword, _In_ DWORD dwLogonType, _In_ DWORD dwLogonProvider, _Out_opt_ PHANDLE phToken)
 
BOOL WINAPI LogonUserExA (_In_ LPSTR lpszUsername, _In_opt_ LPSTR lpszDomain, _In_opt_ LPSTR lpszPassword, _In_ DWORD dwLogonType, _In_ DWORD dwLogonProvider, _Out_opt_ PHANDLE phToken, _Out_opt_ PSID *ppLogonSid, _Out_opt_ PVOID *ppProfileBuffer, _Out_opt_ LPDWORD pdwProfileLength, _Out_opt_ PQUOTA_LIMITS pQuotaLimits)
 
BOOL WINAPI LogonUserW (_In_ LPWSTR lpszUsername, _In_opt_ LPWSTR lpszDomain, _In_opt_ LPWSTR lpszPassword, _In_ DWORD dwLogonType, _In_ DWORD dwLogonProvider, _Out_opt_ PHANDLE phToken)
 
BOOL WINAPI LogonUserExW (_In_ LPWSTR lpszUsername, _In_opt_ LPWSTR lpszDomain, _In_opt_ LPWSTR lpszPassword, _In_ DWORD dwLogonType, _In_ DWORD dwLogonProvider, _Out_opt_ PHANDLE phToken, _Out_opt_ PSID *ppLogonSid, _Out_opt_ PVOID *ppProfileBuffer, _Out_opt_ LPDWORD pdwProfileLength, _Out_opt_ PQUOTA_LIMITS pQuotaLimits)
 

Variables

static const CHAR AdvapiTokenSourceName [] = "Advapi "
 
HANDLE LsaHandle = NULL
 
ULONG AuthenticationPackage = 0
 

Function Documentation

◆ C_ASSERT()

◆ CloseLogonLsaHandle()

NTSTATUS CloseLogonLsaHandle ( VOID  )

Definition at line 75 of file logon.c.

76 {
78 
79  if (LsaHandle != NULL)
80  {
82  if (!NT_SUCCESS(Status))
83  {
84  TRACE("LsaDeregisterLogonProcess failed (Status 0x%08lx)\n", Status);
85  }
86  }
87 
88  return Status;
89 }
LONG NTSTATUS
Definition: precomp.h:26
HANDLE LsaHandle
Definition: logon.c:17
Status
Definition: gdiplustypes.h:24
#define TRACE(s)
Definition: solgame.cpp:4
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI LsaDeregisterLogonProcess(HANDLE)
#define NULL
Definition: types.h:112
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by DllMain().

◆ CreateDefaultProcessSecurityCommon()

static BOOL CreateDefaultProcessSecurityCommon ( _In_ HANDLE  TokenHandle,
_Out_ PSECURITY_DESCRIPTOR Sd 
)
static

Creates a default security descriptor that is going to be used by both the newly created process and thread by a call to CreateProcessAsUserA/W. This descriptor also serves for the newly duplicated token object that is going to be set for the token which acts as the main user.

Parameters
[in]TokenHandleA handle to a token. The function will use this token to query security details such as the owner and primary group associated with the security context of this token. The obtained information will then be assigned to the security descriptor.
[out]SdA pointer to an allocated security descriptor that is given to the caller.
Returns
Return TRUE if the security descriptor has been successfully created, FALSE otherwise.
Remarks
When a process is created on behald of the user's security context this user will be the owner and responsible for that process. Whatever objects created or stuff done within the process space is at the discretion of the user, that is, further objects created are in charge by the user himself as is the owner of the process.

!!!NOTE!!! – On Windows the security descriptor is created by using CreatePrivateObjectSecurity(Ex) API call. Whilst the way the security descriptor is created in our end is not wrong per se, this function serves a placeholder until CreatePrivateObjectSecurity is implemented.

Definition at line 129 of file logon.c.

132 {
134  BOOL Success;
135  PACL Dacl;
136  PTOKEN_OWNER OwnerOfToken;
137  PTOKEN_PRIMARY_GROUP PrimaryGroupOfToken;
138  SECURITY_DESCRIPTOR AbsoluteSd;
139  ULONG DaclSize, TokenOwnerSize, PrimaryGroupSize, RelativeSDSize = 0;
140  PSID OwnerSid = NULL, SystemSid = NULL, PrimaryGroupSid = NULL;
141  PSECURITY_DESCRIPTOR RelativeSD = NULL;
143 
144  /*
145  * Since we do not know how much space
146  * is needed to allocate the buffer to
147  * hold the token owner, first we must
148  * query the exact size.
149  */
151  TokenOwner,
152  NULL,
153  0,
154  &TokenOwnerSize);
156  {
157  ERR("CreateDefaultProcessSecurityCommon(): Unexpected status code returned, must be STATUS_BUFFER_TOO_SMALL (Status 0x%08lx)\n", Status);
158  return FALSE;
159  }
160 
161  /* We have the required space size, allocate the buffer now */
162  OwnerOfToken = RtlAllocateHeap(RtlGetProcessHeap(),
164  TokenOwnerSize);
165  if (OwnerOfToken == NULL)
166  {
167  ERR("CreateDefaultProcessSecurityCommon(): Failed to allocate buffer for token owner!\n");
168  return FALSE;
169  }
170 
171  /* Now query the token owner */
173  TokenOwner,
174  OwnerOfToken,
175  TokenOwnerSize,
176  &TokenOwnerSize);
177  if (!NT_SUCCESS(Status))
178  {
179  ERR("CreateDefaultProcessSecurityCommon(): Failed to query the token owner (Status 0x%08lx)\n", Status);
180  Success = FALSE;
181  goto Quit;
182  }
183 
184  /* Do the same process but for the primary group now */
187  NULL,
188  0,
191  {
192  ERR("CreateDefaultProcessSecurityCommon(): Unexpected status code returned, must be STATUS_BUFFER_TOO_SMALL (Status 0x%08lx)\n", Status);
193  Success = FALSE;
194  goto Quit;
195  }
196 
197  /* Allocate the buffer */
198  PrimaryGroupOfToken = RtlAllocateHeap(RtlGetProcessHeap(),
201  if (PrimaryGroupOfToken == NULL)
202  {
203  ERR("CreateDefaultProcessSecurityCommon(): Failed to allocate buffer for primary group token!\n");
204  Success = FALSE;
205  goto Quit;
206  }
207 
208  /* Query the primary group now */
211  PrimaryGroupOfToken,
214  if (!NT_SUCCESS(Status))
215  {
216  ERR("CreateDefaultProcessSecurityCommon(): Failed to query the token owner (Status 0x%08lx)\n", Status);
217  Success = FALSE;
218  goto Quit;
219  }
220 
221  /* Create the SYSTEM SID */
223  1,
225  0, 0, 0, 0, 0, 0, 0,
226  &SystemSid))
227  {
228  ERR("CreateDefaultProcessSecurityCommon(): Failed to create Local System SID (error code %d)\n", GetLastError());
229  Success = FALSE;
230  goto Quit;
231  }
232 
233  /* Cache the token owner and primary group SID */
234  OwnerSid = OwnerOfToken->Owner;
235  PrimaryGroupSid = PrimaryGroupOfToken->PrimaryGroup;
236 
237  /* Set up the DACL size */
238  DaclSize = sizeof(ACL) +
239  sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(OwnerSid) +
240  sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(SystemSid);
241 
242  /* Allocate buffer for the DACL */
243  Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
245  DaclSize);
246  if (Dacl == NULL)
247  {
248  ERR("CreateDefaultProcessSecurityCommon(): Failed to allocate buffer for DACL!\n");
249  Success = FALSE;
250  goto Quit;
251  }
252 
253  /* Initialize the DACL */
255  {
256  ERR("CreateDefaultProcessSecurityCommon(): Failed to initialize DACL (error code %d)\n", GetLastError());
257  Success = FALSE;
258  goto Quit;
259  }
260 
261  /* Give full powers to the owner */
263  ACL_REVISION,
264  GENERIC_ALL,
265  OwnerSid))
266  {
267  ERR("CreateDefaultProcessSecurityCommon(): Failed to set up ACE for owner (error code %d)\n", GetLastError());
268  Success = FALSE;
269  goto Quit;
270  }
271 
272  /* Give full powers to SYSTEM as well */
274  ACL_REVISION,
275  GENERIC_ALL,
276  SystemSid))
277  {
278  ERR("CreateDefaultProcessSecurityCommon(): Failed to set up ACE for SYSTEM (error code %d)\n", GetLastError());
279  Success = FALSE;
280  goto Quit;
281  }
282 
283  /* Initialize the descriptor in absolute format */
285  {
286  ERR("CreateDefaultProcessSecurityCommon(): Failed to initialize absolute security descriptor (error code %d)\n", GetLastError());
287  Success = FALSE;
288  goto Quit;
289  }
290 
291  /* Set the DACL to the security descriptor */
292  if (!SetSecurityDescriptorDacl(&AbsoluteSd, TRUE, Dacl, FALSE))
293  {
294  ERR("CreateDefaultProcessSecurityCommon(): Failed to set up DACL to absolute security descriptor (error code %d)\n", GetLastError());
295  Success = FALSE;
296  goto Quit;
297  }
298 
299  /* Set the owner for this descriptor */
300  if (!SetSecurityDescriptorOwner(&AbsoluteSd, OwnerSid, FALSE))
301  {
302  ERR("CreateDefaultProcessSecurityCommon(): Failed to set up owner to absolute security descriptor (error code %d)\n", GetLastError());
303  Success = FALSE;
304  goto Quit;
305  }
306 
307  /* Set the primary group for this descriptor */
308  if (!SetSecurityDescriptorGroup(&AbsoluteSd, PrimaryGroupSid, FALSE))
309  {
310  ERR("CreateDefaultProcessSecurityCommon(): Failed to set up group to absolute security descriptor (error code %d)\n", GetLastError());
311  Success = FALSE;
312  goto Quit;
313  }
314 
315  /*
316  * Determine the exact size space of the absolute
317  * descriptor so that we can allocate a buffer
318  * to hold the descriptor in a converted self
319  * relative format.
320  */
321  if (!MakeSelfRelativeSD(&AbsoluteSd, NULL, &RelativeSDSize) && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
322  {
323  ERR("CreateDefaultProcessSecurityCommon(): Unexpected error code (error code %d -- must be ERROR_INSUFFICIENT_BUFFER)\n", GetLastError());
324  Success = FALSE;
325  goto Quit;
326  }
327 
328  /* Allocate the buffer */
329  RelativeSD = RtlAllocateHeap(RtlGetProcessHeap(),
331  RelativeSDSize);
332  if (RelativeSD == NULL)
333  {
334  ERR("CreateDefaultProcessSecurityCommon(): Failed to allocate buffer for self relative descriptor!\n");
335  Success = FALSE;
336  goto Quit;
337  }
338 
339  /* Convert to a self relative format now */
340  if (!MakeSelfRelativeSD(&AbsoluteSd, RelativeSD, &RelativeSDSize))
341  {
342  ERR("CreateDefaultProcessSecurityCommon(): Failed to allocate relative SD, buffer too smal (error code %d)\n", GetLastError());
343  Success = FALSE;
344  goto Quit;
345  }
346 
347  /* Success, give the descriptor to the caller */
348  *Sd = RelativeSD;
349  Success = TRUE;
350 
351 Quit:
352  /* Free all the stuff we have allocated */
353  if (OwnerOfToken != NULL)
354  RtlFreeHeap(RtlGetProcessHeap(), 0, OwnerOfToken);
355 
356  if (PrimaryGroupOfToken != NULL)
357  RtlFreeHeap(RtlGetProcessHeap(), 0, PrimaryGroupOfToken);
358 
359  if (SystemSid != NULL)
360  FreeSid(SystemSid);
361 
362  if (Dacl != NULL)
363  RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);
364 
365  if (Success == FALSE)
366  {
367  if (RelativeSD != NULL)
368  {
369  RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeSD);
370  }
371  }
372 
373  return Success;
374 }
#define GENERIC_ALL
Definition: nt_native.h:92
#define SECURITY_LOCAL_SYSTEM_RID
Definition: setypes.h:574
BOOL WINAPI MakeSelfRelativeSD(PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor, PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor, LPDWORD lpdwBufferLength)
Definition: sec.c:214
BOOL WINAPI SetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR pSecurityDescriptor, BOOL bDaclPresent, PACL pDacl, BOOL bDaclDefaulted)
Definition: sec.c:262
BOOL WINAPI InitializeAcl(PACL pAcl, DWORD nAclLength, DWORD dwAclRevision)
Definition: security.c:1008
#define TRUE
Definition: types.h:120
BOOL WINAPI InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD dwRevision)
Definition: security.c:931
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
BOOL WINAPI AddAccessAllowedAce(PACL pAcl, DWORD dwAceRevision, DWORD AccessMask, PSID pSid)
Definition: security.c:1041
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
struct _ACCESS_ALLOWED_ACE ACCESS_ALLOWED_ACE
BOOL WINAPI SetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID pOwner, BOOL bOwnerDefaulted)
Definition: sec.c:312
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID _Inout_ PULONG _Out_writes_bytes_to_opt_ PrimaryGroupSize PSID _Inout_ PULONG PrimaryGroupSize
Definition: rtlfuncs.h:1599
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
PVOID WINAPI FreeSid(PSID pSid)
Definition: security.c:700
BOOL WINAPI SetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID pGroup, BOOL bGroupDefaulted)
Definition: sec.c:288
struct _ACL ACL
PSID Owner
Definition: setypes.h:1024
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:715
#define SECURITY_NT_AUTHORITY
Definition: setypes.h:554
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
Status
Definition: gdiplustypes.h:24
_Must_inspect_result_ __kernel_entry NTSTATUS NTAPI NtQueryInformationToken(_In_ HANDLE TokenHandle, _In_ TOKEN_INFORMATION_CLASS TokenInformationClass, _Out_writes_bytes_to_opt_(TokenInformationLength, *ReturnLength) PVOID TokenInformation, _In_ ULONG TokenInformationLength, _Out_ PULONG ReturnLength)
Queries a specific type of information in regard of an access token based upon the information class....
Definition: tokencls.c:473
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
DWORD WINAPI GetLengthSid(PSID pSid)
Definition: security.c:921
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1593
static SID_IDENTIFIER_AUTHORITY NtAuthority
Definition: security.c:40
#define ERR(fmt,...)
Definition: debug.h:110
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG DaclSize
Definition: rtlfuncs.h:1593
#define ACL_REVISION
Definition: setypes.h:39
unsigned int ULONG
Definition: retypes.h:1
BOOL WINAPI AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, BYTE nSubAuthorityCount, DWORD nSubAuthority0, DWORD nSubAuthority1, DWORD nSubAuthority2, DWORD nSubAuthority3, DWORD nSubAuthority4, DWORD nSubAuthority5, DWORD nSubAuthority6, DWORD nSubAuthority7, PSID *pSid)
Definition: security.c:676
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10

Referenced by CreateProcessAsUserCommon().

◆ CreateProcessAsUserA()

BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessAsUserA ( _In_opt_ HANDLE  hToken,
_In_opt_ LPCSTR  lpApplicationName,
_Inout_opt_ LPSTR  lpCommandLine,
_In_opt_ LPSECURITY_ATTRIBUTES  lpProcessAttributes,
_In_opt_ LPSECURITY_ATTRIBUTES  lpThreadAttributes,
_In_ BOOL  bInheritHandles,
_In_ DWORD  dwCreationFlags,
_In_opt_ LPVOID  lpEnvironment,
_In_opt_ LPCSTR  lpCurrentDirectory,
_In_ LPSTARTUPINFOA  lpStartupInfo,
_Out_ LPPROCESS_INFORMATION  lpProcessInformation 
)

Definition at line 945 of file logon.c.

957 {
958  TRACE("%p %s %s %p %p %d 0x%08x %p %s %p %p\n", hToken, debugstr_a(lpApplicationName),
959  debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
960  dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
961 
962  /* Create the process with a suspended main thread */
963  if (!CreateProcessA(lpApplicationName,
964  lpCommandLine,
965  lpProcessAttributes,
966  lpThreadAttributes,
967  bInheritHandles,
968  dwCreationFlags | CREATE_SUSPENDED,
969  lpEnvironment,
970  lpCurrentDirectory,
971  lpStartupInfo,
972  lpProcessInformation))
973  {
974  ERR("CreateProcessA failed, last error: %d\n", GetLastError());
975  return FALSE;
976  }
977 
978  /* Call the helper function */
979  return CreateProcessAsUserCommon(hToken,
980  dwCreationFlags,
981  lpProcessAttributes,
982  lpThreadAttributes,
983  lpProcessInformation);
984 }
static BOOL CreateProcessAsUserCommon(_In_opt_ HANDLE hToken, _In_ DWORD dwCreationFlags, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _Inout_ LPPROCESS_INFORMATION lpProcessInformation)
Internal function that serves as a helper for CreateProcessAsUserW/A routines on creating a process w...
Definition: logon.c:645
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
#define CREATE_SUSPENDED
Definition: winbase.h:178
#define FALSE
Definition: types.h:117
#define TRACE(s)
Definition: solgame.cpp:4
#define debugstr_a
Definition: kernel32.h:31
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4743
#define ERR(fmt,...)
Definition: debug.h:110

Referenced by test_token_security_descriptor().

◆ CreateProcessAsUserCommon()

static BOOL CreateProcessAsUserCommon ( _In_opt_ HANDLE  hToken,
_In_ DWORD  dwCreationFlags,
_In_opt_ LPSECURITY_ATTRIBUTES  lpProcessAttributes,
_In_opt_ LPSECURITY_ATTRIBUTES  lpThreadAttributes,
_Inout_ LPPROCESS_INFORMATION  lpProcessInformation 
)
static

Internal function that serves as a helper for CreateProcessAsUserW/A routines on creating a process within the context of the logged in user.

Parameters
[in]hTokenA handle to an access token that is associated with the logged in user. If the caller does not submit a token, the helper will immediately quit and return success, and the newly created process will be created upon using the default security context.
[in]dwCreationFlagsBit masks containing the creation process flags. The function uses this parameter to determine if the process wasn't created in a suspended way and if not the function will resume the main thread.
[in]lpProcessAttributesA pointer to process attributes. This function uses this parameter to gather the security descriptor, if ever present. If it is, this descriptor takes precedence over the default one when setting new security information to the process.
[in]lpThreadAttributesA pointer to thread attributes. This function uses this parameter to gather the security descriptor, if ever present. If it is, this descriptor takes precedence over the default one when setting new security information to the thread.
[in,out]lpProcessInformationA pointer to a structure that contains process creation information data. Such pointer contains the process and thread handles and whatnot.
Returns
Returns TRUE if the helper has successfully assigned the newly created process the user's security context to that process, otherwise FALSE is returned.
Remarks
In order for the helper function to assign the primary token to the process, it has to do a "rinse and repeat" approach. That is, the helper will stop the impersonation and attempt to assign the token to process by acting on behalf of the main process' security context. If that fails, the function will do a second attempt by doing this but with impersonation enabled instead.

Definition at line 645 of file logon.c.

651 {
652  NTSTATUS Status = STATUS_SUCCESS, StatusOnExit;
653  BOOL Success;
657  PSECURITY_DESCRIPTOR DefaultSd = NULL, ProcessSd, ThreadSd;
658  HANDLE hTokenDup = NULL;
659  HANDLE OriginalImpersonationToken = NULL;
660  HANDLE NullToken = NULL;
661 
662  if (hToken != NULL)
663  {
664  /* Check whether the user-provided token is a primary token */
665  // GetTokenInformation();
667  TokenType,
668  &Type,
669  sizeof(Type),
670  &ReturnLength);
671  if (!NT_SUCCESS(Status))
672  {
673  ERR("NtQueryInformationToken() failed, Status 0x%08x\n", Status);
674  Success = FALSE;
675  goto Quit;
676  }
677 
678  if (Type != TokenPrimary)
679  {
680  ERR("Wrong token type for token 0x%p, expected TokenPrimary, got %ld\n", hToken, Type);
682  Success = FALSE;
683  goto Quit;
684  }
685 
686  /*
687  * Open the original token of the calling thread
688  * and halt the impersonation for the moment
689  * being. The opened thread token will be cached
690  * so that we will restore it back when we're done.
691  */
694  TRUE,
695  &OriginalImpersonationToken);
696  if (!NT_SUCCESS(Status))
697  {
698  /* We failed? Does this thread have a token at least? */
699  OriginalImpersonationToken = NULL;
700  if (Status != STATUS_NO_TOKEN)
701  {
702  /*
703  * OK so this thread has a token but we
704  * could not open it for whatever reason.
705  * Bail out then.
706  */
707  ERR("Failed to open thread token with 0x%08lx\n", Status);
708  Success = FALSE;
709  goto Quit;
710  }
711  }
712  else
713  {
714  /* We succeeded, stop the impersonation for now */
717  &NullToken,
718  sizeof(NullToken));
719  if (!NT_SUCCESS(Status))
720  {
721  ERR("Failed to stop impersonation with 0x%08lx\n", Status);
722  Success = FALSE;
723  goto Quit;
724  }
725  }
726 
727  /*
728  * Create a security descriptor that will be common for the
729  * newly created process on behalf of the context user.
730  */
731  if (!CreateDefaultProcessSecurityCommon(hToken, &DefaultSd))
732  {
733  ERR("Failed to create common security descriptor for the token for new process!\n");
734  Success = FALSE;
735  goto Quit;
736  }
737 
738  /*
739  * Duplicate the token for this new process. This token
740  * object will get a default security descriptor that we
741  * have created ourselves in ADVAPI32.
742  */
744  NULL,
745  0,
746  NULL,
747  DefaultSd);
748  Status = NtDuplicateToken(hToken,
749  0,
751  FALSE,
752  TokenPrimary,
753  &hTokenDup);
754  if (!NT_SUCCESS(Status))
755  {
756  ERR("NtDuplicateToken() failed, Status 0x%08x\n", Status);
757  Success = FALSE;
758  goto Quit;
759  }
760 
761  /*
762  * Now it's time to set the primary token into
763  * the process. On the first try, do it by
764  * impersonating the security context of the
765  * calling process (impersonate as self).
766  */
768  lpProcessInformation->hProcess,
769  lpProcessInformation->hThread,
770  hTokenDup);
771  if (!NT_SUCCESS(Status))
772  {
773  /*
774  * OK, we failed. Our second (and last try) is to not
775  * impersonate as self but instead we will try by setting
776  * the original impersonation (thread) token and set the
777  * primary token to the process through this way. This is
778  * what we call -- the "rinse and repeat" approach.
779  */
782  &OriginalImpersonationToken,
783  sizeof(OriginalImpersonationToken));
784  if (!NT_SUCCESS(Status))
785  {
786  ERR("Failed to restore impersonation token for setting process token, Status 0x%08lx\n", Status);
787  NtClose(hTokenDup);
788  Success = FALSE;
789  goto Quit;
790  }
791 
792  /* Retry again */
794  lpProcessInformation->hProcess,
795  lpProcessInformation->hThread,
796  hTokenDup);
797  if (!NT_SUCCESS(Status))
798  {
799  /* Even the second try failed, bail out... */
800  ERR("Failed to insert the primary token into process, Status 0x%08lx\n", Status);
801  NtClose(hTokenDup);
802  Success = FALSE;
803  goto Quit;
804  }
805 
806  /* All good, now stop impersonation */
809  &NullToken,
810  sizeof(NullToken));
811  if (!NT_SUCCESS(Status))
812  {
813  ERR("Failed to unset impersonationg token after setting process token, Status 0x%08lx\n", Status);
814  NtClose(hTokenDup);
815  Success = FALSE;
816  goto Quit;
817  }
818  }
819 
820  /*
821  * FIXME: As we have successfully set up a primary token to
822  * the newly created process, we must set up as well a definite
823  * limit of quota charges for this process on the context of
824  * this user.
825  */
826 
827  /*
828  * As we have successfully set the token into the process now
829  * it is time that we set up new security information for both
830  * the process and its thread as well, that is, these securable
831  * objects will grant a security descriptor. The security descriptors
832  * provided by the caller take precedence so we should use theirs
833  * if possible in this case. Otherwise both the process and thread
834  * will receive the default security descriptor that we have created
835  * ourselves.
836  *
837  * BEAR IN MIND!!! AT THE MOMENT when these securable objects get new
838  * security information, the process (and the thread) can't be opened
839  * by the creator anymore as the new owner will take in charge of
840  * the process and future objects that are going to be created within
841  * the process. For further information in regard of the documentation
842  * see https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessasuserw.
843  */
844  if (lpProcessAttributes && lpProcessAttributes->lpSecurityDescriptor)
845  {
846  ProcessSd = lpProcessAttributes->lpSecurityDescriptor;
847  }
848  else
849  {
850  ProcessSd = DefaultSd;
851  }
852 
853  if (lpThreadAttributes && lpThreadAttributes->lpSecurityDescriptor)
854  {
855  ThreadSd = lpThreadAttributes->lpSecurityDescriptor;
856  }
857  else
858  {
859  ThreadSd = DefaultSd;
860  }
861 
862  /* Set new security info to the process and thread now */
863  if (!InsertProcessSecurityCommon(lpProcessInformation->hProcess,
864  lpProcessInformation->hThread,
865  ProcessSd,
866  ThreadSd))
867  {
868  ERR("Failed to set new security information for process and thread!\n");
869  NtClose(hTokenDup);
870  Success = FALSE;
871  goto Quit;
872  }
873 
874  /* Close the duplicated token */
875  NtClose(hTokenDup);
876  Success = TRUE;
877  }
878 
879  /*
880  * If the caller did not supply a token then just declare
881  * ourselves as job done. The newly created process will use
882  * the default security context at this point anyway.
883  */
884  TRACE("No token supplied, the process will use default security context!\n");
885  Success = TRUE;
886 
887 Quit:
888  /*
889  * If we successfully opened the thread token before
890  * and stopped the impersonation then we have to assign
891  * its original token back and close that token we have
892  * referenced it.
893  */
894  if (OriginalImpersonationToken != NULL)
895  {
896  StatusOnExit = NtSetInformationThread(NtCurrentThread(),
898  &OriginalImpersonationToken,
899  sizeof(OriginalImpersonationToken));
900 
901  /*
902  * We really must assert ourselves that we successfully
903  * set the original token back, otherwise if we fail
904  * then something is seriously going wrong....
905  * The status code is cached in a separate status
906  * variable because we would not want to tamper
907  * with the original status code that could have been
908  * returned by someone else above in this function code.
909  */
910  ASSERT(NT_SUCCESS(StatusOnExit));
911 
912  /* De-reference it */
913  NtClose(OriginalImpersonationToken);
914  }
915 
916  /* Terminate the process and set the last error status */
917  if (!NT_SUCCESS(Status))
918  {
919  TerminateProcess(lpProcessInformation->hProcess, Status);
921  }
922 
923  /* Resume the main thread */
924  if (!(dwCreationFlags & CREATE_SUSPENDED))
925  {
926  ResumeThread(lpProcessInformation->hThread);
927  }
928 
929  /* Free the security descriptor from memory */
930  if (DefaultSd != NULL)
931  {
932  RtlFreeHeap(RtlGetProcessHeap(), 0, DefaultSd);
933  }
934 
935  return Success;
936 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
#define NtCurrentThread()
#define TOKEN_IMPERSONATE
Definition: setypes.h:923
static BOOL CreateDefaultProcessSecurityCommon(_In_ HANDLE TokenHandle, _Out_ PSECURITY_DESCRIPTOR *Sd)
Creates a default security descriptor that is going to be used by both the newly created process and ...
Definition: logon.c:129
#define CREATE_SUSPENDED
Definition: winbase.h:178
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
#define STATUS_BAD_TOKEN_TYPE
Definition: ntstatus.h:404
NTSTATUS NTAPI NtSetInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength)
Definition: query.c:2018
Status
Definition: gdiplustypes.h:24
_Must_inspect_result_ __kernel_entry NTSTATUS NTAPI NtQueryInformationToken(_In_ HANDLE TokenHandle, _In_ TOKEN_INFORMATION_CLASS TokenInformationClass, _Out_writes_bytes_to_opt_(TokenInformationLength, *ReturnLength) PVOID TokenInformation, _In_ ULONG TokenInformationLength, _Out_ PULONG ReturnLength)
Queries a specific type of information in regard of an access token based upon the information class....
Definition: tokencls.c:473
#define TRACE(s)
Definition: solgame.cpp:4
NTSTATUS NTAPI NtOpenThreadToken(_In_ HANDLE ThreadHandle, _In_ ACCESS_MASK DesiredAccess, _In_ BOOLEAN OpenAsSelf, _Out_ PHANDLE TokenHandle)
Opens a token that is tied to a thread handle.
Definition: token.c:2281
#define TOKEN_QUERY
Definition: setypes.h:924
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static BOOL InsertProcessSecurityCommon(_In_ HANDLE ProcessHandle, _In_ HANDLE ThreadHandle, _In_ PSECURITY_DESCRIPTOR ProcessSecurity, _In_ PSECURITY_DESCRIPTOR ThreadSecurity)
Changes the object security information of a process and thread that belongs to the process with new ...
Definition: logon.c:404
Type
Definition: Type.h:6
#define SetLastError(x)
Definition: compat.h:752
#define STATUS_NO_TOKEN
Definition: ntstatus.h:360
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
_Must_inspect_result_ __kernel_entry NTSTATUS NTAPI NtDuplicateToken(_In_ HANDLE ExistingTokenHandle, _In_ ACCESS_MASK DesiredAccess, _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ BOOLEAN EffectiveOnly, _In_ TOKEN_TYPE TokenType, _Out_ PHANDLE NewTokenHandle)
Duplicates a token.
Definition: tokenlif.c:1865
enum _TOKEN_TYPE TOKEN_TYPE
#define ERR(fmt,...)
Definition: debug.h:110
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1532
static NTSTATUS InsertTokenToProcessCommon(_In_ BOOL ImpersonateAsSelf, _In_ HANDLE ProcessHandle, _In_ HANDLE ThreadHandle, _In_ HANDLE DuplicatedTokenHandle)
Sets a primary token to the newly created process. The primary token that gets assigned to is a token...
Definition: logon.c:482
#define NULL
Definition: types.h:112
DWORD WINAPI ResumeThread(IN HANDLE hThread)
Definition: thread.c:567
unsigned int ULONG
Definition: retypes.h:1
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define STATUS_SUCCESS
Definition: shellext.h:65
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_ BOOLEAN _In_ TOKEN_TYPE TokenType
Definition: sefuncs.h:401

Referenced by CreateProcessAsUserA(), and CreateProcessAsUserW().

◆ CreateProcessAsUserW()

BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessAsUserW ( _In_opt_ HANDLE  hToken,
_In_opt_ LPCWSTR  lpApplicationName,
_Inout_opt_ LPWSTR  lpCommandLine,
_In_opt_ LPSECURITY_ATTRIBUTES  lpProcessAttributes,
_In_opt_ LPSECURITY_ATTRIBUTES  lpThreadAttributes,
_In_ BOOL  bInheritHandles,
_In_ DWORD  dwCreationFlags,
_In_opt_ LPVOID  lpEnvironment,
_In_opt_ LPCWSTR  lpCurrentDirectory,
_In_ LPSTARTUPINFOW  lpStartupInfo,
_Out_ LPPROCESS_INFORMATION  lpProcessInformation 
)

Definition at line 993 of file logon.c.

1005 {
1006  TRACE("%p %s %s %p %p %d 0x%08x %p %s %p %p\n", hToken, debugstr_w(lpApplicationName),
1007  debugstr_w(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
1008  dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
1009 
1010  /* Create the process with a suspended main thread */
1011  if (!CreateProcessW(lpApplicationName,
1012  lpCommandLine,
1013  lpProcessAttributes,
1014  lpThreadAttributes,
1015  bInheritHandles,
1016  dwCreationFlags | CREATE_SUSPENDED,
1017  lpEnvironment,
1018  lpCurrentDirectory,
1019  lpStartupInfo,
1020  lpProcessInformation))
1021  {
1022  ERR("CreateProcessW failed, last error: %d\n", GetLastError());
1023  return FALSE;
1024  }
1025 
1026  /* Call the helper function */
1027  return CreateProcessAsUserCommon(hToken,
1028  dwCreationFlags,
1029  lpProcessAttributes,
1030  lpThreadAttributes,
1031  lpProcessInformation);
1032 }
static BOOL CreateProcessAsUserCommon(_In_opt_ HANDLE hToken, _In_ DWORD dwCreationFlags, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _Inout_ LPPROCESS_INFORMATION lpProcessInformation)
Internal function that serves as a helper for CreateProcessAsUserW/A routines on creating a process w...
Definition: logon.c:645
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
#define CREATE_SUSPENDED
Definition: winbase.h:178
#define FALSE
Definition: types.h:117
#define debugstr_w
Definition: kernel32.h:32
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4594
#define TRACE(s)
Definition: solgame.cpp:4
#define ERR(fmt,...)
Definition: debug.h:110

Referenced by custom_start_server(), InstallDevice(), LaunchProcess(), ScmStartUserModeService(), SeclCreateProcessWithLogonW(), StartScreenSaver(), and WlxStartApplication().

◆ InsertProcessSecurityCommon()

static BOOL InsertProcessSecurityCommon ( _In_ HANDLE  ProcessHandle,
_In_ HANDLE  ThreadHandle,
_In_ PSECURITY_DESCRIPTOR  ProcessSecurity,
_In_ PSECURITY_DESCRIPTOR  ThreadSecurity 
)
static

Changes the object security information of a process and thread that belongs to the process with new security data, basically by replacing the previous security descriptor with a new one.

Parameters
[in]ProcessHandleA handle to a valid process of which security information is to be changed by setting up a new security descriptor.
[in]ThreadHandleA handle to a valid thread of which security information is to be changed by setting up a new security descriptor.
[in]ProcessSecurityA pointer to a security descriptor that is for the process.
[in]ThreadSecurityA pointer to a security descriptor that is for the thread.
Returns
Return TRUE if new security information has been set, FALSE otherwise.

Definition at line 404 of file logon.c.

409 {
410  /* Set new security data for the process */
413  ProcessSecurity))
414  {
415  ERR("InsertProcessSecurityCommon(): Failed to set security for process (error code %d)\n", GetLastError());
416  return FALSE;
417  }
418 
419  /* Set new security data for the thread */
420  if (!SetKernelObjectSecurity(ThreadHandle,
422  ThreadSecurity))
423  {
424  ERR("InsertProcessSecurityCommon(): Failed to set security for thread (error code %d)\n", GetLastError());
425  return FALSE;
426  }
427 
428  return TRUE;
429 }
#define TRUE
Definition: types.h:120
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
#define GROUP_SECURITY_INFORMATION
Definition: setypes.h:124
#define FALSE
Definition: types.h:117
BOOL WINAPI SetKernelObjectSecurity(HANDLE Handle, SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR SecurityDescriptor)
Definition: security.c:1727
#define ERR(fmt,...)
Definition: debug.h:110
#define OWNER_SECURITY_INFORMATION
Definition: setypes.h:123
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
#define DACL_SECURITY_INFORMATION
Definition: setypes.h:125

Referenced by CreateProcessAsUserCommon().

◆ InsertTokenToProcessCommon()

static NTSTATUS InsertTokenToProcessCommon ( _In_ BOOL  ImpersonateAsSelf,
_In_ HANDLE  ProcessHandle,
_In_ HANDLE  ThreadHandle,
_In_ HANDLE  DuplicatedTokenHandle 
)
static

Sets a primary token to the newly created process. The primary token that gets assigned to is a token whose security context is associated with the logged in user. For futher documentation information, see Remarks.

Parameters
[in]ImpersonateAsSelfIf set to TRUE, the function will act on behalf of the calling process by impersonating its security context. Generally the caller will disable impersonation and attempt to act on behalf of the said main process as a first tentative to acquire the needed privilege in order to assign a token to the process. If set to FALSE, the function won't act on behalf of the calling process.
[in]ProcessHandleA handle to the newly created process. The function will use it as a mean to assign the primary token to this process.
[in]ThreadHandleA handle to the newly and primary created thread associated with the process.
[in]DuplicatedTokenHandleA handle to a duplicated access token. This token represents as a primary one, initially duplicated in form as a primary type from an impersonation type.
Returns
STATUS_SUCCESS is returned if token assignment to process succeeded, otherwise a failure NTSTATUS code is returned. A potential failure status code is STATUS_ACCESS_DENIED which means the caller doesn't have enough rights to grant access for primary token assignment to process.
Remarks
This function acts like an internal helper for CreateProcessAsUserCommon (and as such for CreateProcessAsUserW/A as well) as once a process is created, the function is tasked to assign the security context of the logged in user to that process. However, the rate of success of inserting the token into the process ultimately depends on the caller.

The caller will either succeed or fail at acquiring SE_ASSIGNPRIMARYTOKEN_PRIVILEGE privilege depending on the security context of the user. If it's allowed, the caller would generally acquire such privilege immediately but if not, the caller will attempt to do a second try.

Definition at line 482 of file logon.c.

487 {
489  PROCESS_ACCESS_TOKEN AccessToken;
490  BOOLEAN PrivilegeSet;
491  BOOLEAN HavePrivilege;
492 
493  /*
494  * Assume the SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
495  * privilege hasn't been set.
496  */
497  PrivilegeSet = FALSE;
498 
499  /*
500  * The caller asked that we must impersonate as
501  * ourselves, that is, we'll be going to impersonate
502  * the security context of the calling process. If
503  * self impersonation fails then the caller has
504  * to do a "rinse and repeat" approach.
505  */
506  if (ImpersonateAsSelf)
507  {
509  if (!NT_SUCCESS(Status))
510  {
511  ERR("RtlImpersonateSelf(SecurityImpersonation) failed, Status 0x%08x\n", Status);
512  return Status;
513  }
514  }
515 
516  /*
517  * Attempt to acquire the process primary token assignment privilege
518  * in case we actually need it.
519  * The call will either succeed or fail when the caller has (or has not)
520  * enough rights.
521  * The last situation may not be dramatic for us. Indeed it may happen
522  * that the user-provided token is a restricted version of the caller's
523  * primary token (aka. a "child" token), or both tokens inherit (i.e. are
524  * children, and are together "siblings") from a common parent token.
525  * In this case the NT kernel allows us to assign the token to the child
526  * process without the need for the assignment privilege, which is fine.
527  * On the contrary, if the user-provided token is completely arbitrary,
528  * then the NT kernel will enforce the presence of the assignment privilege:
529  * because we failed (by assumption) to assign the privilege, the process
530  * token assignment will fail as required. It is then the job of the
531  * caller to manually acquire the necessary privileges.
532  */
534  TRUE, TRUE, &PrivilegeSet);
535  HavePrivilege = NT_SUCCESS(Status);
536  if (!HavePrivilege)
537  {
538  ERR("RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE) failed, Status 0x%08lx, "
539  "attempting to continue without it...\n", Status);
540  }
541 
542  /*
543  * Assign the duplicated token and thread
544  * handle to the structure so that we'll
545  * use it to assign the primary token
546  * to process.
547  */
548  AccessToken.Token = DuplicatedTokenHandle;
549  AccessToken.Thread = ThreadHandle;
550 
551  /* Set the new process token */
554  (PVOID)&AccessToken,
555  sizeof(AccessToken));
556 
557  /* Restore the privilege */
558  if (HavePrivilege)
559  {
561  PrivilegeSet, TRUE, &PrivilegeSet);
562  }
563 
564  /*
565  * Check again if the caller wanted to impersonate
566  * as self. If that is the case we must revert this
567  * impersonation back.
568  */
569  if (ImpersonateAsSelf)
570  {
571  RevertToSelf();
572  }
573 
574  /*
575  * Finally, check if we actually succeeded on assigning
576  * a primary token to the process. If we failed, oh well,
577  * asta la vista baby e arrivederci. The caller has to do
578  * a rinse and repeat approach.
579  */
580  if (!NT_SUCCESS(Status))
581  {
582  ERR("Failed to assign primary token to the process (Status 0x%08lx)\n", Status);
583  return Status;
584  }
585 
586  return STATUS_SUCCESS;
587 }
#define TRUE
Definition: types.h:120
BOOL WINAPI RevertToSelf(VOID)
Definition: security.c:1610
LONG NTSTATUS
Definition: precomp.h:26
NTSYSAPI NTSTATUS NTAPI RtlAdjustPrivilege(_In_ ULONG Privilege, _In_ BOOLEAN NewValue, _In_ BOOLEAN ForThread, _Out_ PBOOLEAN OldValue)
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI NTSTATUS NTAPI RtlImpersonateSelf(IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
Definition: priv.c:45
#define ERR(fmt,...)
Definition: debug.h:110
NTSTATUS NTAPI NtSetInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, IN PVOID ProcessInformation, IN ULONG ProcessInformationLength)
Definition: query.c:1105
#define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
Definition: security.c:657
#define STATUS_SUCCESS
Definition: shellext.h:65
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403

Referenced by CreateProcessAsUserCommon().

◆ LogonUserA()

BOOL WINAPI LogonUserA ( _In_ LPSTR  lpszUsername,
_In_opt_ LPSTR  lpszDomain,
_In_opt_ LPSTR  lpszPassword,
_In_ DWORD  dwLogonType,
_In_ DWORD  dwLogonProvider,
_Out_opt_ PHANDLE  phToken 
)

Definition at line 1040 of file logon.c.

1047 {
1048  return LogonUserExA(lpszUsername,
1049  lpszDomain,
1050  lpszPassword,
1051  dwLogonType,
1053  phToken,
1054  NULL,
1055  NULL,
1056  NULL,
1057  NULL);
1058 }
BOOL WINAPI LogonUserExA(_In_ LPSTR lpszUsername, _In_opt_ LPSTR lpszDomain, _In_opt_ LPSTR lpszPassword, _In_ DWORD dwLogonType, _In_ DWORD dwLogonProvider, _Out_opt_ PHANDLE phToken, _Out_opt_ PSID *ppLogonSid, _Out_opt_ PVOID *ppProfileBuffer, _Out_opt_ LPDWORD pdwProfileLength, _Out_opt_ PQUOTA_LIMITS pQuotaLimits)
Definition: logon.c:1066
_In_opt_ LPSTR _In_opt_ LPSTR lpszPassword
Definition: winbase.h:2698
_In_opt_ LPSTR _In_opt_ LPSTR _In_ DWORD _In_ DWORD _Out_opt_ PHANDLE phToken
Definition: winbase.h:2698
_In_opt_ LPSTR lpszDomain
Definition: winbase.h:2698
#define NULL
Definition: types.h:112
_In_opt_ LPSTR _In_opt_ LPSTR _In_ DWORD dwLogonType
Definition: winbase.h:2698
_In_opt_ LPSTR _In_opt_ LPSTR _In_ DWORD _In_ DWORD dwLogonProvider
Definition: winbase.h:2698

◆ LogonUserExA()

BOOL WINAPI LogonUserExA ( _In_ LPSTR  lpszUsername,
_In_opt_ LPSTR  lpszDomain,
_In_opt_ LPSTR  lpszPassword,
_In_ DWORD  dwLogonType,
_In_ DWORD  dwLogonProvider,
_Out_opt_ PHANDLE  phToken,
_Out_opt_ PSID ppLogonSid,
_Out_opt_ PVOID ppProfileBuffer,
_Out_opt_ LPDWORD  pdwProfileLength,
_Out_opt_ PQUOTA_LIMITS  pQuotaLimits 
)

Definition at line 1066 of file logon.c.

1077 {
1078  UNICODE_STRING UserName;
1079  UNICODE_STRING Domain;
1081  BOOL ret = FALSE;
1082 
1083  UserName.Buffer = NULL;
1084  Domain.Buffer = NULL;
1085  Password.Buffer = NULL;
1086 
1087  if (!RtlCreateUnicodeStringFromAsciiz(&UserName, lpszUsername))
1088  {
1090  goto UsernameDone;
1091  }
1092 
1094  {
1096  goto DomainDone;
1097  }
1098 
1100  {
1102  goto PasswordDone;
1103  }
1104 
1105  ret = LogonUserExW(UserName.Buffer,
1106  Domain.Buffer,
1107  Password.Buffer,
1108  dwLogonType,
1110  phToken,
1111  ppLogonSid,
1114  pQuotaLimits);
1115 
1116  if (Password.Buffer != NULL)
1118 
1119 PasswordDone:
1120  if (Domain.Buffer != NULL)
1121  RtlFreeUnicodeString(&Domain);
1122 
1123 DomainDone:
1124  if (UserName.Buffer != NULL)
1125  RtlFreeUnicodeString(&UserName);
1126 
1127 UsernameDone:
1128  return ret;
1129 }
BOOL WINAPI LogonUserExW(_In_ LPWSTR lpszUsername, _In_opt_ LPWSTR lpszDomain, _In_opt_ LPWSTR lpszPassword, _In_ DWORD dwLogonType, _In_ DWORD dwLogonProvider, _Out_opt_ PHANDLE phToken, _Out_opt_ PSID *ppLogonSid, _Out_opt_ PVOID *ppProfileBuffer, _Out_opt_ LPDWORD pdwProfileLength, _Out_opt_ PQUOTA_LIMITS pQuotaLimits)
Definition: logon.c:1163
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
_In_opt_ LPSTR _In_opt_ LPSTR lpszPassword
Definition: winbase.h:2698
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
_In_opt_ LPSTR _In_opt_ LPSTR _In_ DWORD _In_ DWORD _Out_opt_ PHANDLE phToken
Definition: winbase.h:2698
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define SetLastError(x)
Definition: compat.h:752
_In_opt_ LPSTR _In_opt_ LPSTR _In_ DWORD _In_ DWORD _Out_opt_ PHANDLE _Out_opt_ PSID _Out_opt_ PVOID _Out_opt_ LPDWORD _Out_opt_ PQUOTA_LIMITS pQuotaLimits
Definition: winbase.h:2698
_In_opt_ LPSTR _In_opt_ LPSTR _In_ DWORD _In_ DWORD _Out_opt_ PHANDLE _Out_opt_ PSID * ppLogonSid
Definition: winbase.h:2698
int ret
_In_opt_ LPSTR lpszDomain
Definition: winbase.h:2698
#define NULL
Definition: types.h:112
_In_opt_ LPSTR _In_opt_ LPSTR _In_ DWORD dwLogonType
Definition: winbase.h:2698
_In_opt_ LPSTR _In_opt_ LPSTR _In_ DWORD _In_ DWORD dwLogonProvider
Definition: winbase.h:2698
_In_opt_ LPSTR _In_opt_ LPSTR _In_ DWORD _In_ DWORD _Out_opt_ PHANDLE _Out_opt_ PSID _Out_opt_ PVOID * ppProfileBuffer
Definition: winbase.h:2698
_In_opt_ LPSTR _In_opt_ LPSTR _In_ DWORD _In_ DWORD _Out_opt_ PHANDLE _Out_opt_ PSID _Out_opt_ PVOID _Out_opt_ LPDWORD pdwProfileLength
Definition: winbase.h:2698

Referenced by LogonUserA().

◆ LogonUserExW()

BOOL WINAPI LogonUserExW ( _In_ LPWSTR  lpszUsername,
_In_opt_ LPWSTR  lpszDomain,
_In_opt_ LPWSTR  lpszPassword,
_In_ DWORD  dwLogonType,
_In_ DWORD  dwLogonProvider,
_Out_opt_ PHANDLE  phToken,
_Out_opt_ PSID ppLogonSid,
_Out_opt_ PVOID ppProfileBuffer,
_Out_opt_ LPDWORD  pdwProfileLength,
_Out_opt_ PQUOTA_LIMITS  pQuotaLimits 
)

Definition at line 1163 of file logon.c.

1174 {
1177  PSID LogonSid = NULL;
1178  PSID LocalSid = NULL;
1180  UNICODE_STRING DomainName;
1181  UNICODE_STRING UserName;
1183  PMSV1_0_INTERACTIVE_LOGON AuthInfo = NULL;
1184  ULONG AuthInfoLength;
1185  ULONG_PTR Ptr;
1190  LUID Luid = {0, 0};
1191  LUID LogonId = {0, 0};
1193  QUOTA_LIMITS QuotaLimits;
1196  NTSTATUS Status;
1197 
1198  if ((ppProfileBuffer != NULL && pdwProfileLength == NULL) ||
1200  {
1202  return FALSE;
1203  }
1204 
1206  {
1207  *ppProfileBuffer = NULL;
1208  *pdwProfileLength = 0;
1209  }
1210 
1211  if (phToken != NULL)
1212  *phToken = NULL;
1213 
1214  switch (dwLogonType)
1215  {
1218  break;
1219 
1220  case LOGON32_LOGON_NETWORK:
1221  LogonType = Network;
1222  break;
1223 
1224  case LOGON32_LOGON_BATCH:
1225  LogonType = Batch;
1226  break;
1227 
1228  case LOGON32_LOGON_SERVICE:
1229  LogonType = Service;
1230  break;
1231 
1232  default:
1233  ERR("Invalid logon type: %ul\n", dwLogonType);
1235  goto done;
1236  }
1237 
1238  if (LsaHandle == NULL)
1239  {
1241  if (!NT_SUCCESS(Status))
1242  goto done;
1243  }
1244 
1246  "Advapi32 Logon");
1247 
1248  RtlInitUnicodeString(&DomainName,
1249  lpszDomain);
1250 
1251  RtlInitUnicodeString(&UserName,
1252  lpszUsername);
1253 
1255  lpszPassword);
1256 
1257  AuthInfoLength = sizeof(MSV1_0_INTERACTIVE_LOGON)+
1258  DomainName.MaximumLength +
1259  UserName.MaximumLength +
1260  Password.MaximumLength;
1261 
1262  AuthInfo = RtlAllocateHeap(RtlGetProcessHeap(),
1264  AuthInfoLength);
1265  if (AuthInfo == NULL)
1266  {
1268  goto done;
1269  }
1270 
1271  AuthInfo->MessageType = MsV1_0InteractiveLogon;
1272 
1273  Ptr = (ULONG_PTR)AuthInfo + sizeof(MSV1_0_INTERACTIVE_LOGON);
1274 
1275  AuthInfo->LogonDomainName.Length = DomainName.Length;
1276  AuthInfo->LogonDomainName.MaximumLength = DomainName.MaximumLength;
1277  AuthInfo->LogonDomainName.Buffer = (DomainName.Buffer == NULL) ? NULL : (PWCHAR)Ptr;
1278  if (DomainName.MaximumLength > 0)
1279  {
1281  DomainName.Buffer,
1282  DomainName.MaximumLength);
1283 
1284  Ptr += DomainName.MaximumLength;
1285  }
1286 
1287  AuthInfo->UserName.Length = UserName.Length;
1288  AuthInfo->UserName.MaximumLength = UserName.MaximumLength;
1289  AuthInfo->UserName.Buffer = (PWCHAR)Ptr;
1290  if (UserName.MaximumLength > 0)
1291  RtlCopyMemory(AuthInfo->UserName.Buffer,
1292  UserName.Buffer,
1293  UserName.MaximumLength);
1294 
1295  Ptr += UserName.MaximumLength;
1296 
1297  AuthInfo->Password.Length = Password.Length;
1298  AuthInfo->Password.MaximumLength = Password.MaximumLength;
1299  AuthInfo->Password.Buffer = (PWCHAR)Ptr;
1300  if (Password.MaximumLength > 0)
1301  RtlCopyMemory(AuthInfo->Password.Buffer,
1302  Password.Buffer,
1303  Password.MaximumLength);
1304 
1305  /* Create the Logon SID */
1310  LogonId.HighPart,
1311  LogonId.LowPart,
1317  &LogonSid);
1318  if (!NT_SUCCESS(Status))
1319  goto done;
1320 
1321  /* Create the Local SID */
1322  Status = RtlAllocateAndInitializeSid(&LocalAuthority,
1323  1,
1332  &LocalSid);
1333  if (!NT_SUCCESS(Status))
1334  goto done;
1335 
1336  /* Allocate and set the token groups */
1337  TokenGroups = RtlAllocateHeap(RtlGetProcessHeap(),
1339  sizeof(TOKEN_GROUPS) + ((2 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES)));
1340  if (TokenGroups == NULL)
1341  {
1343  goto done;
1344  }
1345 
1346  TokenGroups->GroupCount = 2;
1347  TokenGroups->Groups[0].Sid = LogonSid;
1348  TokenGroups->Groups[0].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED |
1350  TokenGroups->Groups[1].Sid = LocalSid;
1351  TokenGroups->Groups[1].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED |
1353 
1354  /* Set the token source */
1355  RtlCopyMemory(TokenSource.SourceName,
1357  sizeof(TokenSource.SourceName));
1358  AllocateLocallyUniqueId(&TokenSource.SourceIdentifier);
1359 
1361  &OriginName,
1362  LogonType,
1364  (PVOID)AuthInfo,
1365  AuthInfoLength,
1366  TokenGroups,
1367  &TokenSource,
1368  (PVOID*)&ProfileBuffer,
1370  &Luid,
1371  &TokenHandle,
1372  &QuotaLimits,
1373  &SubStatus);
1374  if (!NT_SUCCESS(Status))
1375  {
1376  ERR("LsaLogonUser failed (Status 0x%08lx)\n", Status);
1377  goto done;
1378  }
1379 
1380  if (ProfileBuffer != NULL)
1381  {
1382  TRACE("ProfileBuffer: %p\n", ProfileBuffer);
1383  TRACE("MessageType: %u\n", ProfileBuffer->MessageType);
1384 
1385  TRACE("FullName: %p\n", ProfileBuffer->FullName.Buffer);
1386  TRACE("FullName: %S\n", ProfileBuffer->FullName.Buffer);
1387 
1388  TRACE("LogonServer: %p\n", ProfileBuffer->LogonServer.Buffer);
1389  TRACE("LogonServer: %S\n", ProfileBuffer->LogonServer.Buffer);
1390  }
1391 
1392  TRACE("Luid: 0x%08lx%08lx\n", Luid.HighPart, Luid.LowPart);
1393 
1394  if (TokenHandle != NULL)
1395  {
1396  TRACE("TokenHandle: %p\n", TokenHandle);
1397  }
1398 
1399  if (phToken != NULL)
1400  *phToken = TokenHandle;
1401 
1402  /* FIXME: return ppLogonSid and pQuotaLimits */
1403 
1404 done:
1405  if (ProfileBuffer != NULL)
1407 
1408  if (!NT_SUCCESS(Status))
1409  {
1410  if (TokenHandle != NULL)
1412  }
1413 
1414  if (TokenGroups != NULL)
1415  RtlFreeHeap(RtlGetProcessHeap(), 0, TokenGroups);
1416 
1417  if (LocalSid != NULL)
1419 
1420  if (LogonSid != NULL)
1421  RtlFreeSid(LogonSid);
1422 
1423  if (AuthInfo != NULL)
1424  RtlFreeHeap(RtlGetProcessHeap(), 0, AuthInfo);
1425 
1426  if (!NT_SUCCESS(Status))
1427  {
1429  return FALSE;
1430  }
1431 
1432  return TRUE;
1433 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
NTSTATUS NTAPI LsaLogonUser(HANDLE, PLSA_STRING, SECURITY_LOGON_TYPE, ULONG, PVOID, ULONG, PTOKEN_GROUPS, PTOKEN_SOURCE, PVOID *, PULONG, PLUID, PHANDLE, PQUOTA_LIMITS, PNTSTATUS)
#define CloseHandle
Definition: compat.h:739
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
MSV1_0_LOGON_SUBMIT_TYPE MessageType
Definition: ntsecapi.h:434
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define ANYSIZE_ARRAY
Definition: typedefs.h:46
#define TRUE
Definition: types.h:120
#define LOGON32_LOGON_BATCH
Definition: winbase.h:393
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSYSAPI PVOID NTAPI RtlFreeSid(_In_ _Post_invalid_ PSID Sid)
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
_In_opt_ LPSTR _In_opt_ LPSTR lpszPassword
Definition: winbase.h:2698
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID _Out_ PULONG ProfileBufferLength
uint16_t * PWCHAR
Definition: typedefs.h:56
PSID LocalSid
Definition: globals.c:15
NTSYSAPI NTSTATUS NTAPI RtlAllocateAndInitializeSid(IN PSID_IDENTIFIER_AUTHORITY IdentifierAuthority, IN UCHAR SubAuthorityCount, IN ULONG SubAuthority0, IN ULONG SubAuthority1, IN ULONG SubAuthority2, IN ULONG SubAuthority3, IN ULONG SubAuthority4, IN ULONG SubAuthority5, IN ULONG SubAuthority6, IN ULONG SubAuthority7, OUT PSID *Sid)
Definition: sid.c:290
_IRQL_requires_same_ _In_ PLSA_STRING OriginName
UNICODE_STRING Password
Definition: ntsecapi.h:437
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define SECURITY_LOGON_IDS_RID_COUNT
Definition: setypes.h:561
HANDLE LsaHandle
Definition: logon.c:17
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
#define FALSE
Definition: types.h:117
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID _Out_ PULONG _Inout_ PLUID _Out_ PHANDLE _Out_ PQUOTA_LIMITS _Out_ PNTSTATUS SubStatus
#define SECURITY_LOCAL_SID_AUTHORITY
Definition: setypes.h:530
#define SE_GROUP_ENABLED_BY_DEFAULT
Definition: setypes.h:91
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:715
static NTSTATUS OpenLogonLsaHandle(VOID)
Definition: logon.c:24
#define LOGON32_LOGON_SERVICE
Definition: winbase.h:394
#define SECURITY_NT_AUTHORITY
Definition: setypes.h:554
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
Status
Definition: gdiplustypes.h:24
struct _MSV1_0_INTERACTIVE_LOGON MSV1_0_INTERACTIVE_LOGON
UNICODE_STRING UserName
Definition: ntsecapi.h:436
#define TRACE(s)
Definition: solgame.cpp:4
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SE_GROUP_ENABLED
Definition: setypes.h:92
DWORD LowPart
#define SECURITY_LOCAL_RID
Definition: setypes.h:542
_In_opt_ LPSTR _In_opt_ LPSTR _In_ DWORD _In_ DWORD _Out_opt_ PHANDLE phToken
Definition: winbase.h:2698
PCHAR Buffer
Definition: ntsecapi.h:174
#define SetLastError(x)
Definition: compat.h:752
#define SE_GROUP_MANDATORY
Definition: setypes.h:90
#define SECURITY_NULL_RID
Definition: setypes.h:540
LONG HighPart
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID * ProfileBuffer
ULONG AuthenticationPackage
Definition: logon.c:18
#define LOGON32_LOGON_INTERACTIVE
Definition: winbase.h:391
#define SE_GROUP_LOGON_ID
Definition: setypes.h:98
#define ERR(fmt,...)
Definition: debug.h:110
#define LOGON32_LOGON_NETWORK
Definition: winbase.h:392
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE LogonType
BOOL WINAPI AllocateLocallyUniqueId(PLUID Luid)
Definition: security.c:1220
enum _SECURITY_LOGON_TYPE SECURITY_LOGON_TYPE
_In_opt_ LPSTR lpszDomain
Definition: winbase.h:2698
#define NULL
Definition: types.h:112
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID _Out_ PULONG _Inout_ PLUID LogonId
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
_In_opt_ LPSTR _In_opt_ LPSTR _In_ DWORD dwLogonType
Definition: winbase.h:2698
#define SECURITY_LOGON_IDS_RID
Definition: setypes.h:560
NTSTATUS NTAPI LsaFreeReturnBuffer(PVOID)
_In_opt_ LPSTR _In_opt_ LPSTR _In_ DWORD _In_ DWORD _Out_opt_ PHANDLE _Out_opt_ PSID _Out_opt_ PVOID * ppProfileBuffer
Definition: winbase.h:2698
static const CHAR AdvapiTokenSourceName[]
Definition: logon.c:14
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define ULONG_PTR
Definition: config.h:101
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
_In_opt_ LPSTR _In_opt_ LPSTR _In_ DWORD _In_ DWORD _Out_opt_ PHANDLE _Out_opt_ PSID _Out_opt_ PVOID _Out_opt_ LPDWORD pdwProfileLength
Definition: winbase.h:2698
UNICODE_STRING LogonDomainName
Definition: ntsecapi.h:435
static SID_IDENTIFIER_AUTHORITY SystemAuthority
Definition: msgina.c:38

Referenced by LogonUserExA(), and LogonUserW().

◆ LogonUserW()

BOOL WINAPI LogonUserW ( _In_ LPWSTR  lpszUsername,
_In_opt_ LPWSTR  lpszDomain,
_In_opt_ LPWSTR  lpszPassword,
_In_ DWORD  dwLogonType,
_In_ DWORD  dwLogonProvider,
_Out_opt_ PHANDLE  phToken 
)

Definition at line 1137 of file logon.c.

1144 {
1145  return LogonUserExW(lpszUsername,
1146  lpszDomain,
1147  lpszPassword,
1148  dwLogonType,
1150  phToken,
1151  NULL,
1152  NULL,
1153  NULL,
1154  NULL);
1155 }
BOOL WINAPI LogonUserExW(_In_ LPWSTR lpszUsername, _In_opt_ LPWSTR lpszDomain, _In_opt_ LPWSTR lpszPassword, _In_ DWORD dwLogonType, _In_ DWORD dwLogonProvider, _Out_opt_ PHANDLE phToken, _Out_opt_ PSID *ppLogonSid, _Out_opt_ PVOID *ppProfileBuffer, _Out_opt_ LPDWORD pdwProfileLength, _Out_opt_ PQUOTA_LIMITS pQuotaLimits)
Definition: logon.c:1163
_In_opt_ LPSTR _In_opt_ LPSTR lpszPassword
Definition: winbase.h:2698
_In_opt_ LPSTR _In_opt_ LPSTR _In_ DWORD _In_ DWORD _Out_opt_ PHANDLE phToken
Definition: winbase.h:2698
_In_opt_ LPSTR lpszDomain
Definition: winbase.h:2698
#define NULL
Definition: types.h:112
_In_opt_ LPSTR _In_opt_ LPSTR _In_ DWORD dwLogonType
Definition: winbase.h:2698
_In_opt_ LPSTR _In_opt_ LPSTR _In_ DWORD _In_ DWORD dwLogonProvider
Definition: winbase.h:2698

Referenced by ScmLogonService().

◆ OpenLogonLsaHandle()

static NTSTATUS OpenLogonLsaHandle ( VOID  )
static

Definition at line 24 of file logon.c.

25 {
26  LSA_STRING LogonProcessName;
27  LSA_STRING PackageName;
30 
31  RtlInitAnsiString((PANSI_STRING)&LogonProcessName,
32  "User32LogonProcess");
33 
34  Status = LsaRegisterLogonProcess(&LogonProcessName,
35  &LsaHandle,
36  &SecurityMode);
37  if (!NT_SUCCESS(Status))
38  {
39  TRACE("LsaRegisterLogonProcess failed (Status 0x%08lx)\n", Status);
40  goto done;
41  }
42 
43  RtlInitAnsiString((PANSI_STRING)&PackageName,
45 
47  &PackageName,
49  if (!NT_SUCCESS(Status))
50  {
51  TRACE("LsaLookupAuthenticationPackage failed (Status 0x%08lx)\n", Status);
52  goto done;
53  }
54 
55  TRACE("AuthenticationPackage: 0x%08lx\n", AuthenticationPackage);
56 
57 done:
58  if (!NT_SUCCESS(Status))
59  {
60  if (LsaHandle != NULL)
61  {
63  if (!NT_SUCCESS(Status))
64  {
65  TRACE("LsaDeregisterLogonProcess failed (Status 0x%08lx)\n", Status);
66  }
67  }
68  }
69 
70  return Status;
71 }
#define MSV1_0_PACKAGE_NAME
Definition: ntsecapi.h:42
LONG NTSTATUS
Definition: precomp.h:26
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
HANDLE LsaHandle
Definition: logon.c:17
_IRQL_requires_same_ _Out_ PHANDLE _Out_ PLSA_OPERATIONAL_MODE SecurityMode
ULONG LSA_OPERATIONAL_MODE
Definition: ntsecapi.h:367
Status
Definition: gdiplustypes.h:24
#define TRACE(s)
Definition: solgame.cpp:4
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI LsaDeregisterLogonProcess(HANDLE)
ULONG AuthenticationPackage
Definition: logon.c:18
NTSTATUS NTAPI LsaLookupAuthenticationPackage(HANDLE, PLSA_STRING, PULONG)
#define NULL
Definition: types.h:112
NTSTATUS NTAPI LsaRegisterLogonProcess(PLSA_STRING, PHANDLE, PLSA_OPERATIONAL_MODE)

Referenced by LogonUserExW().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( advapi  )

Variable Documentation

◆ AdvapiTokenSourceName

const CHAR AdvapiTokenSourceName[] = "Advapi "
static

Definition at line 14 of file logon.c.

Referenced by LogonUserExW().

◆ AuthenticationPackage

◆ LsaHandle

HANDLE LsaHandle = NULL

Definition at line 17 of file logon.c.

Referenced by CloseLogonLsaHandle(), LogonUserExW(), and OpenLogonLsaHandle().