- Merge from trunk
[reactos.git] / dll / win32 / advapi32 / sec / lsa.c
index 0231887..5462280 100644 (file)
@@ -1,73 +1,42 @@
 /*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
- * FILE:            lib/advapi32/sec/lsa.c
+ * FILE:            dll/win32/advapi32/sec/lsa.c
  * PURPOSE:         Local security authority functions
  * PROGRAMMER:      Emanuele Aliberti
  * UPDATE HISTORY:
- *     19990322 EA created
- *     19990515 EA stubs
+ *      19990322 EA created
+ *      19990515 EA stubs
  *      20030202 KJK compressed stubs
  *
  */
 #include <advapi32.h>
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
 
-/* imported from wine 1.1.14 */
-static void* ADVAPI_GetDomainName(unsigned sz, unsigned ofs)
+
+static BOOL LsapIsLocalComputer(PLSA_UNICODE_STRING ServerName)
 {
-    HKEY key;
-    LONG ret;
-    BYTE* ptr = NULL;
-    UNICODE_STRING* ustr;
+    DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
+    BOOL Result;
+    LPWSTR buf;
 
-    static const WCHAR wVNETSUP[] = {
-        'S','y','s','t','e','m','\\',
-        'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
-        'S','e','r','v','i','c','e','s','\\',
-        'V','x','D','\\','V','N','E','T','S','U','P','\0'};
+    if (ServerName == NULL || ServerName->Length == 0 || ServerName->Buffer == NULL)
+        return TRUE;
 
-    ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, wVNETSUP, 0, KEY_READ, &key);
-    if (ret == ERROR_SUCCESS)
-    {
-        DWORD size = 0;
-        static const WCHAR wg[] = { 'W','o','r','k','g','r','o','u','p',0 };
+    buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
+    Result = GetComputerNameW(buf, &dwSize);
+    if (Result && (ServerName->Buffer[0] == '\\') && (ServerName->Buffer[1] == '\\'))
+        ServerName += 2;
+    Result = Result && !lstrcmpW(ServerName->Buffer, buf);
+    HeapFree(GetProcessHeap(), 0, buf);
 
-        ret = RegQueryValueExW(key, wg, NULL, NULL, NULL, &size);
-        if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
-        {
-            ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz + size);
-            if (!ptr) return NULL;
-            ustr = (UNICODE_STRING*)(ptr + ofs);
-            ustr->MaximumLength = size;
-            ustr->Buffer = (WCHAR*)(ptr + sz);
-            ret = RegQueryValueExW(key, wg, NULL, NULL, (LPBYTE)ustr->Buffer, &size);
-            if (ret != ERROR_SUCCESS)
-            {
-                HeapFree(GetProcessHeap(), 0, ptr);
-                ptr = NULL;
-            }   
-            else ustr->Length = size - sizeof(WCHAR);
-        }
-        RegCloseKey(key);
-    }
-    if (!ptr)
-    {
-        static const WCHAR wDomain[] = {'D','O','M','A','I','N','\0'};
-        ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-                        sz + sizeof(wDomain));
-        if (!ptr) return NULL;
-        ustr = (UNICODE_STRING*)(ptr + ofs);
-        ustr->MaximumLength = sizeof(wDomain);
-        ustr->Buffer = (WCHAR*)(ptr + sz);
-        ustr->Length = sizeof(wDomain) - sizeof(WCHAR);
-        memcpy(ustr->Buffer, wDomain, sizeof(wDomain));
-    }
-    return ptr;
+    return Result;
 }
 
