[LSASRV][MSV1_0]
authorEric Kohl <eric.kohl@reactos.org>
Thu, 2 Jan 2014 20:02:33 +0000 (20:02 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Thu, 2 Jan 2014 20:02:33 +0000 (20:02 +0000)
- Create the privilege set for the logon token based on the users group membrships.
- Remove the hard-coded privilege set.

svn path=/trunk/; revision=61493

reactos/dll/win32/lsasrv/authpackage.c
reactos/dll/win32/msv1_0/msv1_0.c

index abda76a..ce95928 100644 (file)
@@ -94,6 +94,9 @@ typedef struct _AUTH_PACKAGE
     PLSA_AP_LOGON_USER_INTERNAL LsaApLogonUser;
 } AUTH_PACKAGE, *PAUTH_PACKAGE;
 
+VOID
+NTAPI
+LsaIFree_LSAPR_PRIVILEGE_SET(IN PLSAPR_PRIVILEGE_SET Ptr);
 
 /* GLOBALS *****************************************************************/
 
@@ -101,6 +104,11 @@ static LIST_ENTRY PackageListHead;
 static ULONG PackageId;
 static LSA_DISPATCH_TABLE DispatchTable;
 
+#define CONST_LUID(x1, x2) {x1, x2}
+static const LUID SeChangeNotifyPrivilege = CONST_LUID(SE_CHANGE_NOTIFY_PRIVILEGE, 0);
+static const LUID SeCreateGlobalPrivilege = CONST_LUID(SE_CREATE_GLOBAL_PRIVILEGE, 0);
+static const LUID SeImpersonatePrivilege = CONST_LUID(SE_IMPERSONATE_PRIVILEGE, 0);
+
 
 /* FUNCTIONS ***************************************************************/
 
@@ -936,6 +944,137 @@ LsapAddTokenDefaultDacl(
 }
 
 
