2020-09-30 17:12:29 +02:00

525 lines
12 KiB
C

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
cuttesu.c
Abstract:
This file contains tests that test functions in context.c, utility.c
and enumeration routines.
THE ROUTINES IN THIS FILE ARE FOR SAM SEVER TEST PURPOSES ONLY.
There are a number of server-side unit tests aimed at private routines
within the SAM server. These tests are defined in this file. This file
should only be compiled into the SAM server when it is built as a stand-
alone executable (built in the \um subdir). Therefore, it is only listed
in the sources file in the \um subdir.
Because the SAM code relies on a fairly large amount of state information
being in place from the initialization of the server, it is difficult to
write a unit test that "plugs in" to the server from the outside.
Author:
Murli Satagopan (ChrisMay) 24-Jun-1996
Environment:
User Mode - Win32
Revision History:
--*/
#include <samsrvp.h>
#include <dsutilp.h>
#include <dslayer.h>
#include <mappings.h>
#include <testutil.h>
NTSTATUS
SampDoAccountCountTests(
VOID
)
/*++
Routine Description:
Doing Account Count Tests , which basically gets hold of all account
counts in the Domain and verfies them
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
ULONG GroupCount1, AliasCount1, UserCount1;
ULONG GroupCount2, AliasCount2, UserCount2;
ULONG GroupCount3, AliasCount3, UserCount3;
//
// Get the Account counts in this Domain , increment and decrement
// them and verify that operations are O.K
//
Status = SampRetrieveAccountCounts(&UserCount1,&GroupCount1,&AliasCount1);
if (Status != STATUS_SUCCESS)
{
printf("\t\tRetrieve Account Counts 1 Failed \n");
goto Error;
}
Status = SampAdjustAccountCount(SampUserObjectType,TRUE);
if (Status != STATUS_SUCCESS)
{
printf("\t\tAdjust Account Counts 1 Failed \n");
goto Error;
}
Status = SampAdjustAccountCount(SampGroupObjectType,TRUE);
if (Status != STATUS_SUCCESS)
{
printf("\t\tAdjust Account Counts 2 Failed \n");
goto Error;
}
Status = SampAdjustAccountCount(SampAliasObjectType,TRUE);
if (Status != STATUS_SUCCESS)
{
printf("\t\tAdjust Account Counts 3 Failed \n");
goto Error;
}
Status = SampRetrieveAccountCounts(&UserCount2,&GroupCount2,&AliasCount2);
if (Status != STATUS_SUCCESS)
{
printf("\t\tRetrieve Account Counts 2 Failed \n");
goto Error;
}
Status = SampAdjustAccountCount(SampUserObjectType,FALSE);
if (Status != STATUS_SUCCESS)
{
printf("\t\tAdjust Account Counts 4 Failed \n");
goto Error;
}
Status = SampAdjustAccountCount(SampGroupObjectType,FALSE);
if (Status != STATUS_SUCCESS)
{
printf("\t\tAdjust Account Counts 5 Failed \n");
goto Error;
}
Status = SampAdjustAccountCount(SampAliasObjectType,FALSE);
if (Status != STATUS_SUCCESS)
{
printf("\t\tAdjust Account Counts 6 Failed \n");
goto Error;
}
Status = SampRetrieveAccountCounts(&UserCount3,&GroupCount3,&AliasCount3);
if (Status != STATUS_SUCCESS)
{
printf("Retrieve Account Counts 3 Failed \n");
goto Error;
}
// Verify the the results
if (
(UserCount1 != UserCount3)
|| (GroupCount1 != GroupCount3)
|| (AliasCount1 != AliasCount3)
|| ((UserCount1+1) != UserCount2)
|| ((GroupCount1+1) != GroupCount2)
|| ((AliasCount1+1) != AliasCount2)
)
{
printf("\t\tError Count Operations Mismatch\n");
Status = STATUS_UNSUCCESSFUL;
goto Error;
}
Error:
if (!NT_SUCCESS(Status))
printf("\t\tTest Failed : Return Code %d\n", Status);
return Status;
}
VOID
SampPrintEnumResults(
PSAMPR_ENUMERATION_BUFFER EnumResults,
ULONG Count
)
{
ULONG Index;
printf("\t\tEnumerating %d Accounts\n",Count);
for (Index=0;Index<Count;Index++)
{
printf("\t\t\tRid= %d ; Name = %S\n",
EnumResults->Buffer[Index].RelativeId,
EnumResults->Buffer[Index].Name.Buffer
);
}
}
NTSTATUS
SampDoEnumerationTests(
PSAMP_OBJECT DomainContext,
ULONG NumAccountsToCreate,
ULONG MaxMemorySize
)
{
NTSTATUS Status = STATUS_SUCCESS;
PSAMPR_ENUMERATION_BUFFER EnumResults;
ULONG Count;
ULONG Index;
SAM_ENUMERATE_HANDLE handle=0;
DSNAME **NewObject = NULL;
ULONG Rid =1;
PSID DomainSid;
//
// Define AttrBlocks
//
//
ATTRVAL CreateAttrsVal[] =
{
{ 0,NULL}, // Place Holder for Security Descriptor
{ 0,NULL}, // Place HOlder for Object Flat Name
{ 0,NULL}, // Place Holder for Account Control field
{sizeof(ULONG), (UCHAR *) &Rid} // Rid Field
};
ATTRTYP CreateAttrsTypes[]=
{
SAMP_USER_SECURITY_DESCRIPTOR,
SAMP_USER_ACCOUNT_NAME,
SAMP_FIXED_USER_ACCOUNT_CONTROL,
SAMP_FIXED_USER_USERID
};
DEFINE_ATTRBLOCK4(CreateAttrs,CreateAttrsTypes,CreateAttrsVal);
//
// At this point of time there are just 2 accounts. So an enumeration
// will go through the case of No Context continuations.
//
printf("\t\tTesting Simple case with 2 initial account objects\n");
Status = SamrEnumerateUsersInDomain(
DomainContext, //DomainHandle,
&handle, // EnumerationContext,
0, //UserAccountControl,
(PSAMPR_ENUMERATION_BUFFER *) & EnumResults,
1024, // Max length
&Count
);
if (Status != STATUS_SUCCESS)
goto Error;
if (handle != 0)
{
Status = STATUS_UNSUCCESSFUL;
goto Error;
}
SampPrintEnumResults(EnumResults, Count);
printf("\t\tTesting with %d more Accounts\n", NumAccountsToCreate);
Status = BuildDefaultSecurityDescriptor(
&(CreateAttrsVal[0].pVal),
&(CreateAttrsVal[0].valLen)
);
// Get the Domain Sid
DomainSid = SampDsGetObjectSid(DomainContext->ObjectNameInDs);
// Create the array that will hold the list of DS Names
NewObject = MIDL_user_allocate(NumAccountsToCreate * sizeof(DSNAME *));
if (NULL==NewObject)
goto Error;
// Zero the memory
RtlZeroMemory(NewObject,NumAccountsToCreate * sizeof(DSNAME *));
// Populate the directory with a large number of users
for (Index=0;Index<NumAccountsToCreate;Index++)
{
WCHAR Buffer[256];
ULONG Len = 0;
//
// Build an Account Name
//
swprintf(Buffer,L"User%d",Index);
Len = wcslen(Buffer) + 2;
CreateAttrsVal[1].pVal = (UCHAR *) Buffer;
CreateAttrsVal[1].valLen = Len * sizeof(WCHAR);
//
// Populate account control field
//
CreateAttrsVal[2].pVal = (UCHAR *) &Index;
CreateAttrsVal[2].valLen = sizeof(ULONG);
//
// Create a New object Name
//
Status = SampDsCreateDsName(
DomainContext->ObjectNameInDs,
Index+100,
&(NewObject[Index])
);
if NT_SUCCESS(Status)
{
NTSTATUS IgnoreStatus;
// Create the new Object in the DS.
Rid = Index + 100;
IgnoreStatus = SampDsCreateObject(
NewObject[Index],
SampUserObjectType,
&CreateAttrs,
(PSID) DomainSid
);
}
else
NewObject[Index]=NULL;
}
//
// Now do the work of Enumeration
//
do
{
Status = SamrEnumerateUsersInDomain(
DomainContext, //DomainHandle,
&handle, // EnumerationContext,
0, //UserAccountControl,
& EnumResults,
MaxMemorySize, // Max length
&Count
);
if (!NT_SUCCESS(Status))
goto Error;
SampPrintEnumResults(EnumResults, Count);
} while (Status==STATUS_MORE_ENTRIES);
Error:
//
// Remove the Host of Accounts that we created.
//
if (NULL!=NewObject)
{
for (Index=0;Index<NumAccountsToCreate;Index++)
{
NTSTATUS IgnoreStatus;
if (NULL!=NewObject[Index])
{
IgnoreStatus = SampDsDeleteObject(
NewObject[Index]
);
MIDL_user_free(NewObject[Index]);
}
}
MIDL_user_free(NewObject);
}
return Status;
}
NTSTATUS
SampTestContextAndUtility(
VOID * Param
)
/*++
Routine Description:
Tests the Context and Utility Routines which do various Functions.
This Rouitne does not require the Storage Layer tests to succeed.
DS Layer tests need to pass before this test can pass.
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
WCHAR Buffer[256];
DSNAME *pDsName;
WCHAR ObjectName[] = L"/cn=Account";
ULONG DomainIndex;
PSAMP_OBJECT AccountHandle;
ULONG Rid;
DSNAME *NewObject=NULL;
TESTINFO *TstInfo = (TESTINFO *)Param;
printf("TESTING CONTEXT AND UTILITY OPERATIONS\n");
//
// Create the required Objects in the DS
//
printf("\tSeeding DS\n");
SampAcquireWriteLock();
Status = SampSeedDS(
TstInfo->EnterpriseName,
TstInfo->EnterpriseNameLen
);
if (Status != STATUS_SUCCESS)
{
printf("SEEDING DS Failed, Reurned Error code %x\n", Status);
goto Error;
}
//
// Initialize an account domain in the DS.
//
printf("\tInitializing a DS Domain\n");
pDsName = (DSNAME *) Buffer;
SampInitializeDsName(
pDsName,
TstInfo->EnterpriseName,
TstInfo->EnterpriseNameLen,
ObjectName,
sizeof(ObjectName)
);
Status = InitDsDomain(pDsName);
if (!NT_SUCCESS(Status))
{
printf("Could not create DS Domain\n");
SampUnseedDs(
TstInfo->EnterpriseName,
TstInfo->EnterpriseNameLen
);
return Status;
}
DomainIndex = SampDefinedDomainsCount -1;
SampSetTransactionDomain(DomainIndex);
//
// Do Account count Tests
//
printf("\tDoing Account Count Test's\n");
Status = SampDoAccountCountTests();
if (Status != STATUS_SUCCESS)
{
printf("Account Count Test's Failed\n");
goto Error;
}
//
// Open Account Test -- Open a user account
//
printf("\tOpening Existing User Account\n");
Status = SampOpenAccount(
SampUserObjectType,
SampDefinedDomains[DomainIndex].Context,
0,
2,
TRUE,
& AccountHandle
);
if (Status != STATUS_SUCCESS)
{
printf("\t\tOpening User Account Failed\n");
goto Error;
}
//
// Now Close the Handle
//
SampDeleteContext(AccountHandle);
//
// Do Account Enumeration Tests
//
printf("\tDoing Enumeration Tests\n");
Status = SampDoEnumerationTests(
SampDefinedDomains[DomainIndex].Context,
8, // Num of Users to Create
64 // Max memory size to use while enumerating
);
if (Status != STATUS_SUCCESS)
{
printf("\t\tEnumeration test's Failed\n");
goto Error;
}
// Commit everything to the DS.
Status = SampMaybeEndDsTransaction(FALSE);
if (Status != STATUS_SUCCESS)
{
printf("\tSampMaybeEndDsTransaction error = 0x%lx\n", Status);
}
printf("CONTEXT AND UTILITY TESTS PASSED\n");
Error:
SampUnseedDs(
TstInfo->EnterpriseName,
TstInfo->EnterpriseNameLen
);
SampReleaseWriteLock(FALSE);
ASSERT(!SampExistsDsTransaction());
return Status;
}