3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/advapi32/misc/logon.c
6 * PURPOSE: Logon functions
7 * PROGRAMMER: Eric Kohl
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
,
58 sizeof (AccessToken
));
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
,
149 SamGetUserSid (LPCWSTR UserName
,
160 /* Open the Users key */
161 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
162 L
"SAM\\SAM\\Domains\\Account\\Users",
167 DPRINT1 ("Failed to open Users key! (Error %lu)\n", GetLastError());
171 /* Open the user key */
172 if (RegOpenKeyExW (hUsersKey
,
178 if (GetLastError () == ERROR_FILE_NOT_FOUND
)
180 DPRINT1 ("Invalid user name!\n");
181 SetLastError (ERROR_NO_SUCH_USER
);
185 DPRINT1 ("Failed to open user key! (Error %lu)\n", GetLastError());
188 RegCloseKey (hUsersKey
);
192 RegCloseKey (hUsersKey
);
196 if (RegQueryValueExW (hUserKey
,
203 DPRINT1 ("Failed to read the SID size! (Error %lu)\n", GetLastError());
204 RegCloseKey (hUserKey
);
208 /* Allocate sid buffer */
209 DPRINT ("Required SID buffer size: %lu\n", dwLength
);
210 lpSid
= (PSID
)RtlAllocateHeap (RtlGetProcessHeap (),
215 DPRINT1 ("Failed to allocate SID buffer!\n");
216 RegCloseKey (hUserKey
);
221 if (RegQueryValueExW (hUserKey
,
228 DPRINT1 ("Failed to read the SID! (Error %lu)\n", GetLastError());
229 RtlFreeHeap (RtlGetProcessHeap (),
232 RegCloseKey (hUserKey
);
236 RegCloseKey (hUserKey
);
245 SamGetDomainSid(PSID
*Sid
)
251 DPRINT("SamGetDomainSid() called\n");
256 /* Open the account domain key */
257 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
258 L
"SAM\\SAM\\Domains\\Account",
263 DPRINT1("Failed to open the account domain key! (Error %lu)\n", GetLastError());
269 if (RegQueryValueExW(hDomainKey
,
276 DPRINT1("Failed to read the SID size! (Error %lu)\n", GetLastError());
277 RegCloseKey(hDomainKey
);
281 /* Allocate sid buffer */
282 DPRINT("Required SID buffer size: %lu\n", dwLength
);
283 lpSid
= (PSID
)RtlAllocateHeap(RtlGetProcessHeap(),
288 DPRINT1("Failed to allocate SID buffer!\n");
289 RegCloseKey(hDomainKey
);
294 if (RegQueryValueExW(hDomainKey
,
301 DPRINT1("Failed to read the SID! (Error %lu)\n", GetLastError());
302 RtlFreeHeap(RtlGetProcessHeap(),
305 RegCloseKey(hDomainKey
);
309 RegCloseKey(hDomainKey
);
313 DPRINT("SamGetDomainSid() done\n");
320 AppendRidToSid(PSID SrcSid
,
323 ULONG Rids
[8] = {0, 0, 0, 0, 0, 0, 0, 0};
328 RidCount
= *RtlSubAuthorityCountSid(SrcSid
);
332 for (i
= 0; i
< RidCount
; i
++)
333 Rids
[i
] = *RtlSubAuthoritySid(SrcSid
, i
);
335 Rids
[RidCount
] = Rid
;
338 RtlAllocateAndInitializeSid(RtlIdentifierAuthoritySid(SrcSid
),
355 AllocateGroupSids(PSID
*PrimaryGroupSid
,
358 SID_IDENTIFIER_AUTHORITY WorldAuthority
= {SECURITY_WORLD_SID_AUTHORITY
};
359 SID_IDENTIFIER_AUTHORITY LocalAuthority
= {SECURITY_LOCAL_SID_AUTHORITY
};
360 SID_IDENTIFIER_AUTHORITY SystemAuthority
= {SECURITY_NT_AUTHORITY
};
361 PTOKEN_GROUPS TokenGroups
;
367 Status
= NtAllocateLocallyUniqueId(&Luid
);
368 if (!NT_SUCCESS(Status
))
373 if (!SamGetDomainSid(&DomainSid
))
378 TokenGroups
= RtlAllocateHeap(GetProcessHeap(), 0,
379 sizeof(TOKEN_GROUPS
) +
380 8 * sizeof(SID_AND_ATTRIBUTES
));
381 if (TokenGroups
== NULL
)
383 RtlFreeHeap (RtlGetProcessHeap (),
389 TokenGroups
->GroupCount
= 8;
391 Sid
= AppendRidToSid(DomainSid
,
392 DOMAIN_GROUP_RID_USERS
);
394 RtlFreeHeap(RtlGetProcessHeap(),
398 TokenGroups
->Groups
[0].Sid
= Sid
;
399 TokenGroups
->Groups
[0].Attributes
= SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
400 *PrimaryGroupSid
= Sid
;
403 RtlAllocateAndInitializeSid(&WorldAuthority
,
415 TokenGroups
->Groups
[1].Sid
= Sid
;
416 TokenGroups
->Groups
[1].Attributes
= SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
419 RtlAllocateAndInitializeSid(&SystemAuthority
,
421 SECURITY_BUILTIN_DOMAIN_RID
,
422 DOMAIN_ALIAS_RID_ADMINS
,
431 TokenGroups
->Groups
[2].Sid
= Sid
;
432 TokenGroups
->Groups
[2].Attributes
= SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
436 RtlAllocateAndInitializeSid(&SystemAuthority
,
438 SECURITY_BUILTIN_DOMAIN_RID
,
439 DOMAIN_ALIAS_RID_USERS
,
448 TokenGroups
->Groups
[3].Sid
= Sid
;
449 TokenGroups
->Groups
[3].Attributes
= SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
452 RtlAllocateAndInitializeSid(&SystemAuthority
,
453 SECURITY_LOGON_IDS_RID_COUNT
,
454 SECURITY_LOGON_IDS_RID
,
464 TokenGroups
->Groups
[4].Sid
= Sid
;
465 TokenGroups
->Groups
[4].Attributes
= SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
| SE_GROUP_LOGON_ID
;
467 RtlAllocateAndInitializeSid(&LocalAuthority
,
479 TokenGroups
->Groups
[5].Sid
= Sid
;
480 TokenGroups
->Groups
[5].Attributes
= SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
482 RtlAllocateAndInitializeSid(&SystemAuthority
,
484 SECURITY_INTERACTIVE_RID
,
494 TokenGroups
->Groups
[6].Sid
= Sid
;
495 TokenGroups
->Groups
[6].Attributes
= SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
497 RtlAllocateAndInitializeSid(&SystemAuthority
,
499 SECURITY_AUTHENTICATED_USER_RID
,
509 TokenGroups
->Groups
[7].Sid
= Sid
;
510 TokenGroups
->Groups
[7].Attributes
= SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
517 FreeGroupSids(PTOKEN_GROUPS TokenGroups
)
521 for (i
= 0; i
< TokenGroups
->GroupCount
; i
++)
523 if (TokenGroups
->Groups
[i
].Sid
!= NULL
)
524 RtlFreeHeap(GetProcessHeap(), 0, TokenGroups
->Groups
[i
].Sid
);
527 RtlFreeHeap(GetProcessHeap(), 0, TokenGroups
);
535 LogonUserW (LPWSTR lpszUsername
,
539 DWORD dwLogonProvider
,
542 /* FIXME shouldn't use hard-coded list of privileges */
550 { L
"SeUnsolicitedInputPrivilege", 0 },
551 { L
"SeMachineAccountPrivilege", 0 },
552 { L
"SeSecurityPrivilege", 0 },
553 { L
"SeTakeOwnershipPrivilege", 0 },
554 { L
"SeLoadDriverPrivilege", 0 },
555 { L
"SeSystemProfilePrivilege", 0 },
556 { L
"SeSystemtimePrivilege", 0 },
557 { L
"SeProfileSingleProcessPrivilege", 0 },
558 { L
"SeIncreaseBasePriorityPrivilege", 0 },
559 { L
"SeCreatePagefilePrivilege", 0 },
560 { L
"SeBackupPrivilege", 0 },
561 { L
"SeRestorePrivilege", 0 },
562 { L
"SeShutdownPrivilege", 0 },
563 { L
"SeDebugPrivilege", 0 },
564 { L
"SeSystemEnvironmentPrivilege", 0 },
565 { L
"SeChangeNotifyPrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
},
566 { L
"SeRemoteShutdownPrivilege", 0 },
567 { L
"SeUndockPrivilege", 0 },
568 { L
"SeEnableDelegationPrivilege", 0 },
569 { L
"SeImpersonatePrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
},
570 { L
"SeCreateGlobalPrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
}
572 OBJECT_ATTRIBUTES ObjectAttributes
;
573 SECURITY_QUALITY_OF_SERVICE Qos
;
574 TOKEN_USER TokenUser
;
575 TOKEN_OWNER TokenOwner
;
576 TOKEN_PRIMARY_GROUP TokenPrimaryGroup
;
577 PTOKEN_GROUPS TokenGroups
;
578 PTOKEN_PRIVILEGES TokenPrivileges
;
579 TOKEN_DEFAULT_DACL TokenDefaultDacl
;
580 LARGE_INTEGER ExpirationTime
;
581 LUID AuthenticationId
;
582 TOKEN_SOURCE TokenSource
;
584 PSID PrimaryGroupSid
= NULL
;
585 PSID OwnerSid
= NULL
;
589 SID_IDENTIFIER_AUTHORITY SystemAuthority
= {SECURITY_NT_AUTHORITY
};
592 Qos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
593 Qos
.ImpersonationLevel
= SecurityAnonymous
;
594 Qos
.ContextTrackingMode
= SECURITY_STATIC_TRACKING
;
595 Qos
.EffectiveOnly
= FALSE
;
597 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
598 ObjectAttributes
.RootDirectory
= NULL
;
599 ObjectAttributes
.ObjectName
= NULL
;
600 ObjectAttributes
.Attributes
= 0;
601 ObjectAttributes
.SecurityDescriptor
= NULL
;
602 ObjectAttributes
.SecurityQualityOfService
= &Qos
;
604 Status
= NtAllocateLocallyUniqueId(&AuthenticationId
);
605 if (!NT_SUCCESS(Status
))
609 ExpirationTime
.QuadPart
= -1;
611 /* Get the user SID from the registry */
612 if (!SamGetUserSid (lpszUsername
, &UserSid
))
614 DPRINT ("SamGetUserSid() failed\n");
615 RtlAllocateAndInitializeSid (&SystemAuthority
,
617 SECURITY_NT_NON_UNIQUE_RID
,
621 DOMAIN_USER_RID_ADMIN
,
628 TokenUser
.User
.Sid
= UserSid
;
629 TokenUser
.User
.Attributes
= 0;
631 /* Allocate and initialize token groups */
632 TokenGroups
= AllocateGroupSids(&PrimaryGroupSid
,
634 if (NULL
== TokenGroups
)
637 SetLastError(ERROR_OUTOFMEMORY
);
641 /* Allocate and initialize token privileges */
642 TokenPrivileges
= RtlAllocateHeap(GetProcessHeap(), 0,
643 sizeof(TOKEN_PRIVILEGES
)
644 + sizeof(DefaultPrivs
) / sizeof(DefaultPrivs
[0])
645 * sizeof(LUID_AND_ATTRIBUTES
));
646 if (NULL
== TokenPrivileges
)
648 FreeGroupSids(TokenGroups
);
650 SetLastError(ERROR_OUTOFMEMORY
);
654 TokenPrivileges
->PrivilegeCount
= 0;
655 for (i
= 0; i
< sizeof(DefaultPrivs
) / sizeof(DefaultPrivs
[0]); i
++)
657 if (! LookupPrivilegeValueW(NULL
, DefaultPrivs
[i
].PrivName
,
658 &TokenPrivileges
->Privileges
[TokenPrivileges
->PrivilegeCount
].Luid
))
660 DPRINT1("Can't set privilege %S\n", DefaultPrivs
[i
].PrivName
);
664 TokenPrivileges
->Privileges
[TokenPrivileges
->PrivilegeCount
].Attributes
= DefaultPrivs
[i
].Attributes
;
665 TokenPrivileges
->PrivilegeCount
++;
669 TokenOwner
.Owner
= OwnerSid
;
670 TokenPrimaryGroup
.PrimaryGroup
= PrimaryGroupSid
;
673 Dacl
= RtlAllocateHeap(GetProcessHeap(), 0, 1024);
676 FreeGroupSids(TokenGroups
);
678 SetLastError(ERROR_OUTOFMEMORY
);
682 Status
= RtlCreateAcl(Dacl
, 1024, ACL_REVISION
);
683 if (!NT_SUCCESS(Status
))
685 RtlFreeHeap(GetProcessHeap(), 0, Dacl
);
686 FreeGroupSids(TokenGroups
);
687 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges
);
692 RtlAddAccessAllowedAce(Dacl
,
697 RtlAllocateAndInitializeSid(&SystemAuthority
,
699 SECURITY_LOCAL_SYSTEM_RID
,
710 RtlAddAccessAllowedAce(Dacl
,
715 RtlFreeSid(LocalSystemSid
);
717 TokenDefaultDacl
.DefaultDacl
= Dacl
;
719 memcpy(TokenSource
.SourceName
,
722 Status
= NtAllocateLocallyUniqueId(&TokenSource
.SourceIdentifier
);
723 if (!NT_SUCCESS(Status
))
725 RtlFreeHeap(GetProcessHeap(), 0, Dacl
);
726 FreeGroupSids(TokenGroups
);
727 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges
);
732 Status
= NtCreateToken(phToken
,
746 RtlFreeHeap(GetProcessHeap(), 0, Dacl
);
747 FreeGroupSids(TokenGroups
);
748 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges
);
751 return NT_SUCCESS(Status
);