[LSASRV]
[reactos.git] / reactos / dll / win32 / lsasrv / lsarpc.c
index 9ec67ee..0f6aef2 100644 (file)
@@ -97,8 +97,7 @@ NTSTATUS WINAPI LsarClose(
 NTSTATUS WINAPI LsarDelete(
     LSAPR_HANDLE ObjectHandle)
 {
-    /* Deprecated */
-    return STATUS_NOT_SUPPORTED;
+    return LsarDeleteObject(&ObjectHandle);
 }
 
 
@@ -109,8 +108,26 @@ NTSTATUS WINAPI LsarEnumeratePrivileges(
     PLSAPR_PRIVILEGE_ENUM_BUFFER EnumerationBuffer,
     DWORD PreferedMaximumLength)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PLSA_DB_OBJECT PolicyObject;
+    NTSTATUS Status;
+
+    TRACE("LsarEnumeratePrivileges(%p %p %p %lu)\n",
+          PolicyHandle, EnumerationContext, EnumerationBuffer,
+          PreferedMaximumLength);
+
+    Status = LsapValidateDbObject(PolicyHandle,
+                                  LsaDbPolicyObject,
+                                  POLICY_VIEW_LOCAL_INFORMATION,
+                                  &PolicyObject);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    if (EnumerationContext == NULL)
+        return STATUS_INVALID_PARAMETER;
+
+    return LsarpEnumeratePrivileges(EnumerationContext,
+                                    EnumerationBuffer,
+                                    PreferedMaximumLength);
 }
 
 
@@ -120,8 +137,80 @@ NTSTATUS WINAPI LsarQuerySecurityObject(
     SECURITY_INFORMATION SecurityInformation,
     PLSAPR_SR_SECURITY_DESCRIPTOR *SecurityDescriptor)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PLSA_DB_OBJECT DbObject = NULL;
+    PSECURITY_DESCRIPTOR RelativeSd = NULL;
+    PLSAPR_SR_SECURITY_DESCRIPTOR SdData = NULL;
+    ACCESS_MASK DesiredAccess = 0;
+    ULONG RelativeSdSize = 0;
+    NTSTATUS Status;
+
+    if (SecurityDescriptor == NULL)
+        return STATUS_INVALID_PARAMETER;
+
+    if ((SecurityInformation & OWNER_SECURITY_INFORMATION) ||
+        (SecurityInformation & GROUP_SECURITY_INFORMATION) ||
+        (SecurityInformation & DACL_SECURITY_INFORMATION))
+        DesiredAccess |= READ_CONTROL;
+
+    if (SecurityInformation & SACL_SECURITY_INFORMATION)
+        DesiredAccess |= ACCESS_SYSTEM_SECURITY;
+
+    /* Validate the ObjectHandle */
+    Status = LsapValidateDbObject(ObjectHandle,
+                                  LsaDbIgnoreObject,
+                                  DesiredAccess,
+                                  &DbObject);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    /* Get the size of the SD */
+    Status = LsapGetObjectAttribute(DbObject,
+                                    L"SecDesc",
+                                    NULL,
+                                    &RelativeSdSize);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    /* Allocate a buffer for the SD */
+    RelativeSd = MIDL_user_allocate(RelativeSdSize);
+    if (RelativeSd == NULL)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    /* Get the SD */
+    Status = LsapGetObjectAttribute(DbObject,
+                                    L"SecDesc",
+                                    RelativeSd,
+                                    &RelativeSdSize);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    /*
+     * FIXME: Invalidate the SD information that was not requested.
+     *        (see SecurityInformation)
+     */
+
+    /* Allocate the SD data buffer */
+    SdData = MIDL_user_allocate(sizeof(LSAPR_SR_SECURITY_DESCRIPTOR));
+    if (SdData == NULL)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto done;
+    }
+
+    /* Fill the SD data buffer and return it to the caller */
+    SdData->Length = RelativeSdSize;
+    SdData->SecurityDescriptor = (PBYTE)RelativeSd;
+
+    *SecurityDescriptor = SdData;
+
+done:
+    if (!NT_SUCCESS(Status))
+    {
+        if (RelativeSd != NULL)
+            MIDL_user_free(RelativeSd);
+    }
+
+    return Status;
 }
 
 