+static
+NTSTATUS
+LsapAddPrivilegeToTokenPrivileges(PTOKEN_PRIVILEGES *TokenPrivileges,
+                                  PLSAPR_LUID_AND_ATTRIBUTES Privilege)
+{
+    PTOKEN_PRIVILEGES LocalPrivileges;
+    ULONG Length, TokenPrivilegeCount, i;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    if (*TokenPrivileges == NULL)
+    {
+        Length = sizeof(TOKEN_PRIVILEGES) +
+                 (1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES);
+        LocalPrivileges = RtlAllocateHeap(RtlGetProcessHeap(),
+                                          0,
+                                          Length);
+        if (LocalPrivileges == NULL)
+            return STATUS_INSUFFICIENT_RESOURCES;
+
+        LocalPrivileges->PrivilegeCount = 1;
+        LocalPrivileges->Privileges[0].Luid = Privilege->Luid;
+        LocalPrivileges->Privileges[0].Attributes = Privilege->Attributes;
+    }
+    else
+    {
+        TokenPrivilegeCount = (*TokenPrivileges)->PrivilegeCount;
+
+        for (i = 0; i < TokenPrivilegeCount; i++)
+        {
+            if (RtlEqualLuid(&(*TokenPrivileges)->Privileges[i].Luid, &Privilege->Luid))
+                return STATUS_SUCCESS;
+        }
+
+        Length = sizeof(TOKEN_PRIVILEGES) +
+                 (TokenPrivilegeCount + 1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES);
+        LocalPrivileges = RtlAllocateHeap(RtlGetProcessHeap(),
+                                          0,
+                                          Length);
+        if (LocalPrivileges == NULL)
+            return STATUS_INSUFFICIENT_RESOURCES;
+
+        LocalPrivileges->PrivilegeCount = TokenPrivilegeCount + 1;
+        for (i = 0; i < TokenPrivilegeCount; i++)
+        {
+            LocalPrivileges->Privileges[i].Luid = (*TokenPrivileges)->Privileges[i].Luid;
+            LocalPrivileges->Privileges[i].Attributes = (*TokenPrivileges)->Privileges[i].Attributes;
+        }
+
+        LocalPrivileges->Privileges[TokenPrivilegeCount].Luid = Privilege->Luid;
+        LocalPrivileges->Privileges[TokenPrivilegeCount].Attributes = Privilege->Attributes;
+
+        RtlFreeHeap(RtlGetProcessHeap(), 0, *TokenPrivileges);
+    }
+
+    *TokenPrivileges = LocalPrivileges;
+
+    return Status;
+}
+
+static
+NTSTATUS
+LsapSetPrivileges(
+    IN PVOID TokenInformation,
+    IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType)
+{
+    PLSA_TOKEN_INFORMATION_V1 TokenInfo1;
+    LSAPR_HANDLE PolicyHandle = NULL;
+    LSAPR_HANDLE AccountHandle = NULL;
+    PLSAPR_PRIVILEGE_SET Privileges = NULL;
+    ULONG i, j;
+    NTSTATUS Status;
+
+    if (TokenInformationType == LsaTokenInformationV1)
+    {
+        TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
+
+        Status = LsarOpenPolicy(NULL,
+                                NULL,
+                                0,
+                                &PolicyHandle);
+        if (!NT_SUCCESS(Status))
+            return Status;
+
+        for (i = 0; i < TokenInfo1->Groups->GroupCount; i++)
+        {
+            Status = LsarOpenAccount(PolicyHandle,
+                                     TokenInfo1->Groups->Groups[i].Sid,
+                                     ACCOUNT_VIEW,
+                                     &AccountHandle);
+            if (NT_SUCCESS(Status))
+            {
+                Status = LsarEnumeratePrivilegesAccount(AccountHandle,
+                                                        &Privileges);
+                if (NT_SUCCESS(Status))
+                {
+                    for (j = 0; j < Privileges->PrivilegeCount; j++)
+                    {
+                        Status = LsapAddPrivilegeToTokenPrivileges(&TokenInfo1->Privileges,
+                                                                   &(Privileges->Privilege[j]));
+                        if (!NT_SUCCESS(Status))
+                            return Status;
+                    }
+
+                    LsaIFree_LSAPR_PRIVILEGE_SET(Privileges);
+                    Privileges = NULL;
+                }
+            }
+
+            LsarClose(&AccountHandle);
+        }
+
+        LsarClose(&PolicyHandle);
+
+        if (TokenInfo1->Privileges != NULL)
+        {
+            for (i = 0; i < TokenInfo1->Privileges->PrivilegeCount; i++)
+            {
+                if (RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeChangeNotifyPrivilege) ||
+                    RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeCreateGlobalPrivilege) ||
+                    RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeImpersonatePrivilege))
+                {
+                    TokenInfo1->Privileges->Privileges[i].Attributes |= SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT;
+                }
+            }
+        }
+    }
+
+    return STATUS_SUCCESS;
+}
+
+
 NTSTATUS
 LsapLogonUser(PLSA_API_MSG RequestMsg,
               PLSAP_LOGON_CONTEXT LogonContext)
@@ -1108,6 +1247,14 @@ LsapLogonUser(PLSA_API_MSG RequestMsg,
         goto done;
     }
 
