public void ValidateContentRulesRequirements(DirectoryEntries childrens, IEnumerable <IObjectOnServer> serverObjects) { bool isContent = true; //Setting some excluded attributes. SetContainer <string> ExcludedAttributes = new SetContainer <string>(); ExcludedAttributes.Add("creationTime"); ExcludedAttributes.Add("forceLogoff"); ExcludedAttributes.Add("lockoutDuration"); ExcludedAttributes.Add("lockOutObservationWindow"); ExcludedAttributes.Add("lockoutThreshold"); ExcludedAttributes.Add("maxPwdAge"); ExcludedAttributes.Add("minPwdAge"); ExcludedAttributes.Add("minPwdLength"); ExcludedAttributes.Add("modifiedCountAtLastProm"); ExcludedAttributes.Add("nextRid"); ExcludedAttributes.Add("pwdProperties"); ExcludedAttributes.Add("pwdHistoryLength"); ExcludedAttributes.Add("objectSid"); ExcludedAttributes.Add("serverState"); ExcludedAttributes.Add("uASCompat"); ExcludedAttributes.Add("modifiedCount"); //For each domain NC object... foreach (DirectoryEntry entry in childrens) { SetContainer <string> mustContain = new SetContainer <string>(); SetContainer <string> mayContain = new SetContainer <string>(); //Get super class chain. object[] superClasses = (object[])entry.Properties[StandardNames.objectClass.ToLower()].Value; //For each super class... foreach (string superClass in superClasses) { foreach (IObjectOnServer serverObj in serverObjects) { //Get the object from server. if (serverObj.Name.StartsWith(superClass)) { //Collect all must and may contain attribute value. if (serverObj.Properties.ContainsKey(StandardNames.mustContain.ToLower())) { foreach (object value in serverObj.Properties[StandardNames.mustContain.ToLower()]) { mustContain.Add((string)value); } } if (serverObj.Properties.ContainsKey(StandardNames.systemMustContain.ToLower())) { foreach (object value in serverObj.Properties[StandardNames.systemMustContain.ToLower()]) { mustContain.Add((string)value); } } if (serverObj.Properties.ContainsKey(StandardNames.mayContain.ToLower())) { foreach (object value in serverObj.Properties[StandardNames.mayContain.ToLower()]) { mayContain.Add((string)value); } } if (serverObj.Properties.ContainsKey(StandardNames.systemMayContain.ToLower())) { foreach (object value in serverObj.Properties[StandardNames.systemMayContain.ToLower()]) { mayContain.Add((string)value); } } break; } } } //For all property name of this object, it should be present in either must or may contain //attribute list. foreach (string attribute in entry.Properties.PropertyNames) { if (!ExcludedAttributes.Contains(attribute)) { //This attribute is in must contain list. if (mustContain.Contains(attribute)) { mustContain.Remove(attribute); } //This attribute is not in must and may contian list. else if (!mayContain.Contains(attribute)) { isContent = false; break; } } } //This is for checking whether some must contain attributes are missed. if (mustContain.Count > 0) { isContent = false; } if (!isContent) { break; } } //MS-ADTS-Schema_R152. DataSchemaSite.CaptureRequirementIfIsTrue( isContent, 152, @"In the content rules union of values in the mustContain and systemMustContain attributes specifies the attributes that are required to be present on an object instance of the class in question."); //MS-ADTS-Schema_R153. DataSchemaSite.CaptureRequirementIfIsTrue( isContent, 153, @"In the content rules the union of values in the mustContain, systemMustContain, mayContain, and systemMayContain attributes specifies the attributes that are allowed to be present on an object instance of the class in question."); }
/// <summary> /// This method validates the requirements under /// LDSConsistencyRules Scenario. /// </summary> public void ValidateLDSConsistencyRules() { #region MS-ADTS-Schema_R73 //The objectClass attribute of the attributeSchema equals the sequence [top, attributeSchema ] //Expected Sequence setting... Sequence <object> actualSeq = new Sequence <object>(); Sequence <object> expectedSeq = new Sequence <object>(); ModelObject objectFromModel = null; string requiredObjectDN = String.Empty; DirectoryEntry serverObject; expectedSeq = expectedSeq.Add("top".ToLower()).Add("classSchema".ToLower()); //Get attributeSchema from Server. requiredObjectDN = "CN=Attribute-Schema,CN=Schema,CN=Configuration," + adAdapter.LDSRootObjectName; if (!adAdapter.GetLdsObjectByDN(requiredObjectDN, out serverObject)) { DataSchemaSite.Assume.IsTrue(false, requiredObjectDN + " Object is not found in server"); } actualSeq = new Sequence <object>(); foreach (string valueString in serverObject.Properties[StandardNames.objectClass.ToLower()]) { actualSeq = actualSeq.Add(valueString.ToLower()); } //MS-ADTS-Schema_R73. DataSchemaSite.CaptureRequirementIfAreEqual <Sequence <object> >( expectedSeq, actualSeq, 73, "The objectClass attribute of the attributeSchema equals the sequence [top, classSchema ]."); #endregion #region MS-ADTS-Schema_R157 //The objectClass attribute of the classSchema equals the sequence [top, classSchema ]. //Expected Sequence setting... expectedSeq = new Sequence <object>(); expectedSeq = expectedSeq.Add("top".ToLower()).Add("classSchema".ToLower()); //Get classSchema from Server. requiredObjectDN = "CN=Class-Schema,CN=Schema,CN=Configuration," + adAdapter.LDSRootObjectName; if (!adAdapter.GetLdsObjectByDN(requiredObjectDN, out serverObject)) { DataSchemaSite.Assume.IsTrue(false, requiredObjectDN + " Object is not found in server"); } actualSeq = new Sequence <object>(); foreach (string valueString in serverObject.Properties[StandardNames.objectClass.ToLower()]) { actualSeq = actualSeq.Add(valueString.ToLower()); } //MS-ADTS-Schema_R157. DataSchemaSite.CaptureRequirementIfAreEqual <Sequence <object> >( expectedSeq, actualSeq, 157, "The objectClass attribute of the classSchema equals the sequence [top, classSchema ]."); #endregion #region MS-ADTS-Schema_R169 //The subClassOf attribute of the classSchema Specifies governsID of the superclass of the class. //Get classSchema from Model. objectFromModel = adamModel.GetClass("classSchema"); if (objectFromModel == null) { DataSchemaSite.Assume.IsNotNull(objectFromModel, "Class classSchema is not existing in Model"); } string expectedValue = (string)objectFromModel[StandardNames.subClassOf].UnderlyingValues.ToArray()[0]; #endregion #region MS-ADTS-Schema_R129-142,179 //Inheritance requirements IEnumerable <IObjectOnServer> serverObjects = (IEnumerable <IObjectOnServer>)adAdapter.GetAllLdsSchemaClasses(); if (serverObjects == null) { DataSchemaSite.Assume.IsNotNull(serverObjects, "Class objects are not existing in Model"); } //This method will validate the requirements MS-ADTS-Schema_R129-142,179 ValidateInheritanceRequirements(serverObjects, false); serverObjects = null; #endregion #region MS-ADTS-Schema_R143-146 //Covering ObjectClass requirements //Get domain NC for validation. DirectoryEntry domainEntry; if (!adAdapter.GetLdsObjectByDN("CN=Configuration," + adAdapter.LDSRootObjectName, out domainEntry)) { DataSchemaSite.Assume.IsTrue( false, "CN=Configuration," + adAdapter.LDSRootObjectName + " Object is not found in server"); } //This method validates teh requirements MS-ADTS-Schema_R143-146 ValidateObjectClassRequirements(domainEntry.Children, false); domainEntry = null; #endregion #region MS-ADTS-Schema_R149,175 //Coverring StructureRule requirements serverObjects = adAdapter.GetAllLdsSchemaClasses(); if (serverObjects == null) { DataSchemaSite.Assume.IsNotNull(serverObjects, "Class objects are not existing in Model"); } //This method validates the requirements MS-ADTS-Schema_R149,175 ValidateStructureRulesRequirements(serverObjects, false); #endregion #region MS-ADTS-Schema_R152,153 //Covering ContentRule requirements //Get the domain NC objects. if (!adAdapter.GetLdsObjectByDN("CN=Configuration," + adAdapter.LDSRootObjectName, out domainEntry)) { DataSchemaSite.Assert.IsTrue(false, "Configuration Object is not found in server"); } //This method validates the requirements MS-ADTS-Schema_R152,153. ValidateContentRulesRequirements(domainEntry.Children, serverObjects); #endregion #region MS-ADTS-Schema_R177 //The systemAuxiliaryClass attribute of the classSchema Specifies governsIDs of the classes that can //be parents of the class within an NC tree, where the parent-child relationships are required for //system operation. DirectoryEntry classSchemaObj; bool isAuxiliary = false; SetContainer <string> auxiliaryClassValue = new SetContainer <string>(); //Get class-schema class from server. if (!adAdapter.GetLdsObjectByDN( "CN=Class-Schema,CN=Schema,CN=Configuration," + adAdapter.LDSRootObjectName, out classSchemaObj)) { DataSchemaSite.Assume.IsTrue( false, "CN=Class-Schema,CN=Schema,CN=Configuration," + adAdapter.rootDomainDN + " Object is not found in server"); } //Collect its auxiliary class value. if (classSchemaObj.Properties.Contains("auxiliaryclass")) { //auxiliaryClassValue.Add foreach (string value in classSchemaObj.Properties["auxiliaryclass"]) { auxiliaryClassValue.Add(value); } } //Collect its system auxiliary class value. if (classSchemaObj.Properties.Contains("systemauxiliaryclass")) { //AuxiliaryClassValue.Add foreach (string value in classSchemaObj.Properties["systemauxiliaryclass"]) { auxiliaryClassValue.Add(value); } } if (auxiliaryClassValue.Count != 0) { //For each auxiliary class... foreach (string auxClass in auxiliaryClassValue) { isAuxiliary = false; foreach (IObjectOnServer serverObj in serverObjects) { //Get it from server. if (serverObj.Name.Equals(auxClass)) { //Get server object governsID. string governsID = (string)serverObj.Properties[StandardNames.governsId.ToLower()][0]; //It should be eqal to the auxiliary class name of the class. if (governsID.Equals(auxClass)) { isAuxiliary = true; continue; } } } if (isAuxiliary) { continue; } else { break; } } } #endregion }
/// <summary> /// This method validates the requirements under /// ConsistencyRules Scenario. /// </summary> public void ValidateConsistencyRules() { #region MS-ADTS-Schema_R73 //The objectClass attribute of the attributeSchema equals the sequence [top, attributeSchema ] //Expected Sequence setting... Sequence <string> expectedSeq = new Sequence <string>(); Sequence <string> actualSeq = new Sequence <string>(); DirectoryEntry serverObject; string requiredObjectDN = String.Empty; expectedSeq.Add("top"); expectedSeq.Add("classSchema"); //Get attributeSchema from Server. requiredObjectDN = "CN=Attribute-Schema,CN=Schema,CN=Configuration," + adAdapter.rootDomainDN; if (!adAdapter.GetObjectByDN(requiredObjectDN, out serverObject)) { DataSchemaSite.Assume.IsTrue(false, requiredObjectDN + " Object is not found in server"); } foreach (string valueString in serverObject.Properties[StandardNames.objectClass.ToLower()]) { actualSeq.Add(valueString.ToLower()); } //MS-ADTS-Schema_R73. DataSchemaSite.CaptureRequirementIfAreEqual <Sequence <string> >( expectedSeq, actualSeq, 73, "The objectClass attribute of the attributeSchema equals the sequence [top, classSchema ]."); #endregion #region MS-ADTS-Schema_R157 //The objectClass attribute of the classSchema equals the sequence [top, classSchema ]. //Get classSchema from Server. requiredObjectDN = "CN=Class-Schema,CN=Schema,CN=Configuration," + adAdapter.rootDomainDN; if (!adAdapter.GetObjectByDN(requiredObjectDN, out serverObject)) { DataSchemaSite.Assume.IsTrue(false, requiredObjectDN + " Object is not found in server"); } actualSeq = new Sequence <string>(); foreach (string valueString in serverObject.Properties[StandardNames.objectClass.ToLower()]) { actualSeq.Add(valueString.ToLower()); } //MS-ADTS-Schema_R157. DataSchemaSite.CaptureRequirementIfAreEqual <Sequence <string> >( expectedSeq, actualSeq, 157, "The objectClass attribute of the classSchema equals the sequence [top, classSchema ]."); #endregion #region MS-ADTS-Schema_R128-133,136-142,179 //Inheritance rule requirements IEnumerable <IObjectOnServer> serverObjects = adAdapter.GetAllSchemaClasses(); if (serverObjects == null) { DataSchemaSite.Assume.IsNotNull(serverObjects, "Class objects are not existing in Server"); } DataSchemaSite.Log.Add(LogEntryKind.Comment, "Begin ValidateInheritanceRequirements"); //This method will validate the requirements MS-ADTS-Schema_R128-133,136-142,179. ValidateInheritanceRequirements(serverObjects, true); #endregion #region MS-ADTS-Schema_R143-146 //Covering ObjectClass requirements //Get domain NC for validation. DirectoryEntry domainEntry; if (!adAdapter.GetObjectByDN(adAdapter.rootDomainDN, out domainEntry)) { DataSchemaSite.Assume.IsTrue(false, adAdapter.rootDomainDN + " Object is not found in server"); } DataSchemaSite.Log.Add(LogEntryKind.Comment, "Begin ValidateObjectClassRequirements"); //This method validates teh requirements MS-ADTS-Schema_R143-146 ValidateObjectClassRequirements(domainEntry.Children, true); #endregion #region MS-ADTS-Schema_R149,175 //Coverring StructureRule requirements DataSchemaSite.Log.Add(LogEntryKind.Comment, "Begin ValidateStructureRulesRequirements"); //This method validates the requirements MS-ADTS-Schema_R149,175 ValidateStructureRulesRequirements(serverObjects, true); #endregion #region MS-ADTS-Schema_R152,153 //Covering ContentRule requirements DataSchemaSite.Log.Add(LogEntryKind.Comment, "Begin ValidateContentRulesRequirements"); //This method validates the requirements MS-ADTS-Schema_R152,153. ValidateContentRulesRequirements(domainEntry.Children, serverObjects); #endregion #region MS-ADTS-Schema_R177 //The systemAuxiliaryClass attribute of the classSchema Specifies governsIDs of the classes that can //be parents of the class within an NC tree, where the parent-child relationships are required for //system operation. DirectoryEntry classSchemaObj; bool isAuxiliary = false; SetContainer <string> auxiliaryClassValue = new SetContainer <string>(); //Get class-schema class from server. if (!adAdapter.GetObjectByDN("CN=Class-Schema,CN=Schema,CN=Configuration," + adAdapter.rootDomainDN, out classSchemaObj)) { DataSchemaSite.Assume.IsTrue( false, "CN=Class-Schema,CN=Schema,CN=Configuration," + adAdapter.rootDomainDN + " Object is not found in server"); } //Collect its auxiliary class value. if (classSchemaObj.Properties.Contains("auxiliaryclass")) { //AuxiliaryClassValue.Add foreach (string value in classSchemaObj.Properties["auxiliaryclass"]) { auxiliaryClassValue.Add(value); } } //Collect its system auxiliary class value. if (classSchemaObj.Properties.Contains("systemauxiliaryclass")) { //AuxiliaryClassValue.Add foreach (string value in classSchemaObj.Properties["systemauxiliaryclass"]) { auxiliaryClassValue.Add(value); } } if (auxiliaryClassValue.Count != 0) { //For each auxiliary class... foreach (string auxClass in auxiliaryClassValue) { isAuxiliary = false; foreach (IObjectOnServer serverObj in serverObjects) { //Get it from server. if (serverObj.Name.Equals(auxClass)) { //Get server object governsID. string governsID = (string)serverObj.Properties[StandardNames.governsId.ToLower()][0]; //It should be eqal to the auxiliary class name of the class. if (governsID.Equals(auxClass)) { isAuxiliary = true; continue; } } } if (isAuxiliary) { continue; } else { break; } } } //MS-ADTS-Schema_R177. DataSchemaSite.Log.Add(LogEntryKind.Comment, "SystemAuxiliaryClass TDI is resolved"); #endregion }
/// <summary> /// Check objectClass. /// </summary> /// <param name="obj">ModelObject.</param> public static void CheckObjectClass(ModelObject obj) { string dn = (string)obj[StandardNames.shortName]; Value objectClass = obj[StandardNames.objectClass]; if (objectClass == null) { Checks.Fail("'{0}' must have object class", dn); return; } // Check for resolution and last/first element compliance int count = 0; Sequence <string> classes = obj.GetAllClassIds(); bool resolveOk = true; foreach (string classId in classes) { ModelObject classObject; //The object must be present in Schema NC. if (!obj.dc.TryGetClass(classId, out classObject)) { Checks.Fail("'{0}' has undefined object class '{1}'", dn, classId); resolveOk = false; continue; } //Checking for the first class is Top if (count == 0 && classId != StandardNames.top) { Checks.Fail("'{0}' first object class must be top", dn); resolveOk = false; } //Checking for the last class is Structural class. if (count == objectClass.UnderlyingValues.Count - 1) { ObjectClassCategory category = (ObjectClassCategory)(int)classObject[StandardNames.objectClassCategory]; if (category != ObjectClassCategory.StructuralClass) { Checks.Fail("'{0}' last object class must be structural"); resolveOk = false; } } count++; } if (!resolveOk) { return; } // Check for superclass chaining // Checks that if the value of object class is [top,ac_1,...,ac_n,sc_1,...,sc_n], // then sc_n is the most specific structural class, sc_1...scn_(n-1) is the super class chain of sc_n (excluding top), // and ac_n is the next auxilary class before that, where ac_1...acn(n-1) is that classes chain excluding classes // which have been seen already before (where there can be a number of ac anchors here). SetContainer <string> includedClasses = new SetContainer <string>(); int i = classes.Count - 1; while (i > 0) { string classId = classes[i--]; if (includedClasses.Contains(classId)) { Checks.Fail("'{0}' object class contains repeated entries", dn); break; } includedClasses.Add(classId); ObjectClassCategory category = (ObjectClassCategory)(int)obj.dc.GetClass(classId)[StandardNames.objectClassCategory]; if (i == classes.Count - 2) { // Most specific class must be structural if (category != ObjectClassCategory.StructuralClass) { Checks.Fail("'{0}' object class most specific class must be structural", dn); } } //If the server is Pre Windows 2003. foreach (string clId in GetSuperClassChain(obj.dc, classId).Revert()) { if (includedClasses.Contains(clId)) { // Already included in a previous chain continue; } includedClasses.Add(clId); if (i <= 0) { Checks.Fail( "'{0}' object class does not contain chain of super classes of '{1}' (classes missing)", dn, classId); break; } if (classes[i--] != clId) { Checks.Fail( "'{0}' object class does not contain chain of super classes '{1}' (found unexpected '{2}')", dn, classId, classes[i + 1]); break; } } } }