+
 handle_t __RPC_USER
 PLSAPR_SERVER_NAME_bind(PLSAPR_SERVER_NAME pszSystemName)
 {
@@ -126,8 +95,9 @@ PLSAPR_SERVER_NAME_unbind(PLSAPR_SERVER_NAME pszSystemName,
 /*
  * @implemented
  */
-NTSTATUS WINAPI
-LsaClose(LSA_HANDLE ObjectHandle)
+NTSTATUS
+WINAPI
+LsaClose(IN LSA_HANDLE ObjectHandle)
 {
     NTSTATUS Status;
 
@@ -150,8 +120,9 @@ LsaClose(LSA_HANDLE ObjectHandle)
 /*
  * @implemented
  */
-NTSTATUS WINAPI
-LsaDelete(LSA_HANDLE ObjectHandle)
+NTSTATUS
+WINAPI
+LsaDelete(IN LSA_HANDLE ObjectHandle)
 {
     NTSTATUS Status;
 
@@ -172,20 +143,130 @@ LsaDelete(LSA_HANDLE ObjectHandle)
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 NTSTATUS
 WINAPI
-LsaAddAccountRights(
-    LSA_HANDLE PolicyHandle,
-    PSID AccountSid,
-    PLSA_UNICODE_STRING UserRights,
-    ULONG CountOfRights)
+LsaAddAccountRights(IN LSA_HANDLE PolicyHandle,
+                    IN PSID AccountSid,
+                    IN PLSA_UNICODE_STRING UserRights,
+                    IN ULONG CountOfRights)
 {
-    FIXME("(%p,%p,%p,0x%08x) stub\n", PolicyHandle, AccountSid, UserRights, CountOfRights);
-    return STATUS_OBJECT_NAME_NOT_FOUND;
+    LSAPR_USER_RIGHT_SET UserRightSet;
+    NTSTATUS Status;
+
+    TRACE("(%p,%p,%p,0x%08x) stub\n", PolicyHandle, AccountSid, UserRights, CountOfRights);
+
+    UserRightSet.Entries = CountOfRights;
+    UserRightSet.UserRights = (PRPC_UNICODE_STRING)UserRights;
+
+    RpcTryExcept
+    {
+        Status = LsarAddAccountRights((LSAPR_HANDLE)PolicyHandle,
+                                      (PRPC_SID)AccountSid,
+                                      &UserRightSet);
+
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
 }
 
+
+/*
+ * @implemented
+ */
+NTSTATUS
+WINAPI
+LsaAddPrivilegesToAccount(IN LSA_HANDLE AccountHandle,
+                          IN PPRIVILEGE_SET PrivilegeSet)
+{
+    NTSTATUS Status;
+
+    TRACE("(%p,%p) stub\n", AccountHandle, PrivilegeSet);
+
+    RpcTryExcept
+    {
+        Status = LsarAddPrivilegesToAccount((LSAPR_HANDLE)AccountHandle,
+                                            (PLSAPR_PRIVILEGE_SET)PrivilegeSet);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
+}
+
+
+/*
+ * @implemented
+ */
+NTSTATUS
+WINAPI
+LsaCreateAccount(IN LSA_HANDLE PolicyHandle,
+                 IN PSID AccountSid,
+                 IN ULONG Flags,
+                 OUT PLSA_HANDLE AccountHandle)
+{
+    NTSTATUS Status;
+
+    TRACE("(%p,%p,0x%08x,%p)\n", PolicyHandle, AccountSid, Flags, AccountHandle);
+
+    RpcTryExcept
+    {
+        Status = LsarCreateAccount((LSAPR_HANDLE)PolicyHandle,
+                                   AccountSid,
+                                   Flags,
+                                   AccountHandle);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
+}
+
+
+/*
+ * @implemented
+ */
+NTSTATUS
+WINAPI
+LsaCreateTrustedDomain(IN LSA_HANDLE PolicyHandle,
+                       IN PLSA_TRUST_INFORMATION TrustedDomainInformation,
+                       IN ACCESS_MASK DesiredAccess,
+                       OUT PLSA_HANDLE TrustedDomainHandle)
+{
+    NTSTATUS Status;
+
+    TRACE("(%p,%p,0x%08x,%p)\n", PolicyHandle, TrustedDomainInformation,
+          DesiredAccess, TrustedDomainHandle);
+
+    RpcTryExcept
+    {
+        Status = LsarCreateTrustedDomain((LSAPR_HANDLE)PolicyHandle,
+                                         (PLSAPR_TRUST_INFORMATION)TrustedDomainInformation,
+                                         DesiredAccess,
+                                         (PLSAPR_HANDLE)TrustedDomainHandle);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
+}
+
+
 /*
  * @unimplemented
  */
@@ -200,39 +281,79 @@ LsaCreateTrustedDomainEx(
 {
     FIXME("(%p,%p,%p,0x%08x,%p) stub\n", PolicyHandle, TrustedDomainInformation, AuthenticationInformation,
           DesiredAccess, TrustedDomainHandle);
-    return STATUS_NOT_IMPLEMENTED;
+    return STATUS_SUCCESS;
 }
 
+
 /*
- * @unimplemented
+ * @implemented
  */
 NTSTATUS
 WINAPI
-LsaDeleteTrustedDomain(
-    LSA_HANDLE PolicyHandle,
-    PSID TrustedDomainSid)
+LsaDeleteTrustedDomain(IN LSA_HANDLE PolicyHandle,
+                       IN PSID TrustedDomainSid)
 {
-    FIXME("(%p,%p) stub\n", PolicyHandle, TrustedDomainSid);
-    return STATUS_SUCCESS;
+    NTSTATUS Status;
+
+    TRACE("(%p,%p)\n", PolicyHandle, TrustedDomainSid);
+
+    RpcTryExcept
+    {
+        Status = LsarDeleteTrustedDomain((LSAPR_HANDLE)PolicyHandle,
+                                         TrustedDomainSid);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
 }
 
+
 /*
- * @unimplemented
+ * @implemented
  */
 NTSTATUS
 WINAPI
-LsaEnumerateAccountRights(
-    LSA_HANDLE PolicyHandle,
-    PSID AccountSid,
-    PLSA_UNICODE_STRING *UserRights,
-    PULONG CountOfRights)
+LsaEnumerateAccountRights(IN LSA_HANDLE PolicyHandle,
+                          IN PSID AccountSid,
+                          OUT PLSA_UNICODE_STRING *UserRights,
+                          OUT PULONG CountOfRights)
 {
-    FIXME("(%p,%p,%p,%p) stub\n", PolicyHandle, AccountSid, UserRights, CountOfRights);
-    *UserRights = 0;
-    *CountOfRights = 0;
-    return STATUS_OBJECT_NAME_NOT_FOUND;
+    LSAPR_USER_RIGHT_SET UserRightsSet;
+    NTSTATUS Status;
+
+    TRACE("(%p,%p,%p,%p) stub\n", PolicyHandle, AccountSid, UserRights, CountOfRights);
+
+    UserRightsSet.Entries = 0;
+    UserRightsSet.UserRights = NULL;
+
+    RpcTryExcept
+    {
+        Status = LsarEnmuerateAccountRights((LSAPR_HANDLE)PolicyHandle,
+                                            AccountSid,
+                                            &UserRightsSet);
+
+        *CountOfRights = UserRightsSet.Entries;
+        *UserRights = (PUNICODE_STRING)UserRightsSet.UserRights;
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+
+        if (UserRightsSet.UserRights != NULL)
+        {
+            MIDL_user_free(UserRightsSet.UserRights);
+        }
+    }
+    RpcEndExcept;
+
+    return Status;
 }
 
+
 /*
  * @unimplemented
  */
@@ -285,66 +406,70 @@ LsaEnumerateTrustedDomainsEx(
     return STATUS_SUCCESS;
 }
 
+
 /*
  * @implemented
  */
-NTSTATUS WINAPI
-LsaFreeMemory(PVOID Buffer)
+NTSTATUS
+WINAPI
+LsaFreeMemory(IN PVOID Buffer)
 {
     TRACE("(%p)\n", Buffer);
     return RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
 }
 
+
 /*
  * @implemented
  */
 NTSTATUS
 WINAPI
-LsaLookupNames(
-    LSA_HANDLE PolicyHandle,
-    ULONG Count,
-    PLSA_UNICODE_STRING Names,
-    PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains,
-    PLSA_TRANSLATED_SID *Sids)
+LsaLookupNames(IN LSA_HANDLE PolicyHandle,
+               IN ULONG Count,
+               IN PLSA_UNICODE_STRING Names,
+               OUT PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains,
+               OUT PLSA_TRANSLATED_SID *Sids)
 {
-    PLSA_TRANSLATED_SID2 Sids2;
-    LSA_TRANSLATED_SID *TranslatedSids;
-    ULONG i;
+    LSAPR_TRANSLATED_SIDS TranslatedSids;
+    ULONG MappedCount = 0;
     NTSTATUS Status;
 
     TRACE("(%p,0x%08x,%p,%p,%p)\n", PolicyHandle, Count, Names,
           ReferencedDomains, Sids);
 
-    /* Call LsaLookupNames2, which supersedes this function */
-    Status = LsaLookupNames2(PolicyHandle, Count, 0, Names, ReferencedDomains, &Sids2);
-    if (!NT_SUCCESS(Status))
-        return Status;
-
-    /* Translate the returned structure */
-    TranslatedSids = RtlAllocateHeap(RtlGetProcessHeap(), 0, Count * sizeof(LSA_TRANSLATED_SID));
-    if (!TranslatedSids)
+    RpcTryExcept
     {
-        LsaFreeMemory(Sids2);
-        return SCESTATUS_NOT_ENOUGH_RESOURCE;
+        *ReferencedDomains = NULL;
+        *Sids = NULL;
+
+        TranslatedSids.Entries = Count;
+        TranslatedSids.Sids = *Sids;
+
+        Status = LsarLookupNames((LSAPR_HANDLE)PolicyHandle,
+                                 Count,
+                                 (PRPC_UNICODE_STRING)Names,
+                                 (PLSAPR_REFERENCED_DOMAIN_LIST *)ReferencedDomains,
+                                 &TranslatedSids,
+                                 LsapLookupWksta,
+                                 &MappedCount);
+
+        *Sids = (PLSA_TRANSLATED_SID)TranslatedSids.Sids;
     }
-    RtlZeroMemory(Sids, Count * sizeof(PLSA_TRANSLATED_SID));
-    for (i = 0; i < Count; i++)
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
     {
-        TranslatedSids[i].Use = Sids2[i].Use;
-        if (Sids2[i].Use != SidTypeInvalid && Sids2[i].Use != SidTypeUnknown)
+        if (TranslatedSids.Sids != NULL)
         {
-            TranslatedSids[i].DomainIndex = Sids2[i].DomainIndex;
-            if (Sids2[i].Use != SidTypeDomain)
-                TranslatedSids[i].RelativeId = *GetSidSubAuthority(Sids2[i].Sid, 0);
+            MIDL_user_free(TranslatedSids.Sids);
         }
-    }
-    LsaFreeMemory(Sids2);
 
-    *Sids = TranslatedSids;
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
     return Status;
 }
 
+
 /*
  * @unimplemented
  */
@@ -360,53 +485,140 @@ LsaLookupNames2(
 {
     FIXME("(%p,0x%08x,0x%08x,%p,%p,%p) stub\n", PolicyHandle, Flags,
         Count, Names, ReferencedDomains, Sids);
+    if (Names != NULL && Count > 0)
+    {
+        *ReferencedDomains = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(LSA_REFERENCED_DOMAIN_LIST));
+        *Sids = RtlAllocateHeap(RtlGetProcessHeap(), 0, Count * sizeof(LSA_TRANSLATED_SID2));
+        return STATUS_SOME_NOT_MAPPED;
+    }
     return STATUS_NONE_MAPPED;
 }
 
+
 /*
- * @unimplemented
+ * @implemented
  */
 NTSTATUS
 WINAPI
-LsaLookupSids(
-    LSA_HANDLE PolicyHandle,
-    ULONG Count,
-    PSID *Sids,
-    PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains,
-    PLSA_TRANSLATED_NAME *Names)
+LsaLookupPrivilegeName(IN LSA_HANDLE PolicyHandle,
+                       IN PLUID Value,
+                       OUT PUNICODE_STRING *Name)
+{
+    PRPC_UNICODE_STRING NameBuffer = NULL;
+    NTSTATUS Status;
+
+    TRACE("(%p,%p,%p)\n", PolicyHandle, Value, Name);
+
+    RpcTryExcept
+    {
+        Status = LsarLookupPrivilegeName(PolicyHandle,
+                                         Value,
+                                         &NameBuffer);
+
+        *Name = (PUNICODE_STRING)NameBuffer;
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        if (NameBuffer != NULL)
+            MIDL_user_free(NameBuffer);
+
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
+}
+
+
+/*
+ * @implemented
+ */
+NTSTATUS
+WINAPI
+LsaLookupPrivilegeValue(IN LSA_HANDLE PolicyHandle,
+                        IN PLSA_UNICODE_STRING Name,
+                        OUT PLUID Value)
+{
+    LUID Luid;
+    NTSTATUS Status;
+
+    TRACE("(%p,%p,%p)\n", PolicyHandle, Name, Value);
+
+    RpcTryExcept
+    {
+        Status = LsarLookupPrivilegeValue(PolicyHandle,
+                                          (PRPC_UNICODE_STRING)Name,
+                                          &Luid);
+        if (Status == STATUS_SUCCESS)
+            *Value = Luid;
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
+}
+
+
+/*
+ * @implemented
+ */
+NTSTATUS
+WINAPI
+LsaLookupSids(IN LSA_HANDLE PolicyHandle,
+              IN ULONG Count,
+              IN PSID *Sids,
+              OUT PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains,
+              OUT PLSA_TRANSLATED_NAME *Names)
 {
-    static const UNICODE_STRING UserName = RTL_CONSTANT_STRING(L"Administrator");
-    PLSA_REFERENCED_DOMAIN_LIST LocalDomains;
-    PLSA_TRANSLATED_NAME LocalNames;
+    LSAPR_SID_ENUM_BUFFER SidEnumBuffer;
+    LSAPR_TRANSLATED_NAMES TranslatedNames;
+    ULONG MappedCount = 0;
+    NTSTATUS  Status;
 
-    TRACE("(%p,%u,%p,%p,%p) stub\n", PolicyHandle, Count, Sids,
+    TRACE("(%p,%u,%p,%p,%p)\n", PolicyHandle, Count, Sids,
           ReferencedDomains, Names);
 
-    WARN("LsaLookupSids(): stub. Always returning 'Administrator'\n");
-    if (Count != 1)
-        return STATUS_NONE_MAPPED;
-    LocalDomains = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(LSA_TRANSLATED_SID));
-    if (!LocalDomains)
-        return SCESTATUS_NOT_ENOUGH_RESOURCE;
-    LocalNames = RtlAllocateHeap(RtlGetProcessHeap(), 0,  sizeof(LSA_TRANSLATED_NAME) + UserName.MaximumLength);
-    if (!LocalNames)
-    {
-        LsaFreeMemory(LocalDomains);
-        return SCESTATUS_NOT_ENOUGH_RESOURCE;
-    }
-    LocalDomains[0].Entries = 0;
-    LocalDomains[0].Domains = NULL;
-    LocalNames[0].Use = SidTypeWellKnownGroup;
-    LocalNames[0].Name.Buffer = (LPWSTR)((ULONG_PTR)(LocalNames) + sizeof(LSA_TRANSLATED_NAME));
-    LocalNames[0].Name.Length = UserName.Length;
-    LocalNames[0].Name.MaximumLength = UserName.MaximumLength;
-    RtlCopyMemory(LocalNames[0].Name.Buffer, UserName.Buffer, UserName.MaximumLength);
-
-    *ReferencedDomains = LocalDomains;
-    *Names = LocalNames;
-    return STATUS_SUCCESS;
+    if (Count == 0)
+        return STATUS_INVALID_PARAMETER;
+
+    SidEnumBuffer.Entries = Count;
+    SidEnumBuffer.SidInfo = (PLSAPR_SID_INFORMATION)Sids;
+
+    RpcTryExcept
+    {
+        *ReferencedDomains = NULL;
+        *Names = NULL;
+
+        TranslatedNames.Entries = 0;
+        TranslatedNames.Names = NULL;
+
+        Status = LsarLookupSids((LSAPR_HANDLE)PolicyHandle,
+                                &SidEnumBuffer,
+                                (PLSAPR_REFERENCED_DOMAIN_LIST *)ReferencedDomains,
+                                &TranslatedNames,
+                                LsapLookupWksta,
+                                &MappedCount);
+
+        *Names = (PLSA_TRANSLATED_NAME)TranslatedNames.Names;
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        if (TranslatedNames.Names != NULL)
+        {
+            MIDL_user_free(TranslatedNames.Names);
+        }
+
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
 }
 
+
 /******************************************************************************
  * LsaNtStatusToWinError
  *
@@ -415,13 +627,46 @@ LsaLookupSids(
  *
  * @implemented
  */
-ULONG WINAPI
-LsaNtStatusToWinError(NTSTATUS Status)
+ULONG
+WINAPI
+LsaNtStatusToWinError(IN NTSTATUS Status)
 {
     TRACE("(%lx)\n", Status);
     return RtlNtStatusToDosError(Status);
 }
 
+
+/*
+ * @implemented
+ */
+NTSTATUS
+WINAPI
+LsaOpenAccount(IN LSA_HANDLE PolicyHandle,
+               IN PSID AccountSid,
+               IN ULONG Flags,
+               OUT PLSA_HANDLE AccountHandle)
+{
+    NTSTATUS Status;
+
+    TRACE("(%p,%p,0x%08x,%p)\n", PolicyHandle, AccountSid, Flags, AccountHandle);
+
+    RpcTryExcept
+    {
+        Status = LsarOpenAccount((LSAPR_HANDLE)PolicyHandle,
+                                 AccountSid,
+                                 Flags,
+                                 AccountHandle);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
+}
+
+
 /******************************************************************************
  * LsaOpenPolicy
  *
@@ -431,15 +676,14 @@ LsaNtStatusToWinError(NTSTATUS Status)
  *   x3 []
  *   x4 []
  *
- * @unimplemented
+ * @implemented
  */
 NTSTATUS
 WINAPI
-LsaOpenPolicy(
-    IN PLSA_UNICODE_STRING SystemName,
-    IN PLSA_OBJECT_ATTRIBUTES ObjectAttributes,
-    IN ACCESS_MASK DesiredAccess,
-    IN OUT PLSA_HANDLE PolicyHandle)
+LsaOpenPolicy(IN PLSA_UNICODE_STRING SystemName,
+              IN PLSA_OBJECT_ATTRIBUTES ObjectAttributes,
+              IN ACCESS_MASK DesiredAccess,
+              OUT PLSA_HANDLE PolicyHandle)
 {
     NTSTATUS Status;
 
@@ -447,6 +691,10 @@ LsaOpenPolicy(
           SystemName ? debugstr_w(SystemName->Buffer) : "(null)",
           ObjectAttributes, DesiredAccess, PolicyHandle);
 
+    /* FIXME: RPC should take care of this */
+    if (!LsapIsLocalComputer(SystemName))
+        return RPC_NT_SERVER_UNAVAILABLE;
+
     RpcTryExcept
     {
         *PolicyHandle = NULL;
@@ -469,20 +717,37 @@ LsaOpenPolicy(
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 NTSTATUS
 WINAPI
-LsaOpenTrustedDomainByName(
-    LSA_HANDLE PolicyHandle,
-    PLSA_UNICODE_STRING TrustedDomainName,
-    ACCESS_MASK DesiredAccess,
-    PLSA_HANDLE TrustedDomainHandle)
+LsaOpenTrustedDomainByName(IN LSA_HANDLE PolicyHandle,
+                           IN PLSA_UNICODE_STRING TrustedDomainName,
+                           IN ACCESS_MASK DesiredAccess,
+                           OUT PLSA_HANDLE TrustedDomainHandle)
 {
-    FIXME("(%p,%p,0x%08x,%p) stub\n", PolicyHandle, TrustedDomainName, DesiredAccess, TrustedDomainHandle);
-    return STATUS_OBJECT_NAME_NOT_FOUND;
+    NTSTATUS Status;
+
+    TRACE("(%p,%p,0x%08x,%p)\n", PolicyHandle, TrustedDomainName,
+          DesiredAccess, TrustedDomainHandle);
+
+    RpcTryExcept
+    {
+        Status = LsarOpenTrustedDomainByName((LSAPR_HANDLE)PolicyHandle,
+                                             (PRPC_UNICODE_STRING)TrustedDomainName,
+                                             DesiredAccess,
+                                             TrustedDomainHandle);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
 }
 
+
 /*
  * @unimplemented
  */
@@ -511,147 +776,130 @@ LsaQueryForestTrustInformation(
     return STATUS_NOT_IMPLEMENTED;
 }
 
+
 /*
- * @unimplemented
+ * @implemented
  */
-NTSTATUS WINAPI
-LsaQueryInformationPolicy(LSA_HANDLE PolicyHandle,
-              POLICY_INFORMATION_CLASS InformationClass,
-              PVOID *Buffer)
+NTSTATUS
+WINAPI
+LsaQueryInformationPolicy(IN LSA_HANDLE PolicyHandle,
+                          IN POLICY_INFORMATION_CLASS InformationClass,
+                          OUT PVOID *Buffer)
 {
+    PLSAPR_POLICY_INFORMATION PolicyInformation = NULL;
+    NTSTATUS Status;
+
     TRACE("(%p,0x%08x,%p)\n", PolicyHandle, InformationClass, Buffer);
 
-    if(!Buffer) return STATUS_INVALID_PARAMETER;
-    switch (InformationClass)
+    RpcTryExcept
     {
-        case PolicyAuditEventsInformation: /* 2 */
-        {
-            PPOLICY_AUDIT_EVENTS_INFO p = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY,
-                                                    sizeof(POLICY_AUDIT_EVENTS_INFO));
-            p->AuditingMode = FALSE; /* no auditing */
-            *Buffer = p;
-        }
-        break;
-        case PolicyPrimaryDomainInformation: /* 3 */
-        {
-            /* Only the domain name is valid for the local computer.
-             * All other fields are zero.
-             */
-            PPOLICY_PRIMARY_DOMAIN_INFO pinfo;
-
-            pinfo = ADVAPI_GetDomainName(sizeof(*pinfo), offsetof(POLICY_PRIMARY_DOMAIN_INFO, Name));
-
-            TRACE("setting domain to %s\n", debugstr_w(pinfo->Name.Buffer));
-
-            *Buffer = pinfo;
-        }
-        case PolicyAccountDomainInformation: /* 5 */
-        {
-            struct di
-            {
-                POLICY_ACCOUNT_DOMAIN_INFO info;
-                SID sid;
-                DWORD padding[3];
-                WCHAR domain[MAX_COMPUTERNAME_LENGTH + 1];
-            };
-            SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
-
-            DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
-            struct di * xdi = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*xdi));
-
-            xdi->info.DomainName.MaximumLength = dwSize * sizeof(WCHAR);
-            xdi->info.DomainName.Buffer = xdi->domain;
-            if (GetComputerNameW(xdi->info.DomainName.Buffer, &dwSize))
-                xdi->info.DomainName.Length = dwSize * sizeof(WCHAR);
-
-            TRACE("setting name to %s\n", debugstr_w(xdi->info.DomainName.Buffer));
-
-            xdi->info.DomainSid = &xdi->sid;
-            xdi->sid.Revision = SID_REVISION;
-            xdi->sid.SubAuthorityCount = 1;
-            xdi->sid.IdentifierAuthority = localSidAuthority;
-            xdi->sid.SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID;
-
-            *Buffer = xdi;
-        }
-        break;
-        case  PolicyDnsDomainInformation:      /* 12 (0xc) */
-        {
-            /* Only the domain name is valid for the local computer.
-             * All other fields are zero.
-             */
-            PPOLICY_DNS_DOMAIN_INFO pinfo;
+        Status = LsarQueryInformationPolicy((LSAPR_HANDLE)PolicyHandle,
+                                            InformationClass,
+                                            &PolicyInformation);
+        *Buffer = PolicyInformation;
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        if (PolicyInformation != NULL)
+            MIDL_user_free(PolicyInformation);
 
-            pinfo = ADVAPI_GetDomainName(sizeof(*pinfo), offsetof(POLICY_DNS_DOMAIN_INFO, Name));
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-            TRACE("setting domain to %s\n", debugstr_w(pinfo->Name.Buffer));
+    TRACE("Done (Status: 0x%08x)\n", Status);
 
-            *Buffer = pinfo;
-        }
-        break;
-        case PolicyAuditLogInformation:
-        case PolicyPdAccountInformation:
-        case PolicyLsaServerRoleInformation:
-        case PolicyReplicaSourceInformation:
-        case PolicyDefaultQuotaInformation:
-        case PolicyModificationInformation:
-        case PolicyAuditFullSetInformation:
-        case PolicyAuditFullQueryInformation:
-        case PolicyEfsInformation:
-        {
-            FIXME("category not implemented\n");
-            return STATUS_UNSUCCESSFUL;
-        }
-    }
-    return STATUS_SUCCESS;
+    return Status;
 }
 
+
 /*
  * @unimplemented
  */
 NTSTATUS
 WINAPI
-LsaQueryTrustedDomainInfoByName(
+LsaQueryTrustedDomainInfo(
     LSA_HANDLE PolicyHandle,
-    PLSA_UNICODE_STRING TrustedDomainName,
+    PSID TrustedDomainSid,
     TRUSTED_INFORMATION_CLASS InformationClass,
     PVOID *Buffer)
 {
-    FIXME("(%p,%p,%d,%p) stub\n", PolicyHandle, TrustedDomainName, InformationClass, Buffer);
+    FIXME("(%p,%p,%d,%p) stub\n", PolicyHandle, TrustedDomainSid, InformationClass, Buffer);
     return STATUS_OBJECT_NAME_NOT_FOUND;
 }
 
+
 /*
- * @unimplemented
+ * @implemented
  */
 NTSTATUS
 WINAPI
-LsaQueryTrustedDomainInfo(
-    LSA_HANDLE PolicyHandle,
-    PSID TrustedDomainSid,
-    TRUSTED_INFORMATION_CLASS InformationClass,
-    PVOID *Buffer)
+LsaQueryTrustedDomainInfoByName(IN LSA_HANDLE PolicyHandle,
+                                IN PLSA_UNICODE_STRING TrustedDomainName,
+                                IN TRUSTED_INFORMATION_CLASS InformationClass,
+                                OUT PVOID *Buffer)
 {
-    FIXME("(%p,%p,%d,%p) stub\n", PolicyHandle, TrustedDomainSid, InformationClass, Buffer);
-    return STATUS_OBJECT_NAME_NOT_FOUND;
+    NTSTATUS Status;
+
+    TRACE("(%p,%p,%d,%p)\n", PolicyHandle, TrustedDomainName, InformationClass, Buffer);
+
+    if (InformationClass == 9 /*TrustedDomainAuthInformationInternal*/ ||
+        InformationClass == 10 /*TrustedDomainFullInformationInternal*/)
+        return STATUS_INVALID_INFO_CLASS;
+
+    RpcTryExcept
+    {
+        Status = LsarQueryTrustedDomainInfoByName((LSAPR_HANDLE)PolicyHandle,
+                                                  (PRPC_UNICODE_STRING)TrustedDomainName,
+                                                  InformationClass,
+                                                  (unsigned long *)Buffer); // Shuld be: (PLSAPR_POLICY_INFORMATION *)Buffer
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
 }
 
+
 /*
- * @unimplemented
+ * @implemented
  */
 NTSTATUS
 WINAPI
-LsaRemoveAccountRights(
-    LSA_HANDLE PolicyHandle,
-    PSID AccountSid,
-    BOOLEAN AllRights,
-    PLSA_UNICODE_STRING UserRights,
-    ULONG CountOfRights)
+LsaRemoveAccountRights(IN LSA_HANDLE PolicyHandle,
+                       IN PSID AccountSid,
+                       IN BOOLEAN AllRights,
+                       IN PLSA_UNICODE_STRING UserRights,
+                       IN ULONG CountOfRights)
 {
-    FIXME("(%p,%p,%d,%p,0x%08x) stub\n", PolicyHandle, AccountSid, AllRights, UserRights, CountOfRights);
+    LSAPR_USER_RIGHT_SET UserRightSet;
+    NTSTATUS Status;
+
+    TRACE("(%p,%p,%d,%p,0x%08x) stub\n", PolicyHandle, AccountSid, AllRights, UserRights, CountOfRights);
+
+    UserRightSet.Entries = CountOfRights;
+    UserRightSet.UserRights = (PRPC_UNICODE_STRING)UserRights;
+
+    RpcTryExcept
+    {
+        Status = LsarRemoveAccountRights((LSAPR_HANDLE)PolicyHandle,
+                                         (PRPC_SID)AccountSid,
+                                         AllRights,
+                                         &UserRightSet);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
     return STATUS_SUCCESS;
 }
 
+
 /*
  * @unimplemented
  */
@@ -663,7 +911,7 @@ LsaRetrievePrivateData(
     PLSA_UNICODE_STRING *PrivateData)
 {
     FIXME("(%p,%p,%p) stub\n", PolicyHandle, KeyName, PrivateData);
-    return STATUS_NOT_IMPLEMENTED;
+    return STATUS_OBJECT_NAME_NOT_FOUND;
 }
 
 /*
@@ -677,21 +925,50 @@ LsaSetDomainInformationPolicy(
     PVOID Buffer)
 {
     FIXME("(%p,0x%08x,%p) stub\n", PolicyHandle, InformationClass, Buffer);
-    return STATUS_NOT_IMPLEMENTED;
+    return STATUS_UNSUCCESSFUL;
 }
 
+
 /*
- * @unimplemented
+ * @implemented
  */
 NTSTATUS
 WINAPI
-LsaSetInformationPolicy(
-    LSA_HANDLE PolicyHandle,
-    POLICY_INFORMATION_CLASS InformationClass,
-    PVOID Buffer)
+LsaSetInformationPolicy(IN LSA_HANDLE PolicyHandle,
+                        IN POLICY_INFORMATION_CLASS InformationClass,
+                        IN PVOID Buffer)
 {
-    FIXME("(%p,0x%08x,%p) stub\n", PolicyHandle, InformationClass, Buffer);
-    return STATUS_UNSUCCESSFUL;
+    NTSTATUS Status;
+
+    TRACE("(%p,0x%08x,%p)\n", PolicyHandle, InformationClass, Buffer);
+
+    RpcTryExcept
+    {
+        Status = LsarSetInformationPolicy((LSAPR_HANDLE)PolicyHandle,
+                                          InformationClass,
+                                          (PLSAPR_POLICY_INFORMATION)Buffer);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = I_RpcMapWin32Status(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    return Status;
+}
+
+
+/*
+ * @unimplemented
+ */
+NTSTATUS WINAPI LsaSetSecret(
+    IN LSA_HANDLE SecretHandle,
+    IN PLSA_UNICODE_STRING EncryptedCurrentValue,
+    IN PLSA_UNICODE_STRING EncryptedOldValue)
+{
+    FIXME("(%p,%p,%p) stub\n", SecretHandle, EncryptedCurrentValue,
+            EncryptedOldValue);
+    return STATUS_SUCCESS;
 }
 
 /*
@@ -725,6 +1002,17 @@ LsaSetTrustedDomainInfoByName(
     return STATUS_SUCCESS;
 }
 
+/*
+ * @unimplemented
+ */
+NTSTATUS WINAPI LsaRegisterPolicyChangeNotification(
+    POLICY_NOTIFICATION_INFORMATION_CLASS class,
+    HANDLE event)
+{
+    FIXME("(%d,%p) stub\n", class, event);
+    return STATUS_UNSUCCESSFUL;
+}
+
 /*
  * @unimplemented
  */
@@ -754,6 +1042,17 @@ LsaStorePrivateData(
     return STATUS_OBJECT_NAME_NOT_FOUND;
 }
 
+/*
+ * @unimplemented
+ */
+NTSTATUS WINAPI LsaUnregisterPolicyChangeNotification(
+    POLICY_NOTIFICATION_INFORMATION_CLASS class,
+    HANDLE event)
+{
+    FIXME("(%d,%p) stub\n", class, event);
+    return STATUS_SUCCESS;
+}
+
 /*
  * @unimplemented
  */