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
14 /* FUNCTIONS ***************************************************************/
20 CreateProcessAsUserA (HANDLE hToken
,
21 LPCSTR lpApplicationName
,
23 LPSECURITY_ATTRIBUTES lpProcessAttributes
,
24 LPSECURITY_ATTRIBUTES lpThreadAttributes
,
26 DWORD dwCreationFlags
,
28 LPCSTR lpCurrentDirectory
,
29 LPSTARTUPINFOA lpStartupInfo
,
30 LPPROCESS_INFORMATION lpProcessInformation
)
32 PROCESS_ACCESS_TOKEN AccessToken
;
35 /* Create the process with a suspended main thread */
36 if (!CreateProcessA (lpApplicationName
,
41 dwCreationFlags
| CREATE_SUSPENDED
,
45 lpProcessInformation
))
50 AccessToken
.Token
= hToken
;
51 AccessToken
.Thread
= NULL
;
53 /* Set the new process token */
54 Status
= NtSetInformationProcess (lpProcessInformation
->hProcess
,
57 sizeof (AccessToken
));
58 if (!NT_SUCCESS (Status
))
60 SetLastError (RtlNtStatusToDosError (Status
));
64 /* Resume the main thread */
65 if (!(dwCreationFlags
& CREATE_SUSPENDED
))
67 ResumeThread (lpProcessInformation
->hThread
);
78 CreateProcessAsUserW (HANDLE hToken
,
79 LPCWSTR lpApplicationName
,
81 LPSECURITY_ATTRIBUTES lpProcessAttributes
,
82 LPSECURITY_ATTRIBUTES lpThreadAttributes
,
84 DWORD dwCreationFlags
,
86 LPCWSTR lpCurrentDirectory
,
87 LPSTARTUPINFOW lpStartupInfo
,
88 LPPROCESS_INFORMATION lpProcessInformation
)
90 PROCESS_ACCESS_TOKEN AccessToken
;
93 /* Create the process with a suspended main thread */
94 if (!CreateProcessW (lpApplicationName
,
99 dwCreationFlags
| CREATE_SUSPENDED
,
103 lpProcessInformation
))
108 AccessToken
.Token
= hToken
;
109 AccessToken
.Thread
= NULL
;
111 /* Set the new process token */
112 Status
= NtSetInformationProcess (lpProcessInformation
->hProcess
,
115 sizeof (AccessToken
));
116 if (!NT_SUCCESS (Status
))
118 SetLastError (RtlNtStatusToDosError (Status
));
122 /* Resume the main thread */
123 if (!(dwCreationFlags
& CREATE_SUSPENDED
))
125 ResumeThread (lpProcessInformation
->hThread
);
136 LogonUserA(LPSTR lpszUsername
,
140 DWORD dwLogonProvider
,
143 UNICODE_STRING UserName
;
144 UNICODE_STRING Domain
;
145 UNICODE_STRING Password
;
149 UserName
.Buffer
= NULL
;
150 Domain
.Buffer
= NULL
;
151 Password
.Buffer
= NULL
;
153 Status
= RtlCreateUnicodeStringFromAsciiz(&UserName
,
155 if (!NT_SUCCESS(Status
))
157 SetLastError(RtlNtStatusToDosError(Status
));
161 Status
= RtlCreateUnicodeStringFromAsciiz(&Domain
,
163 if (!NT_SUCCESS(Status
))
165 SetLastError(RtlNtStatusToDosError(Status
));
169 Status
= RtlCreateUnicodeStringFromAsciiz(&Password
,
171 if (!NT_SUCCESS(Status
))
173 SetLastError(RtlNtStatusToDosError(Status
));
177 ret
= LogonUserW(UserName
.Buffer
,
184 if (Password
.Buffer
!= NULL
)
185 RtlFreeUnicodeString(&Password
);
188 if (Domain
.Buffer
!= NULL
)
189 RtlFreeUnicodeString(&Domain
);
192 if (UserName
.Buffer
!= NULL
)
193 RtlFreeUnicodeString(&UserName
);
201 SamGetUserSid (LPCWSTR UserName
,
212 /* Open the Users key */
213 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
214 L
"SAM\\SAM\\Domains\\Account\\Users",
219 DPRINT1 ("Failed to open Users key! (Error %lu)\n", GetLastError());
223 /* Open the user key */
224 if (RegOpenKeyExW (hUsersKey
,
230 if (GetLastError () == ERROR_FILE_NOT_FOUND
)
232 DPRINT1 ("Invalid user name!\n");
233 SetLastError (ERROR_NO_SUCH_USER
);
237 DPRINT1 ("Failed to open user key! (Error %lu)\n", GetLastError());
240 RegCloseKey (hUsersKey
);
244 RegCloseKey (hUsersKey
);
248 if (RegQueryValueExW (hUserKey
,
255 DPRINT1 ("Failed to read the SID size! (Error %lu)\n", GetLastError());
256 RegCloseKey (hUserKey
);
260 /* Allocate sid buffer */
261 DPRINT ("Required SID buffer size: %lu\n", dwLength
);
262 lpSid
= (PSID
)RtlAllocateHeap (RtlGetProcessHeap (),
267 DPRINT1 ("Failed to allocate SID buffer!\n");
268 RegCloseKey (hUserKey
);
273 if (RegQueryValueExW (hUserKey
,
280 DPRINT1 ("Failed to read the SID! (Error %lu)\n", GetLastError());
281 RtlFreeHeap (RtlGetProcessHeap (),
284 RegCloseKey (hUserKey
);
288 RegCloseKey (hUserKey
);
297 SamGetDomainSid(PSID
*Sid
)
303 DPRINT("SamGetDomainSid() called\n");
308 /* Open the account domain key */
309 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
310 L
"SAM\\SAM\\Domains\\Account",
315 DPRINT1("Failed to open the account domain key! (Error %lu)\n", GetLastError());
321 if (RegQueryValueExW(hDomainKey
,
328 DPRINT1("Failed to read the SID size! (Error %lu)\n", GetLastError());
329 RegCloseKey(hDomainKey
);
333 /* Allocate sid buffer */
334 DPRINT("Required SID buffer size: %lu\n", dwLength
);
335 lpSid
= (PSID
)RtlAllocateHeap(RtlGetProcessHeap(),
340 DPRINT1("Failed to allocate SID buffer!\n");
341 RegCloseKey(hDomainKey
);
346 if (RegQueryValueExW(hDomainKey
,
353 DPRINT1("Failed to read the SID! (Error %lu)\n", GetLastError());
354 RtlFreeHeap(RtlGetProcessHeap(),
357 RegCloseKey(hDomainKey
);
361 RegCloseKey(hDomainKey
);
365 DPRINT("SamGetDomainSid() done\n");
372 AppendRidToSid(PSID SrcSid
,
375 ULONG Rids
[8] = {0, 0, 0, 0, 0, 0, 0, 0};
380 RidCount
= *RtlSubAuthorityCountSid(SrcSid
);
384 for (i
= 0; i
< RidCount
; i
++)
385 Rids
[i
] = *RtlSubAuthoritySid(SrcSid
, i
);
387 Rids
[RidCount
] = Rid
;
390 RtlAllocateAndInitializeSid(RtlIdentifierAuthoritySid(SrcSid
),
407 AllocateGroupSids(PSID
*PrimaryGroupSid
,
410 SID_IDENTIFIER_AUTHORITY WorldAuthority
= {SECURITY_WORLD_SID_AUTHORITY
};
411 SID_IDENTIFIER_AUTHORITY LocalAuthority
= {SECURITY_LOCAL_SID_AUTHORITY
};
412 SID_IDENTIFIER_AUTHORITY SystemAuthority
= {SECURITY_NT_AUTHORITY
};
413 PTOKEN_GROUPS TokenGroups
;
419 Status
= NtAllocateLocallyUniqueId(&Luid
);
420 if (!NT_SUCCESS(Status
))
425 if (!SamGetDomainSid(&DomainSid
))
430 TokenGroups
= RtlAllocateHeap(GetProcessHeap(), 0,
431 sizeof(TOKEN_GROUPS
) +
432 8 * sizeof(SID_AND_ATTRIBUTES
));
433 if (TokenGroups
== NULL
)
435 RtlFreeHeap (RtlGetProcessHeap (),
441 TokenGroups
->GroupCount
= 8;
443 Sid
= AppendRidToSid(DomainSid
,
444 DOMAIN_GROUP_RID_USERS
);
446 RtlFreeHeap(RtlGetProcessHeap(),
450 TokenGroups
->Groups
[0].Sid
= Sid
;
451 TokenGroups
->Groups
[0].Attributes
= SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
452 *PrimaryGroupSid
= Sid
;
455 RtlAllocateAndInitializeSid(&WorldAuthority
,
467 TokenGroups
->Groups
[1].Sid
= Sid
;
468 TokenGroups
->Groups
[1].Attributes
= SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
471 RtlAllocateAndInitializeSid(&SystemAuthority
,
473 SECURITY_BUILTIN_DOMAIN_RID
,
474 DOMAIN_ALIAS_RID_ADMINS
,
483 TokenGroups
->Groups
[2].Sid
= Sid
;
484 TokenGroups
->Groups
[2].Attributes
= SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
488 RtlAllocateAndInitializeSid(&SystemAuthority
,
490 SECURITY_BUILTIN_DOMAIN_RID
,
491 DOMAIN_ALIAS_RID_USERS
,
500 TokenGroups
->Groups
[3].Sid
= Sid
;
501 TokenGroups
->Groups
[3].Attributes
= SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
504 RtlAllocateAndInitializeSid(&SystemAuthority
,
505 SECURITY_LOGON_IDS_RID_COUNT
,
506 SECURITY_LOGON_IDS_RID
,
516 TokenGroups
->Groups
[4].Sid
= Sid
;
517 TokenGroups
->Groups
[4].Attributes
= SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
| SE_GROUP_LOGON_ID
;
519 RtlAllocateAndInitializeSid(&LocalAuthority
,
531 TokenGroups
->Groups
[5].Sid
= Sid
;
532 TokenGroups
->Groups
[5].Attributes
= SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
534 RtlAllocateAndInitializeSid(&SystemAuthority
,
536 SECURITY_INTERACTIVE_RID
,
546 TokenGroups
->Groups
[6].Sid
= Sid
;
547 TokenGroups
->Groups
[6].Attributes
= SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
549 RtlAllocateAndInitializeSid(&SystemAuthority
,
551 SECURITY_AUTHENTICATED_USER_RID
,
561 TokenGroups
->Groups
[7].Sid
= Sid
;
562 TokenGroups
->Groups
[7].Attributes
= SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
569 FreeGroupSids(PTOKEN_GROUPS TokenGroups
)
573 for (i
= 0; i
< TokenGroups
->GroupCount
; i
++)
575 if (TokenGroups
->Groups
[i
].Sid
!= NULL
)
576 RtlFreeHeap(GetProcessHeap(), 0, TokenGroups
->Groups
[i
].Sid
);
579 RtlFreeHeap(GetProcessHeap(), 0, TokenGroups
);
587 LogonUserW (LPWSTR lpszUsername
,
591 DWORD dwLogonProvider
,
594 /* FIXME shouldn't use hard-coded list of privileges */
602 { L
"SeUnsolicitedInputPrivilege", 0 },
603 { L
"SeMachineAccountPrivilege", 0 },
604 { L
"SeSecurityPrivilege", 0 },
605 { L
"SeTakeOwnershipPrivilege", 0 },
606 { L
"SeLoadDriverPrivilege", 0 },
607 { L
"SeSystemProfilePrivilege", 0 },
608 { L
"SeSystemtimePrivilege", 0 },
609 { L
"SeProfileSingleProcessPrivilege", 0 },
610 { L
"SeIncreaseBasePriorityPrivilege", 0 },
611 { L
"SeCreatePagefilePrivilege", 0 },
612 { L
"SeBackupPrivilege", 0 },
613 { L
"SeRestorePrivilege", 0 },
614 { L
"SeShutdownPrivilege", 0 },
615 { L
"SeDebugPrivilege", 0 },
616 { L
"SeSystemEnvironmentPrivilege", 0 },
617 { L
"SeChangeNotifyPrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
},
618 { L
"SeRemoteShutdownPrivilege", 0 },
619 { L
"SeUndockPrivilege", 0 },
620 { L
"SeEnableDelegationPrivilege", 0 },
621 { L
"SeImpersonatePrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
},
622 { L
"SeCreateGlobalPrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
}
624 OBJECT_ATTRIBUTES ObjectAttributes
;
625 SECURITY_QUALITY_OF_SERVICE Qos
;
626 TOKEN_USER TokenUser
;
627 TOKEN_OWNER TokenOwner
;
628 TOKEN_PRIMARY_GROUP TokenPrimaryGroup
;
629 PTOKEN_GROUPS TokenGroups
;
630 PTOKEN_PRIVILEGES TokenPrivileges
;
631 TOKEN_DEFAULT_DACL TokenDefaultDacl
;
632 LARGE_INTEGER ExpirationTime
;
633 LUID AuthenticationId
;
634 TOKEN_SOURCE TokenSource
;
636 PSID PrimaryGroupSid
= NULL
;
637 PSID OwnerSid
= NULL
;
641 SID_IDENTIFIER_AUTHORITY SystemAuthority
= {SECURITY_NT_AUTHORITY
};
644 Qos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
645 Qos
.ImpersonationLevel
= SecurityAnonymous
;
646 Qos
.ContextTrackingMode
= SECURITY_STATIC_TRACKING
;
647 Qos
.EffectiveOnly
= FALSE
;
649 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
650 ObjectAttributes
.RootDirectory
= NULL
;
651 ObjectAttributes
.ObjectName
= NULL
;
652 ObjectAttributes
.Attributes
= 0;
653 ObjectAttributes
.SecurityDescriptor
= NULL
;
654 ObjectAttributes
.SecurityQualityOfService
= &Qos
;
656 Status
= NtAllocateLocallyUniqueId(&AuthenticationId
);
657 if (!NT_SUCCESS(Status
))
661 ExpirationTime
.QuadPart
= -1;
663 /* Get the user SID from the registry */
664 if (!SamGetUserSid (lpszUsername
, &UserSid
))
666 DPRINT ("SamGetUserSid() failed\n");
667 RtlAllocateAndInitializeSid (&SystemAuthority
,
669 SECURITY_NT_NON_UNIQUE_RID
,
673 DOMAIN_USER_RID_ADMIN
,
680 TokenUser
.User
.Sid
= UserSid
;
681 TokenUser
.User
.Attributes
= 0;
683 /* Allocate and initialize token groups */
684 TokenGroups
= AllocateGroupSids(&PrimaryGroupSid
,
686 if (NULL
== TokenGroups
)
689 SetLastError(ERROR_OUTOFMEMORY
);
693 /* Allocate and initialize token privileges */
694 TokenPrivileges
= RtlAllocateHeap(GetProcessHeap(), 0,
695 sizeof(TOKEN_PRIVILEGES
)
696 + sizeof(DefaultPrivs
) / sizeof(DefaultPrivs
[0])
697 * sizeof(LUID_AND_ATTRIBUTES
));
698 if (NULL
== TokenPrivileges
)
700 FreeGroupSids(TokenGroups
);
702 SetLastError(ERROR_OUTOFMEMORY
);
706 TokenPrivileges
->PrivilegeCount
= 0;
707 for (i
= 0; i
< sizeof(DefaultPrivs
) / sizeof(DefaultPrivs
[0]); i
++)
709 if (! LookupPrivilegeValueW(NULL
, DefaultPrivs
[i
].PrivName
,
710 &TokenPrivileges
->Privileges
[TokenPrivileges
->PrivilegeCount
].Luid
))
712 DPRINT1("Can't set privilege %S\n", DefaultPrivs
[i
].PrivName
);
716 TokenPrivileges
->Privileges
[TokenPrivileges
->PrivilegeCount
].Attributes
= DefaultPrivs
[i
].Attributes
;
717 TokenPrivileges
->PrivilegeCount
++;
721 TokenOwner
.Owner
= OwnerSid
;
722 TokenPrimaryGroup
.PrimaryGroup
= PrimaryGroupSid
;
725 Dacl
= RtlAllocateHeap(GetProcessHeap(), 0, 1024);
728 FreeGroupSids(TokenGroups
);
730 SetLastError(ERROR_OUTOFMEMORY
);
734 Status
= RtlCreateAcl(Dacl
, 1024, ACL_REVISION
);
735 if (!NT_SUCCESS(Status
))
737 RtlFreeHeap(GetProcessHeap(), 0, Dacl
);
738 FreeGroupSids(TokenGroups
);
739 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges
);
744 RtlAddAccessAllowedAce(Dacl
,
749 RtlAllocateAndInitializeSid(&SystemAuthority
,
751 SECURITY_LOCAL_SYSTEM_RID
,
762 RtlAddAccessAllowedAce(Dacl
,
767 RtlFreeSid(LocalSystemSid
);
769 TokenDefaultDacl
.DefaultDacl
= Dacl
;
771 memcpy(TokenSource
.SourceName
,
774 Status
= NtAllocateLocallyUniqueId(&TokenSource
.SourceIdentifier
);
775 if (!NT_SUCCESS(Status
))
777 RtlFreeHeap(GetProcessHeap(), 0, Dacl
);
778 FreeGroupSids(TokenGroups
);
779 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges
);
784 Status
= NtCreateToken(phToken
,
798 RtlFreeHeap(GetProcessHeap(), 0, Dacl
);
799 FreeGroupSids(TokenGroups
);
800 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges
);
803 return NT_SUCCESS(Status
);