mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2323 lines
68 KiB
2323 lines
68 KiB
/*++
|
|
|
|
Copyright (c) 1990 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
main.c
|
|
|
|
Abstract:
|
|
|
|
This file contains unit-test routines for the data conversion routines,
|
|
used to convert between SAM and DS in-memory data structures, located in
|
|
dsutil.c.
|
|
|
|
|
|
Author:
|
|
|
|
Chris Mayhall (ChrisMay) 09-May-1996
|
|
|
|
Environment:
|
|
|
|
User Mode - Win32
|
|
|
|
Revision History:
|
|
|
|
ChrisMay 09-May-1996
|
|
Created initial file, added tests for variable-length attributes.
|
|
ChrisMay 14-May-1996
|
|
Added tests for fixed-length attributes.
|
|
ChrisMay 14-May-1996
|
|
Added tests for multi-value attributes.
|
|
|
|
--*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <samsrvp.h>
|
|
#include <dsutilp.h>
|
|
#include <mappings.h>
|
|
|
|
// Constants
|
|
|
|
#define DBG_BUFFER_SIZE 128
|
|
#define MULTI_VALUE_COUNT_MAXIMUM 16
|
|
|
|
// Debugging Macros
|
|
|
|
// Set CNVRTDAT_DBG_PRINTF to zero to turn off debugging trace output; set it
|
|
// to one to enable output.
|
|
|
|
#define CNVRTDAT_DBG_PRINTF 1
|
|
|
|
#if (CNVRTDAT_DBG_PRINTF == 1)
|
|
#define DebugPrint printf
|
|
#else
|
|
#define DebugPrint
|
|
#endif
|
|
|
|
// Global Test Data (for fixed and variable length attributes)
|
|
|
|
DSATTR Attributes[20];
|
|
|
|
DSATTRVAL Attr1Val[MULTI_VALUE_COUNT_MAXIMUM];
|
|
DSATTRVAL Attr2Val[MULTI_VALUE_COUNT_MAXIMUM];
|
|
DSATTRVAL Attr3Val[MULTI_VALUE_COUNT_MAXIMUM];
|
|
DSATTRVAL Attr4Val[MULTI_VALUE_COUNT_MAXIMUM];
|
|
DSATTRVAL Attr5Val[MULTI_VALUE_COUNT_MAXIMUM];
|
|
DSATTRVAL Attr6Val[MULTI_VALUE_COUNT_MAXIMUM];
|
|
DSATTRVAL Attr7Val[MULTI_VALUE_COUNT_MAXIMUM];
|
|
DSATTRVAL Attr8Val[MULTI_VALUE_COUNT_MAXIMUM];
|
|
DSATTRVAL Attr9Val[MULTI_VALUE_COUNT_MAXIMUM];
|
|
DSATTRVAL Attr10Val[MULTI_VALUE_COUNT_MAXIMUM];
|
|
DSATTRVAL Attr11Val[MULTI_VALUE_COUNT_MAXIMUM];
|
|
DSATTRVAL Attr12Val[MULTI_VALUE_COUNT_MAXIMUM];
|
|
DSATTRVAL Attr13Val[MULTI_VALUE_COUNT_MAXIMUM];
|
|
DSATTRVAL Attr14Val[MULTI_VALUE_COUNT_MAXIMUM];
|
|
DSATTRVAL Attr15Val[MULTI_VALUE_COUNT_MAXIMUM];
|
|
DSATTRVAL Attr16Val[MULTI_VALUE_COUNT_MAXIMUM];
|
|
DSATTRVAL Attr17Val[MULTI_VALUE_COUNT_MAXIMUM];
|
|
DSATTRVAL Attr18Val[MULTI_VALUE_COUNT_MAXIMUM];
|
|
DSATTRVAL Attr19Val[MULTI_VALUE_COUNT_MAXIMUM];
|
|
DSATTRVAL Attr20Val[MULTI_VALUE_COUNT_MAXIMUM];
|
|
|
|
SECURITY_DESCRIPTOR SecurityDescriptor;
|
|
|
|
SID Sid;
|
|
SID OwnerSid;
|
|
SID GroupSid;
|
|
|
|
ACL Sacl;
|
|
ACL Dacl;
|
|
|
|
WCHAR OemString[] = {L"Oem Domain Information"};
|
|
UNICODE_STRING OemInfo;
|
|
WCHAR ReplicaString[] = {L"Replica Domain Information"};
|
|
UNICODE_STRING ReplicaInfo;
|
|
WCHAR GroupString[] = {L"GroupName"};
|
|
UNICODE_STRING GroupInfo;
|
|
WCHAR CommentString[] = {L"Group Comment String"};
|
|
UNICODE_STRING CommentInfo;
|
|
|
|
LARGE_INTEGER CreationTime = {1, 1};
|
|
LARGE_INTEGER ModifiedCount = {2, 2};
|
|
LARGE_INTEGER MaxPasswordAge = {3, 3};
|
|
LARGE_INTEGER MinPasswordAge = {4, 4};
|
|
LARGE_INTEGER ForceLogoff = {5, 5};
|
|
LARGE_INTEGER LockoutDuration = {6, 6};
|
|
LARGE_INTEGER LockoutObservationWindow = {7, 7};
|
|
LARGE_INTEGER ModifiedCountAtLastPromotion = {8, 8};
|
|
|
|
ULONG Revision = 100;
|
|
ULONG Unused1 = 200;
|
|
ULONG NextRid = 300;
|
|
USHORT MinPasswordLength = 4;
|
|
USHORT PasswordHistoryLength = 8;
|
|
USHORT LockoutThreshold = 3;
|
|
|
|
// ServerState and ServerRole are enums (see samsrvp.h, ntsam.h).
|
|
|
|
USHORT ServerState = SampServiceInitializing;
|
|
USHORT ServerRole = DomainServerRolePrimary;
|
|
|
|
ULONG Member1 = 0x12345678;
|
|
ULONG Member2 = 0x1234ABCD;
|
|
ULONG Member3 = 0xABCD1234;
|
|
ULONG RelativeId = 0x1111AAAA;
|
|
ULONG AdminCount = 2;
|
|
ULONG OperatorCount = 4;
|
|
|
|
BOOLEAN UasCompatibilityRequired = TRUE;
|
|
ULONG PasswordProperties = 0x1234FFFF;
|
|
ULONG AttributeProperties = 0xFFFF1234;
|
|
|
|
VOID
|
|
DumpBinaryData(
|
|
PBYTE pData,
|
|
DWORD cbData
|
|
)
|
|
{
|
|
DWORD i;
|
|
BYTE AsciiLine[16];
|
|
BYTE BinaryLine[16];
|
|
CHAR Buffer[DBG_BUFFER_SIZE];
|
|
|
|
if (0 == cbData)
|
|
{
|
|
DebugPrint("Zero-Length Data\n");
|
|
return;
|
|
}
|
|
|
|
if (cbData > DBG_BUFFER_SIZE)
|
|
{
|
|
DebugPrint("ShowBinaryData - truncating display to 256 bytes\n");
|
|
cbData = 256;
|
|
}
|
|
|
|
for (; cbData > 0 ;)
|
|
{
|
|
for (i = 0; i < 16 && cbData > 0 ; i++, cbData--)
|
|
{
|
|
BinaryLine[i] = *pData;
|
|
(isprint(*pData)) ? (AsciiLine[i] = *pData) : (AsciiLine[i] = '.');
|
|
pData++;
|
|
}
|
|
|
|
if (i < 15)
|
|
{
|
|
for (; i < 16 ; i++)
|
|
{
|
|
BinaryLine[i] = ' ';
|
|
AsciiLine[i] = ' ';
|
|
}
|
|
}
|
|
|
|
sprintf(Buffer,
|
|
"%02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x %02x %02x %02x\t",
|
|
BinaryLine[0],
|
|
BinaryLine[1],
|
|
BinaryLine[2],
|
|
BinaryLine[3],
|
|
BinaryLine[4],
|
|
BinaryLine[5],
|
|
BinaryLine[6],
|
|
BinaryLine[7],
|
|
BinaryLine[8],
|
|
BinaryLine[9],
|
|
BinaryLine[10],
|
|
BinaryLine[11],
|
|
BinaryLine[12],
|
|
BinaryLine[13],
|
|
BinaryLine[14],
|
|
BinaryLine[15]);
|
|
|
|
DebugPrint(Buffer);
|
|
|
|
sprintf(Buffer,
|
|
"%c%c%c%c%c%c%c%c - %c%c%c%c%c%c%c%c\n",
|
|
AsciiLine[0],
|
|
AsciiLine[1],
|
|
AsciiLine[2],
|
|
AsciiLine[3],
|
|
AsciiLine[4],
|
|
AsciiLine[5],
|
|
AsciiLine[6],
|
|
AsciiLine[7],
|
|
AsciiLine[8],
|
|
AsciiLine[9],
|
|
AsciiLine[10],
|
|
AsciiLine[11],
|
|
AsciiLine[12],
|
|
AsciiLine[13],
|
|
AsciiLine[14],
|
|
AsciiLine[15]);
|
|
|
|
DebugPrint(Buffer);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
DumpNtSid(
|
|
IN SID *Sid
|
|
)
|
|
{
|
|
// Note: PSID is defined as a PVOID, hence, use SID * explicitly.
|
|
|
|
DebugPrint(" Sid.Revision = %d\n", Sid->Revision);
|
|
DebugPrint(" Sid.SubAuthorityCount = %d\n", Sid->SubAuthorityCount);
|
|
DebugPrint(" Sid.IdentifierAuthority.Value[0] = %d\n", Sid->IdentifierAuthority.Value[0]);
|
|
DebugPrint(" Sid.IdentifierAuthority.Value[1] = %d\n", Sid->IdentifierAuthority.Value[1]);
|
|
DebugPrint(" Sid.IdentifierAuthority.Value[2] = %d\n", Sid->IdentifierAuthority.Value[2]);
|
|
DebugPrint(" Sid.IdentifierAuthority.Value[3] = %d\n", Sid->IdentifierAuthority.Value[3]);
|
|
DebugPrint(" Sid.IdentifierAuthority.Value[4] = %d\n", Sid->IdentifierAuthority.Value[4]);
|
|
DebugPrint(" Sid.IdentifierAuthority.Value[5] = %d\n", Sid->IdentifierAuthority.Value[5]);
|
|
DebugPrint(" Sid.SubAuthority[0] = %d\n", Sid->SubAuthority[0]);
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
DumpNtAcl(
|
|
IN ACL *Acl
|
|
)
|
|
{
|
|
DebugPrint(" Acl.AclRevision = %d\n", Acl->AclRevision);
|
|
DebugPrint(" Acl.Sbz1 = %d\n", Acl->Sbz1);
|
|
DebugPrint(" Acl.AclSize = %d\n", Acl->AclSize);
|
|
DebugPrint(" Acl.AceCount = %d\n", Acl->AceCount);
|
|
DebugPrint(" Acl.Sbz2 = %d\n", Acl->Sbz2);
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
DumpNtSecurityDescriptor(
|
|
IN SECURITY_DESCRIPTOR *SecDesc
|
|
)
|
|
{
|
|
// Note: PSSECURITY_DESCRIPTOR is defined as a PVOID, hence, use
|
|
// SECURITY_DESCRIPTOR * explicitly.
|
|
|
|
DebugPrint(" SecurityDescriptor.Revision = %d\n", SecDesc->Revision);
|
|
DebugPrint(" SecurityDescriptor.Sbz1 = %d\n", SecDesc->Sbz1);
|
|
DebugPrint(" SecurityDescriptor.Control = %d\n", SecDesc->Control);
|
|
DumpNtSid(SecDesc->Owner);
|
|
DumpNtSid(SecDesc->Group);
|
|
DumpNtAcl(SecDesc->Sacl);
|
|
DumpNtAcl(SecDesc->Dacl);
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
DumpSamSecurityDescriptor(
|
|
IN PSAMP_VARIABLE_LENGTH_ATTRIBUTE SamAttributes,
|
|
IN ULONG AttrIndex
|
|
)
|
|
{
|
|
NTSTATUS NtStatus = STATUS_INTERNAL_ERROR;
|
|
ULONG Offset = 0;
|
|
ULONG Length = 0;
|
|
ULONG Qualifier = 0;
|
|
PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
|
|
|
|
if (NULL != SamAttributes)
|
|
{
|
|
Offset = (ULONG)((SamAttributes + AttrIndex)->Offset);
|
|
Length = (ULONG)((SamAttributes + AttrIndex)->Length);
|
|
Qualifier = (ULONG)((SamAttributes + AttrIndex)->Qualifier);
|
|
|
|
SecurityDescriptor = (SECURITY_DESCRIPTOR*)((((PBYTE)SamAttributes) + Offset));
|
|
|
|
DebugPrint(" BufAddr = 0x%lx Offset = %lu Length = %lu Qualifier = %lu\n",
|
|
SamAttributes + Offset,
|
|
Offset,
|
|
Length,
|
|
Qualifier);
|
|
|
|
DumpNtSecurityDescriptor(SecurityDescriptor);
|
|
|
|
// BUG: SecurityDescriptor may be NULL.
|
|
|
|
NtStatus = STATUS_SUCCESS;
|
|
}
|
|
|
|
return(NtStatus);
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
DumpSamSid(
|
|
IN PSAMP_VARIABLE_LENGTH_ATTRIBUTE SamAttributes,
|
|
IN ULONG AttrIndex
|
|
)
|
|
{
|
|
NTSTATUS NtStatus = STATUS_SEVERITY_ERROR;
|
|
ULONG Offset = 0;
|
|
ULONG Length = 0;
|
|
ULONG Qualifier = 0;
|
|
PSID Sid = NULL;
|
|
|
|
if (NULL != SamAttributes)
|
|
{
|
|
Offset = (ULONG)((SamAttributes + AttrIndex)->Offset);
|
|
Length = (ULONG)((SamAttributes + AttrIndex)->Length);
|
|
Qualifier = (ULONG)((SamAttributes + AttrIndex)->Qualifier);
|
|
|
|
Sid = (SID *)((((PBYTE)SamAttributes) + Offset));
|
|
|
|
DebugPrint(" BufAddr = 0x%lx Offset = %lu Length = %lu Qualifier = %lu\n",
|
|
SamAttributes + Offset,
|
|
Offset,
|
|
Length,
|
|
Qualifier);
|
|
|
|
DumpNtSid(Sid);
|
|
|
|
// BUG: Sid may be NULL.
|
|
|
|
NtStatus = STATUS_SUCCESS;
|
|
}
|
|
|
|
return(NtStatus);
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
DumpSamOemInformation(
|
|
IN PSAMP_VARIABLE_LENGTH_ATTRIBUTE SamAttributes,
|
|
IN ULONG AttrIndex
|
|
)
|
|
{
|
|
NTSTATUS NtStatus = STATUS_SEVERITY_ERROR;
|
|
ULONG Offset = 0;
|
|
ULONG Length = 0;
|
|
ULONG Qualifier = 0;
|
|
PUNICODE_STRING OemString = NULL;
|
|
|
|
if (NULL != SamAttributes)
|
|
{
|
|
Offset = (ULONG)((SamAttributes + AttrIndex)->Offset);
|
|
Length = (ULONG)((SamAttributes + AttrIndex)->Length);
|
|
Qualifier = (ULONG)((SamAttributes + AttrIndex)->Qualifier);
|
|
|
|
OemString = (PUNICODE_STRING)((((PBYTE)SamAttributes) + Offset));
|
|
|
|
DebugPrint(" BufAddr = 0x%lx Offset = %lu Length = %lu Qualifier = %lu\n",
|
|
SamAttributes + Offset,
|
|
Offset,
|
|
Length,
|
|
Qualifier);
|
|
|
|
DebugPrint(" Oem Data = %ws\n", OemString->Buffer);
|
|
|
|
// BUG: OemString may be NULL.
|
|
|
|
NtStatus = STATUS_SUCCESS;
|
|
}
|
|
|
|
return(NtStatus);
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
DumpSamReplica(
|
|
IN PSAMP_VARIABLE_LENGTH_ATTRIBUTE SamAttributes,
|
|
IN ULONG AttrIndex
|
|
)
|
|
{
|
|
NTSTATUS NtStatus = STATUS_SEVERITY_ERROR;
|
|
ULONG Offset = 0;
|
|
ULONG Length = 0;
|
|
ULONG Qualifier = 0;
|
|
PUNICODE_STRING ReplicaString = NULL;
|
|
|
|
if (NULL != SamAttributes)
|
|
{
|
|
Offset = (ULONG)((SamAttributes + AttrIndex)->Offset);
|
|
Length = (ULONG)((SamAttributes + AttrIndex)->Length);
|
|
Qualifier = (ULONG)((SamAttributes + AttrIndex)->Qualifier);
|
|
|
|
ReplicaString = (PUNICODE_STRING)((((PBYTE)SamAttributes) + Offset));
|
|
|
|
DebugPrint(" BufAddr = 0x%lx Offset = %lu Length = %lu Qualifier = %lu\n",
|
|
SamAttributes + Offset,
|
|
Offset,
|
|
Length,
|
|
Qualifier);
|
|
|
|
DebugPrint(" Replica Data = %ws\n", ReplicaString->Buffer);
|
|
|
|
// BUG: ReplicaString may be NULL.
|
|
|
|
NtStatus = STATUS_SUCCESS;
|
|
}
|
|
|
|
return(NtStatus);
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
DumpSamUnicodeStringAttribute(
|
|
IN PSAMP_VARIABLE_LENGTH_ATTRIBUTE SamAttributes,
|
|
IN ULONG AttrIndex
|
|
)
|
|
{
|
|
NTSTATUS NtStatus = STATUS_SEVERITY_ERROR;
|
|
ULONG Offset = 0;
|
|
ULONG Length = 0;
|
|
ULONG Qualifier = 0;
|
|
PUNICODE_STRING String = NULL;
|
|
|
|
if (NULL != SamAttributes)
|
|
{
|
|
Offset = (ULONG)((SamAttributes + AttrIndex)->Offset);
|
|
Length = (ULONG)((SamAttributes + AttrIndex)->Length);
|
|
Qualifier = (ULONG)((SamAttributes + AttrIndex)->Qualifier);
|
|
|
|
String = (PUNICODE_STRING)((((PBYTE)SamAttributes) + Offset));
|
|
|
|
DebugPrint(" BufAddr = 0x%lx Offset = %lu Length = %lu Qualifier = %lu\n",
|
|
SamAttributes + Offset,
|
|
Offset,
|
|
Length,
|
|
Qualifier);
|
|
|
|
DebugPrint(" String Data = %ws\n", String->Buffer);
|
|
|
|
// BUG: String may be NULL.
|
|
|
|
NtStatus = STATUS_SUCCESS;
|
|
}
|
|
|
|
return(NtStatus);
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
DumpNtGroupMembers(
|
|
IN PULONG Identifiers,
|
|
IN ULONG ValueCount
|
|
)
|
|
{
|
|
ULONG ValueIndex = 0;
|
|
|
|
for (ValueIndex = 0; ValueIndex < ValueCount; ValueIndex++)
|
|
{
|
|
DebugPrint(" Group Member %lu ID = 0x%lx\n",
|
|
ValueIndex,
|
|
*(Identifiers + ValueIndex));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
DumpSamGroupMembers(
|
|
IN PSAMP_VARIABLE_LENGTH_ATTRIBUTE SamAttributes,
|
|
IN ULONG AttrIndex
|
|
)
|
|
{
|
|
NTSTATUS NtStatus = STATUS_SEVERITY_ERROR;
|
|
ULONG Offset = 0;
|
|
ULONG Length = 0;
|
|
ULONG Qualifier = 0;
|
|
PULONG Identifiers = NULL;
|
|
|
|
if (NULL != SamAttributes)
|
|
{
|
|
Offset = (ULONG)((SamAttributes + AttrIndex)->Offset);
|
|
Length = (ULONG)((SamAttributes + AttrIndex)->Length);
|
|
Qualifier = (ULONG)((SamAttributes + AttrIndex)->Qualifier);
|
|
|
|
Identifiers = (PULONG)((((PBYTE)SamAttributes) + Offset));
|
|
|
|
DebugPrint(" BufAddr = 0x%lx Offset = %lu Length = %lu Qualifier = %lu\n",
|
|
SamAttributes + Offset,
|
|
Offset,
|
|
Length,
|
|
Qualifier);
|
|
|
|
DumpNtGroupMembers(Identifiers, Qualifier);
|
|
|
|
// BUG: Identifiers may be NULL.
|
|
|
|
NtStatus = STATUS_SUCCESS;
|
|
}
|
|
|
|
return(NtStatus);
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
DumpDsSecurityDescriptor(
|
|
IN PDSATTR DsAttributes,
|
|
IN ULONG AttrIndex
|
|
)
|
|
{
|
|
NTSTATUS NtStatus = STATUS_SEVERITY_ERROR;
|
|
ULONG Type = 0;
|
|
ULONG Length = 0;
|
|
ULONG ValueCount = 0;
|
|
ULONG Index = 0;
|
|
PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
|
|
|
|
if (NULL != DsAttributes)
|
|
{
|
|
Type = DsAttributes[AttrIndex].attrTyp;
|
|
ValueCount = DsAttributes[AttrIndex].AttrVal.valCount;
|
|
|
|
for (Index = 0; Index < ValueCount; Index++)
|
|
{
|
|
Length = DsAttributes[AttrIndex].AttrVal.pAVal[Index].valLen;
|
|
SecurityDescriptor = (PSECURITY_DESCRIPTOR)DsAttributes[AttrIndex].AttrVal.pAVal[Index].pVal;
|
|
DebugPrint(" AttrType = %lu ValueCount = %lu ValueLength = %lu\n", Type, ValueCount, Length);
|
|
DumpNtSecurityDescriptor(SecurityDescriptor);
|
|
}
|
|
|
|
// BUG: SecurityDescriptor may be NULL.
|
|
|
|
NtStatus = STATUS_SUCCESS;
|
|
}
|
|
|
|
return(NtStatus);
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
DumpDsSid(
|
|
IN PDSATTR DsAttributes,
|
|
IN ULONG AttrIndex
|
|
)
|
|
{
|
|
NTSTATUS NtStatus = STATUS_SEVERITY_ERROR;
|
|
ULONG Type = 0;
|
|
ULONG Length = 0;
|
|
ULONG ValueCount = 0;
|
|
ULONG Index = 0;
|
|
PSID Sid = NULL;
|
|
|
|
if (NULL != DsAttributes)
|
|
{
|
|
Type = DsAttributes[AttrIndex].attrTyp;
|
|
ValueCount = DsAttributes[AttrIndex].AttrVal.valCount;
|
|
|
|
for (Index = 0; Index < ValueCount; Index++)
|
|
{
|
|
Length = DsAttributes[AttrIndex].AttrVal.pAVal[Index].valLen;
|
|
Sid = (PSID)DsAttributes[AttrIndex].AttrVal.pAVal[Index].pVal;
|
|
DebugPrint(" AttrType = %lu ValueCount = %lu ValueLength = %lu\n", Type, ValueCount, Length);
|
|
DumpNtSid(Sid);
|
|
}
|
|
|
|
// BUG: Sid may be NULL.
|
|
|
|
NtStatus = STATUS_SUCCESS;
|
|
}
|
|
|
|
return(NtStatus);
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
DumpDsOemInformation(
|
|
IN PDSATTR DsAttributes,
|
|
IN ULONG AttrIndex
|
|
)
|
|
{
|
|
NTSTATUS NtStatus = STATUS_SEVERITY_ERROR;
|
|
ULONG Type = 0;
|
|
ULONG Length = 0;
|
|
ULONG ValueCount = 0;
|
|
ULONG Index = 0;
|
|
PUNICODE_STRING OemString = NULL;
|
|
|
|
if (NULL != DsAttributes)
|
|
{
|
|
Type = DsAttributes[AttrIndex].attrTyp;
|
|
ValueCount = DsAttributes[AttrIndex].AttrVal.valCount;
|
|
|
|
for (Index = 0; Index < ValueCount; Index++)
|
|
{
|
|
Length = DsAttributes[AttrIndex].AttrVal.pAVal[Index].valLen;
|
|
OemString = (PUNICODE_STRING)DsAttributes[AttrIndex].AttrVal.pAVal[Index].pVal;
|
|
DebugPrint(" AttrType = %lu ValueCount = %lu ValueLength = %lu\n", Type, ValueCount, Length);
|
|
DebugPrint(" Oem Data = %ws\n", OemString->Buffer);
|
|
}
|
|
|
|
// BUG: OemString may be NULL.
|
|
|
|
NtStatus = STATUS_SUCCESS;
|
|
}
|
|
|
|
return(NtStatus);
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
DumpDsReplica(
|
|
IN PDSATTR DsAttributes,
|
|
IN ULONG AttrIndex
|
|
)
|
|
{
|
|
NTSTATUS NtStatus = STATUS_SEVERITY_ERROR;
|
|
ULONG Type = 0;
|
|
ULONG Length = 0;
|
|
ULONG ValueCount = 0;
|
|
ULONG Index = 0;
|
|
PUNICODE_STRING ReplicaString = NULL;
|
|
|
|
if (NULL != DsAttributes)
|
|
{
|
|
Type = DsAttributes[AttrIndex].attrTyp;
|
|
ValueCount = DsAttributes[AttrIndex].AttrVal.valCount;
|
|
|
|
for (Index = 0; Index < ValueCount; Index++)
|
|
{
|
|
Length = DsAttributes[AttrIndex].AttrVal.pAVal[Index].valLen;
|
|
ReplicaString = (PUNICODE_STRING)DsAttributes[AttrIndex].AttrVal.pAVal[Index].pVal;
|
|
DebugPrint(" AttrType = %lu ValueCount = %lu ValueLength = %lu\n", Type, ValueCount, Length);
|
|
DebugPrint(" Replica Data = %ws\n", ReplicaString->Buffer);
|
|
}
|
|
|
|
// BUG: ReplicaString may be NULL.
|
|
|
|
NtStatus = STATUS_SUCCESS;
|
|
}
|
|
|
|
return(NtStatus);
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
DumpDsUnicodeStringAttribute(
|
|
IN PDSATTR DsAttributes,
|
|
IN ULONG AttrIndex
|
|
)
|
|
{
|
|
NTSTATUS NtStatus = STATUS_SEVERITY_ERROR;
|
|
ULONG Type = 0;
|
|
ULONG Length = 0;
|
|
ULONG ValueCount = 0;
|
|
ULONG Index = 0;
|
|
PUNICODE_STRING String = NULL;
|
|
|
|
if (NULL != DsAttributes)
|
|
{
|
|
Type = DsAttributes[AttrIndex].attrTyp;
|
|
ValueCount = DsAttributes[AttrIndex].AttrVal.valCount;
|
|
|
|
for (Index = 0; Index < ValueCount; Index++)
|
|
{
|
|
Length = DsAttributes[AttrIndex].AttrVal.pAVal[Index].valLen;
|
|
String = (PUNICODE_STRING)DsAttributes[AttrIndex].AttrVal.pAVal[Index].pVal;
|
|
DebugPrint(" AttrType = %lu ValueCount = %lu ValueLength = %lu\n", Type, ValueCount, Length);
|
|
DebugPrint(" String Data = %ws\n", String->Buffer);
|
|
}
|
|
|
|
// BUG: String may be NULL.
|
|
|
|
NtStatus = STATUS_SUCCESS;
|
|
}
|
|
|
|
return(NtStatus);
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
DumpDsGroupMembers(
|
|
IN PDSATTR DsAttributes,
|
|
IN ULONG AttrIndex
|
|
)
|
|
{
|
|
NTSTATUS NtStatus = STATUS_SEVERITY_ERROR;
|
|
ULONG Type = 0;
|
|
ULONG Length = 0;
|
|
ULONG ValueCount = 0;
|
|
ULONG Index = 0;
|
|
ULONG Identifier = 0;
|
|
|
|
if (NULL != DsAttributes)
|
|
{
|
|
Type = DsAttributes[AttrIndex].attrTyp;
|
|
ValueCount = DsAttributes[AttrIndex].AttrVal.valCount;
|
|
|
|
for (Index = 0; Index < ValueCount; Index++)
|
|
{
|
|
Length = DsAttributes[AttrIndex].AttrVal.pAVal[Index].valLen;
|
|
Identifier = *(PULONG)DsAttributes[AttrIndex].AttrVal.pAVal[Index].pVal;
|
|
DebugPrint(" AttrType = %lu ValueCount = %lu ValueLength = %lu\n", Type, ValueCount, Length);
|
|
DebugPrint(" Member Identifier = 0x%lx\n", Identifier);
|
|
}
|
|
|
|
// BUG: Identifiers may be NULL.
|
|
|
|
NtStatus = STATUS_SUCCESS;
|
|
}
|
|
|
|
return(NtStatus);
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
CompareDsAttrs(
|
|
DSATTR DsAttr1,
|
|
DSATTR DsAttr2
|
|
)
|
|
{
|
|
NTSTATUS NtStatus = STATUS_INTERNAL_ERROR;
|
|
ULONG ValueCount = 0;
|
|
ULONG ValueCount1 = 0;
|
|
ULONG ValueCount2 = 0;
|
|
PDSATTRVAL AttrValue1 = NULL;
|
|
PDSATTRVAL AttrValue2 = NULL;
|
|
ULONG ValueIndex = 0;
|
|
ULONG ValueLength = 0;
|
|
ULONG ValueLength1 = 0;
|
|
ULONG ValueLength2 = 0;
|
|
PUCHAR Value1 = NULL;
|
|
PUCHAR Value2 = NULL;
|
|
INT Status = -1;
|
|
|
|
if (DsAttr1.attrTyp == DsAttr2.attrTyp)
|
|
{
|
|
ValueCount1 = DsAttr1.AttrVal.valCount;
|
|
ValueCount2 = DsAttr2.AttrVal.valCount;
|
|
|
|
if (ValueCount1 == ValueCount2)
|
|
{
|
|
ValueCount = ValueCount1;
|
|
|
|
AttrValue1 = DsAttr1.AttrVal.pAVal;
|
|
AttrValue2 = DsAttr2.AttrVal.pAVal;
|
|
|
|
if ((NULL != AttrValue1) &&
|
|
(NULL != AttrValue2) &&
|
|
(AttrValue1 != AttrValue2)) // This may be okay
|
|
{
|
|
for (ValueIndex = 0; ValueIndex < ValueCount; ValueIndex++)
|
|
{
|
|
ValueLength1 = AttrValue1[ValueIndex].valLen;
|
|
ValueLength2 = AttrValue2[ValueIndex].valLen;
|
|
|
|
// BUG: Value length test doesn't know about alignment.
|
|
// Variable-length attributes are DWORD aligned if needed
|
|
// by SampExtractAttributeFromDsAttr, but this test does
|
|
// not know about any sort of alignment!
|
|
|
|
if (((ValueLength1 + 1) == ValueLength2) || // DWORD align case
|
|
((ValueLength1 + 2) == ValueLength2) || // DWORD align case
|
|
((ValueLength1 + 3) == ValueLength2)) // DWORD align case
|
|
{
|
|
DebugPrint("ASSUMING DWORD ALIGNMENT: ValueLength1 = %lu ValueLength2 = %lu\n",
|
|
ValueLength1,
|
|
ValueLength2);
|
|
}
|
|
|
|
if ((ValueLength1 == ValueLength2) ||
|
|
((ValueLength1 + 1) == ValueLength2) || // DWORD align case
|
|
((ValueLength1 + 2) == ValueLength2) || // DWORD align case
|
|
((ValueLength1 + 3) == ValueLength2)) // DWORD align case
|
|
{
|
|
ValueLength = ValueLength2;
|
|
|
|
Value1 = AttrValue1[ValueIndex].pVal;
|
|
Value2 = AttrValue2[ValueIndex].pVal;
|
|
|
|
if ((NULL != Value1) &&
|
|
(NULL != Value2) &&
|
|
(Value1 != Value2)) // This may be okay
|
|
{
|
|
Status = memcmp(Value1, Value2, ValueLength);
|
|
|
|
if (0 == Status)
|
|
{
|
|
NtStatus = STATUS_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
DebugPrint("RtlCompareMemory returned %d\n",
|
|
Status);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DebugPrint("Value1 Address = 0x%lx Value2 Address = 0x%lx\n",
|
|
Value1,
|
|
Value2);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DebugPrint("ValueLength1 = %lu ValueLength2 = %lu\n",
|
|
ValueLength1,
|
|
ValueLength2);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DebugPrint("AttrValue1 Address = 0x%lx AttrValue2 Address = 0x%lx\n",
|
|
AttrValue1,
|
|
AttrValue2);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DebugPrint("ValueCount1 = %lu ValueCount2 = %lu\n",
|
|
ValueCount1,
|
|
ValueCount2);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DebugPrint("attrTyp1 = %lu attrTyp2 = %lu\n",
|
|
DsAttr1.attrTyp,
|
|
DsAttr2.attrTyp);
|
|
}
|
|
|
|
return(NtStatus);
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
CompareDsAttrBlocks(
|
|
PDSATTRBLOCK DsAttrBlock1,
|
|
PDSATTRBLOCK DsAttrBlock2
|
|
)
|
|
{
|
|
NTSTATUS NtStatus = STATUS_INTERNAL_ERROR;
|
|
ULONG AttrIndex = 0;
|
|
ULONG AttrCount = 0;
|
|
ULONG AttrCount1 = 0;
|
|
ULONG AttrCount2 = 0;
|
|
PDSATTR Attributes1 = NULL;
|
|
PDSATTR Attributes2 = NULL;
|
|
|
|
if ((NULL != DsAttrBlock1) &&
|
|
(NULL != DsAttrBlock2) &&
|
|
(DsAttrBlock1 != DsAttrBlock2))
|
|
{
|
|
AttrCount1 = DsAttrBlock1->attrCount;
|
|
AttrCount2 = DsAttrBlock2->attrCount;
|
|
|
|
if (AttrCount1 == AttrCount2)
|
|
{
|
|
AttrCount = AttrCount1;
|
|
|
|
Attributes1 = DsAttrBlock1->pAttr;
|
|
Attributes2 = DsAttrBlock2->pAttr;
|
|
|
|
if ((NULL != Attributes1) &&
|
|
(NULL != Attributes2) &&
|
|
(Attributes1 != Attributes2))
|
|
{
|
|
for (AttrIndex = 0; AttrIndex < AttrCount; AttrIndex++)
|
|
{
|
|
NtStatus = CompareDsAttrs(Attributes1[AttrIndex],
|
|
Attributes2[AttrIndex]);
|
|
|
|
if (!NT_SUCCESS(NtStatus))
|
|
{
|
|
DebugPrint("CompareDsAttrs returned 0x%lx\n",
|
|
NtStatus);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DebugPrint("Attributes1 Address = 0x%lx Attributes2 Address = 0x%lx\n",
|
|
Attributes1,
|
|
Attributes2);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DebugPrint("AttrCount1 = %lu AttrCount2 = %lu\n",
|
|
AttrCount1,
|
|
AttrCount2);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DebugPrint("DsAttrBlock1 Address = 0x%lx DsAttrBlock2 Address = 0x%lx\n",
|
|
DsAttrBlock1,
|
|
DsAttrBlock2);
|
|
|
|
NtStatus = STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
return(NtStatus);
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
SetupVariableLengthDomainAttributes(
|
|
PDSATTRBLOCK DsAttributesIn
|
|
)
|
|
{
|
|
ULONG AttrIndex = 0;
|
|
ULONG ValueIndex = 0;
|
|
|
|
// Set up domain security descriptor
|
|
|
|
ValueIndex = 0;
|
|
|
|
// Set up the SIDs and ACLs for the descriptor
|
|
|
|
OwnerSid.Revision = 1; // UCHAR
|
|
OwnerSid.SubAuthorityCount = 1; // UCHAR
|
|
OwnerSid.IdentifierAuthority.Value[0] = 1; // UCHAR[6]
|
|
OwnerSid.IdentifierAuthority.Value[1] = 2;
|
|
OwnerSid.IdentifierAuthority.Value[2] = 3;
|
|
OwnerSid.IdentifierAuthority.Value[3] = 4;
|
|
OwnerSid.IdentifierAuthority.Value[4] = 5;
|
|
OwnerSid.IdentifierAuthority.Value[5] = 6;
|
|
OwnerSid.SubAuthority[0] = 111; // ULONG
|
|
|
|
GroupSid.Revision = 1; // UCHAR
|
|
GroupSid.SubAuthorityCount = 1; // UCHAR
|
|
GroupSid.IdentifierAuthority.Value[0] = 1; // UCHAR[6]
|
|
GroupSid.IdentifierAuthority.Value[1] = 2;
|
|
GroupSid.IdentifierAuthority.Value[2] = 3;
|
|
GroupSid.IdentifierAuthority.Value[3] = 4;
|
|
GroupSid.IdentifierAuthority.Value[4] = 5;
|
|
GroupSid.IdentifierAuthority.Value[5] = 6;
|
|
GroupSid.SubAuthority[0] = 222; // ULONG
|
|
|
|
Sacl.AclRevision = 1; // UCHAR
|
|
Sacl.Sbz1 = 1; // UCHAR
|
|
Sacl.AclSize = 1; // USHORT
|
|
Sacl.AceCount = 1; // USHORT
|
|
Sacl.Sbz2 = 1; // USHORT
|
|
|
|
Dacl.AclRevision = 1; // UCHAR
|
|
Dacl.Sbz1 = 1; // UCHAR
|
|
Dacl.AclSize = 1; // USHORT
|
|
Dacl.AceCount = 1; // USHORT
|
|
Dacl.Sbz2 = 1; // USHORT
|
|
|
|
SecurityDescriptor.Revision = 1; // UCHAR
|
|
SecurityDescriptor.Sbz1 = 1; // UCHAR
|
|
SecurityDescriptor.Control = 1; // USHORT
|
|
SecurityDescriptor.Owner = &OwnerSid; // PSID
|
|
SecurityDescriptor.Group = &GroupSid; // PSID
|
|
SecurityDescriptor.Sacl = &Sacl; // PACL
|
|
SecurityDescriptor.Dacl = &Dacl; // PACL
|
|
|
|
Attr1Val[ValueIndex].valLen = sizeof(SECURITY_DESCRIPTOR) +
|
|
(2 * sizeof(SID)) +
|
|
(2 * sizeof(ACL));
|
|
|
|
Attr1Val[ValueIndex].pVal = (PUCHAR)&SecurityDescriptor;
|
|
|
|
AttrIndex = SAMP_DOMAIN_SECURITY_DESCRIPTOR;
|
|
|
|
// BUG: What should type be set to?
|
|
|
|
Attributes[AttrIndex].attrTyp = 0;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr1Val[ValueIndex];
|
|
|
|
// Set up domain SID
|
|
|
|
ValueIndex = 0;
|
|
|
|
Sid.Revision = 1; // UCHAR
|
|
Sid.SubAuthorityCount = 1; // UCHAR
|
|
Sid.IdentifierAuthority.Value[0] = 1; // UCHAR[6]
|
|
Sid.IdentifierAuthority.Value[1] = 2;
|
|
Sid.IdentifierAuthority.Value[2] = 3;
|
|
Sid.IdentifierAuthority.Value[3] = 4;
|
|
Sid.IdentifierAuthority.Value[4] = 5;
|
|
Sid.IdentifierAuthority.Value[5] = 6;
|
|
Sid.SubAuthority[0] = 333; // ULONG
|
|
|
|
Attr2Val[ValueIndex].valLen = sizeof(SID);
|
|
Attr2Val[ValueIndex].pVal = (PUCHAR)&Sid;
|
|
|
|
AttrIndex = SAMP_DOMAIN_SID;
|
|
|
|
// BUG: What should type be set to?
|
|
|
|
Attributes[AttrIndex].attrTyp = 0;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr2Val[ValueIndex];
|
|
|
|
// Set up domain OEM information
|
|
|
|
ValueIndex = 0;
|
|
|
|
RtlInitUnicodeString(&OemInfo, OemString);
|
|
|
|
// NOTE: valLen should not include space for the null character because it
|
|
// is dropped by the RTL routines that manipulate UNICODE_STRINGs, hence
|
|
// will lead to an erroneous buffer length when tested during the call to
|
|
// CompareDsAttrBlocks.
|
|
|
|
Attr3Val[ValueIndex].valLen = sizeof(UNICODE_STRING) +
|
|
(sizeof(WCHAR) * wcslen(OemString));
|
|
|
|
Attr3Val[ValueIndex].pVal = (PUCHAR)&OemInfo;
|
|
|
|
AttrIndex = SAMP_DOMAIN_OEM_INFORMATION;
|
|
|
|
// BUG: What should type be set to?
|
|
|
|
Attributes[AttrIndex].attrTyp = 0;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr3Val[ValueIndex];
|
|
|
|
// Set up domain replica
|
|
|
|
ValueIndex = 0;
|
|
|
|
RtlInitUnicodeString(&ReplicaInfo, ReplicaString);
|
|
|
|
Attr4Val[ValueIndex].valLen = sizeof(UNICODE_STRING) +
|
|
(sizeof(WCHAR) * wcslen(ReplicaString));
|
|
|
|
Attr4Val[ValueIndex].pVal = (PUCHAR)&ReplicaInfo;
|
|
|
|
AttrIndex = SAMP_DOMAIN_REPLICA;
|
|
|
|
// BUG: What should type be set to?
|
|
|
|
Attributes[AttrIndex].attrTyp = 0;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr4Val[ValueIndex];
|
|
|
|
DsAttributesIn->attrCount = SAMP_DOMAIN_VARIABLE_ATTRIBUTES;
|
|
DsAttributesIn->pAttr = Attributes;
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
BasicVariableLengthAttrTest(
|
|
VOID
|
|
)
|
|
{
|
|
NTSTATUS NtStatus = STATUS_SEVERITY_ERROR;
|
|
INT ObjectType = SampDomainObjectType;
|
|
DSATTRBLOCK DsAttributesIn;
|
|
PDSATTRBLOCK DsAttributesOut;
|
|
PSAMP_VARIABLE_LENGTH_ATTRIBUTE SamAttributes;
|
|
ULONG AttrIndex = 0;
|
|
ULONG Length = 0;
|
|
|
|
SetupVariableLengthDomainAttributes(&DsAttributesIn);
|
|
|
|
NtStatus = SampConvertAttrBlockToVarLengthAttributes(ObjectType,
|
|
&DsAttributesIn,
|
|
&SamAttributes,
|
|
&Length);
|
|
|
|
if (NT_SUCCESS(NtStatus))
|
|
{
|
|
DebugPrint("\nSAM Variable-Length Domain Attributes:\n");
|
|
|
|
for (AttrIndex = 0;
|
|
AttrIndex < SAMP_DOMAIN_VARIABLE_ATTRIBUTES;
|
|
AttrIndex++)
|
|
{
|
|
switch(AttrIndex)
|
|
{
|
|
|
|
case SAMP_DOMAIN_SECURITY_DESCRIPTOR:
|
|
DumpSamSecurityDescriptor(SamAttributes, AttrIndex);
|
|
break;
|
|
|
|
case SAMP_DOMAIN_SID:
|
|
DumpSamSid(SamAttributes, AttrIndex);
|
|
break;
|
|
|
|
case SAMP_DOMAIN_OEM_INFORMATION:
|
|
DumpSamOemInformation(SamAttributes, AttrIndex);
|
|
break;
|
|
|
|
case SAMP_DOMAIN_REPLICA:
|
|
DumpSamReplica(SamAttributes, AttrIndex);
|
|
break;
|
|
|
|
default:
|
|
DebugPrint("ERROR - UNRECOGNIZED ATTRIBUTE\n");
|
|
break;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
if (NT_SUCCESS(NtStatus))
|
|
{
|
|
NtStatus = SampConvertVarLengthAttributesToAttrBlock(ObjectType,
|
|
SamAttributes,
|
|
&DsAttributesOut);
|
|
}
|
|
|
|
if (NT_SUCCESS(NtStatus))
|
|
{
|
|
DebugPrint("\nDS Domain Attributes:\n");
|
|
|
|
DebugPrint(" DsAttributes.attrCount = %lu\n", DsAttributesOut->attrCount);
|
|
|
|
for (AttrIndex = 0;
|
|
AttrIndex < SAMP_DOMAIN_VARIABLE_ATTRIBUTES;
|
|
AttrIndex++)
|
|
{
|
|
switch(AttrIndex)
|
|
{
|
|
|
|
case SAMP_DOMAIN_SECURITY_DESCRIPTOR:
|
|
DumpDsSecurityDescriptor(DsAttributesOut->pAttr, AttrIndex);
|
|
break;
|
|
|
|
case SAMP_DOMAIN_SID:
|
|
DumpDsSid(DsAttributesOut->pAttr, AttrIndex);
|
|
break;
|
|
|
|
case SAMP_DOMAIN_OEM_INFORMATION:
|
|
DumpDsOemInformation(DsAttributesOut->pAttr, AttrIndex);
|
|
break;
|
|
|
|
case SAMP_DOMAIN_REPLICA:
|
|
DumpDsReplica(DsAttributesOut->pAttr, AttrIndex);
|
|
break;
|
|
|
|
default:
|
|
DebugPrint("ERROR - UNRECOGNIZED ATTRIBUTE\n");
|
|
break;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
// Make sure that the input data is the same as the output.
|
|
|
|
NtStatus = CompareDsAttrBlocks(&DsAttributesIn, DsAttributesOut);
|
|
|
|
return(NtStatus);
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
SetupFixedLengthDomainAttributes(
|
|
PDSATTRBLOCK DsAttributesIn
|
|
)
|
|
{
|
|
// ValueIndex is always zero because fixed-length attributess are not
|
|
// multi-valued.
|
|
|
|
ULONG ValueIndex = 0;
|
|
ULONG AttrIndex = 0;
|
|
|
|
// Set up revision
|
|
|
|
AttrIndex = 0;
|
|
|
|
Attr1Val[ValueIndex].valLen = sizeof(ULONG);
|
|
Attr1Val[ValueIndex].pVal = (PUCHAR)&Revision;
|
|
Attributes[AttrIndex].attrTyp = SAMP_FIXED_DOMAIN_REVISION_LEVEL;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr1Val[ValueIndex];
|
|
|
|
// Set up unused1
|
|
|
|
AttrIndex = 1;
|
|
|
|
// BUG: Setting attrTyp to BOGUS_TYPE due to missing types.
|
|
|
|
Attr2Val[ValueIndex].valLen = sizeof(ULONG);
|
|
Attr2Val[ValueIndex].pVal = (PUCHAR)&Unused1;
|
|
Attributes[AttrIndex].attrTyp = BOGUS_TYPE;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr2Val[ValueIndex];
|
|
|
|
// Set up CreationTime
|
|
|
|
AttrIndex = 2;
|
|
|
|
Attr3Val[ValueIndex].valLen = sizeof(LARGE_INTEGER);
|
|
Attr3Val[ValueIndex].pVal = (PUCHAR)&CreationTime;
|
|
Attributes[AttrIndex].attrTyp = SAMP_FIXED_DOMAIN_CREATION_TIME;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr3Val[ValueIndex];
|
|
|
|
// Set up ModifiedCount
|
|
|
|
AttrIndex = 3;
|
|
|
|
Attr4Val[ValueIndex].valLen = sizeof(LARGE_INTEGER);
|
|
Attr4Val[ValueIndex].pVal = (PUCHAR)&ModifiedCount;
|
|
Attributes[AttrIndex].attrTyp = SAMP_FIXED_DOMAIN_MODIFIED_COUNT;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr4Val[ValueIndex];
|
|
|
|
// Set up MaxPasswordAge
|
|
|
|
AttrIndex = 4;
|
|
|
|
Attr5Val[ValueIndex].valLen = sizeof(LARGE_INTEGER);
|
|
Attr5Val[ValueIndex].pVal = (PUCHAR)&MaxPasswordAge;
|
|
Attributes[AttrIndex].attrTyp = SAMP_FIXED_DOMAIN_MAX_PASSWORD_AGE;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr5Val[ValueIndex];
|
|
|
|
// Set up MinPasswordAge
|
|
|
|
AttrIndex = 5;
|
|
|
|
Attr6Val[ValueIndex].valLen = sizeof(LARGE_INTEGER);
|
|
Attr6Val[ValueIndex].pVal = (PUCHAR)&MinPasswordAge;
|
|
Attributes[AttrIndex].attrTyp = SAMP_FIXED_DOMAIN_MIN_PASSWORD_AGE;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr6Val[ValueIndex];
|
|
|
|
// Set up ForceLogoff
|
|
|
|
AttrIndex = 6;
|
|
|
|
Attr7Val[ValueIndex].valLen = sizeof(LARGE_INTEGER);
|
|
Attr7Val[ValueIndex].pVal = (PUCHAR)&ForceLogoff;
|
|
Attributes[AttrIndex].attrTyp = SAMP_FIXED_DOMAIN_FORCE_LOGOFF;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr7Val[ValueIndex];
|
|
|
|
// Set up LockoutDuration
|
|
|
|
AttrIndex = 7;
|
|
|
|
Attr8Val[ValueIndex].valLen = sizeof(LARGE_INTEGER);
|
|
Attr8Val[ValueIndex].pVal = (PUCHAR)&LockoutDuration;
|
|
Attributes[AttrIndex].attrTyp = SAMP_FIXED_DOMAIN_LOCKOUT_DURATION;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr8Val[ValueIndex];
|
|
|
|
// Set up LockoutObservationWindow
|
|
|
|
AttrIndex = 8;
|
|
|
|
// BUG: Setting attrTyp to BOGUS_TYPE due to missing types.
|
|
|
|
Attr9Val[ValueIndex].valLen = sizeof(LARGE_INTEGER);
|
|
Attr9Val[ValueIndex].pVal = (PUCHAR)&LockoutObservationWindow;
|
|
Attributes[AttrIndex].attrTyp = BOGUS_TYPE;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr9Val[ValueIndex];
|
|
|
|
// Set up ModifiedCountAtLastPromotion
|
|
|
|
AttrIndex = 9;
|
|
|
|
Attr10Val[ValueIndex].valLen = sizeof(LARGE_INTEGER);
|
|
Attr10Val[ValueIndex].pVal = (PUCHAR)&ModifiedCountAtLastPromotion;
|
|
Attributes[AttrIndex].attrTyp = SAMP_FIXED_DOMAIN_MODCOUNT_LAST_PROMOTION;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr10Val[ValueIndex];
|
|
|
|
// Set up NextRid
|
|
|
|
AttrIndex = 10;
|
|
|
|
Attr11Val[ValueIndex].valLen = sizeof(ULONG);
|
|
Attr11Val[ValueIndex].pVal = (PUCHAR)&NextRid;
|
|
Attributes[AttrIndex].attrTyp = SAMP_FIXED_DOMAIN_NEXT_RID;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr11Val[ValueIndex];
|
|
|
|
// Set up PasswordProperties
|
|
|
|
AttrIndex = 11;
|
|
|
|
Attr12Val[ValueIndex].valLen = sizeof(ULONG);
|
|
Attr12Val[ValueIndex].pVal = (PUCHAR)&PasswordProperties;
|
|
Attributes[AttrIndex].attrTyp = SAMP_FIXED_DOMAIN_PWD_PROPERTIES;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr12Val[ValueIndex];
|
|
|
|
// Set up MinPasswordLength
|
|
|
|
AttrIndex = 12;
|
|
|
|
Attr13Val[ValueIndex].valLen = sizeof(USHORT);
|
|
Attr13Val[ValueIndex].pVal = (PUCHAR)&MinPasswordLength;
|
|
Attributes[AttrIndex].attrTyp = SAMP_FIXED_DOMAIN_MIN_PASSWORD_LENGTH;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr13Val[ValueIndex];
|
|
|
|
// Set up PasswordHistoryLength
|
|
|
|
AttrIndex = 13;
|
|
|
|
Attr14Val[ValueIndex].valLen = sizeof(USHORT);
|
|
Attr14Val[ValueIndex].pVal = (PUCHAR)&PasswordHistoryLength;
|
|
Attributes[AttrIndex].attrTyp = SAMP_FIXED_DOMAIN_PASSWORD_HISTORY_LENGTH;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr14Val[ValueIndex];
|
|
|
|
// Set up LockoutThreshold
|
|
|
|
AttrIndex = 14;
|
|
|
|
Attr15Val[ValueIndex].valLen = sizeof(USHORT);
|
|
Attr15Val[ValueIndex].pVal = (PUCHAR)&LockoutThreshold;
|
|
Attributes[AttrIndex].attrTyp = SAMP_FIXED_DOMAIN_LOCKOUT_THRESHOLD;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr15Val[ValueIndex];
|
|
|
|
// Set up ServerState
|
|
|
|
AttrIndex = 15;
|
|
|
|
Attr16Val[ValueIndex].valLen = sizeof(DOMAIN_SERVER_ENABLE_STATE);
|
|
Attr16Val[ValueIndex].pVal = (PUCHAR)&ServerState;
|
|
Attributes[AttrIndex].attrTyp = SAMP_FIXED_DOMAIN_SERVER_STATE;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr16Val[ValueIndex];
|
|
|
|
// Set up ServerRole
|
|
|
|
AttrIndex = 16;
|
|
|
|
Attr17Val[ValueIndex].valLen = sizeof(DOMAIN_SERVER_ROLE);
|
|
Attr17Val[ValueIndex].pVal = (PUCHAR)&ServerRole;
|
|
Attributes[AttrIndex].attrTyp = SAMP_FIXED_DOMAIN_SERVER_ROLE;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr17Val[ValueIndex];
|
|
|
|
// Set up UasCompatibilityRequired
|
|
|
|
AttrIndex = 17;
|
|
|
|
Attr18Val[ValueIndex].valLen = sizeof(BOOLEAN);
|
|
Attr18Val[ValueIndex].pVal = (PUCHAR)&UasCompatibilityRequired;
|
|
Attributes[AttrIndex].attrTyp = SAMP_FIXED_DOMAIN_UAS_COMPAT_REQUIRED;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr18Val[ValueIndex];
|
|
|
|
DsAttributesIn->attrCount = SAMP_DOMAIN_FIXED_ATTR_COUNT;
|
|
DsAttributesIn->pAttr = Attributes;
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
BasicFixedLengthAttrTest(
|
|
VOID
|
|
)
|
|
{
|
|
NTSTATUS NtStatus = STATUS_SEVERITY_ERROR;
|
|
INT ObjectType = SampDomainObjectType;
|
|
DSATTRBLOCK DsAttributesIn;
|
|
PDSATTRBLOCK DsAttributesOut;
|
|
PSAMP_V1_0A_FIXED_LENGTH_DOMAIN SamAttributes;
|
|
ULONG AttrIndex = 0;
|
|
ULONG Index = 0;
|
|
ULONG AttrType = 0;
|
|
ULONG ValueCount = 0;
|
|
ULONG ValueLength = 0;
|
|
PUCHAR Value = NULL;
|
|
ULONG Length = 0;
|
|
|
|
SetupFixedLengthDomainAttributes(&DsAttributesIn);
|
|
|
|
NtStatus = SampConvertAttrBlockToFixedLengthAttributes(ObjectType,
|
|
&DsAttributesIn,
|
|
&SamAttributes,
|
|
&Length);
|
|
|
|
if (NT_SUCCESS(NtStatus))
|
|
{
|
|
DebugPrint("\nSAM Fixed-Length Domain Attributes:\n");
|
|
|
|
DebugPrint(" Revision = %lu\n", SamAttributes->Revision);
|
|
DebugPrint(" Unused1 = %lu\n", SamAttributes->Unused1);
|
|
DebugPrint(" CreationTime = %lu:%lu\n",
|
|
SamAttributes->CreationTime.HighPart,
|
|
SamAttributes->CreationTime.LowPart);
|
|
DebugPrint(" ModifiedCount = %lu:%lu\n",
|
|
SamAttributes->ModifiedCount.HighPart,
|
|
SamAttributes->ModifiedCount.LowPart);
|
|
DebugPrint(" MaxPasswordAge = %lu:%lu\n",
|
|
SamAttributes->MaxPasswordAge.HighPart,
|
|
SamAttributes->MaxPasswordAge.LowPart);
|
|
DebugPrint(" MinPasswordAge = %lu:%lu\n",
|
|
SamAttributes->MinPasswordAge.HighPart,
|
|
SamAttributes->MinPasswordAge.LowPart);
|
|
DebugPrint(" ForceLogoff = %lu:%lu\n",
|
|
SamAttributes->ForceLogoff.HighPart,
|
|
SamAttributes->ForceLogoff.LowPart);
|
|
DebugPrint(" LockoutDuration = %lu:%lu\n",
|
|
SamAttributes->LockoutDuration.HighPart,
|
|
SamAttributes->LockoutDuration.LowPart);
|
|
DebugPrint(" LockoutObservationWindow = %lu:%lu\n",
|
|
SamAttributes->LockoutObservationWindow.HighPart,
|
|
SamAttributes->LockoutObservationWindow.LowPart);
|
|
DebugPrint(" ModifiedCountAtLastPromotion = %lu:%lu\n",
|
|
SamAttributes->ModifiedCountAtLastPromotion.HighPart,
|
|
SamAttributes->ModifiedCountAtLastPromotion.LowPart);
|
|
DebugPrint(" NextRid = %lu\n", SamAttributes->NextRid);
|
|
DebugPrint(" PasswordProperties = 0x%lx\n",
|
|
SamAttributes->PasswordProperties);
|
|
DebugPrint(" MinPasswordLength = %d\n",
|
|
SamAttributes->MinPasswordLength);
|
|
DebugPrint(" PasswordHistoryLength = %d\n",
|
|
SamAttributes->PasswordHistoryLength);
|
|
DebugPrint(" LockoutThreshold = %d\n",
|
|
SamAttributes->LockoutThreshold);
|
|
DebugPrint(" ServerState = %lu\n", SamAttributes->ServerState);
|
|
DebugPrint(" ServerRole = %lu\n", SamAttributes->ServerRole);
|
|
DebugPrint(" UasCompatibilityRequired = %d\n",
|
|
SamAttributes->UasCompatibilityRequired);
|
|
}
|
|
|
|
if (NT_SUCCESS(NtStatus))
|
|
{
|
|
NtStatus = SampConvertFixedLengthAttributesToAttrBlock(
|
|
ObjectType,
|
|
SamAttributes,
|
|
&DsAttributesOut);
|
|
}
|
|
|
|
if (NT_SUCCESS(NtStatus))
|
|
{
|
|
DebugPrint("\nDS Domain Attributes:\n");
|
|
DebugPrint(" AttrCount = %lu\n", DsAttributesOut->attrCount);
|
|
|
|
Index = 0;
|
|
|
|
for (AttrIndex = 0;
|
|
AttrIndex < SAMP_DOMAIN_FIXED_ATTR_COUNT;
|
|
AttrIndex++)
|
|
{
|
|
AttrType = DsAttributesOut->pAttr[AttrIndex].attrTyp;
|
|
ValueCount = DsAttributesOut->pAttr[AttrIndex].AttrVal.valCount;
|
|
ValueLength =
|
|
DsAttributesOut->pAttr[AttrIndex].AttrVal.pAVal[Index].valLen;
|
|
|
|
DebugPrint(" AttrType = %lu ValueCount = %lu ValueLength = %lu\n",
|
|
AttrType,
|
|
ValueCount,
|
|
ValueLength);
|
|
|
|
Value =
|
|
DsAttributesOut->pAttr[AttrIndex].AttrVal.pAVal[Index].pVal;
|
|
|
|
switch(AttrIndex)
|
|
{
|
|
|
|
case 0:
|
|
DebugPrint(" Revision = %lu\n", *(PULONG)Value);
|
|
break;
|
|
|
|
case 1:
|
|
DebugPrint(" Unused1 = %lu\n", *(PULONG)Value);
|
|
break;
|
|
|
|
case 2:
|
|
DebugPrint(" CreationTime = %lu:%lu\n",
|
|
((PLARGE_INTEGER)Value)->HighPart,
|
|
((PLARGE_INTEGER)Value)->LowPart);
|
|
break;
|
|
|
|
case 3:
|
|
DebugPrint(" ModifiedCount = %lu:%lu\n",
|
|
((PLARGE_INTEGER)Value)->HighPart,
|
|
((PLARGE_INTEGER)Value)->LowPart);
|
|
break;
|
|
|
|
case 4:
|
|
DebugPrint(" MaxPasswordAge = %lu:%lu\n",
|
|
((PLARGE_INTEGER)Value)->HighPart,
|
|
((PLARGE_INTEGER)Value)->LowPart);
|
|
break;
|
|
|
|
case 5:
|
|
DebugPrint(" MinPasswordAge = %lu:%lu\n",
|
|
((PLARGE_INTEGER)Value)->HighPart,
|
|
((PLARGE_INTEGER)Value)->LowPart);
|
|
break;
|
|
|
|
case 6:
|
|
DebugPrint(" ForceLogoff = %lu:%lu\n",
|
|
((PLARGE_INTEGER)Value)->HighPart,
|
|
((PLARGE_INTEGER)Value)->LowPart);
|
|
break;
|
|
|
|
case 7:
|
|
DebugPrint(" LockoutDuration = %lu:%lu\n",
|
|
((PLARGE_INTEGER)Value)->HighPart,
|
|
((PLARGE_INTEGER)Value)->LowPart);
|
|
break;
|
|
|
|
case 8:
|
|
DebugPrint(" LockoutObservationWindow = %lu:%lu\n",
|
|
((PLARGE_INTEGER)Value)->HighPart,
|
|
((PLARGE_INTEGER)Value)->LowPart);
|
|
break;
|
|
|
|
case 9:
|
|
DebugPrint(" ModifiedCountAtLastPromotion = %lu:%lu\n",
|
|
((PLARGE_INTEGER)Value)->HighPart,
|
|
((PLARGE_INTEGER)Value)->LowPart);
|
|
break;
|
|
|
|
case 10:
|
|
DebugPrint(" NextRid = %lu\n", *(PULONG)Value);
|
|
break;
|
|
|
|
case 11:
|
|
DebugPrint(" PasswordProperties = 0x%lx\n", *(PULONG)Value);
|
|
break;
|
|
|
|
case 12:
|
|
DebugPrint(" MinPasswordLength = %d\n", *(PUSHORT)Value);
|
|
break;
|
|
|
|
case 13:
|
|
DebugPrint(" PasswordHistoryLength = %d\n", *(PUSHORT)Value);
|
|
break;
|
|
|
|
case 14:
|
|
DebugPrint(" LockoutThreshold = %d\n", *(PUSHORT)Value);
|
|
break;
|
|
|
|
case 15:
|
|
DebugPrint(" ServerState = %d\n", *(PUSHORT)Value);
|
|
break;
|
|
|
|
case 16:
|
|
DebugPrint(" ServerRole = %d\n", *(PUSHORT)Value);
|
|
break;
|
|
|
|
case 17:
|
|
DebugPrint(" UasCompatibilityRequired = %d\n", *(BOOLEAN *)Value);
|
|
break;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
// Make sure that the input data is the same as the output.
|
|
|
|
NtStatus = CompareDsAttrBlocks(&DsAttributesIn, DsAttributesOut);
|
|
|
|
return(NtStatus);
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
SetupMultiValuedGroupAttributes(
|
|
PDSATTRBLOCK DsAttributesIn
|
|
)
|
|
{
|
|
ULONG AttrIndex = 0;
|
|
ULONG ValueIndex = 0;
|
|
|
|
// Set up group security descriptor
|
|
|
|
ValueIndex = 0;
|
|
|
|
// Set up the SIDs and ACLs for the descriptor
|
|
|
|
OwnerSid.Revision = 1; // UCHAR
|
|
OwnerSid.SubAuthorityCount = 1; // UCHAR
|
|
OwnerSid.IdentifierAuthority.Value[0] = 1; // UCHAR[6]
|
|
OwnerSid.IdentifierAuthority.Value[1] = 2;
|
|
OwnerSid.IdentifierAuthority.Value[2] = 3;
|
|
OwnerSid.IdentifierAuthority.Value[3] = 4;
|
|
OwnerSid.IdentifierAuthority.Value[4] = 5;
|
|
OwnerSid.IdentifierAuthority.Value[5] = 6;
|
|
OwnerSid.SubAuthority[0] = 111; // ULONG
|
|
|
|
GroupSid.Revision = 1; // UCHAR
|
|
GroupSid.SubAuthorityCount = 1; // UCHAR
|
|
GroupSid.IdentifierAuthority.Value[0] = 1; // UCHAR[6]
|
|
GroupSid.IdentifierAuthority.Value[1] = 2;
|
|
GroupSid.IdentifierAuthority.Value[2] = 3;
|
|
GroupSid.IdentifierAuthority.Value[3] = 4;
|
|
GroupSid.IdentifierAuthority.Value[4] = 5;
|
|
GroupSid.IdentifierAuthority.Value[5] = 6;
|
|
GroupSid.SubAuthority[0] = 222; // ULONG
|
|
|
|
Sacl.AclRevision = 1; // UCHAR
|
|
Sacl.Sbz1 = 1; // UCHAR
|
|
Sacl.AclSize = 1; // USHORT
|
|
Sacl.AceCount = 1; // USHORT
|
|
Sacl.Sbz2 = 1; // USHORT
|
|
|
|
Dacl.AclRevision = 1; // UCHAR
|
|
Dacl.Sbz1 = 1; // UCHAR
|
|
Dacl.AclSize = 1; // USHORT
|
|
Dacl.AceCount = 1; // USHORT
|
|
Dacl.Sbz2 = 1; // USHORT
|
|
|
|
SecurityDescriptor.Revision = 1; // UCHAR
|
|
SecurityDescriptor.Sbz1 = 1; // UCHAR
|
|
SecurityDescriptor.Control = 1; // USHORT
|
|
SecurityDescriptor.Owner = &OwnerSid; // PSID
|
|
SecurityDescriptor.Group = &GroupSid; // PSID
|
|
SecurityDescriptor.Sacl = &Sacl; // PACL
|
|
SecurityDescriptor.Dacl = &Dacl; // PACL
|
|
|
|
Attr1Val[ValueIndex].valLen = sizeof(SECURITY_DESCRIPTOR) +
|
|
(2 * sizeof(SID)) +
|
|
(2 * sizeof(ACL));
|
|
|
|
Attr1Val[ValueIndex].pVal = (PUCHAR)&SecurityDescriptor;
|
|
|
|
AttrIndex = SAMP_GROUP_SECURITY_DESCRIPTOR;
|
|
|
|
// BUG: What should type be set to?
|
|
|
|
Attributes[AttrIndex].attrTyp = 0;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr1Val[ValueIndex];
|
|
|
|
// Set up group name
|
|
|
|
ValueIndex = 0;
|
|
|
|
RtlInitUnicodeString(&GroupInfo, GroupString);
|
|
|
|
Attr2Val[ValueIndex].valLen = sizeof(UNICODE_STRING) +
|
|
(sizeof(WCHAR) * wcslen(GroupString));
|
|
|
|
Attr2Val[ValueIndex].pVal = (PUCHAR)&GroupInfo;
|
|
|
|
AttrIndex = SAMP_GROUP_NAME;
|
|
|
|
// BUG: What should type be set to?
|
|
|
|
Attributes[AttrIndex].attrTyp = 0;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr2Val[ValueIndex];
|
|
|
|
// Set up group admin comment
|
|
|
|
ValueIndex = 0;
|
|
|
|
RtlInitUnicodeString(&CommentInfo, CommentString);
|
|
|
|
Attr3Val[ValueIndex].valLen = sizeof(UNICODE_STRING) +
|
|
(sizeof(WCHAR) * wcslen(CommentString));
|
|
|
|
Attr3Val[ValueIndex].pVal = (PUCHAR)&CommentInfo;
|
|
|
|
AttrIndex = SAMP_GROUP_ADMIN_COMMENT;
|
|
|
|
// BUG: What should type be set to?
|
|
|
|
Attributes[AttrIndex].attrTyp = 0;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr3Val[ValueIndex];
|
|
|
|
// Set up group members
|
|
|
|
ValueIndex = 0;
|
|
|
|
Member1 = 0x1234abcd;
|
|
Attr4Val[ValueIndex].valLen = sizeof(ULONG);
|
|
Attr4Val[ValueIndex].pVal = (PUCHAR)&Member1;
|
|
|
|
ValueIndex = 1;
|
|
|
|
Member2 = 0x5678abef;
|
|
Attr4Val[ValueIndex].valLen = sizeof(ULONG);
|
|
Attr4Val[ValueIndex].pVal = (PUCHAR)&Member2;
|
|
|
|
ValueIndex = 2;
|
|
|
|
Member3 = 0x12345678;
|
|
Attr4Val[ValueIndex].valLen = sizeof(ULONG);
|
|
Attr4Val[ValueIndex].pVal = (PUCHAR)&Member3;
|
|
|
|
AttrIndex = SAMP_GROUP_MEMBERS;
|
|
|
|
// BUG: What should type be set to?
|
|
|
|
Attributes[AttrIndex].attrTyp = 0;
|
|
Attributes[AttrIndex].AttrVal.valCount = 3;
|
|
Attributes[AttrIndex].AttrVal.pAVal = Attr4Val;
|
|
|
|
DsAttributesIn->attrCount = SAMP_GROUP_VARIABLE_ATTRIBUTES;
|
|
DsAttributesIn->pAttr = Attributes;
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
MultiValueAttributeTest(
|
|
VOID
|
|
)
|
|
{
|
|
NTSTATUS NtStatus = STATUS_SEVERITY_ERROR;
|
|
INT ObjectType = SampGroupObjectType;
|
|
DSATTRBLOCK DsAttributesIn;
|
|
PDSATTRBLOCK DsAttributesOut;
|
|
PSAMP_VARIABLE_LENGTH_ATTRIBUTE SamAttributes;
|
|
ULONG AttrIndex = 0;
|
|
ULONG Length = 0;
|
|
|
|
SetupMultiValuedGroupAttributes(&DsAttributesIn);
|
|
|
|
NtStatus = SampConvertAttrBlockToVarLengthAttributes(ObjectType,
|
|
&DsAttributesIn,
|
|
&SamAttributes,
|
|
&Length);
|
|
|
|
if (NT_SUCCESS(NtStatus))
|
|
{
|
|
DebugPrint("\nSAM Variable-Length Group Multi-Value Attributes:\n");
|
|
|
|
for (AttrIndex = 0;
|
|
AttrIndex < SAMP_GROUP_VARIABLE_ATTRIBUTES;
|
|
AttrIndex++)
|
|
{
|
|
switch(AttrIndex)
|
|
{
|
|
|
|
case SAMP_GROUP_SECURITY_DESCRIPTOR:
|
|
DumpSamSecurityDescriptor(SamAttributes, AttrIndex);
|
|
break;
|
|
|
|
case SAMP_GROUP_NAME:
|
|
DumpSamUnicodeStringAttribute(SamAttributes, AttrIndex);
|
|
break;
|
|
|
|
case SAMP_GROUP_ADMIN_COMMENT:
|
|
DumpSamUnicodeStringAttribute(SamAttributes, AttrIndex);
|
|
break;
|
|
|
|
case SAMP_GROUP_MEMBERS:
|
|
DumpSamGroupMembers(SamAttributes, AttrIndex);
|
|
break;
|
|
|
|
default:
|
|
DebugPrint("ERROR - UNRECOGNIZED ATTRIBUTE\n");
|
|
break;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
if (NT_SUCCESS(NtStatus))
|
|
{
|
|
NtStatus = SampConvertVarLengthAttributesToAttrBlock(ObjectType,
|
|
SamAttributes,
|
|
&DsAttributesOut);
|
|
}
|
|
|
|
if (NT_SUCCESS(NtStatus))
|
|
{
|
|
DebugPrint("\nDS Group Multi-Value Attributes:\n");
|
|
|
|
DebugPrint(" DsAttributes.attrCount = %lu\n", DsAttributesOut->attrCount);
|
|
|
|
for (AttrIndex = 0;
|
|
AttrIndex < SAMP_GROUP_VARIABLE_ATTRIBUTES;
|
|
AttrIndex++)
|
|
{
|
|
switch(AttrIndex)
|
|
{
|
|
|
|
case SAMP_GROUP_SECURITY_DESCRIPTOR:
|
|
DumpDsSecurityDescriptor(DsAttributesOut->pAttr, AttrIndex);
|
|
break;
|
|
|
|
case SAMP_GROUP_NAME:
|
|
DumpDsUnicodeStringAttribute(DsAttributesOut->pAttr, AttrIndex);
|
|
break;
|
|
|
|
case SAMP_GROUP_ADMIN_COMMENT:
|
|
DumpDsUnicodeStringAttribute(DsAttributesOut->pAttr, AttrIndex);
|
|
break;
|
|
|
|
case SAMP_GROUP_MEMBERS:
|
|
DumpDsGroupMembers(DsAttributesOut->pAttr, AttrIndex);
|
|
break;
|
|
|
|
default:
|
|
DebugPrint("ERROR - UNRECOGNIZED ATTRIBUTE\n");
|
|
break;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
// Make sure that the input data is the same as the output.
|
|
|
|
NtStatus = CompareDsAttrBlocks(&DsAttributesIn, DsAttributesOut);
|
|
|
|
return(NtStatus);
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
SetupCombinedGroupAttributes(
|
|
PDSATTRBLOCK DsAttributesIn
|
|
)
|
|
{
|
|
// ValueIndex is always zero because fixed-length attributess are not
|
|
// multi-valued.
|
|
|
|
ULONG ValueIndex = 0;
|
|
ULONG AttrIndex = 0;
|
|
|
|
// Set up the fixed-length group attributes.
|
|
|
|
// Set up Revision
|
|
|
|
AttrIndex = 0;
|
|
|
|
Attr1Val[ValueIndex].valLen = sizeof(ULONG);
|
|
Attr1Val[ValueIndex].pVal = (PUCHAR)&Revision;
|
|
Attributes[AttrIndex].attrTyp = SAMP_FIXED_GROUP_REVISION_LEVEL;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr1Val[ValueIndex];
|
|
|
|
// Set up RelativeId
|
|
|
|
AttrIndex = 1;
|
|
|
|
Attr2Val[ValueIndex].valLen = sizeof(ULONG);
|
|
Attr2Val[ValueIndex].pVal = (PUCHAR)&RelativeId;
|
|
Attributes[AttrIndex].attrTyp = SAMP_FIXED_GROUP_RID;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr2Val[ValueIndex];
|
|
|
|
// Set up Attributes
|
|
|
|
AttrIndex = 2;
|
|
|
|
Attr3Val[ValueIndex].valLen = sizeof(ULONG);
|
|
Attr3Val[ValueIndex].pVal = (PUCHAR)&AttributeProperties;
|
|
Attributes[AttrIndex].attrTyp = SAMP_FIXED_GROUP_ATTRIBUTES;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr3Val[ValueIndex];
|
|
|
|
// Set up Unused1
|
|
|
|
AttrIndex = 3;
|
|
|
|
// BUG: Setting attrTyp to BOGUS_TYPE due to missing types.
|
|
|
|
Attr4Val[ValueIndex].valLen = sizeof(ULONG);
|
|
Attr4Val[ValueIndex].pVal = (PUCHAR)&Unused1;
|
|
Attributes[AttrIndex].attrTyp = BOGUS_TYPE;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr4Val[ValueIndex];
|
|
|
|
// Set up AdminCount
|
|
|
|
AttrIndex = 4;
|
|
|
|
Attr5Val[ValueIndex].valLen = sizeof(UCHAR);
|
|
Attr5Val[ValueIndex].pVal = (PUCHAR)&AdminCount;
|
|
Attributes[AttrIndex].attrTyp = SAMP_FIXED_GROUP_ADMIN_COUNT;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr5Val[ValueIndex];
|
|
|
|
// Set up OperatorCount
|
|
|
|
AttrIndex = 5;
|
|
|
|
Attr6Val[ValueIndex].valLen = sizeof(UCHAR);
|
|
Attr6Val[ValueIndex].pVal = (PUCHAR)&OperatorCount;
|
|
Attributes[AttrIndex].attrTyp = SAMP_FIXED_GROUP_OPERATOR_COUNT;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr6Val[ValueIndex];
|
|
|
|
// Set up the variable-length group attributes.
|
|
|
|
// Set up the SIDs and ACLs for the descriptor
|
|
|
|
OwnerSid.Revision = 1; // UCHAR
|
|
OwnerSid.SubAuthorityCount = 1; // UCHAR
|
|
OwnerSid.IdentifierAuthority.Value[0] = 1; // UCHAR[6]
|
|
OwnerSid.IdentifierAuthority.Value[1] = 2;
|
|
OwnerSid.IdentifierAuthority.Value[2] = 3;
|
|
OwnerSid.IdentifierAuthority.Value[3] = 4;
|
|
OwnerSid.IdentifierAuthority.Value[4] = 5;
|
|
OwnerSid.IdentifierAuthority.Value[5] = 6;
|
|
OwnerSid.SubAuthority[0] = 111; // ULONG
|
|
|
|
GroupSid.Revision = 1; // UCHAR
|
|
GroupSid.SubAuthorityCount = 1; // UCHAR
|
|
GroupSid.IdentifierAuthority.Value[0] = 1; // UCHAR[6]
|
|
GroupSid.IdentifierAuthority.Value[1] = 2;
|
|
GroupSid.IdentifierAuthority.Value[2] = 3;
|
|
GroupSid.IdentifierAuthority.Value[3] = 4;
|
|
GroupSid.IdentifierAuthority.Value[4] = 5;
|
|
GroupSid.IdentifierAuthority.Value[5] = 6;
|
|
GroupSid.SubAuthority[0] = 222; // ULONG
|
|
|
|
Sacl.AclRevision = 1; // UCHAR
|
|
Sacl.Sbz1 = 1; // UCHAR
|
|
Sacl.AclSize = 1; // USHORT
|
|
Sacl.AceCount = 1; // USHORT
|
|
Sacl.Sbz2 = 1; // USHORT
|
|
|
|
Dacl.AclRevision = 1; // UCHAR
|
|
Dacl.Sbz1 = 1; // UCHAR
|
|
Dacl.AclSize = 1; // USHORT
|
|
Dacl.AceCount = 1; // USHORT
|
|
Dacl.Sbz2 = 1; // USHORT
|
|
|
|
SecurityDescriptor.Revision = 1; // UCHAR
|
|
SecurityDescriptor.Sbz1 = 1; // UCHAR
|
|
SecurityDescriptor.Control = 1; // USHORT
|
|
SecurityDescriptor.Owner = &OwnerSid; // PSID
|
|
SecurityDescriptor.Group = &GroupSid; // PSID
|
|
SecurityDescriptor.Sacl = &Sacl; // PACL
|
|
SecurityDescriptor.Dacl = &Dacl; // PACL
|
|
|
|
Attr7Val[ValueIndex].valLen = sizeof(SECURITY_DESCRIPTOR) +
|
|
(2 * sizeof(SID)) +
|
|
(2 * sizeof(ACL));
|
|
|
|
Attr7Val[ValueIndex].pVal = (PUCHAR)&SecurityDescriptor;
|
|
|
|
AttrIndex = 6;
|
|
|
|
// BUG: What should type be set to?
|
|
|
|
Attributes[AttrIndex].attrTyp = 0;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr7Val[ValueIndex];
|
|
|
|
// Set up group name
|
|
|
|
ValueIndex = 0;
|
|
|
|
RtlInitUnicodeString(&GroupInfo, GroupString);
|
|
|
|
Attr8Val[ValueIndex].valLen = sizeof(UNICODE_STRING) +
|
|
(sizeof(WCHAR) * wcslen(GroupString));
|
|
|
|
Attr8Val[ValueIndex].pVal = (PUCHAR)&GroupInfo;
|
|
|
|
AttrIndex = 7;
|
|
|
|
// BUG: What should type be set to?
|
|
|
|
Attributes[AttrIndex].attrTyp = 0;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr8Val[ValueIndex];
|
|
|
|
// Set up group admin comment
|
|
|
|
ValueIndex = 0;
|
|
|
|
RtlInitUnicodeString(&CommentInfo, CommentString);
|
|
|
|
Attr9Val[ValueIndex].valLen = sizeof(UNICODE_STRING) +
|
|
(sizeof(WCHAR) * wcslen(CommentString));
|
|
|
|
Attr9Val[ValueIndex].pVal = (PUCHAR)&CommentInfo;
|
|
|
|
AttrIndex = 8;
|
|
|
|
// BUG: What should type be set to?
|
|
|
|
Attributes[AttrIndex].attrTyp = 0;
|
|
Attributes[AttrIndex].AttrVal.valCount = 1;
|
|
Attributes[AttrIndex].AttrVal.pAVal = &Attr9Val[ValueIndex];
|
|
|
|
// Set up group members
|
|
|
|
ValueIndex = 0;
|
|
|
|
Member1 = 0x1234abcd;
|
|
Attr10Val[ValueIndex].valLen = sizeof(ULONG);
|
|
Attr10Val[ValueIndex].pVal = (PUCHAR)&Member1;
|
|
|
|
ValueIndex = 1;
|
|
|
|
Member2 = 0x5678abef;
|
|
Attr10Val[ValueIndex].valLen = sizeof(ULONG);
|
|
Attr10Val[ValueIndex].pVal = (PUCHAR)&Member2;
|
|
|
|
ValueIndex = 2;
|
|
|
|
Member3 = 0x12345678;
|
|
Attr10Val[ValueIndex].valLen = sizeof(ULONG);
|
|
Attr10Val[ValueIndex].pVal = (PUCHAR)&Member3;
|
|
|
|
AttrIndex = 9;
|
|
|
|
// BUG: What should type be set to?
|
|
|
|
Attributes[AttrIndex].attrTyp = 0;
|
|
Attributes[AttrIndex].AttrVal.valCount = 3;
|
|
Attributes[AttrIndex].AttrVal.pAVal = Attr10Val;
|
|
|
|
DsAttributesIn->attrCount =
|
|
SAMP_GROUP_FIXED_ATTR_COUNT + SAMP_GROUP_VARIABLE_ATTRIBUTES;
|
|
|
|
DsAttributesIn->pAttr = Attributes;
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
CombinedAttributeTest(
|
|
VOID
|
|
)
|
|
{
|
|
NTSTATUS NtStatus = STATUS_SEVERITY_ERROR;
|
|
INT ObjectType = SampGroupObjectType;
|
|
DSATTRBLOCK DsAttributesIn;
|
|
PDSATTRBLOCK DsAttributesOut = NULL;
|
|
DSATTRBLOCK DsAttributesTmp;
|
|
PVOID SamAttributes;
|
|
ULONG AttrIndex = 0;
|
|
ULONG Length = 0;
|
|
ULONG FixedLength = 0;
|
|
ULONG VarLength = 0;
|
|
PSAMP_V1_0A_FIXED_LENGTH_GROUP SamFixedGroupAttrs = NULL;
|
|
PSAMP_VARIABLE_LENGTH_ATTRIBUTE SamVarGroupAttrs = NULL;
|
|
ULONG AttributeCount = 0;
|
|
ULONG AttrType = 0;
|
|
ULONG ValueCount = 0;
|
|
ULONG ValueLength = 0;
|
|
PUCHAR Value = NULL;
|
|
ULONG Index = 0;
|
|
|
|
PBYTE ValueTmp = NULL;
|
|
|
|
SetupCombinedGroupAttributes(&DsAttributesIn);
|
|
|
|
NtStatus = SampConvertAttrBlockToCombinedAttributes(ObjectType,
|
|
&DsAttributesIn,
|
|
&SamAttributes,
|
|
&FixedLength,
|
|
&VarLength);
|
|
|
|
if (NT_SUCCESS(NtStatus))
|
|
{
|
|
DebugPrint("\nSAM Combined Group Multi-Value Attributes:\n");
|
|
|
|
SamFixedGroupAttrs = (PSAMP_V1_0A_FIXED_LENGTH_GROUP)SamAttributes;
|
|
|
|
DebugPrint(" Fixed Buffer Addr = 0x%lx FixedLength = %lu VarLength = %lu\n",
|
|
SamFixedGroupAttrs,
|
|
FixedLength,
|
|
VarLength);
|
|
|
|
DebugPrint(" Revision = %lu\n",
|
|
SamFixedGroupAttrs->Revision);
|
|
DebugPrint(" RelativeId = 0x%lx\n",
|
|
SamFixedGroupAttrs->RelativeId);
|
|
DebugPrint(" Attributes = 0x%lx\n",
|
|
SamFixedGroupAttrs->Attributes);
|
|
DebugPrint(" Unused1 = %lu\n",
|
|
SamFixedGroupAttrs->Unused1);
|
|
DebugPrint(" AdminCount = %d\n",
|
|
SamFixedGroupAttrs->AdminCount);
|
|
DebugPrint(" OperatorCount = %d\n",
|
|
SamFixedGroupAttrs->OperatorCount);
|
|
|
|
SamVarGroupAttrs =
|
|
(PSAMP_VARIABLE_LENGTH_ATTRIBUTE)(((PBYTE)SamAttributes) +
|
|
FixedLength);
|
|
|
|
DebugPrint(" Variable Buffer Addr = 0x%lx VariableLength = %lu\n",
|
|
SamVarGroupAttrs,
|
|
VarLength);
|
|
|
|
for (AttrIndex = 0;
|
|
AttrIndex < SAMP_GROUP_VARIABLE_ATTRIBUTES;
|
|
AttrIndex++)
|
|
{
|
|
switch(AttrIndex)
|
|
{
|
|
|
|
case SAMP_GROUP_SECURITY_DESCRIPTOR:
|
|
DumpSamSecurityDescriptor(SamVarGroupAttrs, AttrIndex);
|
|
break;
|
|
|
|
case SAMP_GROUP_NAME:
|
|
DumpSamUnicodeStringAttribute(SamVarGroupAttrs, AttrIndex);
|
|
break;
|
|
|
|
case SAMP_GROUP_ADMIN_COMMENT:
|
|
DumpSamUnicodeStringAttribute(SamVarGroupAttrs, AttrIndex);
|
|
break;
|
|
|
|
case SAMP_GROUP_MEMBERS:
|
|
DumpSamGroupMembers(SamVarGroupAttrs, AttrIndex);
|
|
break;
|
|
|
|
default:
|
|
DebugPrint("ERROR - UNRECOGNIZED ATTRIBUTE\n");
|
|
break;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
if (NT_SUCCESS(NtStatus))
|
|
{
|
|
NtStatus = SampConvertCombinedAttributesToAttrBlock(
|
|
ObjectType,
|
|
SamAttributes,
|
|
FixedLength,
|
|
VarLength,
|
|
&DsAttributesOut);
|
|
}
|
|
|
|
if (NT_SUCCESS(NtStatus))
|
|
{
|
|
DebugPrint("\nDS Combined Group Multi-Value Attributes:\n");
|
|
|
|
DebugPrint(" DsAttributes.attrCount = %lu\n", DsAttributesOut->attrCount);
|
|
|
|
for (AttrIndex = 0;
|
|
AttrIndex < DsAttributesOut->attrCount;
|
|
AttrIndex++)
|
|
{
|
|
|
|
AttrType = DsAttributesOut->pAttr[AttrIndex].attrTyp;
|
|
ValueCount = DsAttributesOut->pAttr[AttrIndex].AttrVal.valCount;
|
|
ValueLength =
|
|
DsAttributesOut->pAttr[AttrIndex].AttrVal.pAVal[Index].valLen;
|
|
|
|
DebugPrint(" AttrType = %lu ValueCount = %lu ValueLength = %lu\n",
|
|
AttrType,
|
|
ValueCount,
|
|
ValueLength);
|
|
|
|
Value =
|
|
DsAttributesOut->pAttr[AttrIndex].AttrVal.pAVal[Index].pVal;
|
|
|
|
switch(AttrIndex)
|
|
{
|
|
|
|
case 0: // Revision
|
|
DebugPrint(" Revision = %lu\n", *(PULONG)Value);
|
|
break;
|
|
|
|
case 1: // RelativeId
|
|
DebugPrint(" RelativeId = 0x%lx\n", *(PULONG)Value);
|
|
break;
|
|
|
|
case 2: // Attributes
|
|
DebugPrint(" Attributes = 0x%lx\n", *(PULONG)Value);
|
|
break;
|
|
|
|
case 3: // Unused1
|
|
DebugPrint(" Unused1 = %lu\n", *(PULONG)Value);
|
|
break;
|
|
|
|
case 4: // AdminCount
|
|
DebugPrint(" AdminCount = %u\n", *(PUCHAR)Value);
|
|
break;
|
|
|
|
case 5: // OperatorCount
|
|
DebugPrint(" OperatorCount = %u\n", *(PUCHAR)Value);
|
|
break;
|
|
|
|
// Because all of the attributes are in one DSATTRBLOCK, the
|
|
// remaining elements correspond to the variable-length attri-
|
|
// butes.
|
|
|
|
case (SAMP_GROUP_SECURITY_DESCRIPTOR + 6):
|
|
DumpDsSecurityDescriptor(DsAttributesOut->pAttr, AttrIndex);
|
|
break;
|
|
|
|
case (SAMP_GROUP_NAME + 6):
|
|
DumpDsUnicodeStringAttribute(DsAttributesOut->pAttr, AttrIndex);
|
|
break;
|
|
|
|
case (SAMP_GROUP_ADMIN_COMMENT + 6):
|
|
DumpDsUnicodeStringAttribute(DsAttributesOut->pAttr, AttrIndex);
|
|
break;
|
|
|
|
case (SAMP_GROUP_MEMBERS + 6):
|
|
DumpDsGroupMembers(DsAttributesOut->pAttr, AttrIndex);
|
|
break;
|
|
|
|
default:
|
|
DebugPrint("ERROR - UNRECOGNIZED ATTRIBUTE\n");
|
|
break;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
// Make sure that the input data is the same as the output.
|
|
|
|
NtStatus = CompareDsAttrBlocks(&DsAttributesIn, DsAttributesOut);
|
|
|
|
return(NtStatus);
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
// BUG: Disabled redundant main, using main from ..\server\main.c.
|
|
|
|
void
|
|
_cdecl
|
|
main(
|
|
int argc,
|
|
char **argv
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This test is designed to test the SAM-DS data conversion routines defined
|
|
in dsutil.c. The tests are as follows:
|
|
|
|
BasicVariableLengthAttrTest - This test constructs a DSATTRBLOCK, calls
|
|
the conversion routines to produce a SAM variable-length buffer, and
|
|
then converts the buffer back into a DSATTRBLOCK.
|
|
|
|
BasicFixedLengthAttrTest - This test constructs a DSATTRBLOCK, calls the
|
|
conversion routines to produce a SAM fixed-length buffer, and then
|
|
converts the buffer back into a DSATTRBLOCK.
|
|
|
|
MultiValueAttributeTest - This test constructs a DSATTRBLOCK with a multi-
|
|
valued attribute, calls the conversion routines to produce a SAM
|
|
variable-length data buffer, and then converts the buffer back into
|
|
a DSATTRBLOCK.
|
|
|
|
(Further tests TBD)
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
The test always calls exit(0) for successful completion, or exit(1) for
|
|
failure during any test.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS NtStatus = STATUS_SEVERITY_ERROR;
|
|
|
|
DebugPrint("Starting CNVRTDAT\n");
|
|
|
|
NtStatus = BasicVariableLengthAttrTest();
|
|
|
|
if (NT_SUCCESS(NtStatus))
|
|
{
|
|
NtStatus = BasicFixedLengthAttrTest();
|
|
}
|
|
|
|
if (NT_SUCCESS(NtStatus))
|
|
{
|
|
NtStatus = MultiValueAttributeTest();
|
|
}
|
|
|
|
if (NT_SUCCESS(NtStatus))
|
|
{
|
|
NtStatus = CombinedAttributeTest();
|
|
}
|
|
|
|
// BUG: Need to perform a memcmp to verfiy correctness.
|
|
|
|
// Display test status to stdout--do not change printf to DebugPrint for
|
|
// the exit messages.
|
|
|
|
if (NT_SUCCESS(NtStatus))
|
|
{
|
|
printf("\nPASSED\n");
|
|
exit(0);
|
|
}
|
|
else
|
|
{
|
|
printf("\nFAILED\n");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#endif
|