+    Status = LsapSetPrivileges(TokenInformation,
+                               TokenInformationType);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapSetPrivileges() failed (Status 0x%08lx)\n", Status);
+        goto done;
+    }
+
     if (TokenInformationType == LsaTokenInformationV1)
     {
         TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation;
index ad9bc89..37fb0da 100644 (file)
@@ -381,92 +381,6 @@ BuildTokenGroups(OUT PTOKEN_GROUPS *Groups,
 }
 
 
-static
-NTSTATUS
-BuildTokenPrivileges(PTOKEN_PRIVILEGES *TokenPrivileges)
-{
-    /* FIXME shouldn't use hard-coded list of privileges */
-    static struct
-    {
-      LPCWSTR PrivName;
-      DWORD Attributes;
-    }
-    DefaultPrivs[] =
-    {
-      { L"SeMachineAccountPrivilege", 0 },
-      { L"SeSecurityPrivilege", 0 },
-      { L"SeTakeOwnershipPrivilege", 0 },
-      { L"SeLoadDriverPrivilege", 0 },
-      { L"SeSystemProfilePrivilege", 0 },
-      { L"SeSystemtimePrivilege", 0 },
-      { L"SeProfileSingleProcessPrivilege", 0 },
-      { L"SeIncreaseBasePriorityPrivilege", 0 },
-      { L"SeCreatePagefilePrivilege", 0 },
-      { L"SeBackupPrivilege", 0 },
-      { L"SeRestorePrivilege", 0 },
-      { L"SeShutdownPrivilege", 0 },
-      { L"SeDebugPrivilege", 0 },
-      { L"SeSystemEnvironmentPrivilege", 0 },
-      { L"SeChangeNotifyPrivilege", SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
-      { L"SeRemoteShutdownPrivilege", 0 },
-      { L"SeUndockPrivilege", 0 },
-      { L"SeEnableDelegationPrivilege", 0 },
-      { L"SeImpersonatePrivilege", SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
-      { L"SeCreateGlobalPrivilege", SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT }
-    };
-    PTOKEN_PRIVILEGES Privileges = NULL;
-    ULONG i;
-    RPC_UNICODE_STRING PrivilegeName;
-    LSAPR_HANDLE PolicyHandle = NULL;
-    NTSTATUS Status = STATUS_SUCCESS;
-
-    Status = LsaIOpenPolicyTrusted(&PolicyHandle);
-    if (!NT_SUCCESS(Status))
-    {
-        goto done;
-    }
-
-    /* Allocate and initialize token privileges */
-    Privileges = DispatchTable.AllocateLsaHeap(sizeof(TOKEN_PRIVILEGES) +
-                                               sizeof(DefaultPrivs) / sizeof(DefaultPrivs[0]) *
-                                               sizeof(LUID_AND_ATTRIBUTES));
-    if (Privileges == NULL)
-    {
-        Status = STATUS_INSUFFICIENT_RESOURCES;
-        goto done;
-    }
-
-    Privileges->PrivilegeCount = 0;
-    for (i = 0; i < sizeof(DefaultPrivs) / sizeof(DefaultPrivs[0]); i++)
-    {
-        PrivilegeName.Length = wcslen(DefaultPrivs[i].PrivName) * sizeof(WCHAR);
-        PrivilegeName.MaximumLength = PrivilegeName.Length + sizeof(WCHAR);
-        PrivilegeName.Buffer = (LPWSTR)DefaultPrivs[i].PrivName;
-
-        Status = LsarLookupPrivilegeValue(PolicyHandle,
-                                          &PrivilegeName,
-                                          &Privileges->Privileges[Privileges->PrivilegeCount].Luid);
-        if (!NT_SUCCESS(Status))
-        {
-            WARN("Can't set privilege %S\n", DefaultPrivs[i].PrivName);
-        }
-        else
-        {
-            Privileges->Privileges[Privileges->PrivilegeCount].Attributes = DefaultPrivs[i].Attributes;
-            Privileges->PrivilegeCount++;
-        }
-    }
-
-    *TokenPrivileges = Privileges;
-
-done:
-    if (PolicyHandle != NULL)
-        LsarClose(&PolicyHandle);
-
-    return Status;
-}
-
-
 static
 NTSTATUS
 BuildTokenInformationBuffer(PLSA_TOKEN_INFORMATION_V1 *TokenInformation,
@@ -505,10 +419,6 @@ BuildTokenInformationBuffer(PLSA_TOKEN_INFORMATION_V1 *TokenInformation,
     if (!NT_SUCCESS(Status))
         goto done;
 
-    Status = BuildTokenPrivileges(&Buffer->Privileges);
-    if (!NT_SUCCESS(Status))
-        goto done;
-
     *TokenInformation = Buffer;
 
 done:
@@ -533,9 +443,6 @@ done:
             if (Buffer->PrimaryGroup.PrimaryGroup != NULL)
                 DispatchTable.FreeLsaHeap(Buffer->PrimaryGroup.PrimaryGroup);
 
-            if (Buffer->Privileges != NULL)
-                DispatchTable.FreeLsaHeap(Buffer->Privileges);
-
             if (Buffer->DefaultDacl.DefaultDacl != NULL)
                 DispatchTable.FreeLsaHeap(Buffer->DefaultDacl.DefaultDacl);