[LSASRV]
[reactos.git] / reactos / dll / win32 / lsasrv / lsarpc.c
index c20a8cd..9ec67ee 100644 (file)
@@ -1,97 +1,26 @@
-/* INCLUDES ****************************************************************/
-
-#define WIN32_NO_STATUS
-#include <windows.h>
-#include <ntsecapi.h>
-#define NTOS_MODE_USER
-#include <ndk/ntndk.h>
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         Local Security Authority (LSA) Server
+ * FILE:            reactos/dll/win32/lsasrv/lsarpc.h
+ * PURPOSE:         RPC interface functions
+ *
+ * PROGRAMMERS:     Eric Kohl
+ */
 
-#include <string.h>
+/* INCLUDES ****************************************************************/
 
 #include "lsasrv.h"
-#include "lsa_s.h"
-
-#include <wine/debug.h>
 
-typedef enum _LSA_DB_HANDLE_TYPE
-{
-    LsaDbIgnoreHandle,
-    LsaDbPolicyHandle,
-    LsaDbAccountHandle
-} LSA_DB_HANDLE_TYPE, *PLSA_DB_HANDLE_TYPE;
+WINE_DEFAULT_DEBUG_CHANNEL(lsasrv);
 
-typedef struct _LSA_DB_HANDLE
-{
-    ULONG Signature;
-    LSA_DB_HANDLE_TYPE HandleType;
-    LONG RefCount;
-    ACCESS_MASK Access;
-} LSA_DB_HANDLE, *PLSA_DB_HANDLE;
 
-#define LSAP_DB_SIGNATURE 0x12345678
+/* GLOBALS *****************************************************************/
 
 static RTL_CRITICAL_SECTION PolicyHandleTableLock;
 
-WINE_DEFAULT_DEBUG_CHANNEL(lsasrv);
-
 
 /* FUNCTIONS ***************************************************************/
 
