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
);
133 BOOL WINAPI
CreateProcessWithLogonW( LPCWSTR lpUsername
, LPCWSTR lpDomain
, LPCWSTR lpPassword
, DWORD dwLogonFlags
,
134 LPCWSTR lpApplicationName
, LPWSTR lpCommandLine
, DWORD dwCreationFlags
, LPVOID lpEnvironment
,
135 LPCWSTR lpCurrentDirectory
, LPSTARTUPINFOW lpStartupInfo
, LPPROCESS_INFORMATION lpProcessInformation
)
137 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername
), debugstr_w(lpDomain
),
138 debugstr_w(lpPassword
), dwLogonFlags
, debugstr_w(lpApplicationName
),
139 debugstr_w(lpCommandLine
), dwCreationFlags
, lpEnvironment
, debugstr_w(lpCurrentDirectory
),
140 lpStartupInfo
, lpProcessInformation
);
149 LogonUserA(LPSTR lpszUsername
,
153 DWORD dwLogonProvider
,
156 UNICODE_STRING UserName
;
157 UNICODE_STRING Domain
;
158 UNICODE_STRING Password
;
162 UserName
.Buffer
= NULL
;
163 Domain
.Buffer
= NULL
;
164 Password
.Buffer
= NULL
;
166 Status
= RtlCreateUnicodeStringFromAsciiz(&UserName
,
168 if (!NT_SUCCESS(Status
))
170 SetLastError(RtlNtStatusToDosError(Status
));
174 Status
= RtlCreateUnicodeStringFromAsciiz(&Domain
,
176 if (!NT_SUCCESS(Status
))
178 SetLastError(RtlNtStatusToDosError(Status
));
182 Status
= RtlCreateUnicodeStringFromAsciiz(&Password
,
184 if (!NT_SUCCESS(Status
))
186 SetLastError(RtlNtStatusToDosError(Status
));
190 ret
= LogonUserW(UserName
.Buffer
,
197 if (Password
.Buffer
!= NULL
)
198 RtlFreeUnicodeString(&Password
);
201 if (Domain
.Buffer
!= NULL
)
202 RtlFreeUnicodeString(&Domain
);
205 if (UserName
.Buffer
!= NULL
)
206 RtlFreeUnicodeString(&UserName
);
214 SamGetUserSid(LPCWSTR UserName
,
225 /* Open the Users key */
226 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
227 L
"SAM\\SAM\\Domains\\Account\\Users",
232 ERR("Failed to open Users key! (Error %lu)\n", GetLastError());
236 /* Open the user key */
237 if (RegOpenKeyExW(hUsersKey
,
243 if (GetLastError() == ERROR_FILE_NOT_FOUND
)
245 ERR("Invalid user name!\n");
246 SetLastError(ERROR_NO_SUCH_USER
);
250 ERR("Failed to open user key! (Error %lu)\n", GetLastError());
253 RegCloseKey(hUsersKey
);
257 RegCloseKey (hUsersKey
);
261 if (RegQueryValueExW(hUserKey
,
268 ERR("Failed to read the SID size! (Error %lu)\n", GetLastError());
269 RegCloseKey(hUserKey
);
273 /* Allocate sid buffer */
274 TRACE("Required SID buffer size: %lu\n", dwLength
);
275 lpSid
= (PSID
)RtlAllocateHeap(RtlGetProcessHeap(),
280 ERR("Failed to allocate SID buffer!\n");
281 RegCloseKey(hUserKey
);
286 if (RegQueryValueExW(hUserKey
,
293 ERR("Failed to read the SID! (Error %lu)\n", GetLastError());
294 RtlFreeHeap(RtlGetProcessHeap(),
297 RegCloseKey(hUserKey
);
301 RegCloseKey(hUserKey
);
310 SamGetDomainSid(PSID
*Sid
)
316 TRACE("SamGetDomainSid() called\n");
321 /* Open the account domain key */
322 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
323 L
"SAM\\SAM\\Domains\\Account",
328 ERR("Failed to open the account domain key! (Error %lu)\n", GetLastError());
334 if (RegQueryValueExW(hDomainKey
,
341 ERR("Failed to read the SID size! (Error %lu)\n", GetLastError());
342 RegCloseKey(hDomainKey
);
346 /* Allocate sid buffer */
347 TRACE("Required SID buffer size: %lu\n", dwLength
);
348 lpSid
= (PSID
)RtlAllocateHeap(RtlGetProcessHeap(),
353 ERR("Failed to allocate SID buffer!\n");
354 RegCloseKey(hDomainKey
);
359 if (RegQueryValueExW(hDomainKey
,
366 ERR("Failed to read the SID! (Error %lu)\n", GetLastError());
367 RtlFreeHeap(RtlGetProcessHeap(),
370 RegCloseKey(hDomainKey
);
374 RegCloseKey(hDomainKey
);
378 TRACE("SamGetDomainSid() done\n");
385 AppendRidToSid(PSID SrcSid
,
388 ULONG Rids
[8] = {0, 0, 0, 0, 0, 0, 0, 0};
393 RidCount
= *RtlSubAuthorityCountSid(SrcSid
);
397 for (i
= 0; i
< RidCount
; i
++)
398 Rids
[i
] = *RtlSubAuthoritySid(SrcSid
, i
);
400 Rids
[RidCount
] = Rid
;
403 RtlAllocateAndInitializeSid(RtlIdentifierAuthoritySid(SrcSid
),
420 AllocateGroupSids(OUT PSID
*PrimaryGroupSid
,
423 SID_IDENTIFIER_AUTHORITY WorldAuthority
= {SECURITY_WORLD_SID_AUTHORITY
};
424 SID_IDENTIFIER_AUTHORITY LocalAuthority
= {SECURITY_LOCAL_SID_AUTHORITY
};
425 SID_IDENTIFIER_AUTHORITY SystemAuthority
= {SECURITY_NT_AUTHORITY
};
426 PTOKEN_GROUPS TokenGroups
;
428 DWORD GroupCount
= 0;
434 Status
= NtAllocateLocallyUniqueId(&Luid
);
435 if (!NT_SUCCESS(Status
))
438 if (!SamGetDomainSid(&DomainSid
))
441 TokenGroups
= RtlAllocateHeap(
443 sizeof(TOKEN_GROUPS
) +
444 MAX_GROUPS
* sizeof(SID_AND_ATTRIBUTES
));
445 if (TokenGroups
== NULL
)
447 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid
);
451 Sid
= AppendRidToSid(DomainSid
, DOMAIN_GROUP_RID_USERS
);
452 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid
);
454 /* Member of the domain */
455 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
456 TokenGroups
->Groups
[GroupCount
].Attributes
=
457 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
458 *PrimaryGroupSid
= Sid
;
461 /* Member of 'Everyone' */
462 RtlAllocateAndInitializeSid(&WorldAuthority
,
473 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
474 TokenGroups
->Groups
[GroupCount
].Attributes
=
475 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
479 /* Member of 'Administrators' */
480 RtlAllocateAndInitializeSid(&SystemAuthority
,
482 SECURITY_BUILTIN_DOMAIN_RID
,
483 DOMAIN_ALIAS_RID_ADMINS
,
491 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
492 TokenGroups
->Groups
[GroupCount
].Attributes
=
493 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
496 TRACE("Not adding user to Administrators group\n");
499 /* Member of 'Users' */
500 RtlAllocateAndInitializeSid(&SystemAuthority
,
502 SECURITY_BUILTIN_DOMAIN_RID
,
503 DOMAIN_ALIAS_RID_USERS
,
511 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
512 TokenGroups
->Groups
[GroupCount
].Attributes
=
513 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
517 RtlAllocateAndInitializeSid(&SystemAuthority
,
518 SECURITY_LOGON_IDS_RID_COUNT
,
519 SECURITY_LOGON_IDS_RID
,
528 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
529 TokenGroups
->Groups
[GroupCount
].Attributes
=
530 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
| SE_GROUP_LOGON_ID
;
534 /* Member of 'Local users */
535 RtlAllocateAndInitializeSid(&LocalAuthority
,
546 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
547 TokenGroups
->Groups
[GroupCount
].Attributes
=
548 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
551 /* Member of 'Interactive users' */
552 RtlAllocateAndInitializeSid(&SystemAuthority
,
554 SECURITY_INTERACTIVE_RID
,
563 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
564 TokenGroups
->Groups
[GroupCount
].Attributes
=
565 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
568 /* Member of 'Authenticated users' */
569 RtlAllocateAndInitializeSid(&SystemAuthority
,
571 SECURITY_AUTHENTICATED_USER_RID
,
580 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
581 TokenGroups
->Groups
[GroupCount
].Attributes
=
582 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
585 TokenGroups
->GroupCount
= GroupCount
;
586 ASSERT(TokenGroups
->GroupCount
<= MAX_GROUPS
);
593 FreeGroupSids(PTOKEN_GROUPS TokenGroups
)
597 for (i
= 0; i
< TokenGroups
->GroupCount
; i
++)
599 if (TokenGroups
->Groups
[i
].Sid
!= NULL
)
600 RtlFreeHeap(GetProcessHeap(), 0, TokenGroups
->Groups
[i
].Sid
);
603 RtlFreeHeap(GetProcessHeap(), 0, TokenGroups
);
611 LogonUserW(LPWSTR lpszUsername
,
615 DWORD dwLogonProvider
,
618 /* FIXME shouldn't use hard-coded list of privileges */
626 { L
"SeUnsolicitedInputPrivilege", 0 },
627 { L
"SeMachineAccountPrivilege", 0 },
628 { L
"SeSecurityPrivilege", 0 },
629 { L
"SeTakeOwnershipPrivilege", 0 },
630 { L
"SeLoadDriverPrivilege", 0 },
631 { L
"SeSystemProfilePrivilege", 0 },
632 { L
"SeSystemtimePrivilege", 0 },
633 { L
"SeProfileSingleProcessPrivilege", 0 },
634 { L
"SeIncreaseBasePriorityPrivilege", 0 },
635 { L
"SeCreatePagefilePrivilege", 0 },
636 { L
"SeBackupPrivilege", 0 },
637 { L
"SeRestorePrivilege", 0 },
638 { L
"SeShutdownPrivilege", 0 },
639 { L
"SeDebugPrivilege", 0 },
640 { L
"SeSystemEnvironmentPrivilege", 0 },
641 { L
"SeChangeNotifyPrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
},
642 { L
"SeRemoteShutdownPrivilege", 0 },
643 { L
"SeUndockPrivilege", 0 },
644 { L
"SeEnableDelegationPrivilege", 0 },
645 { L
"SeImpersonatePrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
},
646 { L
"SeCreateGlobalPrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
}
648 OBJECT_ATTRIBUTES ObjectAttributes
;
649 SECURITY_QUALITY_OF_SERVICE Qos
;
650 TOKEN_USER TokenUser
;
651 TOKEN_OWNER TokenOwner
;
652 TOKEN_PRIMARY_GROUP TokenPrimaryGroup
;
653 PTOKEN_GROUPS TokenGroups
;
654 PTOKEN_PRIVILEGES TokenPrivileges
;
655 TOKEN_DEFAULT_DACL TokenDefaultDacl
;
656 LARGE_INTEGER ExpirationTime
;
657 LUID AuthenticationId
;
658 TOKEN_SOURCE TokenSource
;
660 PSID PrimaryGroupSid
= NULL
;
661 PSID OwnerSid
= NULL
;
665 SID_IDENTIFIER_AUTHORITY SystemAuthority
= {SECURITY_NT_AUTHORITY
};
668 Qos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
669 Qos
.ImpersonationLevel
= SecurityAnonymous
;
670 Qos
.ContextTrackingMode
= SECURITY_STATIC_TRACKING
;
671 Qos
.EffectiveOnly
= FALSE
;
673 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
674 ObjectAttributes
.RootDirectory
= NULL
;
675 ObjectAttributes
.ObjectName
= NULL
;
676 ObjectAttributes
.Attributes
= 0;
677 ObjectAttributes
.SecurityDescriptor
= NULL
;
678 ObjectAttributes
.SecurityQualityOfService
= &Qos
;
680 Status
= NtAllocateLocallyUniqueId(&AuthenticationId
);
681 if (!NT_SUCCESS(Status
))
686 ExpirationTime
.QuadPart
= -1;
688 /* Get the user SID from the registry */
689 if (!SamGetUserSid (lpszUsername
, &UserSid
))
691 ERR("SamGetUserSid() failed\n");
695 TokenUser
.User
.Sid
= UserSid
;
696 TokenUser
.User
.Attributes
= 0;
698 /* Allocate and initialize token groups */
699 TokenGroups
= AllocateGroupSids(&PrimaryGroupSid
,
701 if (NULL
== TokenGroups
)
704 SetLastError(ERROR_OUTOFMEMORY
);
708 /* Allocate and initialize token privileges */
709 TokenPrivileges
= RtlAllocateHeap(GetProcessHeap(), 0,
710 sizeof(TOKEN_PRIVILEGES
)
711 + sizeof(DefaultPrivs
) / sizeof(DefaultPrivs
[0])
712 * sizeof(LUID_AND_ATTRIBUTES
));
713 if (NULL
== TokenPrivileges
)
715 FreeGroupSids(TokenGroups
);
717 SetLastError(ERROR_OUTOFMEMORY
);
721 TokenPrivileges
->PrivilegeCount
= 0;
722 for (i
= 0; i
< sizeof(DefaultPrivs
) / sizeof(DefaultPrivs
[0]); i
++)
724 if (! LookupPrivilegeValueW(NULL
,
725 DefaultPrivs
[i
].PrivName
,
726 &TokenPrivileges
->Privileges
[TokenPrivileges
->PrivilegeCount
].Luid
))
728 WARN("Can't set privilege %S\n", DefaultPrivs
[i
].PrivName
);
732 TokenPrivileges
->Privileges
[TokenPrivileges
->PrivilegeCount
].Attributes
= DefaultPrivs
[i
].Attributes
;
733 TokenPrivileges
->PrivilegeCount
++;
737 TokenOwner
.Owner
= OwnerSid
;
738 TokenPrimaryGroup
.PrimaryGroup
= PrimaryGroupSid
;
740 Dacl
= RtlAllocateHeap(GetProcessHeap(), 0, 1024);
743 FreeGroupSids(TokenGroups
);
745 SetLastError(ERROR_OUTOFMEMORY
);
749 Status
= RtlCreateAcl(Dacl
, 1024, ACL_REVISION
);
750 if (!NT_SUCCESS(Status
))
752 RtlFreeHeap(GetProcessHeap(), 0, Dacl
);
753 FreeGroupSids(TokenGroups
);
754 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges
);
759 RtlAddAccessAllowedAce(Dacl
,
764 RtlAllocateAndInitializeSid(&SystemAuthority
,
766 SECURITY_LOCAL_SYSTEM_RID
,
777 RtlAddAccessAllowedAce(Dacl
,
782 RtlFreeSid(LocalSystemSid
);
784 TokenDefaultDacl
.DefaultDacl
= Dacl
;
786 memcpy(TokenSource
.SourceName
,
790 Status
= NtAllocateLocallyUniqueId(&TokenSource
.SourceIdentifier
);
791 if (!NT_SUCCESS(Status
))
793 RtlFreeHeap(GetProcessHeap(), 0, Dacl
);
794 FreeGroupSids(TokenGroups
);
795 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges
);
800 Status
= NtCreateToken(phToken
,
814 RtlFreeHeap(GetProcessHeap(), 0, Dacl
);
815 FreeGroupSids(TokenGroups
);
816 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges
);
819 return NT_SUCCESS(Status
);