From 040f158fa728c9168dd1016cccee4adcfa6850b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sat, 27 Dec 2014 19:57:42 +0000 Subject: [PATCH] [ADVAPI/LSASRV] Implement LookupPrivilegeDisplayNameA, LookupPrivilegeDisplayNameW, LsaLookupPrivilegeDisplayName, LsarLookupPrivilegeDisplayName Also partly implement LsarpLookupPrivilegeDisplayName (currently, privilege description is the same as privilege name) svn path=/trunk/; revision=65853 --- reactos/dll/win32/advapi32/sec/lsa.c | 30 +++++++++- reactos/dll/win32/advapi32/sec/misc.c | 69 ++++++++++++++++++++++ reactos/dll/win32/advapi32/wine/security.c | 65 +++++++++++++------- reactos/dll/win32/lsasrv/lsarpc.c | 24 +++++++- reactos/dll/win32/lsasrv/lsasrv.h | 7 +++ reactos/dll/win32/lsasrv/privileges.c | 33 +++++++++++ reactos/include/psdk/ntsecapi.h | 2 +- 7 files changed, 203 insertions(+), 27 deletions(-) diff --git a/reactos/dll/win32/advapi32/sec/lsa.c b/reactos/dll/win32/advapi32/sec/lsa.c index 898497cda09..c277dd9a110 100644 --- a/reactos/dll/win32/advapi32/sec/lsa.c +++ b/reactos/dll/win32/advapi32/sec/lsa.c @@ -907,11 +907,35 @@ WINAPI LsaLookupPrivilegeDisplayName(IN LSA_HANDLE PolicyHandle, IN PLSA_UNICODE_STRING Name, OUT PLSA_UNICODE_STRING *DisplayName, - OUT PSHORT LanguageReturned) + OUT PUSHORT LanguageReturned) { - FIXME("LsaLookupPrivilegeDisplayName(%p %p %p %p)\n", + PRPC_UNICODE_STRING DisplayNameBuffer = NULL; + NTSTATUS Status; + + TRACE("LsaLookupPrivilegeDisplayName(%p %p %p %p)\n", PolicyHandle, Name, DisplayName, LanguageReturned); - return STATUS_NOT_IMPLEMENTED; + + RpcTryExcept + { + Status = LsarLookupPrivilegeDisplayName(PolicyHandle, + (PRPC_UNICODE_STRING)Name, + GetUserDefaultUILanguage(), + GetSystemDefaultUILanguage(), + &DisplayNameBuffer, + LanguageReturned); + + *DisplayName = (PUNICODE_STRING)DisplayNameBuffer; + } + RpcExcept(EXCEPTION_EXECUTE_HANDLER) + { + if (DisplayNameBuffer != NULL) + MIDL_user_free(DisplayNameBuffer); + + Status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept; + + return Status; } diff --git a/reactos/dll/win32/advapi32/sec/misc.c b/reactos/dll/win32/advapi32/sec/misc.c index a83f22993f1..a5c1a8676e7 100644 --- a/reactos/dll/win32/advapi32/sec/misc.c +++ b/reactos/dll/win32/advapi32/sec/misc.c @@ -891,6 +891,75 @@ LookupPrivilegeNameW(LPCWSTR lpSystemName, return TRUE; } +/********************************************************************** + * LookupPrivilegeDisplayNameW EXPORTED + * + * @unimplemented + */ +BOOL +WINAPI +LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName, + LPCWSTR lpName, + LPWSTR lpDisplayName, + LPDWORD cchDisplayName, + LPDWORD lpLanguageId) +{ + OBJECT_ATTRIBUTES ObjectAttributes = {0}; + UNICODE_STRING SystemName, Name; + PUNICODE_STRING DisplayName; + LSA_HANDLE PolicyHandle = NULL; + USHORT LanguageId; + NTSTATUS Status; + + TRACE("%S,%S,%p,%p,%p\n", lpSystemName, lpName, lpDisplayName, cchDisplayName, lpLanguageId); + + RtlInitUnicodeString(&SystemName, lpSystemName); + RtlInitUnicodeString(&Name, lpName); + + Status = LsaOpenPolicy(lpSystemName ? &SystemName : NULL, + &ObjectAttributes, + POLICY_LOOKUP_NAMES, + &PolicyHandle); + if (!NT_SUCCESS(Status)) + { + SetLastError(LsaNtStatusToWinError(Status)); + return FALSE; + } + + Status = LsaLookupPrivilegeDisplayName(PolicyHandle, &Name, &DisplayName, &LanguageId); + if (NT_SUCCESS(Status)) + { + *lpLanguageId = LanguageId; + if (DisplayName->Length + sizeof(WCHAR) > *cchDisplayName * sizeof(WCHAR)) + { + Status = STATUS_BUFFER_TOO_SMALL; + + *cchDisplayName = (DisplayName->Length + sizeof(WCHAR)) / sizeof(WCHAR); + } + else + { + RtlMoveMemory(lpDisplayName, + DisplayName->Buffer, + DisplayName->Length); + lpDisplayName[DisplayName->Length / sizeof(WCHAR)] = 0; + + *cchDisplayName = DisplayName->Length / sizeof(WCHAR); + } + + LsaFreeMemory(DisplayName->Buffer); + LsaFreeMemory(DisplayName); + } + + LsaClose(PolicyHandle); + + if (!NT_SUCCESS(Status)) + { + SetLastError(LsaNtStatusToWinError(Status)); + return FALSE; + } + + return TRUE; +} static DWORD pGetSecurityInfoCheck(SECURITY_INFORMATION SecurityInfo, diff --git a/reactos/dll/win32/advapi32/wine/security.c b/reactos/dll/win32/advapi32/wine/security.c index c0a9b198b66..ab59b26165d 100644 --- a/reactos/dll/win32/advapi32/wine/security.c +++ b/reactos/dll/win32/advapi32/wine/security.c @@ -1102,31 +1102,54 @@ WINAPI LookupPrivilegeDisplayNameA(LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName, - LPDWORD cbDisplayName, + LPDWORD cchDisplayName, LPDWORD lpLanguageId) { - FIXME("%s() not implemented!\n", __FUNCTION__); - SetLastError (ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} + UNICODE_STRING lpSystemNameW; + UNICODE_STRING lpNameW; + BOOL ret; + DWORD wLen = 0; + TRACE("%s %s %p %p %p\n", debugstr_a(lpSystemName), debugstr_a(lpName), lpName, cchDisplayName, lpLanguageId); -/********************************************************************** - * LookupPrivilegeDisplayNameW EXPORTED - * - * @unimplemented - */ -BOOL -WINAPI -LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName, - LPCWSTR lpName, - LPWSTR lpDisplayName, - LPDWORD cbDisplayName, - LPDWORD lpLanguageId) -{ - FIXME("%s() not implemented!\n", __FUNCTION__); - SetLastError (ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName); + RtlCreateUnicodeStringFromAsciiz(&lpNameW, lpName); + ret = LookupPrivilegeDisplayNameW(lpSystemNameW.Buffer, lpNameW.Buffer, NULL, &wLen, lpLanguageId); + if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + LPWSTR lpDisplayNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR)); + + ret = LookupPrivilegeDisplayNameW(lpSystemNameW.Buffer, lpNameW.Buffer, lpDisplayNameW, + &wLen, lpLanguageId); + if (ret) + { + unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpDisplayNameW, -1, lpDisplayName, + *cchDisplayName, NULL, NULL); + + if (len == 0) + { + /* WideCharToMultiByte failed */ + ret = FALSE; + } + else if (len > *cchDisplayName) + { + *cchDisplayName = len; + SetLastError(ERROR_INSUFFICIENT_BUFFER); + ret = FALSE; + } + else + { + /* WideCharToMultiByte succeeded, output length needs to be + * length not including NULL terminator + */ + *cchDisplayName = len - 1; + } + } + HeapFree(GetProcessHeap(), 0, lpDisplayNameW); + } + RtlFreeUnicodeString(&lpSystemNameW); + RtlFreeUnicodeString(&lpNameW); + return ret; } /********************************************************************** diff --git a/reactos/dll/win32/lsasrv/lsarpc.c b/reactos/dll/win32/lsasrv/lsarpc.c index 4af41c4a39d..243769de142 100644 --- a/reactos/dll/win32/lsasrv/lsarpc.c +++ b/reactos/dll/win32/lsasrv/lsarpc.c @@ -2104,8 +2104,28 @@ NTSTATUS WINAPI LsarLookupPrivilegeDisplayName( PRPC_UNICODE_STRING *DisplayName, USHORT *LanguageReturned) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + + TRACE("LsarLookupPrivilegeDisplayName(%p, %p, %u, %u, %p, %p)\n", + PolicyHandle, Name, ClientLanguage, ClientSystemDefaultLanguage, DisplayName, LanguageReturned); + + Status = LsapValidateDbObject(PolicyHandle, + LsaDbPolicyObject, + POLICY_LOOKUP_NAMES, + NULL); + if (!NT_SUCCESS(Status)) + { + ERR("Invalid handle\n"); + return Status; + } + + Status = LsarpLookupPrivilegeDisplayName(Name, + ClientLanguage, + ClientSystemDefaultLanguage, + DisplayName, + LanguageReturned); + + return Status; } diff --git a/reactos/dll/win32/lsasrv/lsasrv.h b/reactos/dll/win32/lsasrv/lsasrv.h index d27bc44d0d8..e72db70df48 100644 --- a/reactos/dll/win32/lsasrv/lsasrv.h +++ b/reactos/dll/win32/lsasrv/lsasrv.h @@ -302,6 +302,13 @@ NTSTATUS LsarpLookupPrivilegeName(PLUID Value, PRPC_UNICODE_STRING *Name); +NTSTATUS +LsarpLookupPrivilegeDisplayName(PRPC_UNICODE_STRING Name, + USHORT ClientLanguage, + USHORT ClientSystemDefaultLanguage, + PRPC_UNICODE_STRING *DisplayName, + USHORT *LanguageReturned); + NTSTATUS LsarpLookupPrivilegeValue(PRPC_UNICODE_STRING Name, PLUID Value); diff --git a/reactos/dll/win32/lsasrv/privileges.c b/reactos/dll/win32/lsasrv/privileges.c index 8fabdbf6cd8..a2692953f02 100644 --- a/reactos/dll/win32/lsasrv/privileges.c +++ b/reactos/dll/win32/lsasrv/privileges.c @@ -118,6 +118,39 @@ LsarpLookupPrivilegeName(PLUID Value, return STATUS_NO_SUCH_PRIVILEGE; } +NTSTATUS +LsarpLookupPrivilegeDisplayName(PRPC_UNICODE_STRING Name, + USHORT ClientLanguage, + USHORT ClientSystemDefaultLanguage, + PRPC_UNICODE_STRING *DisplayName, + USHORT *LanguageReturned) +{ + PRPC_UNICODE_STRING DisplayNameBuffer; + UNIMPLEMENTED; + + /* For now, description is equal to privilege name */ + + DisplayNameBuffer = MIDL_user_allocate(sizeof(RPC_UNICODE_STRING)); + if (DisplayNameBuffer == NULL) + { + return STATUS_NO_MEMORY; + } + DisplayNameBuffer->Length = Name->Length; + DisplayNameBuffer->MaximumLength = Name->MaximumLength; + + DisplayNameBuffer->Buffer = MIDL_user_allocate(DisplayNameBuffer->MaximumLength); + if (DisplayNameBuffer->Buffer == NULL) + { + MIDL_user_free(DisplayNameBuffer); + return STATUS_NO_MEMORY; + } + + wcscpy(DisplayNameBuffer->Buffer, Name->Buffer); + + *DisplayName = DisplayNameBuffer; + + return STATUS_SUCCESS; +} NTSTATUS LsarpLookupPrivilegeValue(PRPC_UNICODE_STRING Name, diff --git a/reactos/include/psdk/ntsecapi.h b/reactos/include/psdk/ntsecapi.h index 611b3f3aa21..a66db7b9744 100644 --- a/reactos/include/psdk/ntsecapi.h +++ b/reactos/include/psdk/ntsecapi.h @@ -724,7 +724,7 @@ NTSTATUS NTAPI LsaLookupNames(LSA_HANDLE,ULONG,PLSA_UNICODE_STRING, NTSTATUS NTAPI LsaLookupNames2(LSA_HANDLE,ULONG,ULONG,PLSA_UNICODE_STRING, PLSA_REFERENCED_DOMAIN_LIST*,PLSA_TRANSLATED_SID2*); NTSTATUS NTAPI LsaLookupPrivilegeDisplayName(LSA_HANDLE,PLSA_UNICODE_STRING, - PLSA_UNICODE_STRING*,PSHORT); + PLSA_UNICODE_STRING*,PUSHORT); NTSTATUS NTAPI LsaLookupPrivilegeName(LSA_HANDLE,PLUID,PLSA_UNICODE_STRING*); NTSTATUS NTAPI LsaLookupPrivilegeValue(LSA_HANDLE,PLSA_UNICODE_STRING,PLUID); NTSTATUS NTAPI LsaLookupSids(LSA_HANDLE,ULONG,PSID*,