#include "lsasrv.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 NTSTATUS
-LsapValidateDbHandle(LSAPR_HANDLE Handle,
- LSA_DB_HANDLE_TYPE HandleType,
- ACCESS_MASK GrantedAccess)
-{
- 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;
-
- if (bValid == FALSE)
- return STATUS_INVALID_HANDLE;
-
- if (GrantedAccess != 0)
- {
- /* FIXME: Check for granted access rights */
- }
-
- return STATUS_SUCCESS;
-}
-
-
-
-
VOID
LsarStartRpcServer(VOID)
{
NTSTATUS WINAPI LsarClose(
LSAPR_HANDLE *ObjectHandle)
{
+ PLSA_DB_OBJECT DbObject;
NTSTATUS Status = STATUS_SUCCESS;
TRACE("0x%p\n", ObjectHandle);
// RtlEnterCriticalSection(&PolicyHandleTableLock);
- Status = LsapValidateDbHandle(*ObjectHandle,
- LsaDbIgnoreHandle,
- 0);
-
+ Status = LsapValidateDbObject(*ObjectHandle,
+ LsaDbIgnoreObject,
+ 0,
+ &DbObject);
if (Status == STATUS_SUCCESS)
{
- RtlFreeHeap(RtlGetProcessHeap(), 0, *ObjectHandle);
+ Status = LsapCloseDbObject(DbObject);
*ObjectHandle = NULL;
}
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;
POLICY_INFORMATION_CLASS InformationClass,
PLSAPR_POLICY_INFORMATION *PolicyInformation)
{
+ PLSA_DB_OBJECT DbObject;
+ ACCESS_MASK DesiredAccess = 0;
NTSTATUS Status;
TRACE("LsarQueryInformationPolicy(%p,0x%08x,%p)\n",
TRACE("*PolicyInformation %p\n", *PolicyInformation);
}
- Status = LsapValidateDbHandle(PolicyHandle,
- LsaDbPolicyHandle,
- 0); /* FIXME */
- if (!NT_SUCCESS(Status))
- return Status;
-
switch (InformationClass)
{
- case PolicyAuditEventsInformation: /* 2 */
- {
- PLSAPR_POLICY_AUDIT_EVENTS_INFO p = MIDL_user_allocate(sizeof(LSAPR_POLICY_AUDIT_EVENTS_INFO));
- if (p == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
+ case PolicyAuditLogInformation:
+ case PolicyAuditEventsInformation:
+ case PolicyAuditFullQueryInformation:
+ DesiredAccess = POLICY_VIEW_AUDIT_INFORMATION;
+ break;
- p->AuditingMode = FALSE; /* no auditing */
- p->EventAuditingOptions = NULL;
- p->MaximumAuditEventCount = 0;
+ case PolicyPrimaryDomainInformation:
+ case PolicyAccountDomainInformation:
+ case PolicyLsaServerRoleInformation:
+ case PolicyReplicaSourceInformation:
+ case PolicyDefaultQuotaInformation:
+ case PolicyModificationInformation:
+ case PolicyDnsDomainInformation:
+ case PolicyDnsDomainInformationInt:
+ case PolicyLocalAccountDomainInformation:
+ DesiredAccess = POLICY_VIEW_LOCAL_INFORMATION;
+ break;
- *PolicyInformation = (PLSAPR_POLICY_INFORMATION)p;
- }
- break;
+ case PolicyPdAccountInformation:
+ DesiredAccess = POLICY_GET_PRIVATE_INFORMATION;
+ break;
- case PolicyPrimaryDomainInformation: /* 3 */
- {
- PLSAPR_POLICY_PRIMARY_DOM_INFO p = MIDL_user_allocate(sizeof(LSAPR_POLICY_PRIMARY_DOM_INFO));
- if (p == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- p->Name.Length = 0;
- p->Name.MaximumLength = 0;
- p->Name.Buffer = NULL;
-#if 0
- p->Name.Length = wcslen(L"COMPUTERNAME");
- p->Name.MaximumLength = p->Name.Length + sizeof(WCHAR);
- p->Name.Buffer = MIDL_user_allocate(p->Name.MaximumLength);
- if (p->Name.Buffer == NULL)
- {
- MIDL_user_free(p);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
+ default:
+ ERR("Invalid InformationClass!\n");
+ return STATUS_INVALID_PARAMETER;
+ }
- wcscpy(p->Name.Buffer, L"COMPUTERNAME");
-#endif
+ Status = LsapValidateDbObject(PolicyHandle,
+ LsaDbPolicyObject,
+ DesiredAccess,
+ &DbObject);
+ if (!NT_SUCCESS(Status))
+ return Status;
- p->Sid = NULL; /* no domain, no workgroup */
+ switch (InformationClass)
+ {
+ case PolicyAuditLogInformation: /* 1 */
+ Status = LsarQueryAuditLog(PolicyHandle,
+ PolicyInformation);
- *PolicyInformation = (PLSAPR_POLICY_INFORMATION)p;
- }
- break;
+ case PolicyAuditEventsInformation: /* 2 */
+ Status = LsarQueryAuditEvents(PolicyHandle,
+ PolicyInformation);
+ break;
- case PolicyAccountDomainInformation: /* 5 */
- {
- PLSAPR_POLICY_ACCOUNT_DOM_INFO p = MIDL_user_allocate(sizeof(LSAPR_POLICY_ACCOUNT_DOM_INFO));
- if (p == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- p->DomainName.Length = 0;
- p->DomainName.MaximumLength = 0;
- p->DomainName.Buffer = NULL;
-#if 0
- p->DomainName.Length = wcslen(L"COMPUTERNAME");
- p->DomainName.MaximumLength = p->DomainName.Length + sizeof(WCHAR);
- p->DomainName.Buffer = MIDL_user_allocate(p->DomainName.MaximumLength);
- if (p->DomainName.Buffer == NULL)
- {
- MIDL_user_free(p);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
+ case PolicyPrimaryDomainInformation: /* 3 */
+ Status = LsarQueryPrimaryDomain(PolicyHandle,
+ PolicyInformation);
+ break;
- wcscpy(p->DomainName.Buffer, L"COMPUTERNAME");
-#endif
+ case PolicyPdAccountInformation: /* 4 */
+ Status = LsarQueryPdAccount(PolicyHandle,
+ PolicyInformation);
- p->Sid = NULL; /* no domain, no workgroup */
+ 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;
+ }
- *PolicyInformation = (PLSAPR_POLICY_INFORMATION)p;
- }
- break;
+ return Status;
+}
- case PolicyDnsDomainInformation: /* 12 (0xc) */
- {
- PLSAPR_POLICY_DNS_DOMAIN_INFO p = MIDL_user_allocate(sizeof(LSAPR_POLICY_DNS_DOMAIN_INFO));
- if (p == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- p->Name.Length = 0;
- p->Name.MaximumLength = 0;
- p->Name.Buffer = NULL;
-#if 0
- p->Name.Length = wcslen(L"COMPUTERNAME");
- p->Name.MaximumLength = p->Name.Length + sizeof(WCHAR);
- p->Name.Buffer = MIDL_user_allocate(p->Name.MaximumLength);
- if (p->Name.Buffer == NULL)
- {
- MIDL_user_free(p);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- wcscpy(p->Name.Buffer, L"COMPUTERNAME");
-#endif
+/* Function 8 */
+NTSTATUS WINAPI LsarSetInformationPolicy(
+ LSAPR_HANDLE PolicyHandle,
+ POLICY_INFORMATION_CLASS InformationClass,
+ PLSAPR_POLICY_INFORMATION PolicyInformation)
+{
+ PLSA_DB_OBJECT DbObject;
+ ACCESS_MASK DesiredAccess = 0;
+ NTSTATUS Status;
- p->DnsDomainName.Length = 0;
- p->DnsDomainName.MaximumLength = 0;
- p->DnsDomainName.Buffer = NULL;
+ TRACE("LsarSetInformationPolicy(%p,0x%08x,%p)\n",
+ PolicyHandle, InformationClass, PolicyInformation);
- p->DnsForestName.Length = 0;
- p->DnsForestName.MaximumLength = 0;
- p->DnsForestName.Buffer = 0;
+ if (PolicyInformation)
+ {
+ TRACE("*PolicyInformation %p\n", *PolicyInformation);
+ }
- memset(&p->DomainGuid, 0, sizeof(GUID));
+ switch (InformationClass)
+ {
+ case PolicyAuditLogInformation:
+ case PolicyAuditFullSetInformation:
+ DesiredAccess = POLICY_AUDIT_LOG_ADMIN;
+ break;
- p->Sid = NULL; /* no domain, no workgroup */
+ case PolicyAuditEventsInformation:
+ DesiredAccess = POLICY_SET_AUDIT_REQUIREMENTS;
+ break;
- *PolicyInformation = (PLSAPR_POLICY_INFORMATION)p;
- }
- break;
+ case PolicyPrimaryDomainInformation:
+ case PolicyAccountDomainInformation:
+ case PolicyDnsDomainInformation:
+ case PolicyDnsDomainInformationInt:
+ case PolicyLocalAccountDomainInformation:
+ DesiredAccess = POLICY_TRUST_ADMIN;
+ break;
- case PolicyAuditLogInformation:
- case PolicyPdAccountInformation:
case PolicyLsaServerRoleInformation:
case PolicyReplicaSourceInformation:
+ DesiredAccess = POLICY_SERVER_ADMIN;
+ break;
+
case PolicyDefaultQuotaInformation:
- case PolicyModificationInformation:
- case PolicyAuditFullSetInformation:
- case PolicyAuditFullQueryInformation:
- case PolicyEfsInformation:
- {
- FIXME("category not implemented\n");
- return STATUS_UNSUCCESSFUL;
- }
+ DesiredAccess = POLICY_SET_DEFAULT_QUOTA_LIMITS;
+ break;
+
+ default:
+ ERR("Invalid InformationClass!\n");
+ return STATUS_INVALID_PARAMETER;
}
- return STATUS_SUCCESS;
-}
+ 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;
-/* Function 8 */
-NTSTATUS WINAPI LsarSetInformationPolicy(
- LSAPR_HANDLE PolicyHandle,
- POLICY_INFORMATION_CLASS InformationClass,
- PLSAPR_POLICY_INFORMATION PolicyInformation)
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ 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;
}
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;
}
for (i = 0; i < Count; i++)
{
OutputSids[i].Use = SidTypeWellKnownGroup;
- OutputSids[i].RelativeId = DOMAIN_ALIAS_RID_ADMINS;
+ OutputSids[i].RelativeId = DOMAIN_USER_RID_ADMIN; //DOMAIN_ALIAS_RID_ADMINS;
OutputSids[i].DomainIndex = i;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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 WINAPI LsarSetSecret(
- LSAPR_HANDLE *SecretHandle,
+ 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;
}
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;
}
TRACE("LsarLookupPrivilegeValue(%p, %wZ, %p)\n",
PolicyHandle, Name, Value);
- Status = LsapValidateDbHandle(PolicyHandle,
- LsaDbPolicyHandle,
- 0); /* FIXME */
+ Status = LsapValidateDbObject(PolicyHandle,
+ LsaDbPolicyObject,
+ POLICY_LOOKUP_NAMES,
+ NULL);
if (!NT_SUCCESS(Status))
{
ERR("Invalid handle (Status %lx)\n", Status);
TRACE("LsarLookupPrivilegeName(%p, %p, %p)\n",
PolicyHandle, Value, Name);
- Status = LsapValidateDbHandle(PolicyHandle,
- LsaDbPolicyHandle,
- 0); /* FIXME */
+ Status = LsapValidateDbObject(PolicyHandle,
+ LsaDbPolicyObject,
+ POLICY_LOOKUP_NAMES,
+ NULL);
if (!NT_SUCCESS(Status))
{
ERR("Invalid handle\n");
PRPC_SID AccountSid,
PLSAPR_USER_RIGHT_SET UserRights)
{
+ PLSA_DB_OBJECT PolicyObject;
NTSTATUS Status;
FIXME("(%p,%p,%p) stub\n", PolicyHandle, AccountSid, UserRights);
- Status = LsapValidateDbHandle(PolicyHandle,
- LsaDbPolicyHandle,
- 0); /* FIXME */
+ Status = LsapValidateDbObject(PolicyHandle,
+ LsaDbPolicyObject,
+ ACCOUNT_VIEW,
+ &PolicyObject);
if (!NT_SUCCESS(Status))
return Status;
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);
}
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);
}
NTSTATUS WINAPI LsarQueryDomainInformationPolicy(
LSAPR_HANDLE PolicyHandle,
POLICY_INFORMATION_CLASS InformationClass,
- unsigned long *PolicyInformation)
+ PLSAPR_POLICY_DOMAIN_INFORMATION *PolicyInformation)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
NTSTATUS WINAPI LsarSetDomainInformationPolicy(
LSAPR_HANDLE PolicyHandle,
POLICY_INFORMATION_CLASS InformationClass,
- unsigned long PolicyInformation)
+ PLSAPR_POLICY_DOMAIN_INFORMATION PolicyInformation)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
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,
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;
}
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,