diff --git a/reactos/lib/advapi32/misc/logon.c b/reactos/lib/advapi32/misc/logon.c index cfc0f6f74fa..9059f09038e 100644 --- a/reactos/lib/advapi32/misc/logon.c +++ b/reactos/lib/advapi32/misc/logon.c @@ -1,4 +1,4 @@ -/* $Id: logon.c,v 1.7 2004/07/07 08:41:47 gvg Exp $ +/* $Id: logon.c,v 1.8 2004/07/10 13:12:24 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -237,6 +237,293 @@ SamGetUserSid (LPCWSTR UserName, } +static BOOL STDCALL +SamGetDomainSid(PSID *Sid) +{ + PSID lpSid; + DWORD dwLength; + HKEY hDomainKey; + + DPRINT("SamGetDomainSid() called\n"); + + if (Sid != NULL) + *Sid = NULL; + + /* Open the account domain key */ + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, + L"SAM\\SAM\\Domains\\Account", + 0, + KEY_READ, + &hDomainKey)) + { + DPRINT1("Failed to open the account domain key! (Error %lu)\n", GetLastError()); + return FALSE; + } + + /* Get SID size */ + dwLength = 0; + if (RegQueryValueExW(hDomainKey, + L"Sid", + NULL, + NULL, + NULL, + &dwLength)) + { + DPRINT1("Failed to read the SID size! (Error %lu)\n", GetLastError()); + RegCloseKey(hDomainKey); + return FALSE; + } + + /* Allocate sid buffer */ + DPRINT("Required SID buffer size: %lu\n", dwLength); + lpSid = (PSID)RtlAllocateHeap(RtlGetProcessHeap(), + 0, + dwLength); + if (lpSid == NULL) + { + DPRINT1("Failed to allocate SID buffer!\n"); + RegCloseKey(hDomainKey); + return FALSE; + } + + /* Read sid */ + if (RegQueryValueExW(hDomainKey, + L"Sid", + NULL, + NULL, + (LPBYTE)lpSid, + &dwLength)) + { + DPRINT1("Failed to read the SID! (Error %lu)\n", GetLastError()); + RtlFreeHeap(RtlGetProcessHeap(), + 0, + lpSid); + RegCloseKey(hDomainKey); + return FALSE; + } + + RegCloseKey(hDomainKey); + + *Sid = lpSid; + + DPRINT("SamGetDomainSid() done\n"); + + return TRUE; +} + + +static PSID +AppendRidToSid(PSID SrcSid, + ULONG Rid) +{ + ULONG Rids[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + UCHAR RidCount; + PSID DstSid; + ULONG i; + + RidCount = *RtlSubAuthorityCountSid(SrcSid); + if (RidCount >= 8) + return NULL; + + for (i = 0; i < RidCount; i++) + Rids[i] = *RtlSubAuthoritySid(SrcSid, i); + + Rids[RidCount] = Rid; + RidCount++; + + RtlAllocateAndInitializeSid(RtlIdentifierAuthoritySid(SrcSid), + RidCount, + Rids[0], + Rids[1], + Rids[2], + Rids[3], + Rids[4], + Rids[5], + Rids[6], + Rids[7], + &DstSid); + + return DstSid; +} + + +static PTOKEN_GROUPS +AllocateGroupSids(PSID *PrimaryGroupSid, + PSID *OwnerSid) +{ + SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY}; + SID_IDENTIFIER_AUTHORITY LocalAuthority = {SECURITY_LOCAL_SID_AUTHORITY}; + SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY}; + PTOKEN_GROUPS TokenGroups; + PSID DomainSid; + PSID Sid; + LUID Luid; + NTSTATUS Status; + + Status = NtAllocateLocallyUniqueId(&Luid); + if (!NT_SUCCESS(Status)) + { + return NULL; + } + + if (!SamGetDomainSid(&DomainSid)) + { + return NULL; + } + + TokenGroups = RtlAllocateHeap(GetProcessHeap(), 0, + sizeof(TOKEN_GROUPS) + + 8 * sizeof(SID_AND_ATTRIBUTES)); + if (TokenGroups == NULL) + { + RtlFreeHeap (RtlGetProcessHeap (), + 0, + DomainSid); + return NULL; + } + + TokenGroups->GroupCount = 8; + + Sid = AppendRidToSid(DomainSid, + DOMAIN_GROUP_RID_USERS); + + RtlFreeHeap(RtlGetProcessHeap(), + 0, + DomainSid); + + TokenGroups->Groups[0].Sid = Sid; + TokenGroups->Groups[0].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; + *PrimaryGroupSid = Sid; + + + RtlAllocateAndInitializeSid(&WorldAuthority, + 1, + SECURITY_WORLD_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + &Sid); + + TokenGroups->Groups[1].Sid = Sid; + TokenGroups->Groups[1].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; + + + RtlAllocateAndInitializeSid(&SystemAuthority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + &Sid); + + TokenGroups->Groups[2].Sid = Sid; + TokenGroups->Groups[2].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; + + *OwnerSid = Sid; + + RtlAllocateAndInitializeSid(&SystemAuthority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_USERS, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + &Sid); + + TokenGroups->Groups[3].Sid = Sid; + TokenGroups->Groups[3].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; + + /* Logon SID */ + RtlAllocateAndInitializeSid(&SystemAuthority, + SECURITY_LOGON_IDS_RID_COUNT, + SECURITY_LOGON_IDS_RID, + Luid.HighPart, + Luid.LowPart, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + &Sid); + + TokenGroups->Groups[4].Sid = Sid; + TokenGroups->Groups[4].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY | SE_GROUP_LOGON_ID; + + RtlAllocateAndInitializeSid(&LocalAuthority, + 1, + SECURITY_LOCAL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + &Sid); + + TokenGroups->Groups[5].Sid = Sid; + TokenGroups->Groups[5].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; + + RtlAllocateAndInitializeSid(&SystemAuthority, + 1, + SECURITY_INTERACTIVE_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + &Sid); + + TokenGroups->Groups[6].Sid = Sid; + TokenGroups->Groups[6].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; + + RtlAllocateAndInitializeSid(&SystemAuthority, + 1, + SECURITY_AUTHENTICATED_USER_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + &Sid); + + TokenGroups->Groups[7].Sid = Sid; + TokenGroups->Groups[7].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; + + return TokenGroups; +} + + +static VOID +FreeGroupSids(PTOKEN_GROUPS TokenGroups) +{ + ULONG i; + + for (i = 0; i < TokenGroups->GroupCount; i++) + { + if (TokenGroups->Groups[i].Sid != NULL) + RtlFreeHeap(GetProcessHeap(), 0, TokenGroups->Groups[i].Sid); + } + + RtlFreeHeap(GetProcessHeap(), 0, TokenGroups); +} + + /* * @unimplemented */ @@ -283,14 +570,15 @@ LogonUserW (LPWSTR lpszUsername, TOKEN_USER TokenUser; TOKEN_OWNER TokenOwner; TOKEN_PRIMARY_GROUP TokenPrimaryGroup; - TOKEN_GROUPS TokenGroups; -// PTOKEN_GROUPS TokenGroups; + PTOKEN_GROUPS TokenGroups; PTOKEN_PRIVILEGES TokenPrivileges; TOKEN_DEFAULT_DACL TokenDefaultDacl; LARGE_INTEGER ExpirationTime; LUID AuthenticationId; TOKEN_SOURCE TokenSource; - PSID UserSid; + PSID UserSid = NULL; + PSID PrimaryGroupSid = NULL; + PSID OwnerSid = NULL; ACL Dacl; NTSTATUS Status; SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY}; @@ -333,21 +621,29 @@ LogonUserW (LPWSTR lpszUsername, TokenUser.User.Sid = UserSid; TokenUser.User.Attributes = 0; -// TokenGroups = NULL; - TokenGroups.GroupCount = 1; - TokenGroups.Groups[0].Sid = UserSid; /* FIXME */ - TokenGroups.Groups[0].Attributes = SE_GROUP_ENABLED; + /* Allocate and initialize token groups */ + TokenGroups = AllocateGroupSids(&PrimaryGroupSid, + &OwnerSid); + if (NULL == TokenGroups) + { + RtlFreeSid (UserSid); + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + /* Allocate and initialize token privileges */ TokenPrivileges = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(TOKEN_PRIVILEGES) + sizeof(DefaultPrivs) / sizeof(DefaultPrivs[0]) * sizeof(LUID_AND_ATTRIBUTES)); if (NULL == TokenPrivileges) { + FreeGroupSids(TokenGroups); RtlFreeSid (UserSid); SetLastError(ERROR_OUTOFMEMORY); return FALSE; } + TokenPrivileges->PrivilegeCount = 0; for (i = 0; i < sizeof(DefaultPrivs) / sizeof(DefaultPrivs[0]); i++) { @@ -363,13 +659,14 @@ LogonUserW (LPWSTR lpszUsername, } } - TokenOwner.Owner = UserSid; - - TokenPrimaryGroup.PrimaryGroup = UserSid; + TokenOwner.Owner = OwnerSid; + TokenPrimaryGroup.PrimaryGroup = PrimaryGroupSid; +// TokenPrimaryGroup.PrimaryGroup = UserSid; Status = RtlCreateAcl (&Dacl, sizeof(ACL), ACL_REVISION); if (!NT_SUCCESS(Status)) { + FreeGroupSids(TokenGroups); RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges); RtlFreeSid (UserSid); return FALSE; @@ -383,6 +680,8 @@ LogonUserW (LPWSTR lpszUsername, Status = NtAllocateLocallyUniqueId (&TokenSource.SourceIdentifier); if (!NT_SUCCESS(Status)) { + FreeGroupSids(TokenGroups); + RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges); RtlFreeSid (UserSid); return FALSE; } @@ -394,14 +693,14 @@ LogonUserW (LPWSTR lpszUsername, &AuthenticationId, &ExpirationTime, &TokenUser, -// TokenGroups, - &TokenGroups, + TokenGroups, TokenPrivileges, &TokenOwner, &TokenPrimaryGroup, &TokenDefaultDacl, &TokenSource); + FreeGroupSids(TokenGroups); RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges); RtlFreeSid (UserSid);