From bee5e0baac722c66ad8c1034a65a2cecfe74716e 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.spec | 2 +- dlls/advapi32/advapi32_misc.h | 2 ++ dlls/advapi32/lsa.c | 38 ++++++++++++++++++++++++++++++++++++++ dlls/advapi32/security.c | 27 ++++++++++++++++++--------- include/ntsecapi.h | 1 + 5 files changed, 60 insertions(+), 10 deletions(-) diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec index 078bb8fc25..124f527282 100644 --- a/dlls/advapi32/advapi32.spec +++ b/dlls/advapi32/advapi32.spec @@ -469,7 +469,7 @@ @ stdcall LsaLookupNames(long long ptr ptr ptr) @ stdcall LsaLookupNames2(ptr long long ptr ptr ptr) @ stub LsaLookupPrivilegeDisplayName -# @ stub LsaLookupPrivilegeName +@ stdcall LsaLookupPrivilegeName(long ptr ptr) # @ stub LsaLookupPrivilegeValue @ stdcall LsaLookupSids(ptr long ptr ptr ptr) # @ stub LsaLookupSids2 diff --git a/dlls/advapi32/advapi32_misc.h b/dlls/advapi32/advapi32_misc.h index d116ecb836..ecb07f635a 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 479201bfc1..ceb3b05c05 100644 --- a/dlls/advapi32/lsa.c +++ b/dlls/advapi32/lsa.c @@ -973,3 +973,41 @@ NTSTATUS WINAPI LsaUnregisterPolicyChangeNotification( FIXME("(%d,%p) stub\n", class, event); return STATUS_SUCCESS; } + +/****************************************************************************** + * LsaLookupPrivilegeName [ADVAPI32.@] + * + */ +NTSTATUS WINAPI LsaLookupPrivilegeName( + LSA_HANDLE handle, + PLUID lpLuid, + PUNICODE_STRING *name) +{ + UNICODE_STRING *priv_unicode; + size_t priv_size; + WCHAR *strW; + + TRACE("(%p, %p, %p)\n", handle, lpLuid, name); + + if (!handle) + return STATUS_INVALID_HANDLE; + + if (!name) + return STATUS_INVALID_PARAMETER; + + if (lpLuid->HighPart || + (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE || + lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE)) + return STATUS_NO_SUCH_PRIVILEGE; + + priv_size = (strlenW(WellKnownPrivNames[lpLuid->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[lpLuid->LowPart]); + RtlInitUnicodeString(priv_unicode, strW); + + *name = priv_unicode; + return STATUS_SUCCESS; +} diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c index e36792cff4..3bc8f48b19 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 2bb3d312e4..0bf0eca43e 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.11.0