@@ -165,9 +254,11 @@ NTSTATUS WINAPI LsarOpenPolicy(
     RtlEnterCriticalSection(&PolicyHandleTableLock);
 
     Status = LsapOpenDbObject(NULL,
+                              NULL,
                               L"Policy",
                               LsaDbPolicyObject,
                               DesiredAccess,
+                              FALSE,
                               &PolicyObject);
 
     RtlLeaveCriticalSection(&PolicyHandleTableLock);
@@ -187,7 +278,7 @@ NTSTATUS WINAPI LsarQueryInformationPolicy(
     POLICY_INFORMATION_CLASS InformationClass,
     PLSAPR_POLICY_INFORMATION *PolicyInformation)
 {
-    PLSA_DB_OBJECT DbObject;
+    PLSA_DB_OBJECT PolicyObject;
     ACCESS_MASK DesiredAccess = 0;
     NTSTATUS Status;
 
@@ -212,6 +303,7 @@ NTSTATUS WINAPI LsarQueryInformationPolicy(
         case PolicyLsaServerRoleInformation:
         case PolicyReplicaSourceInformation:
         case PolicyDefaultQuotaInformation:
+        case PolicyModificationInformation:
         case PolicyDnsDomainInformation:
         case PolicyDnsDomainInformationInt:
         case PolicyLocalAccountDomainInformation:
@@ -230,71 +322,74 @@ NTSTATUS WINAPI LsarQueryInformationPolicy(
     Status = LsapValidateDbObject(PolicyHandle,
                                   LsaDbPolicyObject,
                                   DesiredAccess,
-                                  &DbObject);
+                                  &PolicyObject);
     if (!NT_SUCCESS(Status))
         return Status;
 
     switch (InformationClass)
     {
         case PolicyAuditLogInformation:      /* 1 */
-            Status = LsarQueryAuditLog(PolicyHandle,
+            Status = LsarQueryAuditLog(PolicyObject,
                                        PolicyInformation);
+            break;
 
         case PolicyAuditEventsInformation:   /* 2 */
-            Status = LsarQueryAuditEvents(PolicyHandle,
+            Status = LsarQueryAuditEvents(PolicyObject,
                                           PolicyInformation);
             break;
 
         case PolicyPrimaryDomainInformation: /* 3 */
-            Status = LsarQueryPrimaryDomain(PolicyHandle,
+            Status = LsarQueryPrimaryDomain(PolicyObject,
                                             PolicyInformation);
             break;
 
         case PolicyPdAccountInformation:     /* 4 */
-            Status = LsarQueryPdAccount(PolicyHandle,
+            Status = LsarQueryPdAccount(PolicyObject,
                                         PolicyInformation);
+            break;
 
         case PolicyAccountDomainInformation: /* 5 */
-            Status = LsarQueryAccountDomain(PolicyHandle,
+            Status = LsarQueryAccountDomain(PolicyObject,
                                             PolicyInformation);
             break;
 
         case PolicyLsaServerRoleInformation: /* 6 */
-            Status = LsarQueryServerRole(PolicyHandle,
+            Status = LsarQueryServerRole(PolicyObject,
                                          PolicyInformation);
             break;
 
         case PolicyReplicaSourceInformation: /* 7 */
-            Status = LsarQueryReplicaSource(PolicyHandle,
+            Status = LsarQueryReplicaSource(PolicyObject,
                                             PolicyInformation);
+            break;
 
         case PolicyDefaultQuotaInformation:  /* 8 */
-            Status = LsarQueryDefaultQuota(PolicyHandle,
+            Status = LsarQueryDefaultQuota(PolicyObject,
                                            PolicyInformation);
             break;
 
         case PolicyModificationInformation:  /* 9 */
-            Status = LsarQueryModification(PolicyHandle,
+            Status = LsarQueryModification(PolicyObject,
                                            PolicyInformation);
             break;
 
         case PolicyAuditFullQueryInformation: /* 11 (0xB) */
-            Status = LsarQueryAuditFull(PolicyHandle,
+            Status = LsarQueryAuditFull(PolicyObject,
                                         PolicyInformation);
             break;
 
         case PolicyDnsDomainInformation:      /* 12 (0xC) */
-            Status = LsarQueryDnsDomain(PolicyHandle,
+            Status = LsarQueryDnsDomain(PolicyObject,
                                         PolicyInformation);
             break;
 
         case PolicyDnsDomainInformationInt:   /* 13 (0xD) */
-            Status = LsarQueryDnsDomainInt(PolicyHandle,
+            Status = LsarQueryDnsDomainInt(PolicyObject,
                                            PolicyInformation);
             break;
 
         case PolicyLocalAccountDomainInformation: /* 14 (0xE) */
-            Status = LsarQueryLocalAccountDomain(PolicyHandle,
+            Status = LsarQueryLocalAccountDomain(PolicyObject,
                                                  PolicyInformation);
             break;
 
@@ -313,7 +408,7 @@ NTSTATUS WINAPI LsarSetInformationPolicy(
     POLICY_INFORMATION_CLASS InformationClass,
     PLSAPR_POLICY_INFORMATION PolicyInformation)
 {
-    PLSA_DB_OBJECT DbObject;
+    PLSA_DB_OBJECT PolicyObject;
     ACCESS_MASK DesiredAccess = 0;
     NTSTATUS Status;
 
@@ -361,33 +456,70 @@ NTSTATUS WINAPI LsarSetInformationPolicy(
     Status = LsapValidateDbObject(PolicyHandle,
                                   LsaDbPolicyObject,
                                   DesiredAccess,
-                                  &DbObject);
+                                  &PolicyObject);
     if (!NT_SUCCESS(Status))
         return Status;
 
     switch (InformationClass)
     {
-        case PolicyAuditEventsInformation:
-            Status = STATUS_NOT_IMPLEMENTED;
+        case PolicyAuditLogInformation:      /* 1 */
+            Status = LsarSetAuditLog(PolicyObject,
+                                     (PPOLICY_AUDIT_LOG_INFO)PolicyInformation);
             break;
 
-        case PolicyPrimaryDomainInformation:
-            Status = LsarSetPrimaryDomain(PolicyHandle,
+        case PolicyAuditEventsInformation:   /* 2 */
+            Status = LsarSetAuditEvents(PolicyObject,
+                                        (PLSAPR_POLICY_AUDIT_EVENTS_INFO)PolicyInformation);
+            break;
+
+        case PolicyPrimaryDomainInformation: /* 3 */
+            Status = LsarSetPrimaryDomain(PolicyObject,
                                           (PLSAPR_POLICY_PRIMARY_DOM_INFO)PolicyInformation);
             break;
 
-        case PolicyAccountDomainInformation:
-            Status = LsarSetAccountDomain(PolicyHandle,
+        case PolicyAccountDomainInformation: /* 5 */
+            Status = LsarSetAccountDomain(PolicyObject,
                                           (PLSAPR_POLICY_ACCOUNT_DOM_INFO)PolicyInformation);
             break;
 
-        case PolicyDnsDomainInformation:
-            Status = LsarSetDnsDomain(PolicyHandle,
+        case PolicyLsaServerRoleInformation: /* 6 */
+            Status = LsarSetServerRole(PolicyObject,
+                                       (PPOLICY_LSA_SERVER_ROLE_INFO)PolicyInformation);
+            break;
+
+        case PolicyReplicaSourceInformation: /* 7 */
+            Status = LsarSetReplicaSource(PolicyObject,
+                                          (PPOLICY_LSA_REPLICA_SRCE_INFO)PolicyInformation);
+            break;
+
+        case PolicyDefaultQuotaInformation:  /* 8 */
+            Status = LsarSetDefaultQuota(PolicyObject,
+                                         (PPOLICY_DEFAULT_QUOTA_INFO)PolicyInformation);
+            break;
+
+        case PolicyModificationInformation:  /* 9 */
+            Status = LsarSetModification(PolicyObject,
+                                         (PPOLICY_MODIFICATION_INFO)PolicyInformation);
+            break;
+
+        case PolicyAuditFullSetInformation:  /* 10 (0xA) */
+            Status = LsarSetAuditFull(PolicyObject,
+                                      (PPOLICY_AUDIT_FULL_QUERY_INFO)PolicyInformation);
+            break;
+
+        case PolicyDnsDomainInformation:      /* 12 (0xC) */
+            Status = LsarSetDnsDomain(PolicyObject,
                                       (PLSAPR_POLICY_DNS_DOMAIN_INFO)PolicyInformation);
             break;
 
-        case PolicyLsaServerRoleInformation:
-            Status = STATUS_NOT_IMPLEMENTED;
+        case PolicyDnsDomainInformationInt:   /* 13 (0xD) */
+            Status = LsarSetDnsDomainInt(PolicyObject,
+                                         (PLSAPR_POLICY_DNS_DOMAIN_INFO)PolicyInformation);
+            break;
+
+        case PolicyLocalAccountDomainInformation: /* 14 (0xE) */
+            Status = LsarSetLocalAccountDomain(PolicyObject,
+                                               (PLSAPR_POLICY_ACCOUNT_DOM_INFO)PolicyInformation);
             break;
 
         default:
@@ -416,11 +548,16 @@ NTSTATUS WINAPI LsarCreateAccount(
     LSAPR_HANDLE *AccountHandle)
 {
     PLSA_DB_OBJECT PolicyObject;
-    PLSA_DB_OBJECT AccountsObject = NULL;
     PLSA_DB_OBJECT AccountObject = NULL;
     LPWSTR SidString = NULL;
+    PSECURITY_DESCRIPTOR AccountSd = NULL;
+    ULONG AccountSdSize;
     NTSTATUS Status = STATUS_SUCCESS;
 
+    /* Validate the AccountSid */
+    if (!RtlValidSid(AccountSid))
+        return STATUS_INVALID_PARAMETER;
+
     /* Validate the PolicyHandle */
     Status = LsapValidateDbObject(PolicyHandle,
                                   LsaDbPolicyObject,
@@ -432,18 +569,6 @@ NTSTATUS WINAPI LsarCreateAccount(
         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))
@@ -453,15 +578,26 @@ NTSTATUS WINAPI LsarCreateAccount(
         goto done;
     }
 
+    /* Create a security descriptor for the account */
+    Status = LsapCreateAccountSd(&AccountSd,
+                                 &AccountSdSize);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapCreateAccountSd returned 0x%08lx\n", Status);
+        return Status;
+    }
+
     /* Create the Account object */
-    Status = LsapCreateDbObject(AccountsObject,
+    Status = LsapCreateDbObject(PolicyObject,
+                                L"Accounts",
                                 SidString,
                                 LsaDbAccountObject,
                                 DesiredAccess,
+                                PolicyObject->Trusted,
                                 &AccountObject);
     if (!NT_SUCCESS(Status))
     {
-        ERR("LsapCreateDbObject (Account) failed (Status 0x%08lx)\n", Status);
+        ERR("LsapCreateDbObject failed (Status 0x%08lx)\n", Status);
         goto done;
     }
 
@@ -470,11 +606,22 @@ NTSTATUS WINAPI LsarCreateAccount(
                                     L"Sid",
                                     (PVOID)AccountSid,
                                     GetLengthSid(AccountSid));
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    /* Set the SecDesc attribute */
+    Status = LsapSetObjectAttribute(AccountObject,
+                                    L"SecDesc",
+                                    AccountSd,
+                                    AccountSdSize);
 
 done:
     if (SidString != NULL)
         LocalFree(SidString);
 
+    if (AccountSd != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, AccountSd);
+
     if (!NT_SUCCESS(Status))
     {
         if (AccountObject != NULL)
@@ -485,9 +632,6 @@ done:
         *AccountHandle = (LSAPR_HANDLE)AccountObject;
     }
 
-    if (AccountsObject != NULL)
-        LsapCloseDbObject(AccountsObject);
-
     return STATUS_SUCCESS;
 }
 
@@ -499,8 +643,203 @@ NTSTATUS WINAPI LsarEnumerateAccounts(
     PLSAPR_ACCOUNT_ENUM_BUFFER EnumerationBuffer,
     DWORD PreferedMaximumLength)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    LSAPR_ACCOUNT_ENUM_BUFFER EnumBuffer = {0, NULL};
+    PLSA_DB_OBJECT PolicyObject = NULL;
+    WCHAR AccountKeyName[64];
+    HANDLE AccountsKeyHandle = NULL;
+    HANDLE AccountKeyHandle;
+    HANDLE SidKeyHandle;
+    ULONG EnumIndex;
+    ULONG EnumCount;
+    ULONG RequiredLength;
+    ULONG DataLength;
+    ULONG i;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    TRACE("(%p %p %p %lu)\n", PolicyHandle, EnumerationContext,
+          EnumerationBuffer, PreferedMaximumLength);
+
+    if (EnumerationContext == NULL ||
+        EnumerationBuffer == NULL)
+        return STATUS_INVALID_PARAMETER;
+
+    EnumerationBuffer->EntriesRead = 0;
+    EnumerationBuffer->Information = NULL;
+
+    /* Validate the PolicyHandle */
+    Status = LsapValidateDbObject(PolicyHandle,
+                                  LsaDbPolicyObject,
+                                  POLICY_VIEW_LOCAL_INFORMATION,
+                                  &PolicyObject);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
+        return Status;
+    }
+
+    Status = LsapRegOpenKey(PolicyObject->KeyHandle,
+                            L"Accounts",
+                            KEY_READ,
+                            &AccountsKeyHandle);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    EnumIndex = *EnumerationContext;
+    EnumCount = 0;
+    RequiredLength = 0;
+
+    while (TRUE)
+    {
+        Status = LsapRegEnumerateSubKey(AccountsKeyHandle,
+                                        EnumIndex,
+                                        64 * sizeof(WCHAR),
+                                        AccountKeyName);
+        if (!NT_SUCCESS(Status))
+            break;
+
+        TRACE("EnumIndex: %lu\n", EnumIndex);
+        TRACE("Account key name: %S\n", AccountKeyName);
+
+        Status = LsapRegOpenKey(AccountsKeyHandle,
+                                AccountKeyName,
+                                KEY_READ,
+                                &AccountKeyHandle);
+        TRACE("LsapRegOpenKey returned %08lX\n", Status);
+        if (NT_SUCCESS(Status))
+        {
+            Status = LsapRegOpenKey(AccountKeyHandle,
+                                    L"Sid",
+                                    KEY_READ,
+                                    &SidKeyHandle);
+            TRACE("LsapRegOpenKey returned %08lX\n", Status);
+            if (NT_SUCCESS(Status))
+            {
+                DataLength = 0;
+                Status = LsapRegQueryValue(SidKeyHandle,
+                                           NULL,
+                                           NULL,
+                                           NULL,
+                                           &DataLength);
+                TRACE("LsapRegQueryValue returned %08lX\n", Status);
+                if (NT_SUCCESS(Status))
+                {
+                    TRACE("Data length: %lu\n", DataLength);
+
+                    if ((RequiredLength + DataLength + sizeof(LSAPR_ACCOUNT_INFORMATION)) > PreferedMaximumLength)
+                        break;
+
+                    RequiredLength += (DataLength + sizeof(LSAPR_ACCOUNT_INFORMATION));
+                    EnumCount++;
+                }
+
+                LsapRegCloseKey(SidKeyHandle);
+            }
+
+            LsapRegCloseKey(AccountKeyHandle);
+        }
+
+        EnumIndex++;
+    }
+
+    TRACE("EnumCount: %lu\n", EnumCount);
+    TRACE("RequiredLength: %lu\n", RequiredLength);
+
+    EnumBuffer.EntriesRead = EnumCount;
+    EnumBuffer.Information = midl_user_allocate(EnumCount * sizeof(LSAPR_ACCOUNT_INFORMATION));
+    if (EnumBuffer.Information == NULL)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto done;
+    }
+
+    EnumIndex = *EnumerationContext;
+    for (i = 0; i < EnumCount; i++, EnumIndex++)
+    {
+        Status = LsapRegEnumerateSubKey(AccountsKeyHandle,
+                                        EnumIndex,
+                                        64 * sizeof(WCHAR),
+                                        AccountKeyName);
+        if (!NT_SUCCESS(Status))
+            break;
+
+        TRACE("EnumIndex: %lu\n", EnumIndex);
+        TRACE("Account key name: %S\n", AccountKeyName);
+
+        Status = LsapRegOpenKey(AccountsKeyHandle,
+                                AccountKeyName,
+                                KEY_READ,
+                                &AccountKeyHandle);
+        TRACE("LsapRegOpenKey returned %08lX\n", Status);
+        if (NT_SUCCESS(Status))
+        {
+            Status = LsapRegOpenKey(AccountKeyHandle,
+                                    L"Sid",
+                                    KEY_READ,
+                                    &SidKeyHandle);
+            TRACE("LsapRegOpenKey returned %08lX\n", Status);
+            if (NT_SUCCESS(Status))
+            {
+                DataLength = 0;
+                Status = LsapRegQueryValue(SidKeyHandle,
+                                           NULL,
+                                           NULL,
+                                           NULL,
+                                           &DataLength);
+                TRACE("LsapRegQueryValue returned %08lX\n", Status);
+                if (NT_SUCCESS(Status))
+                {
+                    EnumBuffer.Information[i].Sid = midl_user_allocate(DataLength);
+                    if (EnumBuffer.Information[i].Sid == NULL)
+                    {
+                        LsapRegCloseKey(AccountKeyHandle);
+                        Status = STATUS_INSUFFICIENT_RESOURCES;
+                        goto done;
+                    }
+
+                    Status = LsapRegQueryValue(SidKeyHandle,
+                                               NULL,
+                                               NULL,
+                                               EnumBuffer.Information[i].Sid,
+                                               &DataLength);
+                    TRACE("SampRegQueryValue returned %08lX\n", Status);
+                }
+
+                LsapRegCloseKey(SidKeyHandle);
+            }
+
+            LsapRegCloseKey(AccountKeyHandle);
+
+            if (!NT_SUCCESS(Status))
+                goto done;
+        }
+    }
+
+    if (NT_SUCCESS(Status))
+    {
+        *EnumerationContext += EnumCount;
+        EnumerationBuffer->EntriesRead = EnumBuffer.EntriesRead;
+        EnumerationBuffer->Information = EnumBuffer.Information;
+    }
+
+done:
+    if (!NT_SUCCESS(Status))
+    {
+        if (EnumBuffer.Information)
+        {
+            for (i = 0; i < EnumBuffer.EntriesRead; i++)
+            {
+                if (EnumBuffer.Information[i].Sid != NULL)
+                    midl_user_free(EnumBuffer.Information[i].Sid);
+            }
+
+            midl_user_free(EnumBuffer.Information);
+        }
+    }
+
+    if (AccountsKeyHandle != NULL)
+        LsapRegCloseKey(AccountsKeyHandle);
+
+    return Status;
 }
 
 
@@ -538,89 +877,53 @@ NTSTATUS WINAPI LsarLookupNames(
     LSAP_LOOKUP_LEVEL LookupLevel,
     DWORD *MappedCount)
 {
-    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;
+    LSAPR_TRANSLATED_SIDS_EX2 TranslatedSidsEx2;
     ULONG i;
-    PSID Sid;
-    ULONG SidLength;
     NTSTATUS Status;
 
-    TRACE("LsarLookupNames(%p, %lu, %p, %p, %p, %d, %p)\n",
+    TRACE("(%p %lu %p %p %p %d %p)\n",
           PolicyHandle, Count, Names, ReferencedDomains, TranslatedSids,
           LookupLevel, MappedCount);
 
-    TranslatedSids->Entries = Count;
+    TranslatedSids->Entries = 0;
     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;
-    }
+    if (Count == 0)
+        return STATUS_NONE_MAPPED;
 
-    Status = RtlAllocateAndInitializeSid(&IdentifierAuthority,
-                                         2,
-                                         SECURITY_BUILTIN_DOMAIN_RID,
-                                         DOMAIN_ALIAS_RID_ADMINS,
-                                         0, 0, 0, 0, 0, 0,
-                                         &Sid);
+    TranslatedSidsEx2.Entries = 0;
+    TranslatedSidsEx2.Sids = NULL;
+
+    Status = LsapLookupNames(Count,
+                             Names,
+                             ReferencedDomains,
+                             &TranslatedSidsEx2,
+                             LookupLevel,
+                             MappedCount,
+                             0,
+                             0);
     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++)
+    TranslatedSids->Entries = TranslatedSidsEx2.Entries;
+    TranslatedSids->Sids = MIDL_user_allocate(TranslatedSids->Entries * sizeof(LSA_TRANSLATED_SID));
+    if (TranslatedSids->Sids == NULL)
     {
-        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);
+        MIDL_user_free(TranslatedSidsEx2.Sids);
+        MIDL_user_free(*ReferencedDomains);
+        *ReferencedDomains = NULL;
+        return STATUS_INSUFFICIENT_RESOURCES;
     }
 
-    for (i = 0; i < Count; i++)
+    for (i = 0; i < TranslatedSidsEx2.Entries; i++)
     {
-        OutputSids[i].Use = SidTypeWellKnownGroup;
-        OutputSids[i].RelativeId = DOMAIN_USER_RID_ADMIN; //DOMAIN_ALIAS_RID_ADMINS;
-        OutputSids[i].DomainIndex = i;
+        TranslatedSids->Sids[i].Use = TranslatedSidsEx2.Sids[i].Use;
+        TranslatedSids->Sids[i].RelativeId = LsapGetRelativeIdFromSid(TranslatedSidsEx2.Sids[i].Sid);
+        TranslatedSids->Sids[i].DomainIndex = TranslatedSidsEx2.Sids[i].DomainIndex;
     }
 
-    *ReferencedDomains = OutputDomains;
-
-    *MappedCount = Count;
-
-    TranslatedSids->Entries = Count;
-    TranslatedSids->Sids = OutputSids;
+    MIDL_user_free(TranslatedSidsEx2.Sids);
 
     return STATUS_SUCCESS;
 }
@@ -635,85 +938,53 @@ NTSTATUS WINAPI LsarLookupSids(
     LSAP_LOOKUP_LEVEL LookupLevel,
     DWORD *MappedCount)
 {
-    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;
+    LSAPR_TRANSLATED_NAMES_EX TranslatedNamesEx;
     ULONG i;
-    PSID Sid;
-    ULONG SidLength;
     NTSTATUS Status;
 
-    TRACE("LsarLookupSids(%p, %p, %p, %p, %d, %p)\n",
+    TRACE("(%p %p %p %p %d %p)\n",
           PolicyHandle, SidEnumBuffer, ReferencedDomains, TranslatedNames,
           LookupLevel, MappedCount);
 
+    /* FIXME: Fail, if there is an invalid SID in the SidEnumBuffer */
+
     TranslatedNames->Entries = SidEnumBuffer->Entries;
     TranslatedNames->Names = NULL;
     *ReferencedDomains = NULL;
 
-    OutputNamesLength = SidEnumBuffer->Entries * sizeof(LSA_TRANSLATED_NAME);
-    OutputNames = MIDL_user_allocate(OutputNamesLength);
-    if (OutputNames == NULL)
-    {
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    RtlZeroMemory(OutputNames, OutputNamesLength);
+    TranslatedNamesEx.Entries = SidEnumBuffer->Entries;
+    TranslatedNamesEx.Names = NULL;
 
-    OutputDomains = MIDL_user_allocate(sizeof(LSAPR_REFERENCED_DOMAIN_LIST));
-    if (OutputDomains == NULL)
-    {
-        MIDL_user_free(OutputNames);
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
+    Status = LsapLookupSids(SidEnumBuffer,
+                            ReferencedDomains,
+                            &TranslatedNamesEx,
+                            LookupLevel,
+                            MappedCount,
+                            0,
+                            0);
+    if (!NT_SUCCESS(Status))
+        return Status;
 
-    OutputDomains->Entries = SidEnumBuffer->Entries;
-    OutputDomains->Domains = MIDL_user_allocate(SidEnumBuffer->Entries * sizeof(LSA_TRUST_INFORMATION));
-    if (OutputDomains->Domains == NULL)
+    TranslatedNames->Entries = SidEnumBuffer->Entries;
+    TranslatedNames->Names = MIDL_user_allocate(SidEnumBuffer->Entries * sizeof(LSAPR_TRANSLATED_NAME));
+    if (TranslatedNames->Names == NULL)
     {
-        MIDL_user_free(OutputDomains);
-        MIDL_user_free(OutputNames);
+        MIDL_user_free(TranslatedNamesEx.Names);
+        MIDL_user_free(*ReferencedDomains);
+        *ReferencedDomains = NULL;
         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++)
+    for (i = 0; i < TranslatedNamesEx.Entries; 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);
+        TranslatedNames->Names[i].Use = TranslatedNamesEx.Names[i].Use;
+        TranslatedNames->Names[i].Name.Length = TranslatedNamesEx.Names[i].Name.Length;
+        TranslatedNames->Names[i].Name.MaximumLength = TranslatedNamesEx.Names[i].Name.MaximumLength;
+        TranslatedNames->Names[i].Name.Buffer = TranslatedNamesEx.Names[i].Name.Buffer;
+        TranslatedNames->Names[i].DomainIndex = TranslatedNamesEx.Names[i].DomainIndex;
     }
 
-    Status = LsapLookupSids(SidEnumBuffer,
-                            OutputNames);
-
-    *ReferencedDomains = OutputDomains;
-
-    *MappedCount = SidEnumBuffer->Entries;
-
-    TranslatedNames->Entries = SidEnumBuffer->Entries;
-    TranslatedNames->Names = OutputNames;
+    MIDL_user_free(TranslatedNamesEx.Names);
 
     return Status;
 }
@@ -727,9 +998,10 @@ NTSTATUS WINAPI LsarCreateSecret(
     LSAPR_HANDLE *SecretHandle)
 {
     PLSA_DB_OBJECT PolicyObject;
-    PLSA_DB_OBJECT SecretsObject = NULL;
     PLSA_DB_OBJECT SecretObject = NULL;
     LARGE_INTEGER Time;
+    PSECURITY_DESCRIPTOR SecretSd = NULL;
+    ULONG SecretSdSize;
     NTSTATUS Status = STATUS_SUCCESS;
 
     /* Validate the PolicyHandle */
@@ -743,35 +1015,34 @@ NTSTATUS WINAPI LsarCreateSecret(
         return Status;
     }
 
-    /* Open the Secrets object */
-    Status = LsapOpenDbObject(PolicyObject,
-                              L"Secrets",
-                              LsaDbContainerObject,
-                              0,
-                              &SecretsObject);
+    /* Get the current time */
+    Status = NtQuerySystemTime(&Time);
     if (!NT_SUCCESS(Status))
     {
-        ERR("LsapCreateDbObject (Secrets) failed (Status 0x%08lx)\n", Status);
+        ERR("NtQuerySystemTime failed (Status 0x%08lx)\n", Status);
         goto done;
     }
 
-    /* Get the current time */
-    Status = NtQuerySystemTime(&Time);
+    /* Create a security descriptor for the secret */
+    Status = LsapCreateSecretSd(&SecretSd,
+                                &SecretSdSize);
     if (!NT_SUCCESS(Status))
     {
-        ERR("NtQuerySystemTime failed (Status 0x%08lx)\n", Status);
-        goto done;
+        ERR("LsapCreateAccountSd returned 0x%08lx\n", Status);
+        return Status;
     }
 
     /* Create the Secret object */
-    Status = LsapCreateDbObject(SecretsObject,
+    Status = LsapCreateDbObject(PolicyObject,
+                                L"Secrets",
                                 SecretName->Buffer,
                                 LsaDbSecretObject,
                                 DesiredAccess,
+                                PolicyObject->Trusted,
                                 &SecretObject);
     if (!NT_SUCCESS(Status))
     {
-        ERR("LsapCreateDbObject (Secret) failed (Status 0x%08lx)\n", Status);
+        ERR("LsapCreateDbObject failed (Status 0x%08lx)\n", Status);
         goto done;
     }
 
@@ -791,8 +1062,22 @@ NTSTATUS WINAPI LsarCreateSecret(
                                     L"OldTime",
                                     (PVOID)&Time,
                                     sizeof(LARGE_INTEGER));
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapSetObjectAttribute (OldTime) failed (Status 0x%08lx)\n", Status);
+        goto done;
+    }
+
+    /* Set the SecDesc attribute */
+    Status = LsapSetObjectAttribute(SecretObject,
+                                    L"SecDesc",
+                                    SecretSd,
+                                    SecretSdSize);
 
 done:
+    if (SecretSd != NULL)
+        RtlFreeHeap(RtlGetProcessHeap(), 0, SecretSd);
+
     if (!NT_SUCCESS(Status))
     {
         if (SecretObject != NULL)
@@ -803,9 +1088,6 @@ done:
         *SecretHandle = (LSAPR_HANDLE)SecretObject;
     }
 
-    if (SecretsObject != NULL)
-        LsapCloseDbObject(SecretsObject);
-
     return STATUS_SUCCESS;
 }
 
@@ -818,15 +1100,18 @@ NTSTATUS WINAPI LsarOpenAccount(
     LSAPR_HANDLE *AccountHandle)
 {
     PLSA_DB_OBJECT PolicyObject;
-    PLSA_DB_OBJECT AccountsObject = NULL;
     PLSA_DB_OBJECT AccountObject = NULL;
     LPWSTR SidString = NULL;
     NTSTATUS Status = STATUS_SUCCESS;
 
+    /* Validate the AccountSid */
+    if (!RtlValidSid(AccountSid))
+        return STATUS_INVALID_PARAMETER;
+
     /* Validate the PolicyHandle */
     Status = LsapValidateDbObject(PolicyHandle,
                                   LsaDbPolicyObject,
-                                  POLICY_CREATE_ACCOUNT,
+                                  0,
                                   &PolicyObject);
     if (!NT_SUCCESS(Status))
     {
@@ -834,18 +1119,6 @@ NTSTATUS WINAPI LsarOpenAccount(
         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))
@@ -856,14 +1129,16 @@ NTSTATUS WINAPI LsarOpenAccount(
     }
 
     /* Create the Account object */
-    Status = LsapOpenDbObject(AccountsObject,
+    Status = LsapOpenDbObject(PolicyObject,
+                              L"Accounts",
                               SidString,
                               LsaDbAccountObject,
                               DesiredAccess,
+                              PolicyObject->Trusted,
                               &AccountObject);
     if (!NT_SUCCESS(Status))
     {
-        ERR("LsapOpenDbObject (Account) failed (Status 0x%08lx)\n", Status);
+        ERR("LsapOpenDbObject failed (Status 0x%08lx)\n", Status);
         goto done;
     }
 
@@ -887,10 +1162,7 @@ done:
         *AccountHandle = (LSAPR_HANDLE)AccountObject;
     }
 
-    if (AccountsObject != NULL)
-        LsapCloseDbObject(AccountsObject);
-
-    return STATUS_SUCCESS;
+    return Status;
 }
 
 
@@ -973,6 +1245,7 @@ NTSTATUS WINAPI LsarAddPrivilegesToAccount(
         return Status;
     }
 
+    /* Get the size of the Privilgs attribute */
     Status = LsapGetObjectAttribute(AccountObject,
                                     L"Privilgs",
                                     NULL,
@@ -1080,7 +1353,7 @@ NTSTATUS WINAPI LsarAddPrivilegesToAccount(
             }
         }
 
-        /* Set the new priivliege set */
+        /* Set the new privilege set */
         Status = LsapSetObjectAttribute(AccountObject,
                                         L"Privilgs",
                                         NewPrivileges,
@@ -1104,8 +1377,153 @@ NTSTATUS WINAPI LsarRemovePrivilegesFromAccount(
     BOOL AllPrivileges,
     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, k;
+    BOOL bFound;
+    NTSTATUS Status;
+
+    TRACE("(%p %u %p)\n", AccountHandle, AllPrivileges, Privileges);
+
+    /* */
+    if ((AllPrivileges == FALSE && Privileges == NULL) ||
+        (AllPrivileges == TRUE && Privileges != NULL))
+            return STATUS_INVALID_PARAMETER;
+
+    /* Validate the AccountHandle */
+    Status = LsapValidateDbObject(AccountHandle,
+                                  LsaDbAccountObject,
+                                  ACCOUNT_ADJUST_PRIVILEGES,
+                                  &AccountObject);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
+        return Status;
+    }
+
+    if (AllPrivileges == TRUE)
+    {
+        /* Delete the Privilgs attribute */
+        Status = LsapDeleteObjectAttribute(AccountObject,
+                                           L"Privilgs");
+        if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
+            Status = STATUS_SUCCESS;
+    }
+    else
+    {
+        /* Get the size of the Privilgs attribute */
+        Status = LsapGetObjectAttribute(AccountObject,
+                                        L"Privilgs",
+                                        NULL,
+                                        &PrivilegeSetSize);
+        if (!NT_SUCCESS(Status))
+            goto done;
+
+        /* Succeed, if there is no privilege set to remove privileges from */
+        if (PrivilegeSetSize == 0)
+        {
+            Status = STATUS_SUCCESS;
+            goto done;
+        }
+
+        /* 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 of privileges in the new privilege set */
+        for (i = 0; i < CurrentPrivileges->PrivilegeCount; i++)
+        {
+            for (j = 0; j < Privileges->PrivilegeCount; j++)
+            {
+                if (RtlEqualLuid(&(CurrentPrivileges->Privilege[i].Luid),
+                                 &(Privileges->Privilege[j].Luid)))
+                {
+                    if (PrivilegeCount > 0)
+                        PrivilegeCount--;
+                }
+            }
+        }
+        TRACE("New privilege count: %lu\n", PrivilegeCount);
+
+        if (PrivilegeCount == 0)
+        {
+            /* Delete the Privilgs attribute */
+            Status = LsapDeleteObjectAttribute(AccountObject,
+                                               L"Privilgs");
+            if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
+                Status = STATUS_SUCCESS;
+        }
+        else
+        {
+            /* 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 the privileges which are not to be removed */
+            for (i = 0, k = 0; i < CurrentPrivileges->PrivilegeCount; i++)
+            {
+                bFound = FALSE;
+                for (j = 0; j < Privileges->PrivilegeCount; j++)
+                {
+                    if (RtlEqualLuid(&(CurrentPrivileges->Privilege[i].Luid),
+                                     &(Privileges->Privilege[j].Luid)))
+                        bFound = TRUE;
+                }
+
+                if (bFound == FALSE)
+                {
+                    /* Copy the privilege */
+                    RtlCopyLuidAndAttributesArray(1,
+                                                  &(CurrentPrivileges->Privilege[i]),
+                                                  &(NewPrivileges->Privilege[k]));
+                    k++;
+                }
+            }
+
+            /* Set the new privilege 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;
 }
 
 
@@ -1114,8 +1532,30 @@ NTSTATUS WINAPI LsarGetQuotasForAccount(
     LSAPR_HANDLE AccountHandle,
     PQUOTA_LIMITS QuotaLimits)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PLSA_DB_OBJECT AccountObject;
+    ULONG Size;
+    NTSTATUS Status;
+
+    TRACE("(%p %p)\n", AccountHandle, QuotaLimits);
+
+    /* 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 quota attribute */
+    Status = LsapGetObjectAttribute(AccountObject,
+                                    L"DefQuota",
+                                    QuotaLimits,
+                                    &Size);
+
+    return Status;
 }
 
 
@@ -1124,8 +1564,59 @@ NTSTATUS WINAPI LsarSetQuotasForAccount(
     LSAPR_HANDLE AccountHandle,
     PQUOTA_LIMITS QuotaLimits)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PLSA_DB_OBJECT AccountObject;
+    QUOTA_LIMITS InternalQuotaLimits;
+    ULONG Size;
+    NTSTATUS Status;
+
+    TRACE("(%p %p)\n", AccountHandle, QuotaLimits);
+
+    /* Validate the account handle */
+    Status = LsapValidateDbObject(AccountHandle,
+                                  LsaDbAccountObject,
+                                  ACCOUNT_ADJUST_QUOTAS,
+                                  &AccountObject);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("Invalid handle (Status %lx)\n", Status);
+        return Status;
+    }
+
+    /* Get the quota limits attribute */
+    Size = sizeof(QUOTA_LIMITS);
+    Status = LsapGetObjectAttribute(AccountObject,
+                                    L"DefQuota",
+                                    &InternalQuotaLimits,
+                                    &Size);
+    if (!NT_SUCCESS(Status))
+    {
+        TRACE("LsapGetObjectAttribute() failed (Status 0x%08lx)\n", Status);
+        return Status;
+    }
+
+    /* Update the quota limits */
+    if (QuotaLimits->PagedPoolLimit != 0)
+        InternalQuotaLimits.PagedPoolLimit = QuotaLimits->PagedPoolLimit;
+
+    if (QuotaLimits->NonPagedPoolLimit != 0)
+        InternalQuotaLimits.NonPagedPoolLimit = QuotaLimits->NonPagedPoolLimit;
+
+    if (QuotaLimits->MinimumWorkingSetSize != 0)
+        InternalQuotaLimits.MinimumWorkingSetSize = QuotaLimits->MinimumWorkingSetSize;
+
+    if (QuotaLimits->MaximumWorkingSetSize != 0)
+        InternalQuotaLimits.MaximumWorkingSetSize = QuotaLimits->MaximumWorkingSetSize;
+
+    if (QuotaLimits->PagefileLimit != 0)
+        InternalQuotaLimits.PagefileLimit = QuotaLimits->PagefileLimit;
+
+    /* Set the quota limits attribute */
+    Status = LsapSetObjectAttribute(AccountObject,
+                                    L"DefQuota",
+                                    &InternalQuotaLimits,
+                                    sizeof(QUOTA_LIMITS));
+
+    return Status;
 }
 
 
@@ -1230,14 +1721,13 @@ NTSTATUS WINAPI LsarOpenSecret(
     LSAPR_HANDLE *SecretHandle)
 {
     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,
+                                  0,
                                   &PolicyObject);
     if (!NT_SUCCESS(Status))
     {
@@ -1245,27 +1735,17 @@ NTSTATUS WINAPI LsarOpenSecret(
         return Status;
     }
 
-    /* Open the Secrets object */
+    /* Create the secret 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,
+                              PolicyObject->Trusted,
                               &SecretObject);
     if (!NT_SUCCESS(Status))
     {
-        ERR("LsapOpenDbObject (Secret) failed (Status 0x%08lx)\n", Status);
+        ERR("LsapOpenDbObject failed (Status 0x%08lx)\n", Status);
         goto done;
     }
 
@@ -1280,10 +1760,7 @@ done:
         *SecretHandle = (LSAPR_HANDLE)SecretObject;
     }
 
-    if (SecretsObject != NULL)
-        LsapCloseDbObject(SecretsObject);
-
-    return STATUS_SUCCESS;
+    return Status;
 }
 
 
@@ -1588,7 +2065,7 @@ NTSTATUS WINAPI LsarLookupPrivilegeValue(
 
     TRACE("Privilege: %wZ\n", Name);
 
-    Status = LsarpLookupPrivilegeValue((PUNICODE_STRING)Name,
+    Status = LsarpLookupPrivilegeValue(Name,
                                        Value);
 
     return Status;
@@ -1616,7 +2093,8 @@ NTSTATUS WINAPI LsarLookupPrivilegeName(
         return Status;
     }
 
-    Status = LsarpLookupPrivilegeName(Value, (PUNICODE_STRING*)Name);
+    Status = LsarpLookupPrivilegeName(Value,
+                                      Name);
 
     return Status;
 }
@@ -1640,8 +2118,41 @@ NTSTATUS WINAPI LsarLookupPrivilegeDisplayName(
 NTSTATUS WINAPI LsarDeleteObject(
     LSAPR_HANDLE *ObjectHandle)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PLSA_DB_OBJECT DbObject;
+    NTSTATUS Status;
+
+    TRACE("(%p)\n", ObjectHandle);
+
+    if (ObjectHandle == NULL)
+        return STATUS_INVALID_PARAMETER;
+
+    /* Validate the ObjectHandle */
+    Status = LsapValidateDbObject(*ObjectHandle,
+                                  LsaDbIgnoreObject,
+                                  DELETE,
+                                  &DbObject);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapValidateDbObject returned 0x%08lx\n", Status);
+        return Status;
+    }
+
+    /* You cannot delete the policy object */
+    if (DbObject->ObjectType == LsaDbPolicyObject)
+        return STATUS_INVALID_PARAMETER;
+
+    /* Delete the database object */
+    Status = LsapDeleteDbObject(DbObject);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsapDeleteDbObject returned 0x%08lx\n", Status);
+        return Status;
+    }
+
+    /* Invalidate the object handle */
+    *ObjectHandle = NULL;
+
+    return STATUS_SUCCESS;
 }
 
 
@@ -1657,26 +2168,141 @@ NTSTATUS WINAPI LsarEnumerateAccountsWithUserRight(
 
 
 /* Function 36 */
-NTSTATUS WINAPI LsarEnmuerateAccountRights(
+NTSTATUS WINAPI LsarEnumerateAccountRights(
     LSAPR_HANDLE PolicyHandle,
     PRPC_SID AccountSid,
     PLSAPR_USER_RIGHT_SET UserRights)
 {
-    PLSA_DB_OBJECT PolicyObject;
+    LSAPR_HANDLE AccountHandle;
+    PLSAPR_PRIVILEGE_SET PrivilegeSet = NULL;
+    PRPC_UNICODE_STRING RightsBuffer = NULL;
+    PRPC_UNICODE_STRING PrivilegeString;
+    ACCESS_MASK SystemAccess;
+    ULONG RightsCount;
+    ULONG RightsIndex;
+    ULONG i;
     NTSTATUS Status;
 
-    FIXME("(%p,%p,%p) stub\n", PolicyHandle, AccountSid, UserRights);
+    TRACE("LsarEnumerateAccountRights(%p %p %p)\n",
+          PolicyHandle, AccountSid, UserRights);
 
-    Status = LsapValidateDbObject(PolicyHandle,
-                                  LsaDbPolicyObject,
-                                  ACCOUNT_VIEW,
-                                  &PolicyObject);
+    /* Open the account */
+    Status = LsarOpenAccount(PolicyHandle,
+                             AccountSid,
+                             ACCOUNT_VIEW,
+                             &AccountHandle);
     if (!NT_SUCCESS(Status))
+    {
+        ERR("LsarOpenAccount returned 0x%08lx\n", Status);
         return Status;
+    }
+
+    /* Enumerate the privileges */
+    Status = LsarEnumeratePrivilegesAccount(AccountHandle,
+                                            &PrivilegeSet);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsarEnumeratePrivilegesAccount returned 0x%08lx\n", Status);
+        goto done;
+    }
+
+    /* Get account rights */
+    Status = LsarGetSystemAccessAccount(AccountHandle,
+                                        &SystemAccess);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsarGetSystemAccessAccount returned 0x%08lx\n", Status);
+        goto done;
+    }
+
+    RightsCount = PrivilegeSet->PrivilegeCount;
+
+    /* Count account rights */
+    for (i = 0; i < sizeof(ACCESS_MASK) * 8; i++)
+    {
+        if (SystemAccess & (1 << i))
+            RightsCount++;
+    }
+
+    /* We are done if there are no rights to be enumerated */
+    if (RightsCount == 0)
+    {
+        UserRights->Entries = 0;
+        UserRights->UserRights = NULL;
+        Status = STATUS_SUCCESS;
+        goto done;
+    }
+
+    /* Allocate a buffer for the account rights */
+    RightsBuffer = MIDL_user_allocate(RightsCount * sizeof(RPC_UNICODE_STRING));
+    if (RightsBuffer == NULL)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto done;
+    }
+
+    /* Copy the privileges into the buffer */
+    RightsIndex = 0;
+    for (i = 0; i < PrivilegeSet->PrivilegeCount; i++)
+    {
+        PrivilegeString = NULL;
+        Status = LsarLookupPrivilegeName(PolicyHandle,
+                                         (PLUID)&PrivilegeSet->Privilege[i].Luid,
+                                         &PrivilegeString);
+        if (!NT_SUCCESS(Status))
+            goto done;
+
+        RightsBuffer[i].Length = PrivilegeString->Length;
+        RightsBuffer[i].MaximumLength = PrivilegeString->MaximumLength;
+        RightsBuffer[i].Buffer = PrivilegeString->Buffer;
 
-    UserRights->Entries = 0;
-    UserRights->UserRights = NULL;
-    return STATUS_OBJECT_NAME_NOT_FOUND;
+        MIDL_user_free(PrivilegeString);
+        RightsIndex++;
+    }
+
+    /* Copy account rights into the buffer */
+    for (i = 0; i < sizeof(ACCESS_MASK) * 8; i++)
+    {
+        if (SystemAccess & (1 << i))
+        {
+            Status = LsapLookupAccountRightName(1 << i,
+                                                &PrivilegeString);
+            if (!NT_SUCCESS(Status))
+                goto done;
+
+            RightsBuffer[i].Length = PrivilegeString->Length;
+            RightsBuffer[i].MaximumLength = PrivilegeString->MaximumLength;
+            RightsBuffer[i].Buffer = PrivilegeString->Buffer;
+
+            MIDL_user_free(PrivilegeString);
+            RightsIndex++;
+        }
+    }
+
+    UserRights->Entries = RightsCount;
+    UserRights->UserRights = (PRPC_UNICODE_STRING)RightsBuffer;
+
+done:
+    if (!NT_SUCCESS(Status))
+    {
+        if (RightsBuffer != NULL)
+        {
+            for (RightsIndex = 0; RightsIndex < RightsCount; RightsIndex++)
+            {
+                if (RightsBuffer[RightsIndex].Buffer != NULL)
+                    MIDL_user_free(RightsBuffer[RightsIndex].Buffer);
+            }
+
+            MIDL_user_free(RightsBuffer);
+        }
+    }
+
+    if (PrivilegeSet != NULL)
+        MIDL_user_free(PrivilegeSet);
+
+    LsarClose(&AccountHandle);
+
+    return Status;
 }
 
 
@@ -1766,8 +2392,10 @@ NTSTATUS WINAPI LsarOpenPolicy2(
     ACCESS_MASK DesiredAccess,
     LSAPR_HANDLE *PolicyHandle)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    return LsarOpenPolicy(SystemName,
+                          ObjectAttributes,
+                          DesiredAccess,
+                          PolicyHandle);
 }
 
 
@@ -1811,7 +2439,7 @@ NTSTATUS WINAPI LsarQueryTrustedDomainInfoByName(
     LSAPR_HANDLE PolicyHandle,
     PRPC_UNICODE_STRING TrustedDomainName,
     POLICY_INFORMATION_CLASS InformationClass,
-    unsigned long *PolicyInformation)
+    PLSAPR_TRUSTED_DOMAIN_INFO *PolicyInformation)
 {
     UNIMPLEMENTED;
     return STATUS_NOT_IMPLEMENTED;
@@ -1823,7 +2451,7 @@ NTSTATUS WINAPI LsarSetTrustedDomainInfoByName(
     LSAPR_HANDLE PolicyHandle,
     PRPC_UNICODE_STRING TrustedDomainName,
     POLICY_INFORMATION_CLASS InformationClass,
-    unsigned long PolicyInformation)
+    PLSAPR_TRUSTED_DOMAIN_INFO PolicyInformation)
 {
     UNIMPLEMENTED;
     return STATUS_NOT_IMPLEMENTED;
@@ -1868,7 +2496,7 @@ NTSTATUS WINAPI LsarSetPolicyReplicationHandle(
 NTSTATUS WINAPI LsarQueryDomainInformationPolicy(
     LSAPR_HANDLE PolicyHandle,
     POLICY_INFORMATION_CLASS InformationClass,
-    unsigned long *PolicyInformation)
+    PLSAPR_POLICY_DOMAIN_INFORMATION *PolicyInformation)
 {
     UNIMPLEMENTED;
     return STATUS_NOT_IMPLEMENTED;
@@ -1879,7 +2507,7 @@ NTSTATUS WINAPI LsarQueryDomainInformationPolicy(
 NTSTATUS WINAPI LsarSetDomainInformationPolicy(
     LSAPR_HANDLE PolicyHandle,
     POLICY_INFORMATION_CLASS InformationClass,
-    unsigned long PolicyInformation)
+    PLSAPR_POLICY_DOMAIN_INFORMATION PolicyInformation)
 {
     UNIMPLEMENTED;
     return STATUS_NOT_IMPLEMENTED;
@@ -1918,8 +2546,27 @@ NTSTATUS WINAPI LsarLookupSids2(
     DWORD LookupOptions,
     DWORD ClientRevision)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    NTSTATUS Status;
+
+    TRACE("(%p %p %p %p %d %p %lu %lu)\n",
+          PolicyHandle, SidEnumBuffer, ReferencedDomains, TranslatedNames,
+          LookupLevel, MappedCount, LookupOptions, ClientRevision);
+
+    TranslatedNames->Entries = SidEnumBuffer->Entries;
+    TranslatedNames->Names = NULL;
+    *ReferencedDomains = NULL;
+
+    /* FIXME: Fail, if there is an invalid SID in the SidEnumBuffer */
+
+    Status = LsapLookupSids(SidEnumBuffer,
+                            ReferencedDomains,
+                            TranslatedNames,
+                            LookupLevel,
+                            MappedCount,
+                            LookupOptions,
+                            ClientRevision);
+
+    return Status;
 }
 
 
@@ -1935,8 +2582,56 @@ NTSTATUS WINAPI LsarLookupNames2(
     DWORD LookupOptions,
     DWORD ClientRevision)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    LSAPR_TRANSLATED_SIDS_EX2 TranslatedSidsEx2;
+    ULONG i;
+    NTSTATUS Status;
+
+    TRACE("(%p %lu %p %p %p %d %p %lu %lu)\n",
+          PolicyHandle, Count, Names, ReferencedDomains, TranslatedSids,
+          LookupLevel, MappedCount, LookupOptions, ClientRevision);
+
+    TranslatedSids->Entries = 0;
+    TranslatedSids->Sids = NULL;
+    *ReferencedDomains = NULL;
+
+    if (Count == 0)
+        return STATUS_NONE_MAPPED;
+
+    TranslatedSidsEx2.Entries = 0;
+    TranslatedSidsEx2.Sids = NULL;
+
+    Status = LsapLookupNames(Count,
+                             Names,
+                             ReferencedDomains,
+                             &TranslatedSidsEx2,
+                             LookupLevel,
+                             MappedCount,
+                             LookupOptions,
+                             ClientRevision);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    TranslatedSids->Entries = TranslatedSidsEx2.Entries;
+    TranslatedSids->Sids = MIDL_user_allocate(TranslatedSids->Entries * sizeof(LSA_TRANSLATED_SID));
+    if (TranslatedSids->Sids == NULL)
+    {
+        MIDL_user_free(TranslatedSidsEx2.Sids);
+        MIDL_user_free(*ReferencedDomains);
+        *ReferencedDomains = NULL;
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    for (i = 0; i < TranslatedSidsEx2.Entries; i++)
+    {
+        TranslatedSids->Sids[i].Use = TranslatedSidsEx2.Sids[i].Use;
+        TranslatedSids->Sids[i].RelativeId = LsapGetRelativeIdFromSid(TranslatedSidsEx2.Sids[i].Sid);
+        TranslatedSids->Sids[i].DomainIndex = TranslatedSidsEx2.Sids[i].DomainIndex;
+        TranslatedSids->Sids[i].Flags = TranslatedSidsEx2.Sids[i].Flags;
+    }
+
+    MIDL_user_free(TranslatedSidsEx2.Sids);
+
+    return STATUS_SUCCESS;
 }
 
 
@@ -2037,126 +2732,29 @@ NTSTATUS WINAPI LsarLookupNames3(
     DWORD LookupOptions,
     DWORD ClientRevision)
 {
-    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",
+    TRACE("(%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->Entries = 0;
     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;
+    if (Count == 0)
+        return STATUS_NONE_MAPPED;
 
-    TranslatedSids->Entries = Count;
-    TranslatedSids->Sids = SidsBuffer;
+    Status = LsapLookupNames(Count,
+                             Names,
+                             ReferencedDomains,
+                             TranslatedSids,
+                             LookupLevel,
+                             MappedCount,
+                             LookupOptions,
+                             ClientRevision);
 
-    return STATUS_SUCCESS;
+    return Status;
 }
 
 
@@ -2242,8 +2840,27 @@ NTSTATUS WINAPI LsarLookupSids3(
     DWORD LookupOptions,
     DWORD ClientRevision)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    NTSTATUS Status;
+
+    TRACE("(%p %p %p %p %d %p %lu %lu)\n",
+          PolicyHandle, SidEnumBuffer, ReferencedDomains, TranslatedNames,
+          LookupLevel, MappedCount, LookupOptions, ClientRevision);
+
+    TranslatedNames->Entries = SidEnumBuffer->Entries;
+    TranslatedNames->Names = NULL;
+    *ReferencedDomains = NULL;
+
+    /* FIXME: Fail, if there is an invalid SID in the SidEnumBuffer */
+
+    Status = LsapLookupSids(SidEnumBuffer,
+                            ReferencedDomains,
+                            TranslatedNames,
+                            LookupLevel,
+                            MappedCount,
+                            LookupOptions,
+                            ClientRevision);
+
+    return Status;
 }
 
 
@@ -2259,8 +2876,29 @@ NTSTATUS WINAPI LsarLookupNames4(
     DWORD LookupOptions,
     DWORD ClientRevision)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    NTSTATUS Status;
+
+    TRACE("(%p %lu %p %p %p %d %p %lu %lu)\n",
+          RpcHandle, Count, Names, ReferencedDomains, TranslatedSids,
+          LookupLevel, MappedCount, LookupOptions, ClientRevision);
+
+    TranslatedSids->Entries = 0;
+    TranslatedSids->Sids = NULL;
+    *ReferencedDomains = NULL;
+
+    if (Count == 0)
+        return STATUS_NONE_MAPPED;
+
+    Status = LsapLookupNames(Count,
+                             Names,
+                             ReferencedDomains,
+                             TranslatedSids,
+                             LookupLevel,
+                             MappedCount,
+                             LookupOptions,
+                             ClientRevision);
+
+    return Status;
 }
 
 
@@ -2299,121 +2937,4 @@ NTSTATUS WINAPI LsarAdtReportSecurityEvent(
     return STATUS_NOT_IMPLEMENTED;
 }
 
-
-/* Function 82 */
-NTSTATUS WINAPI CredrFindBestCredential(
-    handle_t hBinding)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-
-/* Function 83 */
-NTSTATUS WINAPI LsarSetAuditPolicy(
-    handle_t hBinding)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-
-/* Function 84 */
-NTSTATUS WINAPI LsarQueryAuditPolicy(
-    handle_t hBinding)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-
-/* Function 85 */
-NTSTATUS WINAPI LsarEnumerateAuditPolicy(
-    handle_t hBinding)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-
-/* Function 86 */
-NTSTATUS WINAPI LsarEnumerateAuditCategories(
-    handle_t hBinding)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-
-/* Function 87 */
-NTSTATUS WINAPI LsarEnumerateAuditSubCategories(
-    handle_t hBinding)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-
-/* Function 88 */
-NTSTATUS WINAPI LsarLookupAuditCategoryName(
-    handle_t hBinding)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-
-/* Function 89 */
-NTSTATUS WINAPI LsarLookupAuditSubCategoryName(
-    handle_t hBinding)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-
-/* Function 90 */
-NTSTATUS WINAPI LsarSetAuditSecurity(
-    handle_t hBinding)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-
-/* Function 91 */
-NTSTATUS WINAPI LsarQueryAuditSecurity(
-    handle_t hBinding)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-
-/* Function 92 */
-NTSTATUS WINAPI CredReadByTokenHandle(
-    handle_t hBinding)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-
-/* Function 93 */
-NTSTATUS WINAPI CredrRestoreCredentials(
-    handle_t hBinding)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-
-/* Function 94 */
-NTSTATUS WINAPI CredrBackupCredentials(
-    handle_t hBinding)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
-
 /* EOF */