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
11 #include <wine/debug.h>
12 WINE_DEFAULT_DEBUG_CHANNEL(advapi
);
15 /* FUNCTIONS ***************************************************************/
21 CreateProcessAsUserA(HANDLE hToken
,
22 LPCSTR lpApplicationName
,
24 LPSECURITY_ATTRIBUTES lpProcessAttributes
,
25 LPSECURITY_ATTRIBUTES lpThreadAttributes
,
27 DWORD dwCreationFlags
,
29 LPCSTR lpCurrentDirectory
,
30 LPSTARTUPINFOA lpStartupInfo
,
31 LPPROCESS_INFORMATION lpProcessInformation
)
33 PROCESS_ACCESS_TOKEN AccessToken
;
36 /* Create the process with a suspended main thread */
37 if (!CreateProcessA(lpApplicationName
,
42 dwCreationFlags
| CREATE_SUSPENDED
,
46 lpProcessInformation
))
51 AccessToken
.Token
= hToken
;
52 AccessToken
.Thread
= NULL
;
54 /* Set the new process token */
55 Status
= NtSetInformationProcess(lpProcessInformation
->hProcess
,
59 if (!NT_SUCCESS (Status
))
61 SetLastError(RtlNtStatusToDosError(Status
));
65 /* Resume the main thread */
66 if (!(dwCreationFlags
& CREATE_SUSPENDED
))
68 ResumeThread(lpProcessInformation
->hThread
);
79 CreateProcessAsUserW(HANDLE hToken
,
80 LPCWSTR lpApplicationName
,
82 LPSECURITY_ATTRIBUTES lpProcessAttributes
,
83 LPSECURITY_ATTRIBUTES lpThreadAttributes
,
85 DWORD dwCreationFlags
,
87 LPCWSTR lpCurrentDirectory
,
88 LPSTARTUPINFOW lpStartupInfo
,
89 LPPROCESS_INFORMATION lpProcessInformation
)
91 PROCESS_ACCESS_TOKEN AccessToken
;
94 /* Create the process with a suspended main thread */
95 if (!CreateProcessW(lpApplicationName
,
100 dwCreationFlags
| CREATE_SUSPENDED
,
104 lpProcessInformation
))
109 AccessToken
.Token
= hToken
;
110 AccessToken
.Thread
= NULL
;
112 /* Set the new process token */
113 Status
= NtSetInformationProcess(lpProcessInformation
->hProcess
,
116 sizeof(AccessToken
));
117 if (!NT_SUCCESS (Status
))
119 SetLastError(RtlNtStatusToDosError(Status
));
123 /* Resume the main thread */
124 if (!(dwCreationFlags
& CREATE_SUSPENDED
))
126 ResumeThread(lpProcessInformation
->hThread
);
135 BOOL WINAPI
CreateProcessWithLogonW( LPCWSTR lpUsername
, LPCWSTR lpDomain
, LPCWSTR lpPassword
, DWORD dwLogonFlags
,
136 LPCWSTR lpApplicationName
, LPWSTR lpCommandLine
, DWORD dwCreationFlags
, LPVOID lpEnvironment
,
137 LPCWSTR lpCurrentDirectory
, LPSTARTUPINFOW lpStartupInfo
, LPPROCESS_INFORMATION lpProcessInformation
)
139 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername
), debugstr_w(lpDomain
),
140 debugstr_w(lpPassword
), dwLogonFlags
, debugstr_w(lpApplicationName
),
141 debugstr_w(lpCommandLine
), dwCreationFlags
, lpEnvironment
, debugstr_w(lpCurrentDirectory
),
142 lpStartupInfo
, lpProcessInformation
);
151 LogonUserA(LPSTR lpszUsername
,
155 DWORD dwLogonProvider
,
158 UNICODE_STRING UserName
;
159 UNICODE_STRING Domain
;
160 UNICODE_STRING Password
;
164 UserName
.Buffer
= NULL
;
165 Domain
.Buffer
= NULL
;
166 Password
.Buffer
= NULL
;
168 Status
= RtlCreateUnicodeStringFromAsciiz(&UserName
,
170 if (!NT_SUCCESS(Status
))
172 SetLastError(RtlNtStatusToDosError(Status
));
176 Status
= RtlCreateUnicodeStringFromAsciiz(&Domain
,
178 if (!NT_SUCCESS(Status
))
180 SetLastError(RtlNtStatusToDosError(Status
));
184 Status
= RtlCreateUnicodeStringFromAsciiz(&Password
,
186 if (!NT_SUCCESS(Status
))
188 SetLastError(RtlNtStatusToDosError(Status
));
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 SamGetUserSid(LPCWSTR UserName
,
227 /* Open the Users key */
228 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
229 L
"SAM\\SAM\\Domains\\Account\\Users",
234 ERR("Failed to open Users key! (Error %lu)\n", GetLastError());
238 /* Open the user key */
239 if (RegOpenKeyExW(hUsersKey
,
245 if (GetLastError() == ERROR_FILE_NOT_FOUND
)
247 ERR("Invalid user name!\n");
248 SetLastError(ERROR_NO_SUCH_USER
);
252 ERR("Failed to open user key! (Error %lu)\n", GetLastError());
255 RegCloseKey(hUsersKey
);
259 RegCloseKey (hUsersKey
);
263 if (RegQueryValueExW(hUserKey
,
270 ERR("Failed to read the SID size! (Error %lu)\n", GetLastError());
271 RegCloseKey(hUserKey
);
275 /* Allocate sid buffer */
276 TRACE("Required SID buffer size: %lu\n", dwLength
);
277 lpSid
= (PSID
)RtlAllocateHeap(RtlGetProcessHeap(),
282 ERR("Failed to allocate SID buffer!\n");
283 RegCloseKey(hUserKey
);
288 if (RegQueryValueExW(hUserKey
,
295 ERR("Failed to read the SID! (Error %lu)\n", GetLastError());
296 RtlFreeHeap(RtlGetProcessHeap(),
299 RegCloseKey(hUserKey
);
303 RegCloseKey(hUserKey
);
312 SamGetDomainSid(PSID
*Sid
)
318 TRACE("SamGetDomainSid() called\n");
323 /* Open the account domain key */
324 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
325 L
"SAM\\SAM\\Domains\\Account",
330 ERR("Failed to open the account domain key! (Error %lu)\n", GetLastError());
336 if (RegQueryValueExW(hDomainKey
,
343 ERR("Failed to read the SID size! (Error %lu)\n", GetLastError());
344 RegCloseKey(hDomainKey
);
348 /* Allocate sid buffer */
349 TRACE("Required SID buffer size: %lu\n", dwLength
);
350 lpSid
= (PSID
)RtlAllocateHeap(RtlGetProcessHeap(),
355 ERR("Failed to allocate SID buffer!\n");
356 RegCloseKey(hDomainKey
);
361 if (RegQueryValueExW(hDomainKey
,
368 ERR("Failed to read the SID! (Error %lu)\n", GetLastError());
369 RtlFreeHeap(RtlGetProcessHeap(),
372 RegCloseKey(hDomainKey
);
376 RegCloseKey(hDomainKey
);
380 TRACE("SamGetDomainSid() done\n");
387 AppendRidToSid(PSID SrcSid
,
390 ULONG Rids
[8] = {0, 0, 0, 0, 0, 0, 0, 0};
395 RidCount
= *RtlSubAuthorityCountSid(SrcSid
);
399 for (i
= 0; i
< RidCount
; i
++)
400 Rids
[i
] = *RtlSubAuthoritySid(SrcSid
, i
);
402 Rids
[RidCount
] = Rid
;
405 RtlAllocateAndInitializeSid(RtlIdentifierAuthoritySid(SrcSid
),
422 AllocateGroupSids(OUT PSID
*PrimaryGroupSid
,
425 SID_IDENTIFIER_AUTHORITY WorldAuthority
= {SECURITY_WORLD_SID_AUTHORITY
};
426 SID_IDENTIFIER_AUTHORITY LocalAuthority
= {SECURITY_LOCAL_SID_AUTHORITY
};
427 SID_IDENTIFIER_AUTHORITY SystemAuthority
= {SECURITY_NT_AUTHORITY
};
428 PTOKEN_GROUPS TokenGroups
;
430 DWORD GroupCount
= 0;
436 Status
= NtAllocateLocallyUniqueId(&Luid
);
437 if (!NT_SUCCESS(Status
))
440 if (!SamGetDomainSid(&DomainSid
))
443 TokenGroups
= RtlAllocateHeap(
445 sizeof(TOKEN_GROUPS
) +
446 MAX_GROUPS
* sizeof(SID_AND_ATTRIBUTES
));
447 if (TokenGroups
== NULL
)
449 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid
);
453 Sid
= AppendRidToSid(DomainSid
, DOMAIN_GROUP_RID_USERS
);
454 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid
);
456 /* Member of the domain */
457 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
458 TokenGroups
->Groups
[GroupCount
].Attributes
=
459 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
460 *PrimaryGroupSid
= Sid
;
463 /* Member of 'Everyone' */
464 RtlAllocateAndInitializeSid(&WorldAuthority
,
475 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
476 TokenGroups
->Groups
[GroupCount
].Attributes
=
477 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
481 /* Member of 'Administrators' */
482 RtlAllocateAndInitializeSid(&SystemAuthority
,
484 SECURITY_BUILTIN_DOMAIN_RID
,
485 DOMAIN_ALIAS_RID_ADMINS
,
493 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
494 TokenGroups
->Groups
[GroupCount
].Attributes
=
495 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
498 TRACE("Not adding user to Administrators group\n");
501 /* Member of 'Users' */
502 RtlAllocateAndInitializeSid(&SystemAuthority
,
504 SECURITY_BUILTIN_DOMAIN_RID
,
505 DOMAIN_ALIAS_RID_USERS
,
513 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
514 TokenGroups
->Groups
[GroupCount
].Attributes
=
515 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
519 RtlAllocateAndInitializeSid(&SystemAuthority
,
520 SECURITY_LOGON_IDS_RID_COUNT
,
521 SECURITY_LOGON_IDS_RID
,
530 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
531 TokenGroups
->Groups
[GroupCount
].Attributes
=
532 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
| SE_GROUP_LOGON_ID
;
536 /* Member of 'Local users */
537 RtlAllocateAndInitializeSid(&LocalAuthority
,
548 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
549 TokenGroups
->Groups
[GroupCount
].Attributes
=
550 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
553 /* Member of 'Interactive users' */
554 RtlAllocateAndInitializeSid(&SystemAuthority
,
556 SECURITY_INTERACTIVE_RID
,
565 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
566 TokenGroups
->Groups
[GroupCount
].Attributes
=
567 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
570 /* Member of 'Authenticated users' */
571 RtlAllocateAndInitializeSid(&SystemAuthority
,
573 SECURITY_AUTHENTICATED_USER_RID
,
582 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
583 TokenGroups
->Groups
[GroupCount
].Attributes
=
584 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
587 TokenGroups
->GroupCount
= GroupCount
;
588 ASSERT(TokenGroups
->GroupCount
<= MAX_GROUPS
);
595 FreeGroupSids(PTOKEN_GROUPS TokenGroups
)
599 for (i
= 0; i
< TokenGroups
->GroupCount
; i
++)
601 if (TokenGroups
->Groups
[i
].Sid
!= NULL
)
602 RtlFreeHeap(GetProcessHeap(), 0, TokenGroups
->Groups
[i
].Sid
);
605 RtlFreeHeap(GetProcessHeap(), 0, TokenGroups
);
613 LogonUserW(LPWSTR lpszUsername
,
617 DWORD dwLogonProvider
,
620 /* FIXME shouldn't use hard-coded list of privileges */
628 { L
"SeUnsolicitedInputPrivilege", 0 },
629 { L
"SeMachineAccountPrivilege", 0 },
630 { L
"SeSecurityPrivilege", 0 },
631 { L
"SeTakeOwnershipPrivilege", 0 },
632 { L
"SeLoadDriverPrivilege", 0 },
633 { L
"SeSystemProfilePrivilege", 0 },
634 { L
"SeSystemtimePrivilege", 0 },
635 { L
"SeProfileSingleProcessPrivilege", 0 },
636 { L
"SeIncreaseBasePriorityPrivilege", 0 },
637 { L
"SeCreatePagefilePrivilege", 0 },
638 { L
"SeBackupPrivilege", 0 },
639 { L
"SeRestorePrivilege", 0 },
640 { L
"SeShutdownPrivilege", 0 },
641 { L
"SeDebugPrivilege", 0 },
642 { L
"SeSystemEnvironmentPrivilege", 0 },
643 { L
"SeChangeNotifyPrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
},
644 { L
"SeRemoteShutdownPrivilege", 0 },
645 { L
"SeUndockPrivilege", 0 },
646 { L
"SeEnableDelegationPrivilege", 0 },
647 { L
"SeImpersonatePrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
},
648 { L
"SeCreateGlobalPrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
}
650 OBJECT_ATTRIBUTES ObjectAttributes
;
651 SECURITY_QUALITY_OF_SERVICE Qos
;
652 TOKEN_USER TokenUser
;
653 TOKEN_OWNER TokenOwner
;
654 TOKEN_PRIMARY_GROUP TokenPrimaryGroup
;
655 PTOKEN_GROUPS TokenGroups
;
656 PTOKEN_PRIVILEGES TokenPrivileges
;
657 TOKEN_DEFAULT_DACL TokenDefaultDacl
;
658 LARGE_INTEGER ExpirationTime
;
659 LUID AuthenticationId
;
660 TOKEN_SOURCE TokenSource
;
662 PSID PrimaryGroupSid
= NULL
;
663 PSID OwnerSid
= NULL
;
667 SID_IDENTIFIER_AUTHORITY SystemAuthority
= {SECURITY_NT_AUTHORITY
};
670 Qos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
671 Qos
.ImpersonationLevel
= SecurityAnonymous
;
672 Qos
.ContextTrackingMode
= SECURITY_STATIC_TRACKING
;
673 Qos
.EffectiveOnly
= FALSE
;
675 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
676 ObjectAttributes
.RootDirectory
= NULL
;
677 ObjectAttributes
.ObjectName
= NULL
;
678 ObjectAttributes
.Attributes
= 0;
679 ObjectAttributes
.SecurityDescriptor
= NULL
;
680 ObjectAttributes
.SecurityQualityOfService
= &Qos
;
682 Status
= NtAllocateLocallyUniqueId(&AuthenticationId
);
683 if (!NT_SUCCESS(Status
))
688 ExpirationTime
.QuadPart
= -1;
690 /* Get the user SID from the registry */
691 if (!SamGetUserSid (lpszUsername
, &UserSid
))
693 ERR("SamGetUserSid() failed\n");
697 TokenUser
.User
.Sid
= UserSid
;
698 TokenUser
.User
.Attributes
= 0;
700 /* Allocate and initialize token groups */
701 TokenGroups
= AllocateGroupSids(&PrimaryGroupSid
,
703 if (NULL
== TokenGroups
)
706 SetLastError(ERROR_OUTOFMEMORY
);
710 /* Allocate and initialize token privileges */
711 TokenPrivileges
= RtlAllocateHeap(GetProcessHeap(), 0,
712 sizeof(TOKEN_PRIVILEGES
)
713 + sizeof(DefaultPrivs
) / sizeof(DefaultPrivs
[0])
714 * sizeof(LUID_AND_ATTRIBUTES
));
715 if (NULL
== TokenPrivileges
)
717 FreeGroupSids(TokenGroups
);
719 SetLastError(ERROR_OUTOFMEMORY
);
723 TokenPrivileges
->PrivilegeCount
= 0;
724 for (i
= 0; i
< sizeof(DefaultPrivs
) / sizeof(DefaultPrivs
[0]); i
++)
726 if (! LookupPrivilegeValueW(NULL
,
727 DefaultPrivs
[i
].PrivName
,
728 &TokenPrivileges
->Privileges
[TokenPrivileges
->PrivilegeCount
].Luid
))
730 WARN("Can't set privilege %S\n", DefaultPrivs
[i
].PrivName
);
734 TokenPrivileges
->Privileges
[TokenPrivileges
->PrivilegeCount
].Attributes
= DefaultPrivs
[i
].Attributes
;
735 TokenPrivileges
->PrivilegeCount
++;
739 TokenOwner
.Owner
= OwnerSid
;
740 TokenPrimaryGroup
.PrimaryGroup
= PrimaryGroupSid
;
742 Dacl
= RtlAllocateHeap(GetProcessHeap(), 0, 1024);
745 FreeGroupSids(TokenGroups
);
747 SetLastError(ERROR_OUTOFMEMORY
);
751 Status
= RtlCreateAcl(Dacl
, 1024, ACL_REVISION
);
752 if (!NT_SUCCESS(Status
))
754 RtlFreeHeap(GetProcessHeap(), 0, Dacl
);
755 FreeGroupSids(TokenGroups
);
756 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges
);
761 RtlAddAccessAllowedAce(Dacl
,
766 RtlAllocateAndInitializeSid(&SystemAuthority
,
768 SECURITY_LOCAL_SYSTEM_RID
,
779 RtlAddAccessAllowedAce(Dacl
,
784 RtlFreeSid(LocalSystemSid
);
786 TokenDefaultDacl
.DefaultDacl
= Dacl
;
788 memcpy(TokenSource
.SourceName
,
792 Status
= NtAllocateLocallyUniqueId(&TokenSource
.SourceIdentifier
);
793 if (!NT_SUCCESS(Status
))
795 RtlFreeHeap(GetProcessHeap(), 0, Dacl
);
796 FreeGroupSids(TokenGroups
);
797 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges
);
802 Status
= NtCreateToken(phToken
,
816 RtlFreeHeap(GetProcessHeap(), 0, Dacl
);
817 FreeGroupSids(TokenGroups
);
818 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges
);
821 return NT_SUCCESS(Status
);