[PATCH 3/4] advapi32/lsa: Partially implement LsaLookupPrivilegeName()

Nikolay Sivov <[email protected]>
Newsgroups gmane.comp.emulators.wine.patches
Message-ID <[email protected]>
Based on patch by Michael Müller.

Signed-off-by: Nikolay Sivov <[email protected]>
---
 dlls/advapi32/advapi32_misc.h |  1 +
 dlls/advapi32/lsa.c           | 32 ++++++++++++++++++++++++++------
 dlls/advapi32/security.c      |  9 +++++++++
 dlls/advapi32/tests/lsa.c     | 36 ++++++++++++++++++++++++++++++++++++
 include/ntlsa.h               | 19 +++++++++++++++++++
 5 files changed, 91 insertions(+), 6 deletions(-)
 create mode 100644 include/ntlsa.h

diff --git a/dlls/advapi32/advapi32_misc.h b/dlls/advapi32/advapi32_misc.h
index d116ecb836..7fc02a4a2e 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 a9ec9e4ae3..42da4b4afa 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 e36792cff4..c9d5cfaffa 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 a06c8afca1..861fea0525 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/ntlsa.h b/include/ntlsa.h
new file mode 100644
index 0000000000..468c14e1b4
--- /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);
-- 
2.14.2
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.