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 AccountDomainSid
= NULL
;
316 HKEY hNamesKey
= NULL
;
319 if (!GetAccountDomainSid(&AccountDomainSid
))
324 /* Open the Users\Names key */
325 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
326 L
"SAM\\SAM\\Domains\\Account\\Users\\Names",
331 ERR("Failed to open Users\\Names key! (Error %lu)\n", GetLastError());
336 /* Read the user RID */
337 dwLength
= sizeof(ULONG
);
338 if (RegQueryValueExW(hNamesKey
,
345 ERR("Failed to read the SID! (Error %ld)\n", GetLastError());
350 *Sid
= AppendRidToSid(AccountDomainSid
, ulUserRid
);
353 if (hNamesKey
!= NULL
)
354 RegCloseKey(hNamesKey
);
356 if (AccountDomainSid
!= NULL
)
357 RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid
);
364 AllocateGroupSids(OUT PSID
*PrimaryGroupSid
,
367 SID_IDENTIFIER_AUTHORITY WorldAuthority
= {SECURITY_WORLD_SID_AUTHORITY
};
368 SID_IDENTIFIER_AUTHORITY LocalAuthority
= {SECURITY_LOCAL_SID_AUTHORITY
};
369 SID_IDENTIFIER_AUTHORITY SystemAuthority
= {SECURITY_NT_AUTHORITY
};
370 PTOKEN_GROUPS TokenGroups
;
372 DWORD GroupCount
= 0;
378 Status
= NtAllocateLocallyUniqueId(&Luid
);
379 if (!NT_SUCCESS(Status
))
382 if (!GetAccountDomainSid(&DomainSid
))
385 TokenGroups
= RtlAllocateHeap(
387 sizeof(TOKEN_GROUPS
) +
388 MAX_GROUPS
* sizeof(SID_AND_ATTRIBUTES
));
389 if (TokenGroups
== NULL
)
391 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid
);
395 Sid
= AppendRidToSid(DomainSid
, DOMAIN_GROUP_RID_USERS
);
396 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid
);
398 /* Member of the domain */
399 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
400 TokenGroups
->Groups
[GroupCount
].Attributes
=
401 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
402 *PrimaryGroupSid
= Sid
;
405 /* Member of 'Everyone' */
406 RtlAllocateAndInitializeSid(&WorldAuthority
,
417 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
418 TokenGroups
->Groups
[GroupCount
].Attributes
=
419 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
423 /* Member of 'Administrators' */
424 RtlAllocateAndInitializeSid(&SystemAuthority
,
426 SECURITY_BUILTIN_DOMAIN_RID
,
427 DOMAIN_ALIAS_RID_ADMINS
,
435 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
436 TokenGroups
->Groups
[GroupCount
].Attributes
=
437 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
440 TRACE("Not adding user to Administrators group\n");
443 /* Member of 'Users' */
444 RtlAllocateAndInitializeSid(&SystemAuthority
,
446 SECURITY_BUILTIN_DOMAIN_RID
,
447 DOMAIN_ALIAS_RID_USERS
,
455 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
456 TokenGroups
->Groups
[GroupCount
].Attributes
=
457 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
461 RtlAllocateAndInitializeSid(&SystemAuthority
,
462 SECURITY_LOGON_IDS_RID_COUNT
,
463 SECURITY_LOGON_IDS_RID
,
472 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
473 TokenGroups
->Groups
[GroupCount
].Attributes
=
474 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
| SE_GROUP_LOGON_ID
;
478 /* Member of 'Local users */
479 RtlAllocateAndInitializeSid(&LocalAuthority
,
490 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
491 TokenGroups
->Groups
[GroupCount
].Attributes
=
492 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
495 /* Member of 'Interactive users' */
496 RtlAllocateAndInitializeSid(&SystemAuthority
,
498 SECURITY_INTERACTIVE_RID
,
507 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
508 TokenGroups
->Groups
[GroupCount
].Attributes
=
509 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
512 /* Member of 'Authenticated users' */
513 RtlAllocateAndInitializeSid(&SystemAuthority
,
515 SECURITY_AUTHENTICATED_USER_RID
,
524 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
525 TokenGroups
->Groups
[GroupCount
].Attributes
=
526 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
529 TokenGroups
->GroupCount
= GroupCount
;
530 ASSERT(TokenGroups
->GroupCount
<= MAX_GROUPS
);
537 FreeGroupSids(PTOKEN_GROUPS TokenGroups
)
541 for (i
= 0; i
< TokenGroups
->GroupCount
; i
++)
543 if (TokenGroups
->Groups
[i
].Sid
!= NULL
)
544 RtlFreeHeap(GetProcessHeap(), 0, TokenGroups
->Groups
[i
].Sid
);
547 RtlFreeHeap(GetProcessHeap(), 0, TokenGroups
);
555 LogonUserW(LPWSTR lpszUsername
,
559 DWORD dwLogonProvider
,
562 /* FIXME shouldn't use hard-coded list of privileges */
570 { L
"SeMachineAccountPrivilege", 0 },
571 { L
"SeSecurityPrivilege", 0 },
572 { L
"SeTakeOwnershipPrivilege", 0 },
573 { L
"SeLoadDriverPrivilege", 0 },
574 { L
"SeSystemProfilePrivilege", 0 },
575 { L
"SeSystemtimePrivilege", 0 },
576 { L
"SeProfileSingleProcessPrivilege", 0 },
577 { L
"SeIncreaseBasePriorityPrivilege", 0 },
578 { L
"SeCreatePagefilePrivilege", 0 },
579 { L
"SeBackupPrivilege", 0 },
580 { L
"SeRestorePrivilege", 0 },
581 { L
"SeShutdownPrivilege", 0 },
582 { L
"SeDebugPrivilege", 0 },
583 { L
"SeSystemEnvironmentPrivilege", 0 },
584 { L
"SeChangeNotifyPrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
},
585 { L
"SeRemoteShutdownPrivilege", 0 },
586 { L
"SeUndockPrivilege", 0 },
587 { L
"SeEnableDelegationPrivilege", 0 },
588 { L
"SeImpersonatePrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
},
589 { L
"SeCreateGlobalPrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
}
591 OBJECT_ATTRIBUTES ObjectAttributes
;
592 SECURITY_QUALITY_OF_SERVICE Qos
;
593 TOKEN_USER TokenUser
;
594 TOKEN_OWNER TokenOwner
;
595 TOKEN_PRIMARY_GROUP TokenPrimaryGroup
;
596 PTOKEN_GROUPS TokenGroups
;
597 PTOKEN_PRIVILEGES TokenPrivileges
;
598 TOKEN_DEFAULT_DACL TokenDefaultDacl
;
599 LARGE_INTEGER ExpirationTime
;
600 LUID AuthenticationId
;
601 TOKEN_SOURCE TokenSource
;
603 PSID PrimaryGroupSid
= NULL
;
604 PSID OwnerSid
= NULL
;
608 SID_IDENTIFIER_AUTHORITY SystemAuthority
= {SECURITY_NT_AUTHORITY
};
611 Qos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
612 Qos
.ImpersonationLevel
= SecurityAnonymous
;
613 Qos
.ContextTrackingMode
= SECURITY_STATIC_TRACKING
;
614 Qos
.EffectiveOnly
= FALSE
;
616 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
617 ObjectAttributes
.RootDirectory
= NULL
;
618 ObjectAttributes
.ObjectName
= NULL
;
619 ObjectAttributes
.Attributes
= 0;
620 ObjectAttributes
.SecurityDescriptor
= NULL
;
621 ObjectAttributes
.SecurityQualityOfService
= &Qos
;
623 Status
= NtAllocateLocallyUniqueId(&AuthenticationId
);
624 if (!NT_SUCCESS(Status
))
629 ExpirationTime
.QuadPart
= -1;
631 /* Get the user SID from the registry */
632 if (!GetUserSid (lpszUsername
, &UserSid
))
634 ERR("SamGetUserSid() failed\n");
638 TokenUser
.User
.Sid
= UserSid
;
639 TokenUser
.User
.Attributes
= 0;
641 /* Allocate and initialize token groups */
642 TokenGroups
= AllocateGroupSids(&PrimaryGroupSid
,
644 if (NULL
== TokenGroups
)
647 SetLastError(ERROR_OUTOFMEMORY
);
651 /* Allocate and initialize token privileges */
652 TokenPrivileges
= RtlAllocateHeap(GetProcessHeap(), 0,
653 sizeof(TOKEN_PRIVILEGES
)
654 + sizeof(DefaultPrivs
) / sizeof(DefaultPrivs
[0])
655 * sizeof(LUID_AND_ATTRIBUTES
));
656 if (NULL
== TokenPrivileges
)
658 FreeGroupSids(TokenGroups
);
660 SetLastError(ERROR_OUTOFMEMORY
);
664 TokenPrivileges
->PrivilegeCount
= 0;
665 for (i
= 0; i
< sizeof(DefaultPrivs
) / sizeof(DefaultPrivs
[0]); i
++)
667 if (! LookupPrivilegeValueW(NULL
,
668 DefaultPrivs
[i
].PrivName
,
669 &TokenPrivileges
->Privileges
[TokenPrivileges
->PrivilegeCount
].Luid
))
671 WARN("Can't set privilege %S\n", DefaultPrivs
[i
].PrivName
);
675 TokenPrivileges
->Privileges
[TokenPrivileges
->PrivilegeCount
].Attributes
= DefaultPrivs
[i
].Attributes
;
676 TokenPrivileges
->PrivilegeCount
++;
680 TokenOwner
.Owner
= OwnerSid
;
681 TokenPrimaryGroup
.PrimaryGroup
= PrimaryGroupSid
;
683 Dacl
= RtlAllocateHeap(GetProcessHeap(), 0, 1024);
686 FreeGroupSids(TokenGroups
);
688 SetLastError(ERROR_OUTOFMEMORY
);
692 Status
= RtlCreateAcl(Dacl
, 1024, ACL_REVISION
);
693 if (!NT_SUCCESS(Status
))
695 RtlFreeHeap(GetProcessHeap(), 0, Dacl
);
696 FreeGroupSids(TokenGroups
);
697 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges
);
702 RtlAddAccessAllowedAce(Dacl
,
707 RtlAllocateAndInitializeSid(&SystemAuthority
,
709 SECURITY_LOCAL_SYSTEM_RID
,
720 RtlAddAccessAllowedAce(Dacl
,
725 RtlFreeSid(LocalSystemSid
);
727 TokenDefaultDacl
.DefaultDacl
= Dacl
;
729 memcpy(TokenSource
.SourceName
,
733 Status
= NtAllocateLocallyUniqueId(&TokenSource
.SourceIdentifier
);
734 if (!NT_SUCCESS(Status
))
736 RtlFreeHeap(GetProcessHeap(), 0, Dacl
);
737 FreeGroupSids(TokenGroups
);
738 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges
);
743 Status
= NtCreateToken(phToken
,
757 RtlFreeHeap(GetProcessHeap(), 0, Dacl
);
758 FreeGroupSids(TokenGroups
);
759 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges
);
762 return NT_SUCCESS(Status
);