From 2c8427e0dc59edcbafc3d664d92f04063c69c30c Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Thu, 2 Nov 2017 23:56:19 +0300 Subject: [PATCH] advapi32: Partially implement LsaLookupPrivilegeName(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on patch by Michael Müller. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/advapi32/advapi32_misc.h | 1 + dlls/advapi32/lsa.c | 32 +++++++++++++++++++++++++------ dlls/advapi32/security.c | 9 +++++++++ dlls/advapi32/tests/lsa.c | 36 +++++++++++++++++++++++++++++++++++ include/Makefile.in | 1 + include/ntlsa.h | 19 ++++++++++++++++++ 6 files changed, 92 insertions(+), 6 deletions(-) create mode 100644 include/ntlsa.h diff --git a/dlls/advapi32/advapi32_misc.h b/dlls/advapi32/advapi32_misc.h index d116ecb836e..7fc02a4a2e8 100644 --- a/dlls/advapi32/advapi32_misc.h +++ b/dlls/advapi32/advapi32_misc.h @@ -34,6 +34,7 @@ WCHAR *SERV_dup(const char *str) DECLSPEC_HIDDEN; DWORD SERV_OpenSCManagerW(LPCWSTR, LPCWSTR, DWORD, SC_HANDLE*) DECLSPEC_HIDDEN; DWORD SERV_OpenServiceW(SC_HANDLE, LPCWSTR, DWORD, SC_HANDLE*) DECLSPEC_HIDDEN; NTSTATUS SERV_QueryServiceObjectSecurity(SC_HANDLE, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, DWORD, LPDWORD) DECLSPEC_HIDDEN; +const WCHAR *get_wellknown_privilege_name(const LUID *) DECLSPEC_HIDDEN; /* memory allocation functions */ diff --git a/dlls/advapi32/lsa.c b/dlls/advapi32/lsa.c index a9ec9e4ae37..42da4b4afa0 100644 --- a/dlls/advapi32/lsa.c +++ b/dlls/advapi32/lsa.c @@ -978,11 +978,31 @@ NTSTATUS WINAPI LsaUnregisterPolicyChangeNotification( * LsaLookupPrivilegeName [ADVAPI32.@] * */ -NTSTATUS WINAPI LsaLookupPrivilegeName( - LSA_HANDLE handle, - LUID *luid, - UNICODE_STRING **name) +NTSTATUS WINAPI LsaLookupPrivilegeName(LSA_HANDLE handle, LUID *luid, LSA_UNICODE_STRING **name) { - FIXME("(%p,%p,%p) stub\n", handle, luid, name); - return STATUS_NO_SUCH_PRIVILEGE; + const WCHAR *privnameW; + DWORD length; + WCHAR *strW; + + TRACE("(%p,%p,%p)\n", handle, luid, name); + + if (!luid || !handle) + return STATUS_INVALID_PARAMETER; + + *name = NULL; + + if (!(privnameW = get_wellknown_privilege_name(luid))) + return STATUS_NO_SUCH_PRIVILEGE; + + length = strlenW(privnameW); + *name = heap_alloc(sizeof(**name) + (length + 1) * sizeof(WCHAR)); + if (!*name) + return STATUS_NO_MEMORY; + + strW = (WCHAR *)(*name + 1); + memcpy(strW, privnameW, length * sizeof(WCHAR)); + strW[length] = 0; + RtlInitUnicodeString(*name, strW); + + return STATUS_SUCCESS; } diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c index e36792cff4b..c9d5cfaffad 100644 --- a/dlls/advapi32/security.c +++ b/dlls/advapi32/security.c @@ -1875,6 +1875,15 @@ static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] = SE_CREATE_GLOBAL_NAME_W, }; +const WCHAR *get_wellknown_privilege_name(const LUID *luid) +{ + if (luid->HighPart || luid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE || + luid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE || !WellKnownPrivNames[luid->LowPart]) + return NULL; + + return WellKnownPrivNames[luid->LowPart]; +} + /****************************************************************************** * LookupPrivilegeValueW [ADVAPI32.@] * diff --git a/dlls/advapi32/tests/lsa.c b/dlls/advapi32/tests/lsa.c index a06c8afca11..861fea0525e 100644 --- a/dlls/advapi32/tests/lsa.c +++ b/dlls/advapi32/tests/lsa.c @@ -32,6 +32,8 @@ #include "objbase.h" #include "initguid.h" #include "wine/test.h" +#include "winternl.h" +#include "ntlsa.h" DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); @@ -391,9 +393,43 @@ static void test_LsaLookupSids(void) ok(status == STATUS_SUCCESS, "got 0x%08x\n", status); } +static void test_LsaLookupPrivilegeName(void) +{ + LSA_OBJECT_ATTRIBUTES attrs; + LSA_UNICODE_STRING *name; + LSA_HANDLE policy; + NTSTATUS status; + LUID luid; + + memset(&attrs, 0, sizeof(attrs)); + attrs.Length = sizeof(attrs); + + status = LsaOpenPolicy(NULL, &attrs, POLICY_LOOKUP_NAMES, &policy); + ok(status == STATUS_SUCCESS, "Failed to open policy, %#x.\n", status); + + name = (void *)0xdeadbeef; + status = LsaLookupPrivilegeName(policy, NULL, &name); + ok(status != STATUS_SUCCESS, "Unexpected status %#x.\n", status); + ok(name == (void *)0xdeadbeef, "Unexpected name pointer.\n"); + + name = (void *)0xdeadbeef; + luid.HighPart = 1; + luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE; + status = LsaLookupPrivilegeName(policy, &luid, &name); + ok(status == STATUS_NO_SUCH_PRIVILEGE, "Unexpected status %#x.\n", status); + ok(name == NULL, "Unexpected name pointer.\n"); + + luid.HighPart = 0; + luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE; + status = LsaLookupPrivilegeName(policy, &luid, &name); + ok(status == 0, "got %#x.\n", status); + LsaFreeMemory(name); +} + START_TEST(lsa) { test_lsa(); test_LsaLookupNames2(); test_LsaLookupSids(); + test_LsaLookupPrivilegeName(); } diff --git a/include/Makefile.in b/include/Makefile.in index 025fe774552..cc42f66ebd4 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -550,6 +550,7 @@ HEADER_SRCS = \ ntddstor.h \ ntdef.h \ ntdsapi.h \ + ntlsa.h \ ntquery.h \ ntsecapi.h \ ntsecpkg.h \ diff --git a/include/ntlsa.h b/include/ntlsa.h new file mode 100644 index 00000000000..468c14e1b42 --- /dev/null +++ b/include/ntlsa.h @@ -0,0 +1,19 @@ +/* + * Copyright 2017 Nikolay Sivov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +NTSTATUS WINAPI LsaLookupPrivilegeName(LSA_HANDLE policy, LUID *value, LSA_UNICODE_STRING **name);