From 22d062da043e0bc904611fb88cfca1d354ee8de8 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Thu, 17 May 2012 12:02:50 +0000 Subject: [PATCH] [PSDK/LSASRV] - Add new ntlsa.h file to the PSDK. - LsarAddPrivilegesToAccount: Implement the ability to add new privileges to an existing privilege set. svn path=/trunk/; revision=56594 --- reactos/dll/win32/lsasrv/lsarpc.c | 110 +++++++++++++++++++++++++++++- reactos/dll/win32/lsasrv/lsasrv.h | 1 + reactos/include/psdk/ntlsa.h | 40 +++++++++++ 3 files changed, 148 insertions(+), 3 deletions(-) create mode 100644 reactos/include/psdk/ntlsa.h diff --git a/reactos/dll/win32/lsasrv/lsarpc.c b/reactos/dll/win32/lsasrv/lsarpc.c index f398c800e15..1b380595645 100644 --- a/reactos/dll/win32/lsasrv/lsarpc.c +++ b/reactos/dll/win32/lsasrv/lsarpc.c @@ -733,7 +733,7 @@ NTSTATUS WINAPI LsarEnumeratePrivilegesAccount( /* Validate the AccountHandle */ Status = LsapValidateDbObject(AccountHandle, LsaDbAccountObject, - 0, + ACCOUNT_VIEW, &AccountObject); if (!NT_SUCCESS(Status)) { @@ -778,13 +778,18 @@ NTSTATUS WINAPI LsarAddPrivilegesToAccount( PLSAPR_PRIVILEGE_SET Privileges) { PLSA_DB_OBJECT AccountObject; + PPRIVILEGE_SET CurrentPrivileges = NULL; + PPRIVILEGE_SET NewPrivileges = NULL; ULONG PrivilegeSetSize = 0; + ULONG PrivilegeCount; + ULONG i, j; + BOOL bFound; NTSTATUS Status; /* Validate the AccountHandle */ Status = LsapValidateDbObject(AccountHandle, LsaDbAccountObject, - 0, + ACCOUNT_ADJUST_PRIVILEGES, &AccountObject); if (!NT_SUCCESS(Status)) { @@ -811,9 +816,108 @@ NTSTATUS WINAPI LsarAddPrivilegesToAccount( { /* The Privilgs attribute exists */ - Status = STATUS_NOT_IMPLEMENTED; + /* Allocate memory for the stored privilege set */ + CurrentPrivileges = MIDL_user_allocate(PrivilegeSetSize); + if (CurrentPrivileges == NULL) + return STATUS_NO_MEMORY; + + /* Get the current privilege set */ + Status = LsapGetObjectAttribute(AccountObject, + L"Privilgs", + CurrentPrivileges, + &PrivilegeSetSize); + if (!NT_SUCCESS(Status)) + { + TRACE("LsapGetObjectAttribute() failed (Status 0x%08lx)\n", Status); + goto done; + } + + PrivilegeCount = CurrentPrivileges->PrivilegeCount; + TRACE("Current privilege count: %lu\n", PrivilegeCount); + + /* Calculate the number privileges in the combined privilege set */ + for (i = 0; i < Privileges->PrivilegeCount; i++) + { + bFound = FALSE; + for (j = 0; j < CurrentPrivileges->PrivilegeCount; j++) + { + if (RtlEqualLuid(&(Privileges->Privilege[i].Luid), + &(CurrentPrivileges->Privilege[i].Luid))) + { + bFound = TRUE; + break; + } + } + + if (bFound == FALSE) + { + TRACE("Found new privilege\n"); + PrivilegeCount++; + } + } + TRACE("New privilege count: %lu\n", PrivilegeCount); + + /* Calculate the size of the new privilege set and allocate it */ + PrivilegeSetSize = sizeof(PRIVILEGE_SET) + + (PrivilegeCount - 1) * sizeof(LUID_AND_ATTRIBUTES); + NewPrivileges = MIDL_user_allocate(PrivilegeSetSize); + if (NewPrivileges == NULL) + { + Status = STATUS_NO_MEMORY; + goto done; + } + + /* Initialize the new privilege set */ + NewPrivileges->PrivilegeCount = PrivilegeCount; + NewPrivileges->Control = 0; + + /* Copy all privileges from the current privilege set */ + RtlCopyLuidAndAttributesArray(CurrentPrivileges->PrivilegeCount, + &(CurrentPrivileges->Privilege[0]), + &(NewPrivileges->Privilege[0])); + + /* Add new privileges to the new privilege set */ + PrivilegeCount = CurrentPrivileges->PrivilegeCount; + for (i = 0; i < Privileges->PrivilegeCount; i++) + { + bFound = FALSE; + for (j = 0; j < CurrentPrivileges->PrivilegeCount; j++) + { + if (RtlEqualLuid(&(Privileges->Privilege[i].Luid), + &(CurrentPrivileges->Privilege[i].Luid))) + { + /* Overwrite attributes if a matching privilege was found */ + NewPrivileges->Privilege[j].Attributes = Privileges->Privilege[i].Attributes; + + bFound = TRUE; + break; + } + } + + if (bFound == FALSE) + { + /* Copy the new privilege */ + RtlCopyLuidAndAttributesArray(1, + (PLUID_AND_ATTRIBUTES)&(Privileges->Privilege[i]), + &(NewPrivileges->Privilege[PrivilegeCount])); + PrivilegeCount++; + } + } + + /* Set the new priivliege set */ + Status = LsapSetObjectAttribute(AccountObject, + L"Privilgs", + NewPrivileges, + PrivilegeSetSize); } +done: + if (CurrentPrivileges != NULL) + MIDL_user_free(CurrentPrivileges); + + if (NewPrivileges != NULL) + MIDL_user_free(NewPrivileges); + return Status; } diff --git a/reactos/dll/win32/lsasrv/lsasrv.h b/reactos/dll/win32/lsasrv/lsasrv.h index efed11c5839..79f7ed49937 100644 --- a/reactos/dll/win32/lsasrv/lsasrv.h +++ b/reactos/dll/win32/lsasrv/lsasrv.h @@ -17,6 +17,7 @@ #include #include +#include #include #include diff --git a/reactos/include/psdk/ntlsa.h b/reactos/include/psdk/ntlsa.h new file mode 100644 index 00000000000..3202f1e0732 --- /dev/null +++ b/reactos/include/psdk/ntlsa.h @@ -0,0 +1,40 @@ +/* + * ntlsa.h + * + * This file is part of the ReactOS PSDK package. + * + * Contributors: + * Created by Eric Kohl. + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef _NTLSA_ +#define _NTLSA_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define ACCOUNT_VIEW 1 +#define ACCOUNT_ADJUST_PRIVILEGES 2 +#define ACCOUNT_ADJUST_QUOTAS 4 +#define ACCOUNT_ADJUST_SYSTEM_ACCESS 8 + + + +#ifdef __cplusplus +} +#endif + + +#endif /* _NTLSA_ */ -- 2.17.1