From ca415799729a5330fc9def2df8fb9c4ffef80448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Sun, 5 Mar 2017 23:50:06 +0100 Subject: advapi32: Implement LsaLookupPrivilegeName. --- dlls/advapi32/advapi32_misc.h | 2 ++ dlls/advapi32/lsa.c | 30 ++++++++++++++++++++++++++++-- dlls/advapi32/security.c | 27 ++++++++++++++++++--------- include/ntsecapi.h | 1 + 4 files changed, 49 insertions(+), 11 deletions(-) diff --git a/dlls/advapi32/advapi32_misc.h b/dlls/advapi32/advapi32_misc.h index d116ecb836e..ecb07f635a6 100644 --- a/dlls/advapi32/advapi32_misc.h +++ b/dlls/advapi32/advapi32_misc.h @@ -68,4 +68,6 @@ static inline WCHAR *strdupAW( const char *src ) return dst; } +const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1]; + #endif /* __WINE_ADVAPI32MISC_H */ diff --git a/dlls/advapi32/lsa.c b/dlls/advapi32/lsa.c index 61c91f497eb..e6f88d2fa73 100644 --- a/dlls/advapi32/lsa.c +++ b/dlls/advapi32/lsa.c @@ -983,6 +983,32 @@ NTSTATUS WINAPI LsaLookupPrivilegeName( LUID *luid, UNICODE_STRING **name) { - FIXME("(%p,%p,%p) stub\n", handle, luid, name); - return STATUS_NO_SUCH_PRIVILEGE; + UNICODE_STRING *priv_unicode; + size_t priv_size; + WCHAR *strW; + + TRACE("(%p, %p, %p)\n", handle, luid, name); + + if (!handle) + return STATUS_INVALID_HANDLE; + + if (!name) + return STATUS_INVALID_PARAMETER; + + if (luid->HighPart || + (luid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE || + luid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE || + !WellKnownPrivNames[luid->LowPart])) + return STATUS_NO_SUCH_PRIVILEGE; + + priv_size = (strlenW(WellKnownPrivNames[luid->LowPart]) + 1) * sizeof(WCHAR); + priv_unicode = heap_alloc(sizeof(*priv_unicode) + priv_size); + if (!priv_unicode) return STATUS_NO_MEMORY; + + strW = (WCHAR *)(priv_unicode + 1); + strcpyW(strW, WellKnownPrivNames[luid->LowPart]); + RtlInitUnicodeString(priv_unicode, strW); + + *name = priv_unicode; + return STATUS_SUCCESS; } diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c index e36792cff4b..3bc8f48b19c 100644 --- a/dlls/advapi32/security.c +++ b/dlls/advapi32/security.c @@ -1840,7 +1840,7 @@ static const WCHAR SE_IMPERSONATE_NAME_W[] = static const WCHAR SE_CREATE_GLOBAL_NAME_W[] = { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 }; -static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] = +const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] = { NULL, NULL, @@ -2043,33 +2043,42 @@ BOOL WINAPI LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName, LPDWORD cchName) { + UNICODE_STRING system_name, *priv; + LSA_HANDLE lsa; + NTSTATUS status; size_t privNameLen; TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName); - if (!ADVAPI_IsLocalComputer(lpSystemName)) + RtlInitUnicodeString(&system_name, lpSystemName); + status = LsaOpenPolicy(&system_name, NULL, POLICY_LOOKUP_NAMES, &lsa); + if (status) { - SetLastError(RPC_S_SERVER_UNAVAILABLE); + SetLastError(LsaNtStatusToWinError(status)); return FALSE; } - if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE || - lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE)) + + status = LsaLookupPrivilegeName(&lsa, lpLuid, &priv); + LsaClose(lsa); + if (status) { - SetLastError(ERROR_NO_SUCH_PRIVILEGE); + SetLastError(LsaNtStatusToWinError(status)); return FALSE; } - privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]); - /* Windows crashes if cchName is NULL, so will I */ + + privNameLen = priv->Length / sizeof(WCHAR); if (*cchName <= privNameLen) { *cchName = privNameLen + 1; + LsaFreeMemory(priv); SetLastError(ERROR_INSUFFICIENT_BUFFER); return FALSE; } else { - strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]); + strcpyW(lpName, priv->Buffer); *cchName = privNameLen; + LsaFreeMemory(priv); return TRUE; } } diff --git a/include/ntsecapi.h b/include/ntsecapi.h index 2bb3d312e43..0bf0eca43ed 100644 --- a/include/ntsecapi.h +++ b/include/ntsecapi.h @@ -370,6 +370,7 @@ NTSTATUS WINAPI LsaLookupNames(LSA_HANDLE,ULONG,PLSA_UNICODE_STRING,PLSA_REFEREN PLSA_TRANSLATED_SID*); NTSTATUS WINAPI LsaLookupNames2(LSA_HANDLE,ULONG,ULONG,PLSA_UNICODE_STRING,PLSA_REFERENCED_DOMAIN_LIST*, PLSA_TRANSLATED_SID2*); +NTSTATUS WINAPI LsaLookupPrivilegeName(LSA_HANDLE,PLUID,PUNICODE_STRING*); NTSTATUS WINAPI LsaLookupSids(LSA_HANDLE,ULONG,PSID *,PLSA_REFERENCED_DOMAIN_LIST *,PLSA_TRANSLATED_NAME *); ULONG WINAPI LsaNtStatusToWinError(NTSTATUS); NTSTATUS WINAPI LsaOpenPolicy(PLSA_UNICODE_STRING,PLSA_OBJECT_ATTRIBUTES,ACCESS_MASK,PLSA_HANDLE); -- 2.14.1