-static LSAPR_HANDLE
-LsapCreateDbHandle(LSA_DB_HANDLE_TYPE HandleType,
-                   ACCESS_MASK DesiredAccess)
-{
-    PLSA_DB_HANDLE DbHandle;
-
-//    RtlEnterCriticalSection(&PolicyHandleTableLock);
-
-    DbHandle = (PLSA_DB_HANDLE)RtlAllocateHeap(RtlGetProcessHeap(),
-                                               0,
-                                               sizeof(LSA_DB_HANDLE));
-    if (DbHandle != NULL)
-    {
-        DbHandle->Signature = LSAP_DB_SIGNATURE;
-        DbHandle->RefCount = 1;
-        DbHandle->HandleType = HandleType;
-        DbHandle->Access = DesiredAccess;
-    }
-
-//    RtlLeaveCriticalSection(&PolicyHandleTableLock);
-
-    return (LSAPR_HANDLE)DbHandle;
-}
-
-
-static BOOL
-LsapValidateDbHandle(LSAPR_HANDLE Handle,
-                     LSA_DB_HANDLE_TYPE HandleType)
-{
-    PLSA_DB_HANDLE DbHandle = (PLSA_DB_HANDLE)Handle;
-    BOOL bValid = FALSE;
-
-    _SEH2_TRY
-    {
-        if (DbHandle->Signature == LSAP_DB_SIGNATURE)
-        {
-            if (HandleType == LsaDbIgnoreHandle)
-                bValid = TRUE;
-            else if (DbHandle->HandleType == HandleType)
-                bValid = TRUE;
-        }
-    }
-    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-    {
-        bValid = FALSE;
-    }
-    _SEH2_END;
-
-
-    return bValid;
-}
-
-
-
-
 VOID
 LsarStartRpcServer(VOID)
 {
@@ -138,22 +67,25 @@ void __RPC_USER LSAPR_HANDLE_rundown(LSAPR_HANDLE hHandle)
 
 
 /* Function 0 */
-NTSTATUS LsarClose(
+NTSTATUS WINAPI LsarClose(
     LSAPR_HANDLE *ObjectHandle)
 {
+    PLSA_DB_OBJECT DbObject;
     NTSTATUS Status = STATUS_SUCCESS;
 
     TRACE("0x%p\n", ObjectHandle);
 
 //    RtlEnterCriticalSection(&PolicyHandleTableLock);
 
-    if (LsapValidateDbHandle(*ObjectHandle, LsaDbIgnoreHandle))
+    Status = LsapValidateDbObject(*ObjectHandle,
+                                  LsaDbIgnoreObject,
+                                  0,
+                                  &DbObject);
+    if (Status == STATUS_SUCCESS)
     {
-        RtlFreeHeap(RtlGetProcessHeap(), 0, *ObjectHandle);
+        Status = LsapCloseDbObject(DbObject);
         *ObjectHandle = NULL;
     }
-    else
-        Status = STATUS_INVALID_HANDLE;
 
 //    RtlLeaveCriticalSection(&PolicyHandleTableLock);
 
@@ -162,7 +94,7 @@ NTSTATUS LsarClose(
 
 
 /* Function 1 */
-NTSTATUS LsarDelete(
+NTSTATUS WINAPI LsarDelete(
     LSAPR_HANDLE ObjectHandle)
 {
     /* Deprecated */
@@ -171,7 +103,7 @@ NTSTATUS LsarDelete(
 
 
 /* Function 2 */
-NTSTATUS LsarEnumeratePrivileges(
+NTSTATUS WINAPI LsarEnumeratePrivileges(
     LSAPR_HANDLE PolicyHandle,
     DWORD *EnumerationContext,
     PLSAPR_PRIVILEGE_ENUM_BUFFER EnumerationBuffer,
@@ -183,7 +115,7 @@ NTSTATUS LsarEnumeratePrivileges(
 
 
 /* Function 3 */
-NTSTATUS LsarQuerySecurityObject(
+NTSTATUS WINAPI LsarQuerySecurityObject(
     LSAPR_HANDLE ObjectHandle,
     SECURITY_INFORMATION SecurityInformation,
     PLSAPR_SR_SECURITY_DESCRIPTOR *SecurityDescriptor)
@@ -194,7 +126,7 @@ NTSTATUS LsarQuerySecurityObject(
 
 
 /* Function 4 */
-NTSTATUS LsarSetSecurityObject(
+NTSTATUS WINAPI LsarSetSecurityObject(
     LSAPR_HANDLE ObjectHandle,
     SECURITY_INFORMATION SecurityInformation,
     PLSAPR_SR_SECURITY_DESCRIPTOR SecurityDescriptor)
@@ -205,7 +137,7 @@ NTSTATUS LsarSetSecurityObject(
 
 
 /* Function 5 */
-NTSTATUS LsarChangePassword(
+NTSTATUS WINAPI LsarChangePassword(
     handle_t IDL_handle,
     PRPC_UNICODE_STRING String1,
     PRPC_UNICODE_STRING String2,
@@ -219,25 +151,30 @@ NTSTATUS LsarChangePassword(
 
 
 /* Function 6 */
-NTSTATUS LsarOpenPolicy(
+NTSTATUS WINAPI LsarOpenPolicy(
     LPWSTR SystemName,
     PLSAPR_OBJECT_ATTRIBUTES ObjectAttributes,
     ACCESS_MASK DesiredAccess,
     LSAPR_HANDLE *PolicyHandle)
 {
-    NTSTATUS Status = STATUS_SUCCESS;
+    PLSA_DB_OBJECT PolicyObject;
+    NTSTATUS Status;
 
     TRACE("LsarOpenPolicy called!\n");
 
     RtlEnterCriticalSection(&PolicyHandleTableLock);
 
-    *PolicyHandle = LsapCreateDbHandle(LsaDbPolicyHandle,
-                                       DesiredAccess);
-    if (*PolicyHandle == NULL)
-        Status = STATUS_INSUFFICIENT_RESOURCES;
+    Status = LsapOpenDbObject(NULL,
+                              L"Policy",
+                              LsaDbPolicyObject,
+                              DesiredAccess,
+                              &PolicyObject);
 
     RtlLeaveCriticalSection(&PolicyHandleTableLock);
 
+    if (NT_SUCCESS(Status))
+        *PolicyHandle = (LSAPR_HANDLE)PolicyObject;
+
     TRACE("LsarOpenPolicy done!\n");
 
     return Status;
@@ -245,29 +182,225 @@ NTSTATUS LsarOpenPolicy(
 
 
 /* Function 7 */
-NTSTATUS LsarQueryInformationPolicy(
+NTSTATUS WINAPI LsarQueryInformationPolicy(
     LSAPR_HANDLE PolicyHandle,
     POLICY_INFORMATION_CLASS InformationClass,
     PLSAPR_POLICY_INFORMATION *PolicyInformation)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PLSA_DB_OBJECT DbObject;
+    ACCESS_MASK DesiredAccess = 0;
+    NTSTATUS Status;
+
+    TRACE("LsarQueryInformationPolicy(%p,0x%08x,%p)\n",
+          PolicyHandle, InformationClass, PolicyInformation);
+
+    if (PolicyInformation)
+    {
+        TRACE("*PolicyInformation %p\n", *PolicyInformation);
+    }
+
+    switch (InformationClass)
+    {
+        case PolicyAuditLogInformation:
+        case PolicyAuditEventsInformation:
+        case PolicyAuditFullQueryInformation:
+            DesiredAccess = POLICY_VIEW_AUDIT_INFORMATION;
+            break;
+
+        case PolicyPrimaryDomainInformation:
+        case PolicyAccountDomainInformation:
+        case PolicyLsaServerRoleInformation:
+        case PolicyReplicaSourceInformation:
+        case PolicyDefaultQuotaInformation:
+        case PolicyDnsDomainInformation:
+        case PolicyDnsDomainInformationInt:
+        case PolicyLocalAccountDomainInformation:
+            DesiredAccess = POLICY_VIEW_LOCAL_INFORMATION;
+            break;
+
+        case PolicyPdAccountInformation:
+            DesiredAccess = POLICY_GET_PRIVATE_INFORMATION;
+            break;
+
+        default:
+            ERR("Invalid InformationClass!\n");
+            return STATUS_INVALID_PARAMETER;
+    }
+
+    Status = LsapValidateDbObject(PolicyHandle,
+                                  LsaDbPolicyObject,
+                                  DesiredAccess,
+                                  &DbObject);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    switch (InformationClass)
+    {
+        case PolicyAuditLogInformation:      /* 1 */
+            Status = LsarQueryAuditLog(PolicyHandle,
+                                       PolicyInformation);
+
+        case PolicyAuditEventsInformation:   /* 2 */
+            Status = LsarQueryAuditEvents(PolicyHandle,
+                                          PolicyInformation);
+            break;
+
+        case PolicyPrimaryDomainInformation: /* 3 */
+            Status = LsarQueryPrimaryDomain(PolicyHandle,
+                                            PolicyInformation);
+            break;
+
+        case PolicyPdAccountInformation:     /* 4 */
+            Status = LsarQueryPdAccount(PolicyHandle,
+                                        PolicyInformation);
+
+        case PolicyAccountDomainInformation: /* 5 */
+            Status = LsarQueryAccountDomain(PolicyHandle,
+                                            PolicyInformation);
+            break;
+
+        case PolicyLsaServerRoleInformation: /* 6 */
+            Status = LsarQueryServerRole(PolicyHandle,
+                                         PolicyInformation);
+            break;
+
+        case PolicyReplicaSourceInformation: /* 7 */
+            Status = LsarQueryReplicaSource(PolicyHandle,
+                                            PolicyInformation);
+
+        case PolicyDefaultQuotaInformation:  /* 8 */
+            Status = LsarQueryDefaultQuota(PolicyHandle,
+                                           PolicyInformation);
+            break;
+
+        case PolicyModificationInformation:  /* 9 */
+            Status = LsarQueryModification(PolicyHandle,
+                                           PolicyInformation);
+            break;
+
+        case PolicyAuditFullQueryInformation: /* 11 (0xB) */
+            Status = LsarQueryAuditFull(PolicyHandle,
+                                        PolicyInformation);
+            break;
+
+        case PolicyDnsDomainInformation:      /* 12 (0xC) */
+            Status = LsarQueryDnsDomain(PolicyHandle,
+                                        PolicyInformation);
+            break;
+
+        case PolicyDnsDomainInformationInt:   /* 13 (0xD) */
+            Status = LsarQueryDnsDomainInt(PolicyHandle,
+                                           PolicyInformation);
+            break;
+
+        case PolicyLocalAccountDomainInformation: /* 14 (0xE) */
+            Status = LsarQueryLocalAccountDomain(PolicyHandle,
+                                                 PolicyInformation);
+            break;
+
+        default:
+            ERR("Invalid InformationClass!\n");
+            Status = STATUS_INVALID_PARAMETER;
+    }
+
+    return Status;
 }
 
 
 /* Function 8 */
-NTSTATUS LsarSetInformationPolicy(
+NTSTATUS WINAPI LsarSetInformationPolicy(
     LSAPR_HANDLE PolicyHandle,
     POLICY_INFORMATION_CLASS InformationClass,
     PLSAPR_POLICY_INFORMATION PolicyInformation)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PLSA_DB_OBJECT DbObject;
+    ACCESS_MASK DesiredAccess = 0;
+    NTSTATUS Status;
+
+    TRACE("LsarSetInformationPolicy(%p,0x%08x,%p)\n",
+          PolicyHandle, InformationClass, PolicyInformation);
+
+    if (PolicyInformation)
+    {
+        TRACE("*PolicyInformation %p\n", *PolicyInformation);
+    }
+
+    switch (InformationClass)
+    {
+        case PolicyAuditLogInformation:
+        case PolicyAuditFullSetInformation:
+            DesiredAccess = POLICY_AUDIT_LOG_ADMIN;
+            break;
+
+        case PolicyAuditEventsInformation:
+            DesiredAccess = POLICY_SET_AUDIT_REQUIREMENTS;
+            break;
+
+        case PolicyPrimaryDomainInformation:
+        case PolicyAccountDomainInformation:
+        case PolicyDnsDomainInformation:
+        case PolicyDnsDomainInformationInt:
+        case PolicyLocalAccountDomainInformation:
+            DesiredAccess = POLICY_TRUST_ADMIN;
+            break;
+
+        case PolicyLsaServerRoleInformation:
+        case PolicyReplicaSourceInformation:
+            DesiredAccess = POLICY_SERVER_ADMIN;
+            break;
+
+        case PolicyDefaultQuotaInformation:
+            DesiredAccess = POLICY_SET_DEFAULT_QUOTA_LIMITS;
+            break;
+
+        default:
+            ERR("Invalid InformationClass!\n");
+            return STATUS_INVALID_PARAMETER;
+    }
+
+    Status = LsapValidateDbObject(PolicyHandle,
+                                  LsaDbPolicyObject,
+                                  DesiredAccess,
+                                  &DbObject);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    switch (InformationClass)
+    {
+        case PolicyAuditEventsInformation:
+            Status = STATUS_NOT_IMPLEMENTED;
+            break;
+
+        case PolicyPrimaryDomainInformation:
+            Status = LsarSetPrimaryDomain(PolicyHandle,
+                                          (PLSAPR_POLICY_PRIMARY_DOM_INFO)PolicyInformation);
+            break;
+
+        case PolicyAccountDomainInformation:
+            Status = LsarSetAccountDomain(PolicyHandle,
+                                          (PLSAPR_POLICY_ACCOUNT_DOM_INFO)PolicyInformation);
+            break;
+
+        case PolicyDnsDomainInformation:
+            Status = LsarSetDnsDomain(PolicyHandle,
+                                      (PLSAPR_POLICY_DNS_DOMAIN_INFO)PolicyInformation);
+            break;
+
+        case PolicyLsaServerRoleInformation:
+            Status = STATUS_NOT_IMPLEMENTED;
+            break;
+
+        default:
+            Status = STATUS_INVALID_PARAMETER;
+            break;
+    }
+
+    return Status;
 }
 
 
 /* Function 9 */
-NTSTATUS LsarClearAuditLog(
+NTSTATUS WINAPI LsarClearAuditLog(
     LSAPR_HANDLE ObjectHandle)
 {
     /* Deprecated */
@@ -276,19 +409,91 @@ NTSTATUS LsarClearAuditLog(
 
 
 /* Function 10 */
-NTSTATUS LsarCreateAccount(
+NTSTATUS WINAPI LsarCreateAccount(
     LSAPR_HANDLE PolicyHandle,
     PRPC_SID AccountSid,
     ACCESS_MASK DesiredAccess,
     LSAPR_HANDLE *AccountHandle)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PLSA_DB_OBJECT PolicyObject;
+    PLSA_DB_OBJECT AccountsObject = NULL;
+    PLSA_DB_OBJECT AccountObject = NULL;
+    LPWSTR SidString = NULL;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    /* Validate the PolicyHandle */
+    Status = LsapValidateDbObject(PolicyHandle,
+                                  LsaDbPolicyObject,
+                                  POLICY_CREATE_ACCOUNT,
+                                  &PolicyObject);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
+        return Status;
+    }
+
+    /* Open the Accounts object */
+    Status = LsapOpenDbObject(PolicyObject,
+                              L"Accounts",
+                              LsaDbContainerObject,
+                              0,
+                              &AccountsObject);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapCreateDbObject (Accounts) failed (Status 0x%08lx)\n", Status);
+        goto done;
+    }
+
+    /* Create SID string */
+    if (!ConvertSidToStringSid((PSID)AccountSid,
+                               &SidString))
+    {
+        ERR("ConvertSidToStringSid failed\n");
+        Status = STATUS_INVALID_PARAMETER;
+        goto done;
+    }
+
+    /* Create the Account object */
+    Status = LsapCreateDbObject(AccountsObject,
+                                SidString,
+                                LsaDbAccountObject,
+                                DesiredAccess,
+                                &AccountObject);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapCreateDbObject (Account) failed (Status 0x%08lx)\n", Status);
+        goto done;
+    }
+
+    /* Set the Sid attribute */
+    Status = LsapSetObjectAttribute(AccountObject,
+                                    L"Sid",
+                                    (PVOID)AccountSid,
+                                    GetLengthSid(AccountSid));
+
+done:
+    if (SidString != NULL)
+        LocalFree(SidString);
+
+    if (!NT_SUCCESS(Status))
+    {
+        if (AccountObject != NULL)
+            LsapCloseDbObject(AccountObject);
+    }
+    else
+    {
+        *AccountHandle = (LSAPR_HANDLE)AccountObject;
+    }
+
+    if (AccountsObject != NULL)
+        LsapCloseDbObject(AccountsObject);
+
+    return STATUS_SUCCESS;
 }
 
 
 /* Function 11 */
-NTSTATUS LsarEnumerateAccounts(
+NTSTATUS WINAPI LsarEnumerateAccounts(
     LSAPR_HANDLE PolicyHandle,
     DWORD *EnumerationContext,
     PLSAPR_ACCOUNT_ENUM_BUFFER EnumerationBuffer,
@@ -300,7 +505,7 @@ NTSTATUS LsarEnumerateAccounts(
 
 
 /* Function 12 */
-NTSTATUS LsarCreateTrustedDomain(
+NTSTATUS WINAPI LsarCreateTrustedDomain(
     LSAPR_HANDLE PolicyHandle,
     PLSAPR_TRUST_INFORMATION TrustedDomainInformation,
     ACCESS_MASK DesiredAccess,
@@ -312,7 +517,7 @@ NTSTATUS LsarCreateTrustedDomain(
 
 
 /* Function 13 */
-NTSTATUS LsarEnumerateTrustedDomains(
+NTSTATUS WINAPI LsarEnumerateTrustedDomains(
     LSAPR_HANDLE PolicyHandle,
     DWORD *EnumerationContext,
     PLSAPR_TRUSTED_ENUM_BUFFER EnumerationBuffer,
@@ -324,7 +529,7 @@ NTSTATUS LsarEnumerateTrustedDomains(
 
 
 /* Function 14 */
-NTSTATUS LsarLookupNames(
+NTSTATUS WINAPI LsarLookupNames(
     LSAPR_HANDLE PolicyHandle,
     DWORD Count,
     PRPC_UNICODE_STRING Names,
@@ -333,13 +538,96 @@ NTSTATUS LsarLookupNames(
     LSAP_LOOKUP_LEVEL LookupLevel,
     DWORD *MappedCount)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    SID_IDENTIFIER_AUTHORITY IdentifierAuthority = {SECURITY_NT_AUTHORITY};
+    static const UNICODE_STRING DomainName = RTL_CONSTANT_STRING(L"DOMAIN");
+    PLSAPR_REFERENCED_DOMAIN_LIST OutputDomains = NULL;
+    PLSA_TRANSLATED_SID OutputSids = NULL;
+    ULONG OutputSidsLength;
+    ULONG i;
+    PSID Sid;
+    ULONG SidLength;
+    NTSTATUS Status;
+
+    TRACE("LsarLookupNames(%p, %lu, %p, %p, %p, %d, %p)\n",
+          PolicyHandle, Count, Names, ReferencedDomains, TranslatedSids,
+          LookupLevel, MappedCount);
+
+    TranslatedSids->Entries = Count;
+    TranslatedSids->Sids = NULL;
+    *ReferencedDomains = NULL;
+
+    OutputSidsLength = Count * sizeof(LSA_TRANSLATED_SID);
+    OutputSids = MIDL_user_allocate(OutputSidsLength);
+    if (OutputSids == NULL)
+    {
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    RtlZeroMemory(OutputSids, OutputSidsLength);
+
+    OutputDomains = MIDL_user_allocate(sizeof(LSAPR_REFERENCED_DOMAIN_LIST));
+    if (OutputDomains == NULL)
+    {
+        MIDL_user_free(OutputSids);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    OutputDomains->Entries = Count;
+    OutputDomains->Domains = MIDL_user_allocate(Count * sizeof(LSA_TRUST_INFORMATION));
+    if (OutputDomains->Domains == NULL)
+    {
+        MIDL_user_free(OutputDomains);
+        MIDL_user_free(OutputSids);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    Status = RtlAllocateAndInitializeSid(&IdentifierAuthority,
+                                         2,
+                                         SECURITY_BUILTIN_DOMAIN_RID,
+                                         DOMAIN_ALIAS_RID_ADMINS,
+                                         0, 0, 0, 0, 0, 0,
+                                         &Sid);
+    if (!NT_SUCCESS(Status))
+    {
+        MIDL_user_free(OutputDomains->Domains);
+        MIDL_user_free(OutputDomains);
+        MIDL_user_free(OutputSids);
+        return Status;
+    }
+
+    SidLength = RtlLengthSid(Sid);
+
+    for (i = 0; i < Count; i++)
+    {
+        OutputDomains->Domains[i].Sid = MIDL_user_allocate(SidLength);
+        RtlCopyMemory(OutputDomains->Domains[i].Sid, Sid, SidLength);
+
+        OutputDomains->Domains[i].Name.Buffer = MIDL_user_allocate(DomainName.MaximumLength);
+        OutputDomains->Domains[i].Name.Length = DomainName.Length;
+        OutputDomains->Domains[i].Name.MaximumLength = DomainName.MaximumLength;
+        RtlCopyMemory(OutputDomains->Domains[i].Name.Buffer, DomainName.Buffer, DomainName.MaximumLength);
+    }
+
+    for (i = 0; i < Count; i++)
+    {
+        OutputSids[i].Use = SidTypeWellKnownGroup;
+        OutputSids[i].RelativeId = DOMAIN_USER_RID_ADMIN; //DOMAIN_ALIAS_RID_ADMINS;
+        OutputSids[i].DomainIndex = i;
+    }
+
+    *ReferencedDomains = OutputDomains;
+
+    *MappedCount = Count;
+
+    TranslatedSids->Entries = Count;
+    TranslatedSids->Sids = OutputSids;
+
+    return STATUS_SUCCESS;
 }
 
 
 /* Function 15 */
-NTSTATUS LsarLookupSids(
+NTSTATUS WINAPI LsarLookupSids(
     LSAPR_HANDLE PolicyHandle,
     PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
     PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
@@ -347,10 +635,15 @@ NTSTATUS LsarLookupSids(
     LSAP_LOOKUP_LEVEL LookupLevel,
     DWORD *MappedCount)
 {
-    static const UNICODE_STRING UserName = RTL_CONSTANT_STRING(L"Administrator");
+    SID_IDENTIFIER_AUTHORITY IdentifierAuthority = {SECURITY_NT_AUTHORITY};
+    static const UNICODE_STRING DomainName = RTL_CONSTANT_STRING(L"DOMAIN");
+    PLSAPR_REFERENCED_DOMAIN_LIST OutputDomains = NULL;
     PLSAPR_TRANSLATED_NAME OutputNames = NULL;
     ULONG OutputNamesLength;
     ULONG i;
+    PSID Sid;
+    ULONG SidLength;
+    NTSTATUS Status;
 
     TRACE("LsarLookupSids(%p, %p, %p, %p, %d, %p)\n",
           PolicyHandle, SidEnumBuffer, ReferencedDomains, TranslatedNames,
@@ -369,71 +662,444 @@ NTSTATUS LsarLookupSids(
 
     RtlZeroMemory(OutputNames, OutputNamesLength);
 
+    OutputDomains = MIDL_user_allocate(sizeof(LSAPR_REFERENCED_DOMAIN_LIST));
+    if (OutputDomains == NULL)
+    {
+        MIDL_user_free(OutputNames);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    OutputDomains->Entries = SidEnumBuffer->Entries;
+    OutputDomains->Domains = MIDL_user_allocate(SidEnumBuffer->Entries * sizeof(LSA_TRUST_INFORMATION));
+    if (OutputDomains->Domains == NULL)
+    {
+        MIDL_user_free(OutputDomains);
+        MIDL_user_free(OutputNames);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    Status = RtlAllocateAndInitializeSid(&IdentifierAuthority,
+                                         2,
+                                         SECURITY_BUILTIN_DOMAIN_RID,
+                                         DOMAIN_ALIAS_RID_ADMINS,
+                                         0, 0, 0, 0, 0, 0,
+                                         &Sid);
+    if (!NT_SUCCESS(Status))
+    {
+        MIDL_user_free(OutputDomains->Domains);
+        MIDL_user_free(OutputDomains);
+        MIDL_user_free(OutputNames);
+        return Status;
+    }
+
+    SidLength = RtlLengthSid(Sid);
+
     for (i = 0; i < SidEnumBuffer->Entries; i++)
     {
-        OutputNames[i].Use = SidTypeWellKnownGroup;
-        OutputNames[i].DomainIndex = 0;
-        OutputNames[i].Name.Buffer = MIDL_user_allocate(UserName.MaximumLength);
-        OutputNames[i].Name.Length = UserName.Length;
-        OutputNames[i].Name.MaximumLength = UserName.MaximumLength;
-        RtlCopyMemory(OutputNames[i].Name.Buffer, UserName.Buffer, UserName.MaximumLength);
+        OutputDomains->Domains[i].Sid = MIDL_user_allocate(SidLength);
+        RtlCopyMemory(OutputDomains->Domains[i].Sid, Sid, SidLength);
+
+        OutputDomains->Domains[i].Name.Buffer = MIDL_user_allocate(DomainName.MaximumLength);
+        OutputDomains->Domains[i].Name.Length = DomainName.Length;
+        OutputDomains->Domains[i].Name.MaximumLength = DomainName.MaximumLength;
+        RtlCopyMemory(OutputDomains->Domains[i].Name.Buffer, DomainName.Buffer, DomainName.MaximumLength);
     }
 
+    Status = LsapLookupSids(SidEnumBuffer,
+                            OutputNames);
+
+    *ReferencedDomains = OutputDomains;
+
     *MappedCount = SidEnumBuffer->Entries;
 
-    TranslatedNames->Entries =  SidEnumBuffer->Entries;
+    TranslatedNames->Entries = SidEnumBuffer->Entries;
     TranslatedNames->Names = OutputNames;
 
-    return STATUS_SUCCESS;
+    return Status;
 }
 
 
 /* Function 16 */
-NTSTATUS LsarCreateSecret(
+NTSTATUS WINAPI LsarCreateSecret(
     LSAPR_HANDLE PolicyHandle,
     PRPC_UNICODE_STRING SecretName,
     ACCESS_MASK DesiredAccess,
     LSAPR_HANDLE *SecretHandle)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PLSA_DB_OBJECT PolicyObject;
+    PLSA_DB_OBJECT SecretsObject = NULL;
+    PLSA_DB_OBJECT SecretObject = NULL;
+    LARGE_INTEGER Time;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    /* Validate the PolicyHandle */
+    Status = LsapValidateDbObject(PolicyHandle,
+                                  LsaDbPolicyObject,
+                                  POLICY_CREATE_SECRET,
+                                  &PolicyObject);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
+        return Status;
+    }
+
+    /* Open the Secrets object */
+    Status = LsapOpenDbObject(PolicyObject,
+                              L"Secrets",
+                              LsaDbContainerObject,
+                              0,
+                              &SecretsObject);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapCreateDbObject (Secrets) failed (Status 0x%08lx)\n", Status);
+        goto done;
+    }
+
+    /* Get the current time */
+    Status = NtQuerySystemTime(&Time);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("NtQuerySystemTime failed (Status 0x%08lx)\n", Status);
+        goto done;
+    }
+
+    /* Create the Secret object */
+    Status = LsapCreateDbObject(SecretsObject,
+                                SecretName->Buffer,
+                                LsaDbSecretObject,
+                                DesiredAccess,
+                                &SecretObject);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapCreateDbObject (Secret) failed (Status 0x%08lx)\n", Status);
+        goto done;
+    }
+
+    /* Set the CurrentTime attribute */
+    Status = LsapSetObjectAttribute(SecretObject,
+                                    L"CurrentTime",
+                                    (PVOID)&Time,
+                                    sizeof(LARGE_INTEGER));
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapSetObjectAttribute (CurrentTime) failed (Status 0x%08lx)\n", Status);
+        goto done;
+    }
+
+    /* Set the OldTime attribute */
+    Status = LsapSetObjectAttribute(SecretObject,
+                                    L"OldTime",
+                                    (PVOID)&Time,
+                                    sizeof(LARGE_INTEGER));
+
+done:
+    if (!NT_SUCCESS(Status))
+    {
+        if (SecretObject != NULL)
+            LsapCloseDbObject(SecretObject);
+    }
+    else
+    {
+        *SecretHandle = (LSAPR_HANDLE)SecretObject;
+    }
+
+    if (SecretsObject != NULL)
+        LsapCloseDbObject(SecretsObject);
+
+    return STATUS_SUCCESS;
 }
 
 
 /* Function 17 */
-NTSTATUS LsarOpenAccount(
+NTSTATUS WINAPI LsarOpenAccount(
     LSAPR_HANDLE PolicyHandle,
     PRPC_SID AccountSid,
     ACCESS_MASK DesiredAccess,
     LSAPR_HANDLE *AccountHandle)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PLSA_DB_OBJECT PolicyObject;
+    PLSA_DB_OBJECT AccountsObject = NULL;
+    PLSA_DB_OBJECT AccountObject = NULL;
+    LPWSTR SidString = NULL;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    /* Validate the PolicyHandle */
+    Status = LsapValidateDbObject(PolicyHandle,
+                                  LsaDbPolicyObject,
+                                  POLICY_CREATE_ACCOUNT,
+                                  &PolicyObject);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
+        return Status;
+    }
+
+    /* Open the Accounts object */
+    Status = LsapOpenDbObject(PolicyObject,
+                              L"Accounts",
+                              LsaDbContainerObject,
+                              0,
+                              &AccountsObject);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapCreateDbObject (Accounts) failed (Status 0x%08lx)\n", Status);
+        goto done;
+    }
+
+    /* Create SID string */
+    if (!ConvertSidToStringSid((PSID)AccountSid,
+                               &SidString))
+    {
+        ERR("ConvertSidToStringSid failed\n");
+        Status = STATUS_INVALID_PARAMETER;
+        goto done;
+    }
+
+    /* Create the Account object */
+    Status = LsapOpenDbObject(AccountsObject,
+                              SidString,
+                              LsaDbAccountObject,
+                              DesiredAccess,
+                              &AccountObject);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapOpenDbObject (Account) failed (Status 0x%08lx)\n", Status);
+        goto done;
+    }
+
+    /* Set the Sid attribute */
+    Status = LsapSetObjectAttribute(AccountObject,
+                                    L"Sid",
+                                    (PVOID)AccountSid,
+                                    GetLengthSid(AccountSid));
+
+done:
+    if (SidString != NULL)
+        LocalFree(SidString);
+
+    if (!NT_SUCCESS(Status))
+    {
+        if (AccountObject != NULL)
+            LsapCloseDbObject(AccountObject);
+    }
+    else
+    {
+        *AccountHandle = (LSAPR_HANDLE)AccountObject;
+    }
+
+    if (AccountsObject != NULL)
+        LsapCloseDbObject(AccountsObject);
+
+    return STATUS_SUCCESS;
 }
 
 
 /* Function 18 */
-NTSTATUS LsarEnumeratePrivilegesAccount(
+NTSTATUS WINAPI LsarEnumeratePrivilegesAccount(
     LSAPR_HANDLE AccountHandle,
     PLSAPR_PRIVILEGE_SET *Privileges)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PLSA_DB_OBJECT AccountObject;
+    ULONG PrivilegeSetSize = 0;
+    PLSAPR_PRIVILEGE_SET PrivilegeSet = NULL;
+    NTSTATUS Status;
+
+    *Privileges = NULL;
+
+    /* Validate the AccountHandle */
+    Status = LsapValidateDbObject(AccountHandle,
+                                  LsaDbAccountObject,
+                                  ACCOUNT_VIEW,
+                                  &AccountObject);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
+        return Status;
+    }
+
+    /* Get the size of the privilege set */
+    Status = LsapGetObjectAttribute(AccountObject,
+                                    L"Privilgs",
+                                    NULL,
+                                    &PrivilegeSetSize);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    /* Allocate a buffer for the privilege set */
+    PrivilegeSet = MIDL_user_allocate(PrivilegeSetSize);
+    if (PrivilegeSet == NULL)
+        return STATUS_NO_MEMORY;
+
+    /* Get the privilege set */
+    Status = LsapGetObjectAttribute(AccountObject,
+                                    L"Privilgs",
+                                    PrivilegeSet,
+                                    &PrivilegeSetSize);
+    if (!NT_SUCCESS(Status))
+    {
+        MIDL_user_free(PrivilegeSet);
+        return Status;
+    }
+
+    /* Return a pointer to the privilege set */
+    *Privileges = PrivilegeSet;
+
+    return STATUS_SUCCESS;
 }
 
 
 /* Function 19 */
-NTSTATUS LsarAddPrivilegesToAccount(
+NTSTATUS WINAPI LsarAddPrivilegesToAccount(
     LSAPR_HANDLE AccountHandle,
     PLSAPR_PRIVILEGE_SET Privileges)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PLSA_DB_OBJECT AccountObject;
+    PPRIVILEGE_SET CurrentPrivileges = NULL;
+    PPRIVILEGE_SET NewPrivileges = NULL;
+    ULONG PrivilegeSetSize = 0;
+    ULONG PrivilegeCount;
+    ULONG i, j;
+    BOOL bFound;
+    NTSTATUS Status;
+
+    /* Validate the AccountHandle */
+    Status = LsapValidateDbObject(AccountHandle,
+                                  LsaDbAccountObject,
+                                  ACCOUNT_ADJUST_PRIVILEGES,
+                                  &AccountObject);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
+        return Status;
+    }
+
+    Status = LsapGetObjectAttribute(AccountObject,
+                                    L"Privilgs",
+                                    NULL,
+                                    &PrivilegeSetSize);
+    if (!NT_SUCCESS(Status) || PrivilegeSetSize == 0)
+    {
+        /* The Privilgs attribute does not exist */
+
+        PrivilegeSetSize = sizeof(PRIVILEGE_SET) +
+                           (Privileges->PrivilegeCount - 1) * sizeof(LUID_AND_ATTRIBUTES);
+        Status = LsapSetObjectAttribute(AccountObject,
+                                        L"Privilgs",
+                                        Privileges,
+                                        PrivilegeSetSize);
+    }
+    else
+    {
+        /* The Privilgs attribute exists */
+
+        /* Allocate memory for the stored privilege set */
+        CurrentPrivileges = MIDL_user_allocate(PrivilegeSetSize);
+        if (CurrentPrivileges == NULL)
+            return STATUS_NO_MEMORY;
+
+        /* Get the current privilege set */
+        Status = LsapGetObjectAttribute(AccountObject,
+                                        L"Privilgs",
+                                        CurrentPrivileges,
+                                        &PrivilegeSetSize);
+        if (!NT_SUCCESS(Status))
+        {
+            TRACE("LsapGetObjectAttribute() failed (Status 0x%08lx)\n", Status);
+            goto done;
+        }
+
+        PrivilegeCount = CurrentPrivileges->PrivilegeCount;
+        TRACE("Current privilege count: %lu\n", PrivilegeCount);
+
+        /* Calculate the number privileges in the combined privilege set */
+        for (i = 0; i < Privileges->PrivilegeCount; i++)
+        {
+            bFound = FALSE;
+            for (j = 0; j < CurrentPrivileges->PrivilegeCount; j++)
+            {
+                if (RtlEqualLuid(&(Privileges->Privilege[i].Luid),
+                                 &(CurrentPrivileges->Privilege[i].Luid)))
+                {
+                    bFound = TRUE;
+                    break;
+                }
+            }
+
+            if (bFound == FALSE)
+            {
+                TRACE("Found new privilege\n");
+                PrivilegeCount++;
+            }
+        }
+        TRACE("New privilege count: %lu\n", PrivilegeCount);
+
+        /* Calculate the size of the new privilege set and allocate it */
+        PrivilegeSetSize = sizeof(PRIVILEGE_SET) +
+                           (PrivilegeCount - 1) * sizeof(LUID_AND_ATTRIBUTES);
+        NewPrivileges = MIDL_user_allocate(PrivilegeSetSize);
+        if (NewPrivileges == NULL)
+        {
+            Status = STATUS_NO_MEMORY;
+            goto done;
+        }
+
+        /* Initialize the new privilege set */
+        NewPrivileges->PrivilegeCount = PrivilegeCount;
+        NewPrivileges->Control = 0;
+
+        /* Copy all privileges from the current privilege set */
+        RtlCopyLuidAndAttributesArray(CurrentPrivileges->PrivilegeCount,
+                                      &(CurrentPrivileges->Privilege[0]),
+                                      &(NewPrivileges->Privilege[0]));
+
+        /* Add new privileges to the new privilege set */
+        PrivilegeCount = CurrentPrivileges->PrivilegeCount;
+        for (i = 0; i < Privileges->PrivilegeCount; i++)
+        {
+            bFound = FALSE;
+            for (j = 0; j < CurrentPrivileges->PrivilegeCount; j++)
+            {
+                if (RtlEqualLuid(&(Privileges->Privilege[i].Luid),
+                                 &(CurrentPrivileges->Privilege[i].Luid)))
+                {
+                    /* Overwrite attributes if a matching privilege was found */
+                    NewPrivileges->Privilege[j].Attributes = Privileges->Privilege[i].Attributes;
+
+                    bFound = TRUE;
+                    break;
+                }
+            }
+
+            if (bFound == FALSE)
+            {
+                /* Copy the new privilege */
+                RtlCopyLuidAndAttributesArray(1,
+                                              (PLUID_AND_ATTRIBUTES)&(Privileges->Privilege[i]),
+                                              &(NewPrivileges->Privilege[PrivilegeCount]));
+                PrivilegeCount++;
+            }
+        }
+
+        /* Set the new priivliege set */
+        Status = LsapSetObjectAttribute(AccountObject,
+                                        L"Privilgs",
+                                        NewPrivileges,
+                                        PrivilegeSetSize);
+    }
+
+done:
+    if (CurrentPrivileges != NULL)
+        MIDL_user_free(CurrentPrivileges);
+
+    if (NewPrivileges != NULL)
+        MIDL_user_free(NewPrivileges);
+
+    return Status;
 }
 
 
 /* Function 20 */
-NTSTATUS LsarRemovePrivilegesFromAccount(
+NTSTATUS WINAPI LsarRemovePrivilegesFromAccount(
     LSAPR_HANDLE AccountHandle,
     BOOL AllPrivileges,
     PLSAPR_PRIVILEGE_SET Privileges)
@@ -444,7 +1110,7 @@ NTSTATUS LsarRemovePrivilegesFromAccount(
 
 
 /* Function 21 */
-NTSTATUS LsarGetQuotasForAccount(
+NTSTATUS WINAPI LsarGetQuotasForAccount(
     LSAPR_HANDLE AccountHandle,
     PQUOTA_LIMITS QuotaLimits)
 {
@@ -454,7 +1120,7 @@ NTSTATUS LsarGetQuotasForAccount(
 
 
 /* Function 22 */
-NTSTATUS LsarSetQuotasForAccount(
+NTSTATUS WINAPI LsarSetQuotasForAccount(
     LSAPR_HANDLE AccountHandle,
     PQUOTA_LIMITS QuotaLimits)
 {
@@ -464,27 +1130,66 @@ NTSTATUS LsarSetQuotasForAccount(
 
 
 /* Function 23 */
-NTSTATUS LsarGetSystemAccessAccount(
+NTSTATUS WINAPI LsarGetSystemAccessAccount(
     LSAPR_HANDLE AccountHandle,
     ACCESS_MASK *SystemAccess)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PLSA_DB_OBJECT AccountObject;
+    ULONG Size;
+    NTSTATUS Status;
+
+    /* Validate the account handle */
+    Status = LsapValidateDbObject(AccountHandle,
+                                  LsaDbAccountObject,
+                                  ACCOUNT_VIEW,
+                                  &AccountObject);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("Invalid handle (Status %lx)\n", Status);
+        return Status;
+    }
+
+    /* Get the system access flags */
+    Status = LsapGetObjectAttribute(AccountObject,
+                                    L"ActSysAc",
+                                    SystemAccess,
+                                    &Size);
+
+    return Status;
 }
 
 
 /* Function 24 */
-NTSTATUS LsarSetSystemAccessAccount(
+NTSTATUS WINAPI LsarSetSystemAccessAccount(
     LSAPR_HANDLE AccountHandle,
     ACCESS_MASK SystemAccess)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PLSA_DB_OBJECT AccountObject;
+    NTSTATUS Status;
+
+    /* Validate the account handle */
+    Status = LsapValidateDbObject(AccountHandle,
+                                  LsaDbAccountObject,
+                                  ACCOUNT_ADJUST_SYSTEM_ACCESS,
+                                  &AccountObject);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("Invalid handle (Status %lx)\n", Status);
+        return Status;
+    }
+
+    /* Set the system access flags */
+    Status = LsapSetObjectAttribute(AccountObject,
+                                    L"ActSysAc",
+                                    &SystemAccess,
+                                    sizeof(ACCESS_MASK));
+
+    return Status;
 }
 
 
 /* Function 25 */
-NTSTATUS LsarOpenTrustedDomain(
+NTSTATUS WINAPI LsarOpenTrustedDomain(
     LSAPR_HANDLE PolicyHandle,
     PRPC_SID TrustedDomainSid,
     ACCESS_MASK DesiredAccess,
@@ -496,7 +1201,7 @@ NTSTATUS LsarOpenTrustedDomain(
 
 
 /* Function 26 */
-NTSTATUS LsarQueryInfoTrustedDomain(
+NTSTATUS WINAPI LsarQueryInfoTrustedDomain(
     LSAPR_HANDLE TrustedDomainHandle,
     TRUSTED_INFORMATION_CLASS InformationClass,
     PLSAPR_TRUSTED_DOMAIN_INFO *TrustedDomainInformation)
@@ -507,7 +1212,7 @@ NTSTATUS LsarQueryInfoTrustedDomain(
 
 
 /* Function 27 */
-NTSTATUS LsarSetInformationTrustedDomain(
+NTSTATUS WINAPI LsarSetInformationTrustedDomain(
     LSAPR_HANDLE TrustedDomainHandle,
     TRUSTED_INFORMATION_CLASS InformationClass,
     PLSAPR_TRUSTED_DOMAIN_INFO TrustedDomainInformation)
@@ -518,43 +1223,350 @@ NTSTATUS LsarSetInformationTrustedDomain(
 
 
 /* Function 28 */
-NTSTATUS LsarOpenSecret(
+NTSTATUS WINAPI LsarOpenSecret(
     LSAPR_HANDLE PolicyHandle,
     PRPC_UNICODE_STRING SecretName,
     ACCESS_MASK DesiredAccess,
     LSAPR_HANDLE *SecretHandle)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PLSA_DB_OBJECT PolicyObject;
+    PLSA_DB_OBJECT SecretsObject = NULL;
+    PLSA_DB_OBJECT SecretObject = NULL;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    /* Validate the PolicyHandle */
+    Status = LsapValidateDbObject(PolicyHandle,
+                                  LsaDbPolicyObject,
+                                  POLICY_CREATE_SECRET,
+                                  &PolicyObject);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
+        return Status;
+    }
+
+    /* Open the Secrets object */
+    Status = LsapOpenDbObject(PolicyObject,
+                              L"Secrets",
+                              LsaDbContainerObject,
+                              0,
+                              &SecretsObject);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapCreateDbObject (Secrets) failed (Status 0x%08lx)\n", Status);
+        goto done;
+    }
+
+    /* Create the secret object */
+    Status = LsapOpenDbObject(SecretsObject,
+                              SecretName->Buffer,
+                              LsaDbSecretObject,
+                              DesiredAccess,
+                              &SecretObject);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapOpenDbObject (Secret) failed (Status 0x%08lx)\n", Status);
+        goto done;
+    }
+
+done:
+    if (!NT_SUCCESS(Status))
+    {
+        if (SecretObject != NULL)
+            LsapCloseDbObject(SecretObject);
+    }
+    else
+    {
+        *SecretHandle = (LSAPR_HANDLE)SecretObject;
+    }
+
+    if (SecretsObject != NULL)
+        LsapCloseDbObject(SecretsObject);
+
+    return STATUS_SUCCESS;
 }
 
 
 /* Function 29 */
-NTSTATUS LsarSetSecret(
-    LSAPR_HANDLE *SecretHandle,
+NTSTATUS WINAPI LsarSetSecret(
+    LSAPR_HANDLE SecretHandle,
     PLSAPR_CR_CIPHER_VALUE EncryptedCurrentValue,
     PLSAPR_CR_CIPHER_VALUE EncryptedOldValue)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PLSA_DB_OBJECT SecretObject;
+    PBYTE CurrentValue = NULL;
+    PBYTE OldValue = NULL;
+    ULONG CurrentValueLength = 0;
+    ULONG OldValueLength = 0;
+    LARGE_INTEGER Time;
+    NTSTATUS Status;
+
+    TRACE("LsarSetSecret(%p %p %p)\n", SecretHandle,
+          EncryptedCurrentValue, EncryptedOldValue);
+
+    /* Validate the SecretHandle */
+    Status = LsapValidateDbObject(SecretHandle,
+                                  LsaDbSecretObject,
+                                  SECRET_SET_VALUE,
+                                  &SecretObject);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
+        return Status;
+    }
+
+    if (EncryptedCurrentValue != NULL)
+    {
+        /* FIXME: Decrypt the current value */
+        CurrentValue = EncryptedCurrentValue->Buffer;
+        CurrentValueLength = EncryptedCurrentValue->MaximumLength;
+    }
+
+    /* Set the current value */
+    Status = LsapSetObjectAttribute(SecretObject,
+                                    L"CurrentValue",
+                                    CurrentValue,
+                                    CurrentValueLength);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapSetObjectAttribute failed (Status 0x%08lx)\n", Status);
+        goto done;
+    }
+
+    /* Get the current time */
+    Status = NtQuerySystemTime(&Time);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("NtQuerySystemTime failed (Status 0x%08lx)\n", Status);
+        goto done;
+    }
+
+    /* Set the current time */
+    Status = LsapSetObjectAttribute(SecretObject,
+                                    L"CurrentTime",
+                                    &Time,
+                                    sizeof(LARGE_INTEGER));
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapSetObjectAttribute failed (Status 0x%08lx)\n", Status);
+        goto done;
+    }
+
+    if (EncryptedOldValue != NULL)
+    {
+        /* FIXME: Decrypt the old value */
+        OldValue = EncryptedOldValue->Buffer;
+        OldValueLength = EncryptedOldValue->MaximumLength;
+    }
+
+    /* Set the old value */
+    Status = LsapSetObjectAttribute(SecretObject,
+                                    L"OldValue",
+                                    OldValue,
+                                    OldValueLength);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapSetObjectAttribute failed (Status 0x%08lx)\n", Status);
+        goto done;
+    }
+
+    /* Set the old time */
+    Status = LsapSetObjectAttribute(SecretObject,
+                                    L"OldTime",
+                                    &Time,
+                                    sizeof(LARGE_INTEGER));
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapSetObjectAttribute failed (Status 0x%08lx)\n", Status);
+    }
+
+done:
+    return Status;
 }
 
 
 /* Function 30 */
-NTSTATUS LsarQuerySecret(
+NTSTATUS WINAPI LsarQuerySecret(
     LSAPR_HANDLE SecretHandle,
     PLSAPR_CR_CIPHER_VALUE *EncryptedCurrentValue,
     PLARGE_INTEGER CurrentValueSetTime,
     PLSAPR_CR_CIPHER_VALUE *EncryptedOldValue,
     PLARGE_INTEGER OldValueSetTime)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PLSA_DB_OBJECT SecretObject;
+    PLSAPR_CR_CIPHER_VALUE EncCurrentValue = NULL;
+    PLSAPR_CR_CIPHER_VALUE EncOldValue = NULL;
+    PBYTE CurrentValue = NULL;
+    PBYTE OldValue = NULL;
+    ULONG CurrentValueLength = 0;
+    ULONG OldValueLength = 0;
+    ULONG BufferSize;
+    NTSTATUS Status;
+
+    TRACE("LsarQuerySecret(%p %p %p %p %p)\n", SecretHandle,
+          EncryptedCurrentValue, CurrentValueSetTime,
+          EncryptedOldValue, OldValueSetTime);
+
+    /* Validate the SecretHandle */
+    Status = LsapValidateDbObject(SecretHandle,
+                                  LsaDbSecretObject,
+                                  SECRET_QUERY_VALUE,
+                                  &SecretObject);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
+        return Status;
+    }
+
+    if (EncryptedCurrentValue != NULL)
+    {
+        CurrentValueLength = 0;
+
+        /* Get the size of the current value */
+        Status = LsapGetObjectAttribute(SecretObject,
+                                        L"CurrentValue",
+                                        NULL,
+                                        &CurrentValueLength);
+        if (!NT_SUCCESS(Status))
+            goto done;
+
+        /* Allocate a buffer for the current value */
+        CurrentValue = midl_user_allocate(CurrentValueLength);
+        if (CurrentValue == NULL)
+        {
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+            goto done;
+        }
+
+        /* Get the current value */
+        Status = LsapGetObjectAttribute(SecretObject,
+                                        L"CurrentValue",
+                                        CurrentValue,
+                                        &CurrentValueLength);
+        if (!NT_SUCCESS(Status))
+            goto done;
+
+        /* Allocate a buffer for the encrypted current value */
+        EncCurrentValue = midl_user_allocate(sizeof(LSAPR_CR_CIPHER_VALUE));
+        if (EncCurrentValue == NULL)
+        {
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+            goto done;
+        }
+
+        /* FIXME: Encrypt the current value */
+        EncCurrentValue->Length = (USHORT)(CurrentValueLength - sizeof(WCHAR));
+        EncCurrentValue->MaximumLength = (USHORT)CurrentValueLength;
+        EncCurrentValue->Buffer = (PBYTE)CurrentValue;
+    }
+
+    if (CurrentValueSetTime != NULL)
+    {
+        BufferSize = sizeof(LARGE_INTEGER);
+
+        /* Get the current value time */
+        Status = LsapGetObjectAttribute(SecretObject,
+                                        L"CurrentTime",
+                                        (PBYTE)CurrentValueSetTime,
+                                        &BufferSize);
+        if (!NT_SUCCESS(Status))
+            goto done;
+    }
+
+    if (EncryptedOldValue != NULL)
+    {
+        OldValueLength = 0;
+
+        /* Get the size of the old value */
+        Status = LsapGetObjectAttribute(SecretObject,
+                                        L"OldValue",
+                                        NULL,
+                                        &OldValueLength);
+        if (!NT_SUCCESS(Status))
+            goto done;
+
+        /* Allocate a buffer for the old value */
+        OldValue = midl_user_allocate(OldValueLength);
+        if (OldValue == NULL)
+        {
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+            goto done;
+        }
+
+        /* Get the old value */
+        Status = LsapGetObjectAttribute(SecretObject,
+                                        L"OldValue",
+                                        OldValue,
+                                        &OldValueLength);
+        if (!NT_SUCCESS(Status))
+            goto done;
+
+        /* Allocate a buffer for the encrypted old value */
+        EncOldValue = midl_user_allocate(sizeof(LSAPR_CR_CIPHER_VALUE) + OldValueLength);
+        if (EncOldValue == NULL)
+        {
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+            goto done;
+        }
+
+        /* FIXME: Encrypt the old value */
+        EncOldValue->Length = (USHORT)(OldValueLength - sizeof(WCHAR));
+        EncOldValue->MaximumLength = (USHORT)OldValueLength;
+        EncOldValue->Buffer = (PBYTE)OldValue;
+    }
+
+    if (OldValueSetTime != NULL)
+    {
+        BufferSize = sizeof(LARGE_INTEGER);
+
+        /* Get the old value time */
+        Status = LsapGetObjectAttribute(SecretObject,
+                                        L"OldTime",
+                                        (PBYTE)OldValueSetTime,
+                                        &BufferSize);
+        if (!NT_SUCCESS(Status))
+            goto done;
+    }
+
+
+done:
+    if (NT_SUCCESS(Status))
+    {
+        if (EncryptedCurrentValue != NULL)
+            *EncryptedCurrentValue = EncCurrentValue;
+
+        if (EncryptedOldValue != NULL)
+            *EncryptedOldValue = EncOldValue;
+    }
+    else
+    {
+        if (EncryptedCurrentValue != NULL)
+            *EncryptedCurrentValue = NULL;
+
+        if (EncryptedOldValue != NULL)
+            *EncryptedOldValue = NULL;
+
+        if (EncCurrentValue != NULL)
+            midl_user_free(EncCurrentValue);
+
+        if (EncOldValue != NULL)
+            midl_user_free(EncOldValue);
+
+        if (CurrentValue != NULL)
+            midl_user_free(CurrentValue);
+
+        if (OldValue != NULL)
+            midl_user_free(OldValue);
+    }
+
+    TRACE("LsarQuerySecret done (Status 0x%08lx)\n", Status);
+
+    return Status;
 }
 
 
 /* Function 31 */
-NTSTATUS LsarLookupPrivilegeValue(
+NTSTATUS WINAPI LsarLookupPrivilegeValue(
     LSAPR_HANDLE PolicyHandle,
     PRPC_UNICODE_STRING Name,
     PLUID Value)
@@ -564,10 +1576,14 @@ NTSTATUS LsarLookupPrivilegeValue(
     TRACE("LsarLookupPrivilegeValue(%p, %wZ, %p)\n",
           PolicyHandle, Name, Value);
 
-    if (!LsapValidateDbHandle(PolicyHandle, LsaDbPolicyHandle))
+    Status = LsapValidateDbObject(PolicyHandle,
+                                  LsaDbPolicyObject,
+                                  POLICY_LOOKUP_NAMES,
+                                  NULL);
+    if (!NT_SUCCESS(Status))
     {
-        ERR("Invalid handle\n");
-        return STATUS_INVALID_HANDLE;
+        ERR("Invalid handle (Status %lx)\n", Status);
+        return Status;
     }
 
     TRACE("Privilege: %wZ\n", Name);
@@ -580,7 +1596,7 @@ NTSTATUS LsarLookupPrivilegeValue(
 
 
 /* Function 32 */
-NTSTATUS LsarLookupPrivilegeName(
+NTSTATUS WINAPI LsarLookupPrivilegeName(
     LSAPR_HANDLE PolicyHandle,
     PLUID Value,
     PRPC_UNICODE_STRING *Name)
@@ -590,10 +1606,14 @@ NTSTATUS LsarLookupPrivilegeName(
     TRACE("LsarLookupPrivilegeName(%p, %p, %p)\n",
           PolicyHandle, Value, Name);
 
-    if (!LsapValidateDbHandle(PolicyHandle, LsaDbPolicyHandle))
+    Status = LsapValidateDbObject(PolicyHandle,
+                                  LsaDbPolicyObject,
+                                  POLICY_LOOKUP_NAMES,
+                                  NULL);
+    if (!NT_SUCCESS(Status))
     {
         ERR("Invalid handle\n");
-        return STATUS_INVALID_HANDLE;
+        return Status;
     }
 
     Status = LsarpLookupPrivilegeName(Value, (PUNICODE_STRING*)Name);
@@ -603,7 +1623,7 @@ NTSTATUS LsarLookupPrivilegeName(
 
 
 /* Function 33 */
-NTSTATUS LsarLookupPrivilegeDisplayName(
+NTSTATUS WINAPI LsarLookupPrivilegeDisplayName(
     LSAPR_HANDLE PolicyHandle,
     PRPC_UNICODE_STRING Name,
     USHORT ClientLanguage,
@@ -617,7 +1637,7 @@ NTSTATUS LsarLookupPrivilegeDisplayName(
 
 
 /* Function 34 */
-NTSTATUS LsarDeleteObject(
+NTSTATUS WINAPI LsarDeleteObject(
     LSAPR_HANDLE *ObjectHandle)
 {
     UNIMPLEMENTED;
@@ -626,7 +1646,7 @@ NTSTATUS LsarDeleteObject(
 
 
 /* Function 35 */
-NTSTATUS LsarEnumerateAccountsWithUserRight(
+NTSTATUS WINAPI LsarEnumerateAccountsWithUserRight(
     LSAPR_HANDLE PolicyHandle,
     PRPC_UNICODE_STRING UserRight,
     PLSAPR_ACCOUNT_ENUM_BUFFER EnumerationBuffer)
@@ -637,15 +1657,22 @@ NTSTATUS LsarEnumerateAccountsWithUserRight(
 
 
 /* Function 36 */
-NTSTATUS LsarEnmuerateAccountRights(
+NTSTATUS WINAPI LsarEnmuerateAccountRights(
     LSAPR_HANDLE PolicyHandle,
     PRPC_SID AccountSid,
     PLSAPR_USER_RIGHT_SET UserRights)
 {
+    PLSA_DB_OBJECT PolicyObject;
+    NTSTATUS Status;
+
     FIXME("(%p,%p,%p) stub\n", PolicyHandle, AccountSid, UserRights);
 
-    if (!LsapValidateDbHandle(PolicyHandle, LsaDbPolicyHandle))
-        return STATUS_INVALID_HANDLE;
+    Status = LsapValidateDbObject(PolicyHandle,
+                                  LsaDbPolicyObject,
+                                  ACCOUNT_VIEW,
+                                  &PolicyObject);
+    if (!NT_SUCCESS(Status))
+        return Status;
 
     UserRights->Entries = 0;
     UserRights->UserRights = NULL;
@@ -654,7 +1681,7 @@ NTSTATUS LsarEnmuerateAccountRights(
 
 
 /* Function 37 */
-NTSTATUS LsarAddAccountRights(
+NTSTATUS WINAPI LsarAddAccountRights(
     LSAPR_HANDLE PolicyHandle,
     PRPC_SID AccountSid,
     PLSAPR_USER_RIGHT_SET UserRights)
@@ -665,7 +1692,7 @@ NTSTATUS LsarAddAccountRights(
 
 
 /* Function 38 */
-NTSTATUS LsarRemoveAccountRights(
+NTSTATUS WINAPI LsarRemoveAccountRights(
     LSAPR_HANDLE PolicyHandle,
     PRPC_SID AccountSid,
     BOOL AllRights,
@@ -677,7 +1704,7 @@ NTSTATUS LsarRemoveAccountRights(
 
 
 /* Function 39 */
-NTSTATUS LsarQueryTrustedDomainInfo(
+NTSTATUS WINAPI LsarQueryTrustedDomainInfo(
     LSAPR_HANDLE PolicyHandle,
     PRPC_SID TrustedDomainSid,
     TRUSTED_INFORMATION_CLASS InformationClass,
@@ -689,7 +1716,7 @@ NTSTATUS LsarQueryTrustedDomainInfo(
 
 
 /* Function 40 */
-NTSTATUS LsarSetTrustedDomainInfo(
+NTSTATUS WINAPI LsarSetTrustedDomainInfo(
     LSAPR_HANDLE PolicyHandle,
     PRPC_SID TrustedDomainSid,
     TRUSTED_INFORMATION_CLASS InformationClass,
@@ -701,7 +1728,7 @@ NTSTATUS LsarSetTrustedDomainInfo(
 
 
 /* Function 41 */
-NTSTATUS LsarDeleteTrustedDomain(
+NTSTATUS WINAPI LsarDeleteTrustedDomain(
     LSAPR_HANDLE PolicyHandle,
     PRPC_SID TrustedDomainSid)
 {
@@ -711,7 +1738,7 @@ NTSTATUS LsarDeleteTrustedDomain(
 
 
 /* Function 42 */
-NTSTATUS LsarStorePrivateData(
+NTSTATUS WINAPI LsarStorePrivateData(
     LSAPR_HANDLE PolicyHandle,
     PRPC_UNICODE_STRING KeyName,
     PLSAPR_CR_CIPHER_VALUE EncryptedData)
@@ -722,7 +1749,7 @@ NTSTATUS LsarStorePrivateData(
 
 
 /* Function 43 */
-NTSTATUS LsarRetrievePrivateData(
+NTSTATUS WINAPI LsarRetrievePrivateData(
     LSAPR_HANDLE PolicyHandle,
     PRPC_UNICODE_STRING KeyName,
     PLSAPR_CR_CIPHER_VALUE *EncryptedData)
@@ -733,7 +1760,7 @@ NTSTATUS LsarRetrievePrivateData(
 
 
 /* Function 44 */
-NTSTATUS LsarOpenPolicy2(
+NTSTATUS WINAPI LsarOpenPolicy2(
     LPWSTR SystemName,
     PLSAPR_OBJECT_ATTRIBUTES ObjectAttributes,
     ACCESS_MASK DesiredAccess,
@@ -745,7 +1772,7 @@ NTSTATUS LsarOpenPolicy2(
 
 
 /* Function 45 */
-NTSTATUS LsarGetUserName(
+NTSTATUS WINAPI LsarGetUserName(
     LPWSTR SystemName,
     PRPC_UNICODE_STRING *UserName,
     PRPC_UNICODE_STRING *DomainName)
@@ -756,29 +1783,31 @@ NTSTATUS LsarGetUserName(
 
 
 /* Function 46 */
-NTSTATUS LsarQueryInformationPolicy2(
+NTSTATUS WINAPI LsarQueryInformationPolicy2(
     LSAPR_HANDLE PolicyHandle,
     POLICY_INFORMATION_CLASS InformationClass,
-    unsigned long *PolicyInformation)
+    PLSAPR_POLICY_INFORMATION *PolicyInformation)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    return LsarQueryInformationPolicy(PolicyHandle,
+                                      InformationClass,
+                                      PolicyInformation);
 }
 
 
 /* Function 47 */
-NTSTATUS LsarSetInformationPolicy2(
+NTSTATUS WINAPI LsarSetInformationPolicy2(
     LSAPR_HANDLE PolicyHandle,
     POLICY_INFORMATION_CLASS InformationClass,
-    unsigned long PolicyInformation)
+    PLSAPR_POLICY_INFORMATION PolicyInformation)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    return LsarSetInformationPolicy(PolicyHandle,
+                                    InformationClass,
+                                    PolicyInformation);
 }
 
 
 /* Function 48 */
-NTSTATUS LsarQueryTrustedDomainInfoByName(
+NTSTATUS WINAPI LsarQueryTrustedDomainInfoByName(
     LSAPR_HANDLE PolicyHandle,
     PRPC_UNICODE_STRING TrustedDomainName,
     POLICY_INFORMATION_CLASS InformationClass,
@@ -790,7 +1819,7 @@ NTSTATUS LsarQueryTrustedDomainInfoByName(
 
 
 /* Function 49 */
-NTSTATUS LsarSetTrustedDomainInfoByName(
+NTSTATUS WINAPI LsarSetTrustedDomainInfoByName(
     LSAPR_HANDLE PolicyHandle,
     PRPC_UNICODE_STRING TrustedDomainName,
     POLICY_INFORMATION_CLASS InformationClass,
@@ -802,7 +1831,7 @@ NTSTATUS LsarSetTrustedDomainInfoByName(
 
 
 /* Function 50 */
-NTSTATUS LsarEnumerateTrustedDomainsEx(
+NTSTATUS WINAPI LsarEnumerateTrustedDomainsEx(
     LSAPR_HANDLE PolicyHandle,
     DWORD *EnumerationContext,
     PLSAPR_TRUSTED_ENUM_BUFFER_EX EnumerationBuffer,
@@ -814,7 +1843,7 @@ NTSTATUS LsarEnumerateTrustedDomainsEx(
 
 
 /* Function 51 */
-NTSTATUS LsarCreateTrustedDomainEx(
+NTSTATUS WINAPI LsarCreateTrustedDomainEx(
     LSAPR_HANDLE PolicyHandle,
     PLSAPR_TRUSTED_DOMAIN_INFORMATION_EX TrustedDomainInformation,
     PLSAPR_TRUSTED_DOMAIN_AUTH_INFORMATION AuthentificationInformation,
@@ -827,7 +1856,7 @@ NTSTATUS LsarCreateTrustedDomainEx(
 
 
 /* Function 52 */
-NTSTATUS LsarSetPolicyReplicationHandle(
+NTSTATUS WINAPI LsarSetPolicyReplicationHandle(
     PLSAPR_HANDLE PolicyHandle)
 {
     /* Deprecated */
@@ -836,7 +1865,7 @@ NTSTATUS LsarSetPolicyReplicationHandle(
 
 
 /* Function 53 */
-NTSTATUS LsarQueryDomainInformationPolicy(
+NTSTATUS WINAPI LsarQueryDomainInformationPolicy(
     LSAPR_HANDLE PolicyHandle,
     POLICY_INFORMATION_CLASS InformationClass,
     unsigned long *PolicyInformation)
@@ -847,7 +1876,7 @@ NTSTATUS LsarQueryDomainInformationPolicy(
 
 
 /* Function 54 */
-NTSTATUS LsarSetDomainInformationPolicy(
+NTSTATUS WINAPI LsarSetDomainInformationPolicy(
     LSAPR_HANDLE PolicyHandle,
     POLICY_INFORMATION_CLASS InformationClass,
     unsigned long PolicyInformation)
@@ -858,7 +1887,7 @@ NTSTATUS LsarSetDomainInformationPolicy(
 
 
 /* Function 55 */
-NTSTATUS LsarOpenTrustedDomainByName(
+NTSTATUS WINAPI LsarOpenTrustedDomainByName(
     LSAPR_HANDLE PolicyHandle,
     PRPC_UNICODE_STRING TrustedDomainName,
     ACCESS_MASK DesiredAccess,
@@ -870,7 +1899,7 @@ NTSTATUS LsarOpenTrustedDomainByName(
 
 
 /* Function 56 */
-NTSTATUS LsarTestCall(
+NTSTATUS WINAPI LsarTestCall(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -879,7 +1908,7 @@ NTSTATUS LsarTestCall(
 
 
 /* Function 57 */
-NTSTATUS LsarLookupSids2(
+NTSTATUS WINAPI LsarLookupSids2(
     LSAPR_HANDLE PolicyHandle,
     PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
     PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
@@ -895,12 +1924,12 @@ NTSTATUS LsarLookupSids2(
 
 
 /* Function 58 */
-NTSTATUS LsarLookupNames2(
+NTSTATUS WINAPI LsarLookupNames2(
     LSAPR_HANDLE PolicyHandle,
     DWORD Count,
     PRPC_UNICODE_STRING Names,
     PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
-    PLSAPR_TRANSLATED_SID_EX TranslatedSids,
+    PLSAPR_TRANSLATED_SIDS_EX TranslatedSids,
     LSAP_LOOKUP_LEVEL LookupLevel,
     DWORD *MappedCount,
     DWORD LookupOptions,
@@ -912,7 +1941,7 @@ NTSTATUS LsarLookupNames2(
 
 
 /* Function 59 */
-NTSTATUS LsarCreateTrustedDomainEx2(
+NTSTATUS WINAPI LsarCreateTrustedDomainEx2(
     LSAPR_HANDLE PolicyHandle,
     PLSAPR_TRUSTED_DOMAIN_INFORMATION_EX TrustedDomainInformation,
     PLSAPR_TRUSTED_DOMAIN_AUTH_INFORMATION_INTERNAL AuthentificationInformation,
@@ -925,7 +1954,7 @@ NTSTATUS LsarCreateTrustedDomainEx2(
 
 
 /* Function 60 */
-NTSTATUS CredrWrite(
+NTSTATUS WINAPI CredrWrite(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -934,7 +1963,7 @@ NTSTATUS CredrWrite(
 
 
 /* Function 61 */
-NTSTATUS CredrRead(
+NTSTATUS WINAPI CredrRead(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -943,7 +1972,7 @@ NTSTATUS CredrRead(
 
 
 /* Function 62 */
-NTSTATUS CredrEnumerate(
+NTSTATUS WINAPI CredrEnumerate(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -952,7 +1981,7 @@ NTSTATUS CredrEnumerate(
 
 
 /* Function 63 */
-NTSTATUS CredrWriteDomainCredentials(
+NTSTATUS WINAPI CredrWriteDomainCredentials(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -961,7 +1990,7 @@ NTSTATUS CredrWriteDomainCredentials(
 
 
 /* Function 64 */
-NTSTATUS CredrReadDomainCredentials(
+NTSTATUS WINAPI CredrReadDomainCredentials(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -970,7 +1999,7 @@ NTSTATUS CredrReadDomainCredentials(
 
 
 /* Function 65 */
-NTSTATUS CredrDelete(
+NTSTATUS WINAPI CredrDelete(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -979,7 +2008,7 @@ NTSTATUS CredrDelete(
 
 
 /* Function 66 */
-NTSTATUS CredrGetTargetInfo(
+NTSTATUS WINAPI CredrGetTargetInfo(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -988,7 +2017,7 @@ NTSTATUS CredrGetTargetInfo(
 
 
 /* Function 67 */
-NTSTATUS CredrProfileLoaded(
+NTSTATUS WINAPI CredrProfileLoaded(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -997,24 +2026,142 @@ NTSTATUS CredrProfileLoaded(
 
 
 /* Function 68 */
-NTSTATUS LsarLookupNames3(
+NTSTATUS WINAPI LsarLookupNames3(
     LSAPR_HANDLE PolicyHandle,
     DWORD Count,
     PRPC_UNICODE_STRING Names,
     PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
-    PLSAPR_TRANSLATED_SID_EX2 TranslatedSids,
+    PLSAPR_TRANSLATED_SIDS_EX2 TranslatedSids,
     LSAP_LOOKUP_LEVEL LookupLevel,
     DWORD *MappedCount,
     DWORD LookupOptions,
     DWORD ClientRevision)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    SID_IDENTIFIER_AUTHORITY IdentifierAuthority = {SECURITY_NT_AUTHORITY};
+    static const UNICODE_STRING DomainName = RTL_CONSTANT_STRING(L"DOMAIN");
+    PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer = NULL;
+    PLSAPR_TRANSLATED_SID_EX2 SidsBuffer = NULL;
+    ULONG SidsBufferLength;
+    ULONG DomainSidLength;
+    ULONG AccountSidLength;
+    PSID DomainSid;
+    PSID AccountSid;
+    ULONG i;
+    NTSTATUS Status;
+
+    TRACE("LsarLookupNames3(%p, %lu, %p, %p, %p, %d, %p, %lu, %lu)\n",
+          PolicyHandle, Count, Names, ReferencedDomains, TranslatedSids,
+          LookupLevel, MappedCount, LookupOptions, ClientRevision);
+
+    if (Count == 0)
+        return STATUS_NONE_MAPPED;
+
+    TranslatedSids->Entries = Count;
+    TranslatedSids->Sids = NULL;
+    *ReferencedDomains = NULL;
+
+    SidsBufferLength = Count * sizeof(LSAPR_TRANSLATED_SID_EX2);
+    SidsBuffer = MIDL_user_allocate(SidsBufferLength);
+    if (SidsBuffer == NULL)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    for (i = 0; i < Count; i++)
+    {
+        SidsBuffer[i].Use = SidTypeUser;
+        SidsBuffer[i].Sid = NULL;
+        SidsBuffer[i].DomainIndex = -1;
+        SidsBuffer[i].Flags = 0;
+    }
+
+    DomainsBuffer = MIDL_user_allocate(sizeof(LSAPR_REFERENCED_DOMAIN_LIST));
+    if (DomainsBuffer == NULL)
+    {
+        MIDL_user_free(SidsBuffer);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    DomainsBuffer->Entries = Count;
+    DomainsBuffer->Domains = MIDL_user_allocate(Count * sizeof(LSA_TRUST_INFORMATION));
+    if (DomainsBuffer->Domains == NULL)
+    {
+        MIDL_user_free(DomainsBuffer);
+        MIDL_user_free(SidsBuffer);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    Status = RtlAllocateAndInitializeSid(&IdentifierAuthority,
+                                         2,
+                                         SECURITY_BUILTIN_DOMAIN_RID,
+                                         DOMAIN_ALIAS_RID_ADMINS,
+                                         0, 0, 0, 0, 0, 0,
+                                         &DomainSid);
+    if (!NT_SUCCESS(Status))
+    {
+        MIDL_user_free(DomainsBuffer->Domains);
+        MIDL_user_free(DomainsBuffer);
+        MIDL_user_free(SidsBuffer);
+        return Status;
+    }
+
+    DomainSidLength = RtlLengthSid(DomainSid);
+
+    for (i = 0; i < Count; i++)
+    {
+        DomainsBuffer->Domains[i].Sid = MIDL_user_allocate(DomainSidLength);
+        RtlCopyMemory(DomainsBuffer->Domains[i].Sid,
+                      DomainSid,
+                      DomainSidLength);
+
+        DomainsBuffer->Domains[i].Name.Buffer = MIDL_user_allocate(DomainName.MaximumLength);
+        DomainsBuffer->Domains[i].Name.Length = DomainName.Length;
+        DomainsBuffer->Domains[i].Name.MaximumLength = DomainName.MaximumLength;
+        RtlCopyMemory(DomainsBuffer->Domains[i].Name.Buffer,
+                      DomainName.Buffer,
+                      DomainName.MaximumLength);
+    }
+
+    Status = RtlAllocateAndInitializeSid(&IdentifierAuthority,
+                                         3,
+                                         SECURITY_BUILTIN_DOMAIN_RID,
+                                         DOMAIN_ALIAS_RID_ADMINS,
+                                         DOMAIN_USER_RID_ADMIN,
+                                         0, 0, 0, 0, 0,
+                                         &AccountSid);
+    if (!NT_SUCCESS(Status))
+    {
+        MIDL_user_free(DomainsBuffer->Domains);
+        MIDL_user_free(DomainsBuffer);
+        MIDL_user_free(SidsBuffer);
+        return Status;
+    }
+
+    AccountSidLength = RtlLengthSid(AccountSid);
+
+    for (i = 0; i < Count; i++)
+    {
+        SidsBuffer[i].Use = SidTypeWellKnownGroup;
+        SidsBuffer[i].Sid = MIDL_user_allocate(AccountSidLength);
+
+        RtlCopyMemory(SidsBuffer[i].Sid,
+                      AccountSid,
+                      AccountSidLength);
+
+        SidsBuffer[i].DomainIndex = i;
+        SidsBuffer[i].Flags = 0;
+    }
+
+    *ReferencedDomains = DomainsBuffer;
+    *MappedCount = Count;
+
+    TranslatedSids->Entries = Count;
+    TranslatedSids->Sids = SidsBuffer;
+
+    return STATUS_SUCCESS;
 }
 
 
 /* Function 69 */
-NTSTATUS CredrGetSessionTypes(
+NTSTATUS WINAPI CredrGetSessionTypes(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -1023,7 +2170,7 @@ NTSTATUS CredrGetSessionTypes(
 
 
 /* Function 70 */
-NTSTATUS LsarRegisterAuditEvent(
+NTSTATUS WINAPI LsarRegisterAuditEvent(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -1032,7 +2179,7 @@ NTSTATUS LsarRegisterAuditEvent(
 
 
 /* Function 71 */
-NTSTATUS LsarGenAuditEvent(
+NTSTATUS WINAPI LsarGenAuditEvent(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -1041,7 +2188,7 @@ NTSTATUS LsarGenAuditEvent(
 
 
 /* Function 72 */
-NTSTATUS LsarUnregisterAuditEvent(
+NTSTATUS WINAPI LsarUnregisterAuditEvent(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -1050,7 +2197,7 @@ NTSTATUS LsarUnregisterAuditEvent(
 
 
 /* Function 73 */
-NTSTATUS LsarQueryForestTrustInformation(
+NTSTATUS WINAPI LsarQueryForestTrustInformation(
     LSAPR_HANDLE PolicyHandle,
     PLSA_UNICODE_STRING TrustedDomainName,
     LSA_FOREST_TRUST_RECORD_TYPE HighestRecordType,
@@ -1062,7 +2209,7 @@ NTSTATUS LsarQueryForestTrustInformation(
 
 
 /* Function 74 */
-NTSTATUS LsarSetForestTrustInformation(
+NTSTATUS WINAPI LsarSetForestTrustInformation(
     LSAPR_HANDLE PolicyHandle,
     PLSA_UNICODE_STRING TrustedDomainName,
     LSA_FOREST_TRUST_RECORD_TYPE HighestRecordType,
@@ -1076,7 +2223,7 @@ NTSTATUS LsarSetForestTrustInformation(
 
 
 /* Function 75 */
-NTSTATUS CredrRename(
+NTSTATUS WINAPI CredrRename(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -1085,7 +2232,7 @@ NTSTATUS CredrRename(
 
 
 /* Function 76 */
-NTSTATUS LsarLookupSids3(
+NTSTATUS WINAPI LsarLookupSids3(
     LSAPR_HANDLE PolicyHandle,
     PLSAPR_SID_ENUM_BUFFER SidEnumBuffer,
     PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
@@ -1101,12 +2248,12 @@ NTSTATUS LsarLookupSids3(
 
 
 /* Function 77 */
-NTSTATUS LsarLookupNames4(
+NTSTATUS WINAPI LsarLookupNames4(
     handle_t RpcHandle,
     DWORD Count,
     PRPC_UNICODE_STRING Names,
     PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
-    PLSAPR_TRANSLATED_SID_EX2 TranslatedSids,
+    PLSAPR_TRANSLATED_SIDS_EX2 TranslatedSids,
     LSAP_LOOKUP_LEVEL LookupLevel,
     DWORD *MappedCount,
     DWORD LookupOptions,
@@ -1118,7 +2265,7 @@ NTSTATUS LsarLookupNames4(
 
 
 /* Function 78 */
-NTSTATUS LsarOpenPolicySce(
+NTSTATUS WINAPI LsarOpenPolicySce(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -1127,7 +2274,7 @@ NTSTATUS LsarOpenPolicySce(
 
 
 /* Function 79 */
-NTSTATUS LsarAdtRegisterSecurityEventSource(
+NTSTATUS WINAPI LsarAdtRegisterSecurityEventSource(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -1136,7 +2283,7 @@ NTSTATUS LsarAdtRegisterSecurityEventSource(
 
 
 /* Function 80 */
-NTSTATUS LsarAdtUnregisterSecurityEventSource(
+NTSTATUS WINAPI LsarAdtUnregisterSecurityEventSource(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -1145,7 +2292,7 @@ NTSTATUS LsarAdtUnregisterSecurityEventSource(
 
 
 /* Function 81 */
-NTSTATUS LsarAdtReportSecurityEvent(
+NTSTATUS WINAPI LsarAdtReportSecurityEvent(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -1154,7 +2301,7 @@ NTSTATUS LsarAdtReportSecurityEvent(
 
 
 /* Function 82 */
-NTSTATUS CredrFindBestCredential(
+NTSTATUS WINAPI CredrFindBestCredential(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -1163,7 +2310,7 @@ NTSTATUS CredrFindBestCredential(
 
 
 /* Function 83 */
-NTSTATUS LsarSetAuditPolicy(
+NTSTATUS WINAPI LsarSetAuditPolicy(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -1172,7 +2319,7 @@ NTSTATUS LsarSetAuditPolicy(
 
 
 /* Function 84 */
-NTSTATUS LsarQueryAuditPolicy(
+NTSTATUS WINAPI LsarQueryAuditPolicy(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -1181,7 +2328,7 @@ NTSTATUS LsarQueryAuditPolicy(
 
 
 /* Function 85 */
-NTSTATUS LsarEnumerateAuditPolicy(
+NTSTATUS WINAPI LsarEnumerateAuditPolicy(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -1190,7 +2337,7 @@ NTSTATUS LsarEnumerateAuditPolicy(
 
 
 /* Function 86 */
-NTSTATUS LsarEnumerateAuditCategories(
+NTSTATUS WINAPI LsarEnumerateAuditCategories(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -1199,7 +2346,7 @@ NTSTATUS LsarEnumerateAuditCategories(
 
 
 /* Function 87 */
-NTSTATUS LsarEnumerateAuditSubCategories(
+NTSTATUS WINAPI LsarEnumerateAuditSubCategories(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -1208,7 +2355,7 @@ NTSTATUS LsarEnumerateAuditSubCategories(
 
 
 /* Function 88 */
-NTSTATUS LsarLookupAuditCategoryName(
+NTSTATUS WINAPI LsarLookupAuditCategoryName(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -1217,7 +2364,7 @@ NTSTATUS LsarLookupAuditCategoryName(
 
 
 /* Function 89 */
-NTSTATUS LsarLookupAuditSubCategoryName(
+NTSTATUS WINAPI LsarLookupAuditSubCategoryName(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -1226,7 +2373,7 @@ NTSTATUS LsarLookupAuditSubCategoryName(
 
 
 /* Function 90 */
-NTSTATUS LsarSetAuditSecurity(
+NTSTATUS WINAPI LsarSetAuditSecurity(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -1235,7 +2382,7 @@ NTSTATUS LsarSetAuditSecurity(
 
 
 /* Function 91 */
-NTSTATUS LsarQueryAuditSecurity(
+NTSTATUS WINAPI LsarQueryAuditSecurity(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -1244,7 +2391,7 @@ NTSTATUS LsarQueryAuditSecurity(
 
 
 /* Function 92 */
-NTSTATUS CredReadByTokenHandle(
+NTSTATUS WINAPI CredReadByTokenHandle(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -1253,7 +2400,7 @@ NTSTATUS CredReadByTokenHandle(
 
 
 /* Function 93 */
-NTSTATUS CredrRestoreCredentials(
+NTSTATUS WINAPI CredrRestoreCredentials(
     handle_t hBinding)
 {
     UNIMPLEMENTED;
@@ -1262,7 +2409,7 @@ NTSTATUS CredrRestoreCredentials(
 
 
 /* Function 94 */
-NTSTATUS CredrBackupCredentials(
+NTSTATUS WINAPI CredrBackupCredentials(
     handle_t hBinding)
 {
     UNIMPLEMENTED;