2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/advapi32/misc/logon.c
5 * PURPOSE: Logon functions
6 * PROGRAMMER: Eric Kohl
10 WINE_DEFAULT_DEBUG_CHANNEL(advapi
);
13 /* FUNCTIONS ***************************************************************/
19 CreateProcessAsUserA(HANDLE hToken
,
20 LPCSTR lpApplicationName
,
22 LPSECURITY_ATTRIBUTES lpProcessAttributes
,
23 LPSECURITY_ATTRIBUTES lpThreadAttributes
,
25 DWORD dwCreationFlags
,
27 LPCSTR lpCurrentDirectory
,
28 LPSTARTUPINFOA lpStartupInfo
,
29 LPPROCESS_INFORMATION lpProcessInformation
)
31 PROCESS_ACCESS_TOKEN AccessToken
;
34 /* Create the process with a suspended main thread */
35 if (!CreateProcessA(lpApplicationName
,
40 dwCreationFlags
| CREATE_SUSPENDED
,
44 lpProcessInformation
))
49 AccessToken
.Token
= hToken
;
50 AccessToken
.Thread
= NULL
;
52 /* Set the new process token */
53 Status
= NtSetInformationProcess(lpProcessInformation
->hProcess
,
57 if (!NT_SUCCESS (Status
))
59 SetLastError(RtlNtStatusToDosError(Status
));
63 /* Resume the main thread */
64 if (!(dwCreationFlags
& CREATE_SUSPENDED
))
66 ResumeThread(lpProcessInformation
->hThread
);
77 CreateProcessAsUserW(HANDLE hToken
,
78 LPCWSTR lpApplicationName
,
80 LPSECURITY_ATTRIBUTES lpProcessAttributes
,
81 LPSECURITY_ATTRIBUTES lpThreadAttributes
,
83 DWORD dwCreationFlags
,
85 LPCWSTR lpCurrentDirectory
,
86 LPSTARTUPINFOW lpStartupInfo
,
87 LPPROCESS_INFORMATION lpProcessInformation
)
89 PROCESS_ACCESS_TOKEN AccessToken
;
92 /* Create the process with a suspended main thread */
93 if (!CreateProcessW(lpApplicationName
,
98 dwCreationFlags
| CREATE_SUSPENDED
,
102 lpProcessInformation
))
107 AccessToken
.Token
= hToken
;
108 AccessToken
.Thread
= NULL
;
110 /* Set the new process token */
111 Status
= NtSetInformationProcess(lpProcessInformation
->hProcess
,
114 sizeof(AccessToken
));
115 if (!NT_SUCCESS (Status
))
117 SetLastError(RtlNtStatusToDosError(Status
));
121 /* Resume the main thread */
122 if (!(dwCreationFlags
& CREATE_SUSPENDED
))
124 ResumeThread(lpProcessInformation
->hThread
);
134 CreateProcessWithLogonW(LPCWSTR lpUsername
,
138 LPCWSTR lpApplicationName
,
139 LPWSTR lpCommandLine
,
140 DWORD dwCreationFlags
,
141 LPVOID lpEnvironment
,
142 LPCWSTR lpCurrentDirectory
,
143 LPSTARTUPINFOW lpStartupInfo
,
144 LPPROCESS_INFORMATION lpProcessInformation
)
146 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername
), debugstr_w(lpDomain
),
147 debugstr_w(lpPassword
), dwLogonFlags
, debugstr_w(lpApplicationName
),
148 debugstr_w(lpCommandLine
), dwCreationFlags
, lpEnvironment
, debugstr_w(lpCurrentDirectory
),
149 lpStartupInfo
, lpProcessInformation
);
158 LogonUserA(LPSTR lpszUsername
,
162 DWORD dwLogonProvider
,
165 UNICODE_STRING UserName
;
166 UNICODE_STRING Domain
;
167 UNICODE_STRING Password
;
170 UserName
.Buffer
= NULL
;
171 Domain
.Buffer
= NULL
;
172 Password
.Buffer
= NULL
;
174 if (!RtlCreateUnicodeStringFromAsciiz(&UserName
, lpszUsername
))
176 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
180 if (!RtlCreateUnicodeStringFromAsciiz(&Domain
, lpszDomain
))
182 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
186 if (!RtlCreateUnicodeStringFromAsciiz(&Password
, lpszPassword
))
188 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
192 ret
= LogonUserW(UserName
.Buffer
,
199 if (Password
.Buffer
!= NULL
)
200 RtlFreeUnicodeString(&Password
);
203 if (Domain
.Buffer
!= NULL
)
204 RtlFreeUnicodeString(&Domain
);
207 if (UserName
.Buffer
!= NULL
)
208 RtlFreeUnicodeString(&UserName
);
216 GetAccountDomainSid(PSID
*Sid
)
218 PPOLICY_ACCOUNT_DOMAIN_INFO Info
= NULL
;
219 LSA_OBJECT_ATTRIBUTES ObjectAttributes
;
220 LSA_HANDLE PolicyHandle
;
227 memset(&ObjectAttributes
, 0, sizeof(LSA_OBJECT_ATTRIBUTES
));
228 ObjectAttributes
.Length
= sizeof(LSA_OBJECT_ATTRIBUTES
);
230 Status
= LsaOpenPolicy(NULL
,
232 POLICY_VIEW_LOCAL_INFORMATION
,
234 if (!NT_SUCCESS(Status
))
236 ERR("LsaOpenPolicy failed (Status: 0x%08lx)\n", Status
);
240 Status
= LsaQueryInformationPolicy(PolicyHandle
,
241 PolicyAccountDomainInformation
,
243 if (!NT_SUCCESS(Status
))
245 ERR("LsaQueryInformationPolicy failed (Status: 0x%08lx)\n", Status
);
246 LsaClose(PolicyHandle
);
250 Length
= RtlLengthSid(Info
->DomainSid
);
252 lpSid
= RtlAllocateHeap(RtlGetProcessHeap(),
257 ERR("Failed to allocate SID buffer!\n");
259 LsaClose(PolicyHandle
);
263 memcpy(lpSid
, Info
->DomainSid
, Length
);
268 LsaClose(PolicyHandle
);
275 AppendRidToSid(PSID SrcSid
,
278 ULONG Rids
[8] = {0, 0, 0, 0, 0, 0, 0, 0};
283 RidCount
= *RtlSubAuthorityCountSid(SrcSid
);
287 for (i
= 0; i
< RidCount
; i
++)
288 Rids
[i
] = *RtlSubAuthoritySid(SrcSid
, i
);
290 Rids
[RidCount
] = Rid
;
293 RtlAllocateAndInitializeSid(RtlIdentifierAuthoritySid(SrcSid
),
310 GetUserSid(LPCWSTR UserName
,
313 PSID SidBuffer
= NULL
;
314 PWSTR DomainBuffer
= NULL
;
316 DWORD cchDomSize
= 0;
322 LookupAccountNameW(NULL
,
330 if (cbSidSize
== 0 || cchDomSize
== 0)
333 SidBuffer
= RtlAllocateHeap(RtlGetProcessHeap(),
336 if (SidBuffer
== NULL
)
339 DomainBuffer
= RtlAllocateHeap(RtlGetProcessHeap(),
341 cchDomSize
* sizeof(WCHAR
));
342 if (DomainBuffer
== NULL
)
348 if (!LookupAccountNameW(NULL
,
360 if (Use
!= SidTypeUser
)
369 if (DomainBuffer
!= NULL
)
370 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainBuffer
);
374 if (SidBuffer
!= NULL
)
375 RtlFreeHeap(RtlGetProcessHeap(), 0, SidBuffer
);
383 AllocateGroupSids(OUT PSID
*PrimaryGroupSid
,
386 SID_IDENTIFIER_AUTHORITY WorldAuthority
= {SECURITY_WORLD_SID_AUTHORITY
};
387 SID_IDENTIFIER_AUTHORITY LocalAuthority
= {SECURITY_LOCAL_SID_AUTHORITY
};
388 SID_IDENTIFIER_AUTHORITY SystemAuthority
= {SECURITY_NT_AUTHORITY
};
389 PTOKEN_GROUPS TokenGroups
;
391 DWORD GroupCount
= 0;
397 Status
= NtAllocateLocallyUniqueId(&Luid
);
398 if (!NT_SUCCESS(Status
))
401 if (!GetAccountDomainSid(&DomainSid
))
404 TokenGroups
= RtlAllocateHeap(
406 sizeof(TOKEN_GROUPS
) +
407 MAX_GROUPS
* sizeof(SID_AND_ATTRIBUTES
));
408 if (TokenGroups
== NULL
)
410 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid
);
414 Sid
= AppendRidToSid(DomainSid
, DOMAIN_GROUP_RID_USERS
);
415 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid
);
417 /* Member of the domain */
418 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
419 TokenGroups
->Groups
[GroupCount
].Attributes
=
420 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
421 *PrimaryGroupSid
= Sid
;
424 /* Member of 'Everyone' */
425 RtlAllocateAndInitializeSid(&WorldAuthority
,
436 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
437 TokenGroups
->Groups
[GroupCount
].Attributes
=
438 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
442 /* Member of 'Administrators' */
443 RtlAllocateAndInitializeSid(&SystemAuthority
,
445 SECURITY_BUILTIN_DOMAIN_RID
,
446 DOMAIN_ALIAS_RID_ADMINS
,
454 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
455 TokenGroups
->Groups
[GroupCount
].Attributes
=
456 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
459 TRACE("Not adding user to Administrators group\n");
462 /* Member of 'Users' */
463 RtlAllocateAndInitializeSid(&SystemAuthority
,
465 SECURITY_BUILTIN_DOMAIN_RID
,
466 DOMAIN_ALIAS_RID_USERS
,
474 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
475 TokenGroups
->Groups
[GroupCount
].Attributes
=
476 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
480 RtlAllocateAndInitializeSid(&SystemAuthority
,
481 SECURITY_LOGON_IDS_RID_COUNT
,
482 SECURITY_LOGON_IDS_RID
,
491 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
492 TokenGroups
->Groups
[GroupCount
].Attributes
=
493 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
| SE_GROUP_LOGON_ID
;
497 /* Member of 'Local users */
498 RtlAllocateAndInitializeSid(&LocalAuthority
,
509 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
510 TokenGroups
->Groups
[GroupCount
].Attributes
=
511 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
514 /* Member of 'Interactive users' */
515 RtlAllocateAndInitializeSid(&SystemAuthority
,
517 SECURITY_INTERACTIVE_RID
,
526 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
527 TokenGroups
->Groups
[GroupCount
].Attributes
=
528 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
531 /* Member of 'Authenticated users' */
532 RtlAllocateAndInitializeSid(&SystemAuthority
,
534 SECURITY_AUTHENTICATED_USER_RID
,
543 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
544 TokenGroups
->Groups
[GroupCount
].Attributes
=
545 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
548 TokenGroups
->GroupCount
= GroupCount
;
549 ASSERT(TokenGroups
->GroupCount
<= MAX_GROUPS
);
556 FreeGroupSids(PTOKEN_GROUPS TokenGroups
)
560 for (i
= 0; i
< TokenGroups
->GroupCount
; i
++)
562 if (TokenGroups
->Groups
[i
].Sid
!= NULL
)
563 RtlFreeHeap(GetProcessHeap(), 0, TokenGroups
->Groups
[i
].Sid
);
566 RtlFreeHeap(GetProcessHeap(), 0, TokenGroups
);
574 LogonUserW(LPWSTR lpszUsername
,
578 DWORD dwLogonProvider
,
581 /* FIXME shouldn't use hard-coded list of privileges */
589 { L
"SeMachineAccountPrivilege", 0 },
590 { L
"SeSecurityPrivilege", 0 },
591 { L
"SeTakeOwnershipPrivilege", 0 },
592 { L
"SeLoadDriverPrivilege", 0 },
593 { L
"SeSystemProfilePrivilege", 0 },
594 { L
"SeSystemtimePrivilege", 0 },
595 { L
"SeProfileSingleProcessPrivilege", 0 },
596 { L
"SeIncreaseBasePriorityPrivilege", 0 },
597 { L
"SeCreatePagefilePrivilege", 0 },
598 { L
"SeBackupPrivilege", 0 },
599 { L
"SeRestorePrivilege", 0 },
600 { L
"SeShutdownPrivilege", 0 },
601 { L
"SeDebugPrivilege", 0 },
602 { L
"SeSystemEnvironmentPrivilege", 0 },
603 { L
"SeChangeNotifyPrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
},
604 { L
"SeRemoteShutdownPrivilege", 0 },
605 { L
"SeUndockPrivilege", 0 },
606 { L
"SeEnableDelegationPrivilege", 0 },
607 { L
"SeImpersonatePrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
},
608 { L
"SeCreateGlobalPrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
}
610 OBJECT_ATTRIBUTES ObjectAttributes
;
611 SECURITY_QUALITY_OF_SERVICE Qos
;
612 TOKEN_USER TokenUser
;
613 TOKEN_OWNER TokenOwner
;
614 TOKEN_PRIMARY_GROUP TokenPrimaryGroup
;
615 PTOKEN_GROUPS TokenGroups
= NULL
;
616 PTOKEN_PRIVILEGES TokenPrivileges
= NULL
;
617 TOKEN_DEFAULT_DACL TokenDefaultDacl
;
618 LARGE_INTEGER ExpirationTime
;
619 LUID AuthenticationId
;
620 TOKEN_SOURCE TokenSource
;
622 PSID PrimaryGroupSid
= NULL
;
623 PSID OwnerSid
= NULL
;
626 SID_IDENTIFIER_AUTHORITY SystemAuthority
= {SECURITY_NT_AUTHORITY
};
628 NTSTATUS Status
= STATUS_SUCCESS
;
630 Qos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
631 Qos
.ImpersonationLevel
= SecurityAnonymous
;
632 Qos
.ContextTrackingMode
= SECURITY_STATIC_TRACKING
;
633 Qos
.EffectiveOnly
= FALSE
;
635 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
636 ObjectAttributes
.RootDirectory
= NULL
;
637 ObjectAttributes
.ObjectName
= NULL
;
638 ObjectAttributes
.Attributes
= 0;
639 ObjectAttributes
.SecurityDescriptor
= NULL
;
640 ObjectAttributes
.SecurityQualityOfService
= &Qos
;
642 Status
= NtAllocateLocallyUniqueId(&AuthenticationId
);
643 if (!NT_SUCCESS(Status
))
648 ExpirationTime
.QuadPart
= -1;
650 /* Get the user SID from the registry */
651 if (!GetUserSid (lpszUsername
, &UserSid
))
653 ERR("SamGetUserSid() failed\n");
657 TokenUser
.User
.Sid
= UserSid
;
658 TokenUser
.User
.Attributes
= 0;
660 /* Allocate and initialize token groups */
661 TokenGroups
= AllocateGroupSids(&PrimaryGroupSid
,
663 if (TokenGroups
== NULL
)
665 Status
= STATUS_INSUFFICIENT_RESOURCES
;
669 /* Allocate and initialize token privileges */
670 TokenPrivileges
= RtlAllocateHeap(GetProcessHeap(), 0,
671 sizeof(TOKEN_PRIVILEGES
)
672 + sizeof(DefaultPrivs
) / sizeof(DefaultPrivs
[0])
673 * sizeof(LUID_AND_ATTRIBUTES
));
674 if (TokenPrivileges
== NULL
)
676 Status
= STATUS_INSUFFICIENT_RESOURCES
;
680 TokenPrivileges
->PrivilegeCount
= 0;
681 for (i
= 0; i
< sizeof(DefaultPrivs
) / sizeof(DefaultPrivs
[0]); i
++)
683 if (! LookupPrivilegeValueW(NULL
,
684 DefaultPrivs
[i
].PrivName
,
685 &TokenPrivileges
->Privileges
[TokenPrivileges
->PrivilegeCount
].Luid
))
687 WARN("Can't set privilege %S\n", DefaultPrivs
[i
].PrivName
);
691 TokenPrivileges
->Privileges
[TokenPrivileges
->PrivilegeCount
].Attributes
= DefaultPrivs
[i
].Attributes
;
692 TokenPrivileges
->PrivilegeCount
++;
696 TokenOwner
.Owner
= OwnerSid
;
697 TokenPrimaryGroup
.PrimaryGroup
= PrimaryGroupSid
;
699 Dacl
= RtlAllocateHeap(GetProcessHeap(), 0, 1024);
702 Status
= STATUS_INSUFFICIENT_RESOURCES
;
706 Status
= RtlCreateAcl(Dacl
, 1024, ACL_REVISION
);
707 if (!NT_SUCCESS(Status
))
710 RtlAddAccessAllowedAce(Dacl
,
715 RtlAllocateAndInitializeSid(&SystemAuthority
,
717 SECURITY_LOCAL_SYSTEM_RID
,
728 RtlAddAccessAllowedAce(Dacl
,
733 RtlFreeSid(LocalSystemSid
);
735 TokenDefaultDacl
.DefaultDacl
= Dacl
;
737 memcpy(TokenSource
.SourceName
,
741 Status
= NtAllocateLocallyUniqueId(&TokenSource
.SourceIdentifier
);
742 if (!NT_SUCCESS(Status
))
744 RtlFreeHeap(GetProcessHeap(), 0, Dacl
);
745 FreeGroupSids(TokenGroups
);
746 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges
);
751 Status
= NtCreateToken(phToken
,
767 RtlFreeHeap(GetProcessHeap(), 0, Dacl
);
769 if (TokenGroups
!= NULL
)
770 FreeGroupSids(TokenGroups
);
772 if (TokenPrivileges
!= NULL
)
773 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges
);
776 RtlFreeHeap(GetProcessHeap(), 0, UserSid
);
778 return NT_SUCCESS(Status
);