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
);
137 LogonUserA(LPSTR lpszUsername
,
141 DWORD dwLogonProvider
,
144 UNICODE_STRING UserName
;
145 UNICODE_STRING Domain
;
146 UNICODE_STRING Password
;
150 UserName
.Buffer
= NULL
;
151 Domain
.Buffer
= NULL
;
152 Password
.Buffer
= NULL
;
154 Status
= RtlCreateUnicodeStringFromAsciiz(&UserName
,
156 if (!NT_SUCCESS(Status
))
158 SetLastError(RtlNtStatusToDosError(Status
));
162 Status
= RtlCreateUnicodeStringFromAsciiz(&Domain
,
164 if (!NT_SUCCESS(Status
))
166 SetLastError(RtlNtStatusToDosError(Status
));
170 Status
= RtlCreateUnicodeStringFromAsciiz(&Password
,
172 if (!NT_SUCCESS(Status
))
174 SetLastError(RtlNtStatusToDosError(Status
));
178 ret
= LogonUserW(UserName
.Buffer
,
185 if (Password
.Buffer
!= NULL
)
186 RtlFreeUnicodeString(&Password
);
189 if (Domain
.Buffer
!= NULL
)
190 RtlFreeUnicodeString(&Domain
);
193 if (UserName
.Buffer
!= NULL
)
194 RtlFreeUnicodeString(&UserName
);
202 SamGetUserSid(LPCWSTR UserName
,
213 /* Open the Users key */
214 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
215 L
"SAM\\SAM\\Domains\\Account\\Users",
220 ERR("Failed to open Users key! (Error %lu)\n", GetLastError());
224 /* Open the user key */
225 if (RegOpenKeyExW(hUsersKey
,
231 if (GetLastError() == ERROR_FILE_NOT_FOUND
)
233 ERR("Invalid user name!\n");
234 SetLastError(ERROR_NO_SUCH_USER
);
238 ERR("Failed to open user key! (Error %lu)\n", GetLastError());
241 RegCloseKey(hUsersKey
);
245 RegCloseKey (hUsersKey
);
249 if (RegQueryValueExW(hUserKey
,
256 ERR("Failed to read the SID size! (Error %lu)\n", GetLastError());
257 RegCloseKey(hUserKey
);
261 /* Allocate sid buffer */
262 TRACE("Required SID buffer size: %lu\n", dwLength
);
263 lpSid
= (PSID
)RtlAllocateHeap(RtlGetProcessHeap(),
268 ERR("Failed to allocate SID buffer!\n");
269 RegCloseKey(hUserKey
);
274 if (RegQueryValueExW(hUserKey
,
281 ERR("Failed to read the SID! (Error %lu)\n", GetLastError());
282 RtlFreeHeap(RtlGetProcessHeap(),
285 RegCloseKey(hUserKey
);
289 RegCloseKey(hUserKey
);
298 SamGetDomainSid(PSID
*Sid
)
304 TRACE("SamGetDomainSid() called\n");
309 /* Open the account domain key */
310 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
311 L
"SAM\\SAM\\Domains\\Account",
316 ERR("Failed to open the account domain key! (Error %lu)\n", GetLastError());
322 if (RegQueryValueExW(hDomainKey
,
329 ERR("Failed to read the SID size! (Error %lu)\n", GetLastError());
330 RegCloseKey(hDomainKey
);
334 /* Allocate sid buffer */
335 TRACE("Required SID buffer size: %lu\n", dwLength
);
336 lpSid
= (PSID
)RtlAllocateHeap(RtlGetProcessHeap(),
341 ERR("Failed to allocate SID buffer!\n");
342 RegCloseKey(hDomainKey
);
347 if (RegQueryValueExW(hDomainKey
,
354 ERR("Failed to read the SID! (Error %lu)\n", GetLastError());
355 RtlFreeHeap(RtlGetProcessHeap(),
358 RegCloseKey(hDomainKey
);
362 RegCloseKey(hDomainKey
);
366 TRACE("SamGetDomainSid() done\n");
373 AppendRidToSid(PSID SrcSid
,
376 ULONG Rids
[8] = {0, 0, 0, 0, 0, 0, 0, 0};
381 RidCount
= *RtlSubAuthorityCountSid(SrcSid
);
385 for (i
= 0; i
< RidCount
; i
++)
386 Rids
[i
] = *RtlSubAuthoritySid(SrcSid
, i
);
388 Rids
[RidCount
] = Rid
;
391 RtlAllocateAndInitializeSid(RtlIdentifierAuthoritySid(SrcSid
),
408 AllocateGroupSids(OUT PSID
*PrimaryGroupSid
,
411 SID_IDENTIFIER_AUTHORITY WorldAuthority
= {SECURITY_WORLD_SID_AUTHORITY
};
412 SID_IDENTIFIER_AUTHORITY LocalAuthority
= {SECURITY_LOCAL_SID_AUTHORITY
};
413 SID_IDENTIFIER_AUTHORITY SystemAuthority
= {SECURITY_NT_AUTHORITY
};
414 PTOKEN_GROUPS TokenGroups
;
416 DWORD GroupCount
= 0;
422 Status
= NtAllocateLocallyUniqueId(&Luid
);
423 if (!NT_SUCCESS(Status
))
426 if (!SamGetDomainSid(&DomainSid
))
429 TokenGroups
= RtlAllocateHeap(
431 sizeof(TOKEN_GROUPS
) +
432 MAX_GROUPS
* sizeof(SID_AND_ATTRIBUTES
));
433 if (TokenGroups
== NULL
)
435 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid
);
439 Sid
= AppendRidToSid(DomainSid
, DOMAIN_GROUP_RID_USERS
);
440 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid
);
442 /* Member of the domain */
443 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
444 TokenGroups
->Groups
[GroupCount
].Attributes
=
445 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
446 *PrimaryGroupSid
= Sid
;
449 /* Member of 'Everyone' */
450 RtlAllocateAndInitializeSid(&WorldAuthority
,
461 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
462 TokenGroups
->Groups
[GroupCount
].Attributes
=
463 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
467 /* Member of 'Administrators' */
468 RtlAllocateAndInitializeSid(&SystemAuthority
,
470 SECURITY_BUILTIN_DOMAIN_RID
,
471 DOMAIN_ALIAS_RID_ADMINS
,
479 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
480 TokenGroups
->Groups
[GroupCount
].Attributes
=
481 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
484 TRACE("Not adding user to Administrators group\n");
487 /* Member of 'Users' */
488 RtlAllocateAndInitializeSid(&SystemAuthority
,
490 SECURITY_BUILTIN_DOMAIN_RID
,
491 DOMAIN_ALIAS_RID_USERS
,
499 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
500 TokenGroups
->Groups
[GroupCount
].Attributes
=
501 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
505 RtlAllocateAndInitializeSid(&SystemAuthority
,
506 SECURITY_LOGON_IDS_RID_COUNT
,
507 SECURITY_LOGON_IDS_RID
,
516 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
517 TokenGroups
->Groups
[GroupCount
].Attributes
=
518 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
| SE_GROUP_LOGON_ID
;
522 /* Member of 'Local users */
523 RtlAllocateAndInitializeSid(&LocalAuthority
,
534 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
535 TokenGroups
->Groups
[GroupCount
].Attributes
=
536 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
539 /* Member of 'Interactive users' */
540 RtlAllocateAndInitializeSid(&SystemAuthority
,
542 SECURITY_INTERACTIVE_RID
,
551 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
552 TokenGroups
->Groups
[GroupCount
].Attributes
=
553 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
556 /* Member of 'Authenticated users' */
557 RtlAllocateAndInitializeSid(&SystemAuthority
,
559 SECURITY_AUTHENTICATED_USER_RID
,
568 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
569 TokenGroups
->Groups
[GroupCount
].Attributes
=
570 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
573 TokenGroups
->GroupCount
= GroupCount
;
574 ASSERT(TokenGroups
->GroupCount
<= MAX_GROUPS
);
581 FreeGroupSids(PTOKEN_GROUPS TokenGroups
)
585 for (i
= 0; i
< TokenGroups
->GroupCount
; i
++)
587 if (TokenGroups
->Groups
[i
].Sid
!= NULL
)
588 RtlFreeHeap(GetProcessHeap(), 0, TokenGroups
->Groups
[i
].Sid
);
591 RtlFreeHeap(GetProcessHeap(), 0, TokenGroups
);
599 LogonUserW(LPWSTR lpszUsername
,
603 DWORD dwLogonProvider
,
606 /* FIXME shouldn't use hard-coded list of privileges */
614 { L
"SeUnsolicitedInputPrivilege", 0 },
615 { L
"SeMachineAccountPrivilege", 0 },
616 { L
"SeSecurityPrivilege", 0 },
617 { L
"SeTakeOwnershipPrivilege", 0 },
618 { L
"SeLoadDriverPrivilege", 0 },
619 { L
"SeSystemProfilePrivilege", 0 },
620 { L
"SeSystemtimePrivilege", 0 },
621 { L
"SeProfileSingleProcessPrivilege", 0 },
622 { L
"SeIncreaseBasePriorityPrivilege", 0 },
623 { L
"SeCreatePagefilePrivilege", 0 },
624 { L
"SeBackupPrivilege", 0 },
625 { L
"SeRestorePrivilege", 0 },
626 { L
"SeShutdownPrivilege", 0 },
627 { L
"SeDebugPrivilege", 0 },
628 { L
"SeSystemEnvironmentPrivilege", 0 },
629 { L
"SeChangeNotifyPrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
},
630 { L
"SeRemoteShutdownPrivilege", 0 },
631 { L
"SeUndockPrivilege", 0 },
632 { L
"SeEnableDelegationPrivilege", 0 },
633 { L
"SeImpersonatePrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
},
634 { L
"SeCreateGlobalPrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
}
636 OBJECT_ATTRIBUTES ObjectAttributes
;
637 SECURITY_QUALITY_OF_SERVICE Qos
;
638 TOKEN_USER TokenUser
;
639 TOKEN_OWNER TokenOwner
;
640 TOKEN_PRIMARY_GROUP TokenPrimaryGroup
;
641 PTOKEN_GROUPS TokenGroups
;
642 PTOKEN_PRIVILEGES TokenPrivileges
;
643 TOKEN_DEFAULT_DACL TokenDefaultDacl
;
644 LARGE_INTEGER ExpirationTime
;
645 LUID AuthenticationId
;
646 TOKEN_SOURCE TokenSource
;
648 PSID PrimaryGroupSid
= NULL
;
649 PSID OwnerSid
= NULL
;
653 SID_IDENTIFIER_AUTHORITY SystemAuthority
= {SECURITY_NT_AUTHORITY
};
656 Qos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
657 Qos
.ImpersonationLevel
= SecurityAnonymous
;
658 Qos
.ContextTrackingMode
= SECURITY_STATIC_TRACKING
;
659 Qos
.EffectiveOnly
= FALSE
;
661 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
662 ObjectAttributes
.RootDirectory
= NULL
;
663 ObjectAttributes
.ObjectName
= NULL
;
664 ObjectAttributes
.Attributes
= 0;
665 ObjectAttributes
.SecurityDescriptor
= NULL
;
666 ObjectAttributes
.SecurityQualityOfService
= &Qos
;
668 Status
= NtAllocateLocallyUniqueId(&AuthenticationId
);
669 if (!NT_SUCCESS(Status
))
674 ExpirationTime
.QuadPart
= -1;
676 /* Get the user SID from the registry */
677 if (!SamGetUserSid (lpszUsername
, &UserSid
))
679 ERR("SamGetUserSid() failed\n");
683 TokenUser
.User
.Sid
= UserSid
;
684 TokenUser
.User
.Attributes
= 0;
686 /* Allocate and initialize token groups */
687 TokenGroups
= AllocateGroupSids(&PrimaryGroupSid
,
689 if (NULL
== TokenGroups
)
692 SetLastError(ERROR_OUTOFMEMORY
);
696 /* Allocate and initialize token privileges */
697 TokenPrivileges
= RtlAllocateHeap(GetProcessHeap(), 0,
698 sizeof(TOKEN_PRIVILEGES
)
699 + sizeof(DefaultPrivs
) / sizeof(DefaultPrivs
[0])
700 * sizeof(LUID_AND_ATTRIBUTES
));
701 if (NULL
== TokenPrivileges
)
703 FreeGroupSids(TokenGroups
);
705 SetLastError(ERROR_OUTOFMEMORY
);
709 TokenPrivileges
->PrivilegeCount
= 0;
710 for (i
= 0; i
< sizeof(DefaultPrivs
) / sizeof(DefaultPrivs
[0]); i
++)
712 if (! LookupPrivilegeValueW(NULL
,
713 DefaultPrivs
[i
].PrivName
,
714 &TokenPrivileges
->Privileges
[TokenPrivileges
->PrivilegeCount
].Luid
))
716 WARN("Can't set privilege %S\n", DefaultPrivs
[i
].PrivName
);
720 TokenPrivileges
->Privileges
[TokenPrivileges
->PrivilegeCount
].Attributes
= DefaultPrivs
[i
].Attributes
;
721 TokenPrivileges
->PrivilegeCount
++;
725 TokenOwner
.Owner
= OwnerSid
;
726 TokenPrimaryGroup
.PrimaryGroup
= PrimaryGroupSid
;
728 Dacl
= RtlAllocateHeap(GetProcessHeap(), 0, 1024);
731 FreeGroupSids(TokenGroups
);
733 SetLastError(ERROR_OUTOFMEMORY
);
737 Status
= RtlCreateAcl(Dacl
, 1024, ACL_REVISION
);
738 if (!NT_SUCCESS(Status
))
740 RtlFreeHeap(GetProcessHeap(), 0, Dacl
);
741 FreeGroupSids(TokenGroups
);
742 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges
);
747 RtlAddAccessAllowedAce(Dacl
,
752 RtlAllocateAndInitializeSid(&SystemAuthority
,
754 SECURITY_LOCAL_SYSTEM_RID
,
765 RtlAddAccessAllowedAce(Dacl
,
770 RtlFreeSid(LocalSystemSid
);
772 TokenDefaultDacl
.DefaultDacl
= Dacl
;
774 memcpy(TokenSource
.SourceName
,
778 Status
= NtAllocateLocallyUniqueId(&TokenSource
.SourceIdentifier
);
779 if (!NT_SUCCESS(Status
))
781 RtlFreeHeap(GetProcessHeap(), 0, Dacl
);
782 FreeGroupSids(TokenGroups
);
783 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges
);
788 Status
= NtCreateToken(phToken
,
802 RtlFreeHeap(GetProcessHeap(), 0, Dacl
);
803 FreeGroupSids(TokenGroups
);
804 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges
);
807 return NT_SUCCESS(Status
);