void IsSingleValued(DirectoryEntry dirEntry) { //Count variables for verifying the number of values occurred so far. int count = 0, serverCount; ModelObject obj = dcModel.GetAttribute(StandardNames.cn); if (SingleValued(obj, StandardNames.cn)) { count = 1; } serverCount = dirEntry.Properties[StandardNames.cn].Count; //MS-ADTS-Schema_R92 DataSchemaSite.CaptureRequirementIfIsTrue( count == serverCount, 92, "The attribute isSingleValued is true, if this attribute is a single-valued."); ModelObject obj1 = dcModel.GetAttribute(StandardNames.objectClass); if (!SingleValued(obj1, StandardNames.objectClass)) { //For multivalued attributes the values will be more than 2. count = 2; } serverCount = dirEntry.Properties[StandardNames.objectClass].Count; //MS-ADTS-Schema_R93 DataSchemaSite.CaptureRequirementIfIsTrue( count <= serverCount, 93, "The attribute isSingleValued is false, if this attribute is a multi-valued."); }
/// <summary> /// This method validates the requirements under /// LDSQueryNC Scenario. /// </summary> public void ValidateLDSQueryNC() { DirectoryEntry dirEntry = new DirectoryEntry(); DirectoryEntry schemaEntry = new DirectoryEntry(); DirectoryEntry serverDirEntry = new DirectoryEntry(); if (!adAdapter.GetLdsObjectByDN("CN=Configuration," + adAdapter.LDSRootObjectName, out dirEntry)) { DataSchemaSite.Assert.IsTrue( false, "CN=Configuration," + adAdapter.rootDomainDN + " Object is not found in server"); } if (!adAdapter.GetLdsObjectByDN("CN=Schema,CN=Configuration," + adAdapter.LDSRootObjectName, out schemaEntry)) { DataSchemaSite.Assert.IsTrue( false, "CN=Schema,CN=Configuration," + adAdapter.rootDomainDN + " Object is not found in server"); } if (!adAdapter.GetLdsObjectByDN( "CN=" + adAdapter.LDSServerInstance + ",CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration," + adAdapter.LDSRootObjectName, out serverDirEntry)) { DataSchemaSite.Assert.IsTrue( false, "CN=" + adAdapter.LDSServerInstance + ",CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration," + adAdapter.LDSRootObjectName + " Object is not found in server"); } //Validate the objectVersion of Schema NC if (serverOS == OSVersion.WinSvr2008) { DataSchemaSite.Assert.AreEqual <string>("30", schemaEntry.Properties["objectVersion"].Value.ToString(), "The objectVersion of {0} should be 30.", serverOS); } else if (serverOS >= OSVersion.WinSvr2008R2) { DataSchemaSite.Assert.AreEqual <string>("31", schemaEntry.Properties["objectVersion"].Value.ToString(), "The objectVersion of {0} should be 31.", serverOS); } //MS-ADTS-Schema_R846 DataSchemaSite.CaptureRequirementIfAreEqual <string>( adAdapter.LDSServerInstance.ToLower(), serverDirEntry.Properties["cn"].Value.ToString().ToLower(), 846, "On AD/LDS, the name of the server object is the computer name, followed by \"$\",followed by the " + "instance name of the DC."); }
/// <summary> /// This method validates the requirements under /// LDSServiceAndQueryPolicyContainer Scenario. /// </summary> public void ValidateLDSServiceAndQueryPolicyContainer() { DirectoryEntry requiredEntry = new DirectoryEntry(); DirectoryEntry childEntry = new DirectoryEntry(); string configNCForLDS = "CN=Configuration," + adAdapter.LDSRootObjectName, parentAttribute; PropertyValueCollection objectClass; if (!adAdapter.GetLdsObjectByDN("CN=Services," + configNCForLDS, out requiredEntry)) { DataSchemaSite.Assume.IsTrue( false, "CN=Services," + configNCForLDS + " Object is not found in server"); } //This method is for LDS/DS common requirement call for Services and QueryPolicy Container. LDSAndDSCommonCallForServices(requiredEntry); //This only present in AD/LDS. //MS-ADTS-Schema_R494 if (!adAdapter.GetLdsObjectByDN("CN=Directory Service,CN=Windows NT,CN=Services," + configNCForLDS, out requiredEntry)) { DataSchemaSite.Assume.IsTrue( false, "CN=Directory Service,CN=Windows NT,CN=Services," + configNCForLDS + " Object is not found in server"); } childEntry = requiredEntry.Children.Find("CN=SCP Publication Service"); DataSchemaSite.CaptureRequirementIfIsNotNull( childEntry, 494, "SCP Publication Service Object is present only in AD/LDS."); //MS-ADTS-Schema_R495 parentAttribute = childEntry.Parent.Name.ToString(); DataSchemaSite.CaptureRequirementIfIsTrue(parentAttribute.Equals( "CN=Directory Service"), 495, @"The Parent of the SCP Publication Service Object which is a type of Windows NT Service must be Directory Service."); //MS-ADTS-Schema_R496 objectClass = childEntry.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"msDS-ServiceConnectionPointPublicationService"), 496, @"The ObjectClass attribute of the SCP Publication Service Object which is a type of Windows NT Service must be msDS-ServiceConnectionPointPublicationService."); }
/// <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> /// Method validates the requirements under LDS OptionalFeature Scenario. /// </summary> public void ValidateLDSOptionalFeature() { #region Variables required for Directory Entries. DirectoryEntry dirPartitions = new DirectoryEntry(); DirectoryEntry domainEntry = new DirectoryEntry(); DirectoryEntry childEntry = new DirectoryEntry(); string configNC = "CN=Configuration," + adAdapter.LDSRootObjectName; string SchemaNC = "CN=Schema," + configNC; string recycleBin = "CN=Recycle Bin Feature,CN=Optional Features,CN=Directory Service,CN=Windows NT,CN=Services," + configNC; #endregion #region Verify Recycle Bin Feature enabled //Get recycle bin feature entry if (!adAdapter.GetLdsObjectByDN(recycleBin, out dirPartitions)) { DataSchemaSite.Assume.Fail( "CN=Recycle Bin Feature,CN=Optional Features,CN=Directory Service,CN=Windows NT,CN=Services,," + configNC + " Object is not found in server"); } bool isForestbitflag = false; bool isRecyclebinfeature = false; bool isWIN2008R2 = false; //According to TD 2.2.16, forest feature value is 0x1 const int FOREST_OPTIONAL_FEATURE = 0x00000001; //According to TD 7.1.4.2, windows 2008 R2 version is 4 const int Win2K8R2VerionNumber = 4; if (FOREST_OPTIONAL_FEATURE == (int)(dirPartitions.Properties["msDS-OptionalFeatureFlags"].Value)) { isForestbitflag = true; } if (dirPartitions.Name == "CN=Recycle Bin Feature") { isRecyclebinfeature = true; } if (Win2K8R2VerionNumber == (int)(dirPartitions.Properties["msDS-RequiredForestBehaviorVersion"].Value)) { isWIN2008R2 = true; } List <string> forestScope = new List <string>(); List <string> serverScope = new List <string>(); foreach (string scope in dirPartitions.Properties["msDS-EnabledFeatureBL"]) { //Check if this is server-scope if (scope.Contains("CN=Servers")) { serverScope.Add(scope); } //Check if this is forest scope else if (scope.Contains("CN=Partitions")) { forestScope.Add(scope); } } bool allEnabledRecycleBin = true; foreach (string server in serverScope) { DirectoryEntry serverObj; adAdapter.GetLdsObjectByDN(server, out serverObj); //Check if all server objects included in recycle bin feature has this feature in //msDS-EnableFeature attribute if (!serverObj.Properties["msDS-EnabledFeature"].Contains(recycleBin)) { allEnabledRecycleBin = false; } //Check for nTDSDSA object if (serverObj.SchemaClassName != "nTDSDSA") { allEnabledRecycleBin = false; } } foreach (string forest in forestScope) { DirectoryEntry forestObj; adAdapter.GetLdsObjectByDN(forest, out forestObj); //Check if all forest objects included in recycle bin feature has this feature in //msDS-EnableFeature attribute if (!forestObj.Properties["msDS-EnabledFeature"].Contains(recycleBin)) { allEnabledRecycleBin = false; } } //Verify MS-AD_Schema requirement:MS-AD_Schema_R4486 DataSchemaSite.CaptureRequirementIfIsTrue( dirPartitions.Properties["msDS-RequiredForestBehaviorVersion"] != null, 4486, @"[Optional Features]If an optional feature requires a specific forest functional level before it can be enabled, the forest functional level required is stored in the msDS-RequiredForestBehaviorVersion attribute of the object representing the optional feature."); //Verify MS-AD_Schema requirement:MS-AD_Schema_R4477 DataSchemaSite.CaptureRequirementIfIsTrue( isForestbitflag, 4477, @"[Optional Features]If an optional feature is permissible for a forest-wide scope, the attribute contains the bit flag FOREST_OPTIONAL_FEATURE."); //Verify MS-AD_Schema requirement:MS-AD_Schema_R4468 DataSchemaSite.CaptureRequirementIfIsTrue( allEnabledRecycleBin, 4468, @"[Optional Features]The list of optional features enabled for a scope is stored in the msDS-EnabledFeature attribute on the object representing the scope."); //Verify MS-AD_Schema requirement:MS-AD_Schema_R4470 DataSchemaSite.CaptureRequirementIfIsTrue( allEnabledRecycleBin, 4470, @"[Optional Features]The list of scopes in which an optional feature is enabled is stored in the msDS-EnabledFeatureBL attribute on the object representing the optional feature."); //Verify MS-AD_Schema requirement:MS-AD_Schema_R4471 DataSchemaSite.CaptureRequirementIfIsTrue( allEnabledRecycleBin, 4471, @"[Optional Features]The values stored[stored in the msDS-EnabledFeatureBL attribute] are references to the objects representing the scopes where the feature is enabled."); //Verify MS-AD_Schema requirement:MS-AD_Schema_R4472 DataSchemaSite.CaptureRequirementIfIsTrue( allEnabledRecycleBin, 4472, @"[Optional Features]If an optional feature is enabled in some scope, then, depending on the feature, it might be automatically enabled in another scope; for example, the Recycle Bin optional feature (section 3.1.1.8.1)."); //Verify MS-AD_Schema requirement:MS-AD_Schema_R4475 DataSchemaSite.CaptureRequirementIfIsTrue( allEnabledRecycleBin, 4475, @"[Optional Features]The following procedure determines whether an optional feature is enabled in a scope by using the msDS-EnabledFeature attribute: procedure IsOptionalFeatureEnabled ( scope: DSNAME, featureGuid: GUID): boolean Returns true if scope!msDS-EnabledFeature contains the DN of a msDS-optionalFeature object o such that o!msDS-optionalFeatureGuid equals featureGuid. Returns false otherwise."); //Verify MS-AD_Schema requirement:MS-AD_Schema_R4464 DataSchemaSite.CaptureRequirementIfAreEqual <string>( "msDS-OptionalFeature", dirPartitions.SchemaClassName, 4464, @"[Optional Features]Optional features are represented by instances of the object class msDS-OptionalFeature."); //Verify MS-AD_Schema requirement:MS-AD_Schema_R4496 DataSchemaSite.CaptureRequirementIfIsTrue( isWIN2008R2 && dirPartitions != null, 4496, @"[Recycle Bin Optional Feature]The Recycle Bin optional feature requires a Forest Functional " + "Level of DS_BEHAVIOR_WIN2008R2 or greater."); //Verify MS-AD_Schema requirement:MS-AD_Schema_R4488 //The Recycle Bin Optional feature itsself is a new property for the Windows Server 2008R2 DS and LDS //And before calling the method,it has been determined the version of platform for Windows Server 2008R2. DataSchemaSite.CaptureRequirement( "MS-ADTS-Schema", 4488, @"[Optional Features]Recycle Bin Optional feature is available in Windows Server 2008 R2 AD DS and Windows Server 2008 R2 AD LDS."); //Verify MS-AD_Schema requirement:MS-AD_Schema_R4489 DataSchemaSite.CaptureRequirementIfIsTrue( isRecyclebinfeature, 4489, @"[Recycle Bin Optional Feature]The Recycle Bin optional feature is represented by the Recycle Bin Feature Object (see section 7.1.1.2.4.1.3.1)."); //Verify MS-AD_Schema requirement:MS-AD_Schema_R4500 DataSchemaSite.CaptureRequirementIfIsTrue( isWIN2008R2, 4500, "[Recycle Bin Optional Feature]Any DC with a behavior version of DS_BEHAVIOR_WIN2008R2 or greater " + "MUST be capable of supporting the Recycle Bin optional feature."); DirectoryEntry parent = dirPartitions.Parent; //Verify MS-AD_Schema requirement:MS-AD_Schema_R4465 DataSchemaSite.CaptureRequirementIfIsTrue( parent.Name == "CN=Optional Features" && parent.SchemaClassName == "container" && parent.Parent.Name == "CN=Directory Service", 4465, @"[Optional Features]Objects representing optional features are stored in the Optional Features container in the Config NC (see section 7.1.1.2.4.1.3)."); bool isR4474AndR14473Satisfied = false; if (dirPartitions.Properties.Contains("msDS-OptionalFeatureGUID")) { try { //Get the optional feature Guid Guid featureGUID = new Guid((byte[])dirPartitions.Properties["msDS-OptionalFeatureGUID"][0]); Guid expectedGUID = new Guid("766ddcd8-acd0-445e-f3b9-a7f9b6744f2a"); if (featureGUID != null && featureGUID != Guid.Empty) { isR4474AndR14473Satisfied = true; } //Verify MS-AD_Schema requirement:MS-AD_Schema_R4495 DataSchemaSite.CaptureRequirementIfIsTrue( featureGUID == expectedGUID, 4495, @"[Recycle Bin Optional Feature]The Recycle Bin optional feature is identified by the feature GUID {766ddcd8-acd0-445e-f3b9-a7f9b6744f2a}."); //Verify MS-AD_Schema requirement:MS-AD_Schema_R14473 DataSchemaSite.CaptureRequirementIfIsTrue( isR4474AndR14473Satisfied, 14473, @"[Optional Features]Recycle Bin Optional Feature is uniquely identified by a GUID."); //Verify MS-AD_Schema requirement:MS-AD_Schema_R4474 DataSchemaSite.CaptureRequirementIfIsTrue( isR4474AndR14473Satisfied, 4474, @"[Optional Features] The GUID is stored in the msDS-OptionalFeatureGUID attribute of the object representing the optional feature."); } catch (System.InvalidCastException e) { DataSchemaSite.Assert.Fail(e.ToString()); } } #endregion #region Verify Deleted Objects //Deleted objects are stored in Deleted Objects NC DirectoryEntry deletedObjects = new DirectoryEntry( "LDAP://" + adAdapter.adamServerPort + "/CN=Deleted Objects," + configNC, adAdapter.PrimaryDomainDnsName + @"\" + adAdapter.ClientUserName, adAdapter.ClientUserPassword); deletedObjects.AuthenticationType = AuthenticationTypes.Secure; DirectorySearcher searcher = new DirectorySearcher(deletedObjects); searcher.SearchScope = System.DirectoryServices.SearchScope.OneLevel; searcher.Tombstone = true; //Get all deleted objects try { SearchResultCollection results = searcher.FindAll(); bool isDeleted = false; int RecycledCount; foreach (System.DirectoryServices.SearchResult res in results) { if (res.Path.Contains("CN=" + adAdapter.DeletedGroupName)) { if (res.Properties["isDeleted"] != null) { isDeleted = (bool)res.Properties["isDeleted"][0]; } RecycledCount = res.Properties["isRecycled"].Count; } } } catch (System.DirectoryServices.DirectoryServicesCOMException e) { DataSchemaSite.Log.Add(LogEntryKind.Warning, "Can't access deleted objects: " + e.Message); } AdamInstance adam = AdamInstance.GetAdamInstance( new DirectoryContext(DirectoryContextType.DirectoryServer, adAdapter.adamServerPort, adAdapter.ClientUserName, adAdapter.ClientUserPassword)); Guid invocationID = adam.GetReplicationMetadata( "CN=Deleted Objects,CN=Configuration," + adAdapter.LDSRootObjectName)["isDeleted"].LastOriginatingInvocationId; DateTime deletedTime = adam.GetReplicationMetadata( "CN=Deleted Objects,CN=Configuration," + adAdapter.LDSRootObjectName)["isDeleted"].LastOriginatingChangeTime; #endregion #region Verify Delete Settings int tombstoneLifetime = 0; int deletedObjectLifetime = 0; if (adAdapter.GetLdsObjectByDN( "CN=Directory Service,CN=Windows NT,CN=Services," + configNC, out dirPartitions)) { if (dirPartitions.Properties["deletedObjectLifetime"].Value != null) { deletedObjectLifetime = (int)dirPartitions.Properties["deletedObjectLifetime"][0]; } if (dirPartitions.Properties["tombstoneLifetime"].Value != null) { tombstoneLifetime = (int)dirPartitions.Properties["tombstoneLifetime"][0]; } } else { DataSchemaSite.Assert.Fail("Can't access Directory Service NC"); } #endregion }
public void ValidateContentRulesRequirements(DirectoryEntries childrens, IEnumerable <IObjectOnServer> serverObjects) { bool isContent = true; //Setting some excluded attributes. List <string> ExcludedAttributes = new List <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) { List <string> mustContain = new List <string>(); List <string> mayContain = new List <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."); }
public void ValidateObjectClassRequirements(DirectoryEntries childrens, bool isADDS) { bool isObjectClassMultiValued = false; bool isObjectClassAppeared = false; bool isObjectClassTop = false; bool isObjectClassStructural = false; foreach (DirectoryEntry child in childrens) { //Get objectClass value. PropertyValueCollection propValColln = child.Properties[StandardNames.objectClass]; //If it is not existing Requirement 130 will fail. if (propValColln != null) { isObjectClassAppeared = true; } //It is multivalued. so it should be more than one value. if (propValColln.Count >= 1) { isObjectClassMultiValued = true; } //Get objectClassValue in array. string[] objectClassElements = new string[propValColln.Count]; int loopVariable = 0; foreach (string propVal in (IEnumerable <object>)propValColln.Value) { objectClassElements[loopVariable++] = propVal; } //The first element is always top. if (objectClassElements[0].ToLower().Equals("top")) { isObjectClassTop = true; } //Get last element. string structuralClassName = (string)child.Properties["objectCategory"].Value; DirectoryEntry lastClassObject; if (isADDS) { if (!adAdapter.GetObjectByDN(structuralClassName, out lastClassObject)) { DataSchemaSite.Assume.IsTrue(false, structuralClassName + " Object is not found in server"); } } else { if (!adAdapter.GetLdsObjectByDN(structuralClassName, out lastClassObject)) { DataSchemaSite.Assume.IsTrue(false, structuralClassName + " Object is not found in server"); } } ObjectClassCategory lastClassCategory = (ObjectClassCategory)(int)lastClassObject. Properties[StandardNames.objectClassCategory.ToLower()][0]; //The last element should be structural class. if (lastClassCategory == ObjectClassCategory.StructuralClass) { isObjectClassStructural = true; } if (isObjectClassAppeared && isObjectClassMultiValued && isObjectClassStructural && isObjectClassTop) { continue; } else { break; } } //MS-ADTS-Schema_R143. DataSchemaSite.CaptureRequirementIfIsTrue( isObjectClassMultiValued && isObjectClassAppeared, 143, "Attribute objectClass is a multivalued attribute that appears on all the objects in the directory."); //MS-ADTS-Schema_R144. DataSchemaSite.CaptureRequirementIfIsTrue( isObjectClassMultiValued && isObjectClassAppeared, 144, @"When instantiating a structural class, the objectClass attribute of the new object contains a sequence of class names"); //MS-ADTS-Schema_R145. DataSchemaSite.CaptureRequirementIfIsTrue( isObjectClassTop, 145, "In the ObjectClass first element is always class top."); //MS-ADTS-Schema_R146. DataSchemaSite.CaptureRequirementIfIsTrue( isObjectClassStructural, 146, "In the ObjectClass last element is the name of the structural class that was instantiated."); }
/// <summary> /// Method validates the requirements under LDSCrossRefContainer Scenario. /// </summary> public void ValidateLDSCrossRefContainer() { DirectoryEntry dirPartitions = new DirectoryEntry(); DirectoryEntry domainEntry = new DirectoryEntry(); DirectoryEntry childEntry = new DirectoryEntry(); DirectoryEntry requiredEntry = new DirectoryEntry(); string systemFlag; int systemFlagVal; //Variables for holding the paths for NCs. if (!adAdapter.GetLdsObjectByDN("CN=Partitions,CN=Configuration," + adAdapter.LDSRootObjectName, out dirPartitions)) { DataSchemaSite.Assert.IsTrue( false, "CN=Partitions,CN=Configuration," + adAdapter.LDSRootObjectName + "Object is not found in server"); } string parentAttribute = dirPartitions.Parent.Name.ToString(); //MS-ADTS-Schema_R402 DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=Configuration", parentAttribute, 402, "The Parent of the Cross-Ref-Container Container must be Config NC root."); //MS-ADTS-Schema_R403 DataSchemaSite.CaptureRequirementIfAreEqual <string>( "Partitions", dirPartitions.Properties["name"].Value.ToString(), 403, "The name attribute of the Cross-Ref-Container Container must be Partitions."); PropertyValueCollection objectClass = dirPartitions.Properties["objectClass"]; //MS-ADTS-Schema_R404 DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"crossRefContainer"), 404, "The objectClass attribute of the Cross-Ref-Container Container must be crossRefContainer."); //MS-ADTS-Schema_R406 systemFlag = dirPartitions.Properties["systemFlags"].Value.ToString(); systemFlagVal = ParseSystemFlagsValue("FLAG_DISALLOW_DELETE"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( systemFlagVal.ToString(), systemFlag, 406, "The systemFlags attribute of the Cross-Ref-Container Container must be FLAG_DISALLOW_DELETE."); bool isCrossRef = true; bool isObjectClassCrossRef = true; DirectoryEntries Childs = dirPartitions.Children; foreach (DirectoryEntry child in Childs) { if (!child.Parent.Name.Equals("CN=Partitions")) { isCrossRef = false; } PropertyValueCollection objClass = child.Properties["objectClass"]; objClass.RemoveAt(0); if (objClass.Count != 1 || !objClass.Contains((object)"crossRef")) { isObjectClassCrossRef = false; } } //MS-ADTS-Schema_R408 DataSchemaSite.CaptureRequirementIfIsTrue( isCrossRef, 408, "The parent of the Cross-Ref Objects must be crossRefContainer object."); //MS-ADTS-Schema_R409 DataSchemaSite.CaptureRequirementIfIsTrue( isObjectClassCrossRef, 409, "The objectClass attribute of the Cross-Ref Objects must be crossRef."); childEntry = dirPartitions.Children.Find("CN=Enterprise Configuration"); //MS-ADTS-Schema_R410 DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=Configuration," + adAdapter.LDSRootObjectName, childEntry.Properties["nCName"].Value.ToString(), 410, "The nCName attribute of the Configuration crossRef Object must equal to the config NC root."); //MS-ADTS-Schema_R412 DataSchemaSite.CaptureRequirementIfIsFalse( childEntry.Properties.Contains("dnsRoot"), 412, "In AD/LDS the dnsroot attribute is not presented for the Configuration crossRef Object. "); childEntry = dirPartitions.Children.Find("CN=Enterprise Schema"); //MS-ADTS-Schema_R413 DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=Schema,CN=Configuration," + adAdapter.LDSRootObjectName, childEntry.Properties["nCName"].Value.ToString(), 413, "The nCName attribute of the Schema crossRef Object must equal to the Schema NC root."); //MS-ADTS-Schema_R415 DataSchemaSite.CaptureRequirementIfIsFalse( childEntry.Properties.Contains("dnsRoot"), 415, "In AD/LDS the dnsroot attribute is not presented for the Schema crossRef Object."); childEntry = dirPartitions.Children.Find("CN=Enterprise Configuration"); //MS-ADTS-Schema_R421 DataSchemaSite.CaptureRequirementIfIsFalse( childEntry.Properties.Contains("dnsRoot"), 421, "In AD/LDS the dnsroot attribute is not presented for Application NC crossRef Object."); //MS-ADTS-Schema_R852 childEntry = dirPartitions.Children.Find("CN=Enterprise Schema"); if (!adAdapter.GetLdsObjectByDN("CN=Schema,CN=Configuration," + adAdapter.LDSRootObjectName, out dirPartitions)) { DataSchemaSite.Assert.IsTrue( false, "CN=Schema,CN=Configuration," + adAdapter.LDSRootObjectName + " Object is not found in server"); } DataSchemaSite.CaptureRequirementIfAreEqual <string>( childEntry.Properties["nCName"].Value.ToString(), dirPartitions.Properties["distinguishedName"].Value.ToString(), 852, "The nCName attribute of the crossRef object must equal the dsname of the NC root object."); }
/// <summary> /// This method validates the requirements under /// UniqueID Scenario. /// </summary> public void ValidateUniqueID() { //If the flag fANR is set on the searchFlags attribute of the attributeSchema, then fATTINDEX must also be set. HashSet <string> attrIDs = new HashSet <string>(); HashSet <string> schemaIDs = new HashSet <string>(); HashSet <string> attrLDAPDisplayNameIDs = new HashSet <string>(); HashSet <string> linkIDs = new HashSet <string>(); ModelObject attributeObject, classObject; bool uniqueAttrID = false, uniqueSchemaID = false, uniqueGovernsID = false, uniqueSttrlDAPDisplayName = false, uniqueClasslDAPDisplayName = false, uniquelinkID = false, flagfANR = false; foreach (IObjectOnServer serverObject in adAdapter.GetAllSchemaAttributes()) { if (!dcModel.TryGetAttribute(serverObject.Name, out attributeObject)) { DataSchemaSite.Log.Add( LogEntryKind.Warning, "schema attribute '{0}' exists on server but not in model", serverObject.Name); continue; } Value attrIDValue = attributeObject["attributeID"]; Value schemaIDGUIDValue = attributeObject["schemaIDGUID"]; Value lDAPDisplayNameValue = attributeObject["lDAPDisplayName"]; Value linkIDValue = attributeObject["linkID"]; if (attrIDs.Contains(attrIDValue.ToString())) { uniqueAttrID = true; DataSchemaSite.Log.Add( LogEntryKind.Warning, "attributeID of '{0}' is already exists", serverObject.Name); } if (schemaIDs.Contains(schemaIDGUIDValue.ToString())) { uniqueSchemaID = true; DataSchemaSite.Log.Add( LogEntryKind.Warning, "schemaIDGUID of '{0}' is already exists", serverObject.Name); } if (attrLDAPDisplayNameIDs.Contains(lDAPDisplayNameValue.ToString())) { uniqueSttrlDAPDisplayName = true; DataSchemaSite.Log.Add( LogEntryKind.Warning, "lDAPDisplayName of '{0}' is already exists", serverObject.Name); } if (linkIDValue != null) { if (linkIDs.Contains(linkIDValue.ToString())) { uniquelinkID = true; DataSchemaSite.Log.Add( LogEntryKind.Comment, "linkID of '{0}' is already exists", serverObject.Name); } } attrIDs.Add(attrIDValue.ToString()); schemaIDs.Add(schemaIDGUIDValue.ToString()); attrLDAPDisplayNameIDs.Add(lDAPDisplayNameValue.ToString()); if (linkIDValue != null) { linkIDs.Add(linkIDValue.ToString()); } Value valueOfSearchFlag = attributeObject["searchFlags"]; Type flagType = IntegerSymbols.GetSymbolEnumType("SearchFlags"); string searchFlag = Enum.Format(flagType, (uint)((int)valueOfSearchFlag), "g"); if (searchFlag.Contains("fANR")) { if (!searchFlag.Contains("fATTINDEX")) { flagfANR = true; } } } //MS-ADTS-Schema_R76 DataSchemaSite.CaptureRequirementIfIsTrue( !uniqueAttrID, 76, @"The attributeID attribute of the attributeSchema objects described in MS-ADA1, MS-ADA2, MS-ADA3 is Unique OID's that identifies this attribute."); //MS-ADTS-Schema_R80 DataSchemaSite.CaptureRequirementIfIsTrue( !uniqueSchemaID, 80, @"The schemaIDGUID attribute of the attributeSchema objects described in MS-ADA1, MS-ADA2, MS-ADA3 is Unique GUID that identifies this attribute."); //MS-ADTS-Schema_R102 DataSchemaSite.CaptureRequirementIfIsTrue( !uniqueSttrlDAPDisplayName, 102, @"The lDAPDisplayName attribute of the attributeSchema objects described in MS-ADA1, MS-ADA2, MS-ADA3 is Unique that identifies this attribute."); //MS-ADTS-Schema_R86 DataSchemaSite.CaptureRequirementIfIsTrue( !uniquelinkID, 86, "The value of the linkID attribute of the attributeSchema, " + "is unique among all values of this attribute on objects in MS-ADA1, MS-ADA2 and MS-ADA3, " + "regardless of forest functional level."); //MS-ADTS-Schema_R125 DataSchemaSite.CaptureRequirementIfIsTrue( !flagfANR, 125, @"If the flag fANR is set on the searchFlags attribute of the attributeSchema, then fATTINDEX must also be set."); HashSet <string> governsIDs = new HashSet <string>(); HashSet <string> classLDAPDisplayNameIDs = new HashSet <string>(); foreach (IObjectOnServer serverObject in adAdapter.GetAllSchemaClasses()) { if (!dcModel.TryGetClass(serverObject.Name, out classObject)) { DataSchemaSite.Log.Add( LogEntryKind.Warning, "schema class '{0}' exists on server but not in model", serverObject.Name); continue; } Value governsIDValue = classObject["governsID"]; Value lDAPDisplayNameValue = classObject["lDAPDisplayName"]; if (governsIDs.Contains(governsIDValue.ToString())) { uniqueGovernsID = true; DataSchemaSite.Log.Add( LogEntryKind.Warning, "governsID of '{0}' is already exists", serverObject.Name); } if (classLDAPDisplayNameIDs.Contains(lDAPDisplayNameValue.ToString())) { uniqueClasslDAPDisplayName = true; DataSchemaSite.Log.Add( LogEntryKind.Warning, "classlDAPDisplayName of '{0}' is already exists", serverObject.Name); } governsIDs.Add(governsIDValue.ToString()); classLDAPDisplayNameIDs.Add(lDAPDisplayNameValue.ToString()); } //MS-ADTS-Schema_R160 DataSchemaSite.CaptureRequirementIfIsTrue( !uniqueGovernsID, 160, @"The governsID attribute of the classSchema objects described in MS-ADSC is unique that identifies the class."); //MS-ADTS-Schema_R187 DataSchemaSite.CaptureRequirementIfIsTrue( !uniqueClasslDAPDisplayName, 187, @"The lDAPDisplayName attribute of the classSchema objects described in MS-ADSC is unique name that identifies the class."); }
/// <summary> /// Validates requirements related to DC. /// </summary> public void DRSRRequirementValidation() { //Dn of DomainController string distinguishName = "LDAP://CN=" + adAdapter.PDCNetbiosName + ",OU=Domain Controllers," + adAdapter.rootDomainDN; //Instance of DirectoryEntry eith dn. DirectoryEntry compEntry = new DirectoryEntry(distinguishName); #region Validation of MS-AD_Schema_R933 SearchResponse ntdsdsResponse = null; bool condition1 = false; bool condition2 = false; int instanceType = 0; #region Validate MS-AD_Schema_R933 distinguishName = "CN=NTDS Settings,CN=" + adAdapter.PDCNetbiosName + ",CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration," + adAdapter.rootDomainDN; GetLDAPObject( distinguishName, adAdapter.PDCNetbiosName, "objectclass=ntdsdsa", System.DirectoryServices.Protocols.SearchScope.Base, new string[] { "msDS-hasMasterNCs", "hasMasterNCs", "msDS-HasInstantiatedNCs", "msDS-HasDomainNCs", "options", "hasPartialReplicaNCs" }, out ntdsdsResponse); string[] instantiatedNCValue = (string[])ntdsdsResponse.Entries[0].Attributes["msDS-HasInstantiatedNCs"].GetValues(typeof(string)); if (ntdsdsResponse.Entries[0].Attributes.Contains("hasPartialReplicaNCs")) { string[] partialReplicas = (string[])ntdsdsResponse.Entries[0].Attributes["hasPartialReplicaNCs"].GetValues(typeof(string)); condition1 = false; foreach (string replica in partialReplicas) { if (replica.ToLower().Contains(adAdapter.rootDomainDN.ToLower())) { condition1 = true; break; } } distinguishName = "CN=NTDS Settings,CN=" + adAdapter.PDCNetbiosName + ",CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration," + adAdapter.rootDomainDN; GetLDAPObject( distinguishName, adAdapter.PDCNetbiosName, "objectclass=ntdsdsa", System.DirectoryServices.Protocols.SearchScope.Base, new string[] { "msDS-HasInstantiatedNCs" }, out ntdsdsResponse); instanceType = int.Parse(new DirectoryEntry("LDAP://" + adAdapter.rootDomainDN).Properties["instancetype"].Value.ToString()); condition2 = false; foreach (string value in instantiatedNCValue) { if (value.Contains(instanceType.ToString("X") + ":" + adAdapter.rootDomainDN)) { condition2 = true; break; } } condition1 = condition1 && condition2; DataSchemaSite.CaptureRequirementIfIsTrue( condition1, 933, @"A DC hosts a partial NC replica of a domain NC when the attribute hasPartialReplicaNCs on the nTDSDSA object representing the DC contains the dsname of the NC roots representing the domain NC and the attribute msDS-HasInstantiatedNCs on the nTDSDSA object representing the DC contains an Object(DN-Binary) value such that the DN field is the dsname of the NC root representing the NC, and the Data field contains the value of the instanceType attribute on the NC root object on the DC."); } #endregion #endregion }
/// <summary> /// CaptureSystemOnly is a Common method for Both AD/DS and AD/LDS, /// which takes the Object entry from ObjectList and /// Verify the SystemOnly Value is set to TRUE or not /// </summary> /// <param name="entry">entry from the objectList</param> private void CaptureSystemOnly(string entry) { // Creating attribute model Object ModelObject attributeObject; //Checking For AD/DS or AD/LDS. if (isDS) { dcModel.attributeMap.TryGetValue(entry.ToLower(), out attributeObject); } else { adamModel.attributeMap.TryGetValue(entry.ToLower(), out attributeObject); } bool value = (bool)attributeObject[StandardNames.systemOnly].UnderlyingValues.ToArray()[0]; switch (entry) { case "objectClass": //MS-ADTS-Schema_R74 DataSchemaSite.CaptureRequirementIfIsTrue( value, 74, "The objectClass attribute of the attributeSchema is System-only."); //MS-ADTS-Schema_R158 DataSchemaSite.CaptureRequirementIfIsTrue( value, 158, "The objectClass attribute of the classSchema is System-only."); break; case "attributeID": //MS-ADTS-Schema_R78 DataSchemaSite.CaptureRequirementIfIsTrue( value, 78, "The attributeID attribute of the attributeSchema is System-only."); break; case "schemaIDGUID": //MS-ADTS-Schema_R82 DataSchemaSite.CaptureRequirementIfIsTrue( value, 82, "The schemaIDGUID attribute of the attributeSchema is System-only."); //MS-ADTS-Schema_R163 DataSchemaSite.CaptureRequirementIfIsTrue( value, 163, "The schemaIDGUID attribute of the classSchema is System-only."); break; case "msDS-IntId": //MS-ADTS-Schema_R84 DataSchemaSite.CaptureRequirementIfIsTrue( value, 84, "The msDS-IntId attribute of the attributeSchema is System-only."); //MS-ADTS-Schema_R165 DataSchemaSite.CaptureRequirementIfIsTrue( value, 165, "The msDS-IntId attribute of the classSchema is System-only."); break; case "mAPIID": //MS-ADTS-Schema_R88 DataSchemaSite.CaptureRequirementIfIsTrue( value, 88, "The mAPIID attribute of the attributeSchema is System-only."); break; case "attributeSyntax": //MS-ADTS-Schema_R89 DataSchemaSite.CaptureRequirementIfIsTrue( value, 89, "The attributeSyntax attribute of the attributeSchema is System-only."); break; case "oMSyntax": //MS-ADTS-Schema_R90 DataSchemaSite.CaptureRequirementIfIsTrue( value, 90, "The oMSyntax attribute of the attributeSchema is System-only."); break; case "oMObjectClass": //MS-ADTS-Schema_R91 DataSchemaSite.CaptureRequirementIfIsTrue( value, 91, "The oMObjectClass attribute of the attributeSchema is System-only."); break; case "isSingleValued": //MS-ADTS-Schema_R94 DataSchemaSite.CaptureRequirementIfIsTrue( value, 94, "The isSingleValued attribute of the attributeSchema is System-only."); break; case "systemFlags": //MS-ADTS-Schema_R98 DataSchemaSite.CaptureRequirementIfIsTrue( value, 98, "The systemFlags attribute of the attributeSchema is System-only."); //MS-ADTS-Schema_R183 DataSchemaSite.CaptureRequirementIfIsTrue( value, 183, "The systemFlags attribute of the classSchema is System-only."); break; case "systemOnly": //MS-ADTS-Schema_R99 DataSchemaSite.CaptureRequirementIfIsTrue( value, 99, "The systemOnly attribute of the attributeSchema is System-only."); //MS-ADTS-Schema_R184 DataSchemaSite.CaptureRequirementIfIsTrue( value, 184, "The systemOnly attribute of the classSchema is System-only."); break; case "governsID": //MS-ADTS-Schema_R162 DataSchemaSite.CaptureRequirementIfIsTrue( value, 162, "The governsID attribute of the classSchema is System-only."); break; case "rDNAttID": //MS-ADTS-Schema_R168 DataSchemaSite.CaptureRequirementIfIsTrue( value, 168, "The rDNAttID attribute of the classSchema is System-only."); break; case "subClassOf": //MS-ADTS-Schema_R170 DataSchemaSite.CaptureRequirementIfIsTrue( value, 170, "The subClassOf attribute of the classSchema is System-only."); break; case "systemMustContain": //MS-ADTS-Schema_R172 DataSchemaSite.CaptureRequirementIfIsTrue( value, 172, "The systemMustContain attribute of the classSchema is System-only."); break; case "systemMayContain": //MS-ADTS-Schema_R174 DataSchemaSite.CaptureRequirementIfIsTrue( value, 174, "The systemMayContain attribute of the classSchema is System-only."); break; case "systemPossSuperiors": //MS-ADTS-Schema_R176 DataSchemaSite.CaptureRequirementIfIsTrue( value, 176, "The systemPossSuperiors attribute of the classSchema is System-only."); break; case "systemAuxiliaryClass": //MS-ADTS-Schema_R178 DataSchemaSite.CaptureRequirementIfIsTrue( value, 178, "The systemAuxiliaryClass attribute of the classSchema is System-only."); break; case "objectClassCategory": //MS-ADTS-Schema_R180 DataSchemaSite.CaptureRequirementIfIsTrue( value, 180, "The objectClassCategory attribute of the classSchema is System-only."); break; } }
private void SyntaxRequirements() { //MS-ADTS-Schema_R17 DataSchemaSite.CaptureRequirementIfIsTrue( !boolean, 17, "For Boolean LDAP syntax name corresponding attributeSyntax and oMSyntax are 2.5.5.8 and 1."); //MS-ADTS-Schema_R18 DataSchemaSite.CaptureRequirementIfIsTrue( !enumeration, 18, "For Enumeration LDAP syntax name corresponding attributeSyntax and oMSyntax are 2.5.5.9 and 10."); // MS-ADTS-Schema_R19 DataSchemaSite.CaptureRequirementIfIsTrue( !integer, 19, "For Integer LDAP syntax name corresponding attributeSyntax and oMSyntax are 2.5.5.9 and 2."); // MS-ADTS-Schema_R20 DataSchemaSite.CaptureRequirementIfIsTrue( !largeInt, 20, "For LargeInteger LDAP syntax name corresponding attributeSyntax and oMSyntax are 2.5.5.16 and 65."); // MS-ADTS-Schema_R21 DataSchemaSite.CaptureRequirementIfIsTrue( !accessPoint, 21, @"For Object(Access-Point) LDAP syntax name corresponding attributeSyntax, oMSyntax and oMObjectClass are 2.5.5.14, 127 and 1.3.12.2.1011.28.0.702."); // MS-ADTS-Schema_R22 DataSchemaSite.CaptureRequirementIfIsTrue( !DNString, 22, @"For Object(DN-String) LDAP syntax name corresponding attributeSyntax, oMSyntax and oMObjectClass are 2.5.5.14, 127 and 1.2.840.113556.1.1.1.12."); // MS-ADTS-Schema_R23 DataSchemaSite.CaptureRequirementIfIsTrue( !ORName, 23, @"For Object(OR-Name) LDAP syntax name corresponding attributeSyntax, oMSyntax and oMObjectClass are 2.5.5.7, 127 and 2.6.6.1.2.5.11.29."); // MS-ADTS-Schema_R24 DataSchemaSite.CaptureRequirementIfIsTrue( !DNBinary, 24, @"For Object(DN-Binary) LDAP syntax name corresponding attributeSyntax, oMSyntax and oMObjectClass are 2.5.5.7, 127 and 1.2.840.113556.1.1.1.11."); // MS-ADTS-Schema_R25 DataSchemaSite.CaptureRequirementIfIsTrue( !DSDN, 25, @"For Object(DS-DN) LDAP syntax name corresponding attributeSyntax, oMSyntax and oMObjectClass are 2.5.5.1, 127 and 1.3.12.2.1011.28.0.714."); // MS-ADTS-Schema_R26 DataSchemaSite.CaptureRequirementIfIsTrue( !preAddr, 26, @"For Object(Presentation-Address) LDAP syntax name corresponding attributeSyntax, oMSyntax and oMObjectClass are 2.5.5.13, 127 and 1.3.12.2.1011.28.0.732."); // MS-ADTS-Schema_R27 DataSchemaSite.CaptureRequirementIfIsTrue( !repLink, 27, @"For Object(Replica-Link) LDAP syntax name corresponding attributeSyntax, oMSyntax and oMObjectClass are 2.5.5.10, 127 and 1.2.840.113556.1.1.1.6."); // MS-ADTS-Schema_R28 DataSchemaSite.CaptureRequirementIfIsTrue( !strCase, 28, "For String(Case) LDAP syntax name corresponding attributeSyntax and oMSyntax are 2.5.5.3 and 27."); // MS-ADTS-Schema_R29 DataSchemaSite.CaptureRequirementIfIsTrue( !strIA5, 29, "For String(IA5) LDAP syntax name corresponding attributeSyntax and oMSyntax are 2.5.5.5 and 22."); // MS-ADTS-Schema_R30 DataSchemaSite.CaptureRequirementIfIsTrue( !NTSecDesc, 30, @"For String(NT-Sec-Desc) LDAP syntax name corresponding attributeSyntax and oMSyntax are 2.5.5.15 and 66."); // MS-ADTS-Schema_R31 DataSchemaSite.CaptureRequirementIfIsTrue(!numeric, 31, @"For String(Numeric) LDAP syntax name corresponding attributeSyntax and oMSyntax are 2.5.5.6 and 18."); // MS-ADTS-Schema_R32 DataSchemaSite.CaptureRequirementIfIsTrue( !objIdentifier, 32, @"For String(Object-Identifier) LDAP syntax name corresponding attributeSyntax and oMSyntax are 2.5.5.2 and 6."); // MS-ADTS-Schema_R33 DataSchemaSite.CaptureRequirementIfIsTrue( !octet, 33, @"For String(Octet) LDAP syntax name corresponding attributeSyntax and oMSyntax are 2.5.5.10 and 4."); // MS-ADTS-Schema_R34 DataSchemaSite.CaptureRequirementIfIsTrue( !printable, 34, @"For String(Printable) LDAP syntax name corresponding attributeSyntax and oMSyntax are 2.5.5.5 and 19."); // MS-ADTS-Schema_R35 DataSchemaSite.CaptureRequirementIfIsTrue( !sid, 35, @"For String(Sid) LDAP syntax name corresponding attributeSyntax and oMSyntax are 2.5.5.17 and 4."); // MS-ADTS-Schema_R36 DataSchemaSite.CaptureRequirementIfIsTrue( !teletext, 36, @"For String(Teletex) LDAP syntax name corresponding attributeSyntax and oMSyntax are 2.5.5.4 and 20."); // MS-ADTS-Schema_R37 DataSchemaSite.CaptureRequirementIfIsTrue( !unicode, 37, @"For String(Unicode) LDAP syntax name corresponding attributeSyntax and oMSyntax are 2.5.5.12 and 64."); // MS-ADTS-Schema_R38 DataSchemaSite.CaptureRequirementIfIsTrue( !UTCTime, 38, "For String(UTC-Time) LDAP syntax name corresponding attributeSyntax and oMSyntax are 2.5.5.11 and 23."); // MS-ADTS-Schema_R39 DataSchemaSite.CaptureRequirementIfIsTrue( !genTime, 39, @"For String(Generalized-Time) LDAP syntax name corresponding attributeSyntax and oMSyntax are 2.5.5.11 and 24."); // MS-ADTS-Schema_R40 DataSchemaSite.CaptureRequirementIfIsTrue( !intRange, 40, "The Integer syntax in Active Directory is restricted to 32-bit integers."); // MS-ADTS-Schema_R41 DataSchemaSite.CaptureRequirementIfIsTrue( !larIntRange, 41, "The LargeInteger syntax in Active Directory is restricted to 64-bit integers."); // MS-ADTS-Schema_R49 DataSchemaSite.CaptureRequirementIfIsTrue( !binaryFormat, 49, @"A value with Object(DN-Binary) syntax is a UTF-8 string is in the format 'B:char_count:binary_value:object_DN'."); // MS-ADTS-Schema_R50 DataSchemaSite.CaptureRequirementIfIsTrue( !hexCount, 50, @"In Object(DN-Binary) syntax char_count is the number (in decimal) of hexadecimal digits in binary_value, binary_value is the hexadecimal representation of a binary value, object_DN is a DN in Object(DS-DN) form, and all remaining characters are string literals."); // MS-ADTS-Schema_R51 DataSchemaSite.CaptureRequirementIfIsTrue( byteToHex != null, 51, @"Each byte in Object(DN-Binary) syntax is represented by a pair of hexadecimal characters in binary_value, with the first character of each pair corresponding to the most-significant nibble of the byte."); // MS-ADTS-Schema_R95 DataSchemaSite.CaptureRequirementIfIsTrue( !extCharsAllow, 95, @"The attribute extendedCharsAllowed of the attributeSchema is applicable to attributes of syntax String(IA5), String(Numeric), String(Teletex), String(Printable)."); // MS-ADTS-Schema_R113 DataSchemaSite.CaptureRequirementIfIsTrue( !rangeLower32, 113, "rangeLower attribute of the attributeSchema is a 32-bit integer."); // MS-ADTS-Schema_R123 DataSchemaSite.CaptureRequirementIfIsTrue( !rangeUpper32, 123, "rangeUpper attribute of the attributeSchema is a 32-bit integer."); // MS-ADTS-Schema_R156 DataSchemaSite.CaptureRequirementIfIsTrue( !attrType, 156, "The RDN attribute is of syntax String(Unicode)."); // MS-ADTS-Schema_R271 DataSchemaSite.CaptureRequirementIfIsTrue( !rDNSyntax, 271, @"Active Directory imposes the additional restriction that the AttributeType used must be of String(Unicode) syntax."); }
/// <summary> /// Method validates the requirements under RolesContainer Scenario. /// </summary> public void ValidateLDSRoleContainer() { DirectoryEntry dirEntryConfig = new DirectoryEntry(); DirectoryEntry dirEntryApp = new DirectoryEntry(); DirectoryEntry dirEntrySch = new DirectoryEntry(); DirectoryEntry dirEntry = new DirectoryEntry(); if (!adAdapter.GetLdsObjectByDN("CN=Roles," + adAdapter.LDSApplicationNC, out dirEntryApp)) { DataSchemaSite.Assert.IsTrue( false, "CN=Roles," + adAdapter.LDSApplicationNC + " Object is not found in server"); } if (!adAdapter.GetLdsObjectByDN("CN=Roles,CN=Configuration," + adAdapter.LDSRootObjectName, out dirEntryConfig)) { DataSchemaSite.Assert.IsTrue( false, "CN=Roles,CN=Configuration," + adAdapter.LDSRootObjectName + " Object is not found in server"); } //MS-ADTS-Schema_R768 DataSchemaSite.CaptureRequirementIfIsTrue( dirEntryApp != null && dirEntryConfig != null, 768, "For the Roles Container the Parent must be Application NC root or config NC root."); //MS-ADTS-Schema_R769 DataSchemaSite.CaptureRequirementIfIsTrue( dirEntryApp.Properties["objectClass"].Contains((object)"container"), 769, "The objectClass attribute of Roles Container must be container."); //MS-ADTS-Schema_R770 string systemFlag = dirEntryConfig.Properties["systemFlags"].Value.ToString(); int systemFlagVal = ParseSystemFlagsValue("FLAG_DISALLOW_DELETE"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( systemFlag, systemFlagVal.ToString(), 770, "The systemFlags attribute of Roles Container must be FLAG_DISALLOW_DELETE."); DirectoryEntries rolesChilds = dirEntryConfig.Children; bool isParentRoles = true; foreach (DirectoryEntry child in rolesChilds) { if (!child.Parent.Name.ToString().Equals("CN=Roles")) { isParentRoles = false; } } //MS-ADTS-Schema_R771 DataSchemaSite.CaptureRequirementIfIsTrue( isParentRoles, 771, "For each child of the Roles Container the Parent must be Roles Container."); //MS-ADTS-Schema_R772 rolesChilds = dirEntryConfig.Children; List <DirectoryEntry> wellKnownRolesChilds = new List <DirectoryEntry>(); bool isGroup = true; foreach (DirectoryEntry child in rolesChilds) { if (child.Properties["cn"].ToString().Equals("Administrators") || child.Properties["cn"].ToString().Equals("Instances") || child.Properties["cn"].ToString().Equals("Readers") || child.Properties["cn"].ToString().Equals("Users")) { wellKnownRolesChilds.Add(child); if (!child.Properties["objectClass"].Contains((object)"group")) { isGroup = false; } } } DataSchemaSite.CaptureRequirementIfIsTrue( isGroup, 772, "The objectClass attribute for each child of the Roles Container must be group."); if (serverOS >= OSVersion.WinSvr2008) { //MS-ADTS-Schema_R773 if (!adAdapter.GetLdsObjectByDN( "CN=Administrators,CN=Roles,CN=Configuration," + adAdapter.LDSRootObjectName, out dirEntry)) { DataSchemaSite.Assume.IsTrue( false, "CN=Administrators,CN=Roles,CN=Configuration," + adAdapter.LDSRootObjectName + " Object is not found in server"); } byte[] objSid = (byte[])dirEntry.Properties["objectSid"].Value; dirEntry.RefreshCache(new string[] { "primaryGrouptoken" }); PropertyValueCollection primaryGroup = dirEntry.Properties["primaryGroupToken"]; SecurityIdentifier sid = new SecurityIdentifier(objSid, 0); string objectSid = sid.ToString(); objectSid = objectSid.Substring(objectSid.LastIndexOf('-') + 1); DataSchemaSite.CaptureRequirementIfAreEqual <string>( objectSid, primaryGroup.Value.ToString(), 773, @"The objectSid attribute for each child of the Roles Container must be a SID with two SubAuthority values,consisting of the objectSid of the NC root followed by the RID."); } //MS-ADTS-Schema_R778 if (!adAdapter.GetLdsObjectByDN( "CN=Administrators,CN=Roles,CN=Configuration," + adAdapter.LDSRootObjectName, out dirEntry)) { DataSchemaSite.Assume.IsTrue( false, "CN=Administrators,CN=Roles,CN=Configuration," + adAdapter.LDSRootObjectName + " Object is not found in server"); } PropertyValueCollection memberSec = dirEntry.Properties["member"]; bool isForeignSecurityPrincipalsContained = false; foreach (var prop in memberSec) { if (prop.ToString().Contains("CN=ForeignSecurityPrincipals")) { isForeignSecurityPrincipalsContained = true; break; } } DataSchemaSite.CaptureRequirementIfIsTrue( isForeignSecurityPrincipalsContained, 778, @"The member attribute of Administrators Group Object must be that at least one foreignSecurityPrincipal is configured into this group by the administrator when creating a forest."); //MS-ADTS-Schema_R774 foreach (DirectoryEntry dir1 in wellKnownRolesChilds) { PropertyValueCollection groupType = dir1.Properties["groupType"]; //The {ACCOUNT_GROUP | SECURITY_ENABLED} flag value is equivalent to "0x80000002" with reference //from ADTS groupFlags. int groupTypeValue = (int)groupType.Value; string groupValueType = "0x80000002"; int modelGroup = Convert.ToInt32(groupValueType, 16); if (groupTypeValue == modelGroup) { isGroup = true; } } DataSchemaSite.CaptureRequirementIfIsTrue( isGroup, 774, @"The groupType attribute for each child of theRoles Container must be ACCOUNT_GROUP | SECURITY_ENABLED."); //MS-ADTS-Schema_R776 dirEntry.RefreshCache(new string[] { "primaryGroupToken" }); string primary = dirEntry.Properties["primaryGroupToken"].Value.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "519", primary, 776, "The RID attribute of Administrators Group Object must be 519 (in the config NC)."); //MS-ADTS-Schema_R777 if (!adAdapter.GetLdsObjectByDN( "CN=Administrators,CN=Roles," + adAdapter.LDSApplicationNC, out dirEntry)) { DataSchemaSite.Assume.IsTrue( false, "CN=Administrators,CN=Roles," + adAdapter.LDSApplicationNC + " Object is not found in server"); } dirEntry.RefreshCache(new string[] { "primaryGroupToken" }); primary = dirEntry.Properties["primaryGroupToken"].Value.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "512", primary, 777, "The RID attribute of Administrators Group Object must be 512 (in an application NC)."); //MS-ADTS-Schema_R779 if (!adAdapter.GetLdsObjectByDN("CN=Readers,CN=Roles," + adAdapter.LDSApplicationNC, out dirEntry)) { DataSchemaSite.Assume.IsTrue( false, "CN=Readers,CN=Roles," + adAdapter.LDSApplicationNC + " Object is not found in server"); } dirEntry.RefreshCache(new string[] { "primaryGroupToken" }); primary = dirEntry.Properties["primaryGroupToken"].Value.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "514", primary, 779, "The RID attribute of Readers Group Object must be 514."); dirEntry.RefreshCache(new string[] { "member" }); PropertyValueCollection member = dirEntry.Properties["member"]; object memberValue = member.Value; //MS-ADTS-Schema_R775 DataSchemaSite.CaptureRequirementIfIsNull( memberValue, 775, @"Unless otherwise noted, the initial membership of the member attribute,for each child of the Roles Container must be empty."); //MS-ADTS-Schema_R779 if (!adAdapter.GetLdsObjectByDN( "CN=Readers,CN=Roles,CN=Configuration," + adAdapter.LDSRootObjectName, out dirEntry)) { DataSchemaSite.Assume.IsTrue( false, "CN=Readers,CN=Roles,CN=Configuration," + adAdapter.LDSRootObjectName + " Object is not found in server"); } dirEntry.RefreshCache(new string[] { "primaryGroupToken" }); primary = dirEntry.Properties["primaryGroupToken"].Value.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "514", primary, 779, "The RID attribute of Readers Group Object must be 514."); //MS-ADTS-Schema_R780 if (!adAdapter.GetLdsObjectByDN("CN=Users,CN=Roles," + adAdapter.LDSApplicationNC, out dirEntry)) { DataSchemaSite.Assume.IsTrue( false, "CN=Users,CN=Roles," + adAdapter.LDSApplicationNC + " Object is not found in server"); } dirEntry.RefreshCache(new string[] { "primaryGroupToken" }); primary = dirEntry.Properties["primaryGroupToken"].Value.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "513", primary, 780, "The RID attribute of Users Group Object must be 513."); if (!adAdapter.GetLdsObjectByDN( "CN=Users,CN=Roles,CN=Configuration," + adAdapter.LDSRootObjectName, out dirEntry)) { DataSchemaSite.Assume.IsTrue( false, "CN=Users,CN=Roles,CN=Configuration," + adAdapter.LDSRootObjectName + " Object is not found in server"); } dirEntry.RefreshCache(new string[] { "primaryGroupToken" }); primary = dirEntry.Properties["primaryGroupToken"].Value.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "513", primary, 780, "The RID attribute of Users Group Object must be 513."); //MS-ADTS-Schema_R782 if (!adAdapter.GetLdsObjectByDN( "CN=Instances,CN=Roles,CN=Configuration," + adAdapter.LDSRootObjectName, out dirEntry)) { DataSchemaSite.Assume.IsTrue( false, "CN=Instances,CN=Roles,CN=Configuration," + adAdapter.LDSRootObjectName + " Object is not found in server"); } dirEntry.RefreshCache(new string[] { "primaryGroupToken" }); primary = dirEntry.Properties["primaryGroupToken"].Value.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "518", primary, 782, "The RID attribute of Instances Group Object must be 518."); }
/// <summary> /// This method validates the requirements under /// ForestUpdatesContainer Scenario. /// </summary> public void ValidateForestUpdatesContainer() { DirectoryEntry dirPartitions = new DirectoryEntry(); string currDomain = adAdapter.rootDomainDN; string parent; PropertyValueCollection objectClass; if (!adAdapter.GetObjectByDN( "CN=Operations,CN=ForestUpdates,CN=Configuration," + currDomain, out dirPartitions)) { DataSchemaSite.Assume.IsTrue( false, "CN=Operations,CN=ForestUpdates,CN=Configuration," + currDomain + " Object is not found in server"); } parent = dirPartitions.Parent.Name; //MS-ADTS-Schema_R676 DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=ForestUpdates", parent, 676, @"The Parent of the Operations Container, which is a type of Forest Updates Container must be equal to the Forest Updates container."); //MS-ADTS-Schema_R677 objectClass = dirPartitions.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"container"), 677, @"The objectClass attribute of the Operations Container , which is a type of Forest Updates Container must be container."); if (!adAdapter.GetObjectByDN( "CN=Windows2003Update,CN=ForestUpdates,CN=Configuration," + currDomain, out dirPartitions)) { DataSchemaSite.Assume.IsTrue( false, "CN=Windows2003Update,CN=ForestUpdates,CN=Configuration," + currDomain + " Object is not found in server"); } parent = dirPartitions.Parent.Name; //MS-ADTS-Schema_R678 DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=ForestUpdates", parent, 678, @"The Parent of the Windows2003Update Container , which is a type of Forest Updates Container must be equal to the Forest Updates container."); //MS-ADTS-Schema_R679 objectClass = dirPartitions.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"container"), 679, @"The objectClass attribute of the Windows2003Update Container , which is a type of Forest Updates Container must be container."); if (serverOS >= OSVersion.WinSvr2008) { if (!adAdapter.GetObjectByDN( "CN=ActiveDirectoryUpdate,CN=ForestUpdates,CN=Configuration," + currDomain, out dirPartitions)) { DataSchemaSite.Assume.IsTrue( false, "CN=ActiveDirectoryUpdate,CN=ForestUpdates," + "CN=Configuration," + currDomain + " Object is not found in server"); } parent = dirPartitions.Parent.Name; //MS-ADTS-Schema_R681 DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=ForestUpdates", parent, 681, @"The Parent of the ActiveDirectoryUpdate Container , which is a type of Forest Updates Container must be equal to the Forest Updates container."); //MS-ADTS-Schema_R682 objectClass = dirPartitions.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"container"), 682, @"The objectClass attribute of the ActiveDirectoryUpdate Container , which is a type of Forest Updates Container must be container."); if (!adAdapter.GetObjectByDN( "CN=ActiveDirectoryRodcUpdate,CN=ForestUpdates,CN=Configuration," + currDomain, out dirPartitions)) { DataSchemaSite.Assume.IsTrue( false, "CN=ActiveDirectoryRodcUpdate,CN=ForestUpdates," + "CN=Configuration," + currDomain + " Object is not found in server"); } parent = dirPartitions.Parent.Name; //MS-ADTS-Schema_R684 DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=ForestUpdates", parent, 684, @"The Parent of the ActiveDirectoryRodcUpdate Container , which is a type of Forest Updates Container must be equal to the Forest Updates container."); //MS-ADTS-Schema_R685 objectClass = dirPartitions.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"container"), 685, @"The objectClass attribute of the ActiveDirectoryRodcUpdate Container , which is a type of Forest Updates Container must be container."); } //Check revisions string updatesNC = "CN=ForestUpdates,CN=Configuration," + currDomain; int rodcRevision = 0; int operationRevision = 0; bool isStoredOnActive = false; bool isStoredOnWin2003Up = false; bool isStoredOnActiveRodc = false; ForestRevision forest = new ForestRevision(); //Get RODC revision adAdapter.GetObjectByDN("CN=ActiveDirectoryRodcUpdate," + updatesNC, out dirPartitions); if (dirPartitions != null) { if (dirPartitions.Properties["Revision"].Value != null) { //Verify MS-AD_Schema requirement:MS-AD_Schema_R264500 DataSchemaSite.CaptureRequirementIfIsTrue( dirPartitions.Properties["Revision"].Value.GetType() == typeof(int), 264500, @"[In RODC Revision] The version of the RODC revision is an integer."); rodcRevision = (int)dirPartitions.Properties["Revision"].Value; isStoredOnActiveRodc = true; } else { DataSchemaSite.Assert.Fail("Failed to get RODC Update container"); } //Verify MS-AD_Schema requirement:MS-AD_Schema_R224533 DataSchemaSite.CaptureRequirementIfIsTrue( isStoredOnActiveRodc, 224533, @"[In Forest Updates Container] The version of the RODC revision is stored on the revision attribute of the ActiveDirectoryRodcUpdate container."); if (2 == rodcRevision) { parent = dirPartitions.Parent.Name; //Verify MS-AD_Schema requirement:MS-AD_Schema_R144533 DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=ForestUpdates", parent, 144533, @"[In Forest Updates Container] If the version of the RODC revision is 2, the Forest Updates container includes the child container ActiveDirectoryRodcUpdate."); } } //Get forest major revision adAdapter.GetObjectByDN("CN=ActiveDirectoryUpdate," + updatesNC, out dirPartitions); if (dirPartitions != null) { if (dirPartitions.Properties["Revision"].Value != null) { forest.major = (int)dirPartitions.Properties["Revision"].Value; isStoredOnActive = true; } //Verify MS-AD_Schema requirement:MS-AD_Schema_R164533 DataSchemaSite.CaptureRequirementIfIsTrue( isStoredOnActive, 164533, @"[In Forest Updates Container] The major version of the forest revision is stored on the revision attribute of the ActiveDirectoryUpdate container."); } //Get Operations revision adAdapter.GetObjectByDN("CN=Operations," + updatesNC, out dirPartitions); if (dirPartitions != null) { if (dirPartitions.Properties["Revision"].Value != null) { operationRevision = (int)dirPartitions.Properties["Revision"].Value; } } //Get forest minor revision adAdapter.GetObjectByDN("CN=Windows2003Update," + updatesNC, out dirPartitions); if (dirPartitions != null) { if (dirPartitions.Properties["Revision"].Value != null) { forest.minor = (int)dirPartitions.Properties["Revision"].Value; isStoredOnWin2003Up = true; } //Verify MS-AD_Schema requirement:MS-AD_Schema_R194533 DataSchemaSite.CaptureRequirementIfIsTrue( isStoredOnWin2003Up, 194533, @"[In Forest Updates Container] The minor version of the forest revision is stored on the revision attribute of the Windows2003Update container."); } ForestRevision DsBehavior = new ForestRevision(); bool isForestForCorrectDsBehavior = false; // The forest revision for WinSvr2008 is 2.10 if (serverOS == OSVersion.WinSvr2008) { DsBehavior.major = 2; DsBehavior.minor = 10; } // The forest revision for WinSvr2008R2 is 5.9 else if (serverOS == OSVersion.WinSvr2008R2) { DsBehavior.major = 5; DsBehavior.minor = 9; } // The forest revision for Win2012 is 10.9 else if (serverOS == OSVersion.WinSvr2012) { DsBehavior.major = 10; DsBehavior.minor = 9; } // The forest revision for Win2012R2 is 12.10 else if (serverOS == OSVersion.WinSvr2012R2) { DsBehavior.major = 12; DsBehavior.minor = 10; } // Check forest revision if ((forest.major > DsBehavior.major) || (forest.major == DsBehavior.major && forest.minor >= DsBehavior.minor)) { isForestForCorrectDsBehavior = true; } // Verify MS-AD_Schema requirement:MS-AD_Schema_R194500 DataSchemaSite.CaptureRequirementIfIsTrue( isForestForCorrectDsBehavior, 194500, @"[In Forest Revision] The forest revision is below the minimal requirement of the current DC functional level."); }
// <summary> /// This method validates the requirements under /// LDSSitesContainer Scenario. /// </summary> public void ValidateLDSSitesContainer() { DirectoryEntry dirPartitions = new DirectoryEntry(); DirectoryEntry domainEntry = new DirectoryEntry(); DirectoryEntry childEntry = new DirectoryEntry(); string systemFlag; int systemFlagVal; string configNCForLDS = "CN=Configuration," + adAdapter.LDSRootObjectName; string SchemaNC = "CN=Schema," + configNCForLDS; //MS-ADTS-Schema_R423 if (!adAdapter.GetLdsObjectByDN("CN=Sites," + configNCForLDS, out dirPartitions)) { DataSchemaSite.Assume.IsTrue( false, "CN=Sites," + configNCForLDS + " Object is not found in server"); } DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=Configuration", dirPartitions.Parent.Name.ToString(), 423, "Each forest contains a Sites container in the Config NC."); //MS-ADTS-Schema_R425 DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=Configuration", dirPartitions.Parent.Name.ToString(), 425, "The parent of the Sites Container must be Config NC root object."); //MS-ADTS-Schema_R426 DataSchemaSite.CaptureRequirementIfIsTrue( dirPartitions.Properties["objectClass"].Contains((object)"sitesContainer"), 426, "The objectClass attribute of the Sites Container must be sitesContainer."); //MS-ADTS-Schema_R427 systemFlag = dirPartitions.Properties["systemFlags"].Value.ToString(); systemFlagVal = ParseSystemFlagsValue("FLAG_DISALLOW_DELETE|FLAG_DISALLOW_MOVE_ON_DELETE"); if (systemFlag != (systemFlagVal.ToString())) { isParseSystemFlagsValue = false; } DataSchemaSite.CaptureRequirementIfAreEqual <string>( systemFlagVal.ToString(), systemFlag, 427, @"The SytemFlags attribute of the Sites Container must be either of FLAG_DISALLOW_DELETE|FLAG_DISALLOW_MOVE_ON_DELETE."); if (systemFlag != (systemFlagVal.ToString())) { isParseSystemFlagsValue = false; } //MS-ADTS-Schema_R428 DirectoryEntries dirEntriesForValue = dirPartitions.Children; bool isParentRoles = false; foreach (DirectoryEntry child in dirEntriesForValue) { if (child.Properties["objectCategory"].Value.ToString().ToLower().Contains("cn=site")) { isParentRoles = true; } } DataSchemaSite.CaptureRequirementIfIsTrue( isParentRoles, 428, "The parent of the Site Object must be Sites container."); //MS-ADTS-Schema_R429 childEntry = dirPartitions.Children.Find("CN=Default-First-Site-Name"); DataSchemaSite.CaptureRequirementIfIsTrue( childEntry.Properties["objectClass"].Contains((object)"site"), 429, "The objectClass attribute of the Site Object must be Site."); //MS-ADTS-Schema_R430 systemFlag = childEntry.Properties["systemFlags"].Value.ToString(); systemFlagVal = ParseSystemFlagsValue("FLAG_CONFIG_ALLOW_RENAME|FLAG_DISALLOW_MOVE_ON_DELETE"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( systemFlagVal.ToString(), systemFlag, 430, @"The SytemFlags attribute of the Site Object must be either of FLAG_CONFIG_ALLOW_RENAME|FLAG_DISALLOW_MOVE_ON_DELETE."); if (systemFlag != (systemFlagVal.ToString())) { isParseSystemFlagsValue = false; } //MS-ADTS-Schema_R457 if (!adAdapter.GetLdsObjectByDN("CN=Subnets,CN=Sites," + configNCForLDS, out dirPartitions)) { DataSchemaSite.Assume.IsTrue( false, "CN=Subnets,CN=Sites," + configNCForLDS + " Object is not found in server"); } DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=Sites", dirPartitions.Parent.Name.ToString(), 457, "Each forest contains a Subnets container in the config NC."); //MS-ADTS-Schema_R458 DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=Sites", dirPartitions.Parent.Name.ToString(), 458, "The Parent of the Subnet container must be Sites container."); //MS-ADTS-Schema_R459 DataSchemaSite.CaptureRequirementIfIsTrue( dirPartitions.Properties["objectClass"].Contains((object)"subnetContainer"), 459, "The ObjectClass attribute of the Subnet container must be subnetContainer."); //MS-ADTS-Schema_R460 systemFlag = dirPartitions.Properties["systemFlags"].Value.ToString(); systemFlagVal = ParseSystemFlagsValue("FLAG_DISALLOW_DELETE"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( systemFlagVal.ToString(), systemFlag, 460, "The SystemFlags attribute of the Subnet container must be FLAG_DISALLOW_DELETE."); if (systemFlag != (systemFlagVal.ToString())) { isParseSystemFlagsValue = false; } //MS-ADTS-Schema_R465 if (!adAdapter.GetLdsObjectByDN("CN=Inter-Site Transports,CN=Sites," + configNCForLDS, out dirPartitions)) { DataSchemaSite.Assume.IsTrue( false, "CN=Inter-Site Transports,CN=Sites," + configNCForLDS + " Object is not found in server."); } DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=Sites", dirPartitions.Parent.Name.ToString(), 465, "The Parent of the IP Transport Container must be Inter-Site Transports container."); //MS-ADTS-Schema_R466 DataSchemaSite.CaptureRequirementIfIsTrue( dirPartitions.Properties["objectClass"].Contains((object)"interSiteTransportContainer"), 466, "The ObjectClass attribute of the Inter-Site Transports Container must be interSiteTransportContainer."); //MS-ADTS-Schema_R467 systemFlag = dirPartitions.Properties["systemFlags"].Value.ToString(); systemFlagVal = ParseSystemFlagsValue("FLAG_DISALLOW_DELETE"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( systemFlagVal.ToString(), systemFlag, 467, "The SystemFlags attribute of the Inter-Site Transports Container must be FLAG_DISALLOW_DELETE."); if (systemFlag != (systemFlagVal.ToString())) { isParseSystemFlagsValue = false; } //MS-ADTS-Schema_R468 childEntry = dirPartitions.Children.Find("CN=IP"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=Inter-Site Transports", childEntry.Parent.Name.ToString(), 468, "The Parent of the IP Transport Container must be Inter-Site Transports container."); //MS-ADTS-Schema_R469 DataSchemaSite.CaptureRequirementIfIsTrue( childEntry.Properties["objectClass"].Contains((object)"interSiteTransport"), 469, "The ObjectClass attribute of the IP Transport Container must be interSiteTransport."); //MS-ADTS-Schema_R472 domainEntry = childEntry.Children.Find("CN=DEFAULTIPSITELINK"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=IP", domainEntry.Parent.Name.ToString(), 472, @"The Parent of the Site Link Bridge Object must be Either IP Transport container or SMTP Transport container."); //MS-ADTS-Schema_R473 DataSchemaSite.CaptureRequirementIfIsTrue( domainEntry.Properties["objectClass"].Contains((object)"siteLink"), 473, "The ObjectClass attribute of the Site Link Object must be siteLink."); }
// <summary> /// This method validates the requirements under /// SitesContainer Scenario. /// </summary> public void ValidateSitesContainer() { //Declaring the DirectoryEntry variables for holding the objects. DirectoryEntry dirPartitions = new DirectoryEntry(); DirectoryEntry domainEntry = new DirectoryEntry(); DirectoryEntry childEntry = new DirectoryEntry(); string currDomain = adAdapter.rootDomainDN; string configNC = "CN=Configuration," + currDomain; string SchemaNC = "CN=Schema," + configNC; string systemFlag = String.Empty; int systemFlagVal; //MS-ADTS-Schema_R423 if (!adAdapter.GetObjectByDN("CN=Sites," + configNC, out dirPartitions)) { DataSchemaSite.Assume.IsTrue(false, "CN=Sites," + configNC + " Object is not found in server"); } DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=Configuration", dirPartitions.Parent.Name.ToString(), 423, "Each forest contains a Sites container in the Config NC."); //MS-ADTS-Schema_R425 DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=Configuration", dirPartitions.Parent.Name.ToString(), 425, "The parent of the Sites Container must be Config NC root object."); //MS-ADTS-Schema_R426 DataSchemaSite.CaptureRequirementIfIsTrue( dirPartitions.Properties["objectClass"].Contains((object)"sitesContainer"), 426, "The objectClass attribute of the Sites Container must be sitesContainer."); //MS-ADTS-Schema_R428 DirectoryEntries dirEntriesForValue = dirPartitions.Children; bool isParentRoles = false; foreach (DirectoryEntry child in dirEntriesForValue) { if (child.Parent.Name.ToString().Equals("CN=Sites")) { isParentRoles = true; } } DataSchemaSite.CaptureRequirementIfIsTrue( isParentRoles, 428, "The parent of the Site Object must be Sites container."); //MS-ADTS-Schema_R429 childEntry = dirPartitions.Children.Find("CN=Default-First-Site-Name"); DataSchemaSite.CaptureRequirementIfIsTrue( childEntry.Properties["objectClass"].Contains((object)"site"), 429, "The objectClass attribute of the Site Object must be Site."); //MS-ADTS-Schema_R427 systemFlag = dirPartitions.Properties["systemFlags"].Value.ToString(); systemFlagVal = ParseSystemFlagsValue("FLAG_DISALLOW_DELETE|FLAG_DISALLOW_MOVE_ON_DELETE"); if (systemFlag != (systemFlagVal.ToString())) { isParseSystemFlagsValue = false; } DataSchemaSite.CaptureRequirementIfAreEqual <string>( systemFlagVal.ToString(), systemFlag, 427, @"The SytemFlags attribute of the Sites Container must be either of FLAG_DISALLOW_DELETE|FLAG_DISALLOW_MOVE_ON_DELETE."); if (systemFlag != (systemFlagVal.ToString())) { isParseSystemFlagsValue = false; } //MS-ADTS-Schema_R430 systemFlag = childEntry.Properties["systemFlags"].Value.ToString(); systemFlagVal = ParseSystemFlagsValue("FLAG_CONFIG_ALLOW_RENAME|FLAG_DISALLOW_MOVE_ON_DELETE"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( systemFlagVal.ToString(), systemFlag, 430, @"The SytemFlags attribute of the Site Object must be either of FLAG_CONFIG_ALLOW_RENAME|FLAG_DISALLOW_MOVE_ON_DELETE."); if (systemFlag != (systemFlagVal.ToString())) { isParseSystemFlagsValue = false; } //MS-ADTS-Schema_R431 DirectoryEntry sitesEntry = new DirectoryEntry(); if (!adAdapter.GetObjectByDN("CN=Sites,CN=Configuration," + currDomain, out sitesEntry)) { DataSchemaSite.Assume.IsTrue( false, "CN=Sites,CN=Configuration," + currDomain + " Object is not found in server"); } sitesEntry = sitesEntry.Children.Find("CN=Default-First-Site-Name"); DirectoryEntries sitesChildren = sitesEntry.Children; foreach (DirectoryEntry child in sitesChildren) { PropertyValueCollection v = child.Properties["objectClass"]; if (child.Properties["objectClass"].Contains((object)"nTDSSiteSettings")) { //MS-ADTS-Schema_R432 // [Since objectClass (sitesEntry) contains nTDSSiteSettings, R432 is captured.] DataSchemaSite.CaptureRequirement( 432, "The objectClass attribute of the NTDS Site Settings Object must be nTDSSiteSettings."); } } //MS-ADTS-Schema_R431 DataSchemaSite.Log.Add(LogEntryKind.Debug, "Verify MS-ADTS-Schema_R431"); DataSchemaSite.CaptureRequirementIfIsTrue( sitesEntry.Parent.Name.ToString().Contains("CN=Sites"), 431, "The parent of the NTDS Site Settings Object must be site object."); //MS-ADTS-Schema_R457 if (!adAdapter.GetObjectByDN("CN=Subnets,CN=Sites," + configNC, out dirPartitions)) { DataSchemaSite.Assume.IsTrue( false, "CN=Subnets,CN=Sites," + configNC + " Object is not found in server"); } DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=Sites", dirPartitions.Parent.Name.ToString(), 457, "Each forest contains a Subnets container in the config NC."); //MS-ADTS-Schema_R458 DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=Sites", dirPartitions.Parent.Name.ToString(), 458, "The Parent of the Subnet container must be Sites container."); //MS-ADTS-Schema_R459 DataSchemaSite.CaptureRequirementIfIsTrue( dirPartitions.Properties["objectClass"].Contains((object)"subnetContainer"), 459, "The ObjectClass attribute of the Subnet container must be subnetContainer."); //MS-ADTS-Schema_R460 systemFlag = dirPartitions.Properties["systemFlags"].Value.ToString(); systemFlagVal = ParseSystemFlagsValue("FLAG_DISALLOW_DELETE"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( systemFlagVal.ToString(), systemFlag, 460, "The SystemFlags attribute of the Subnet container must be FLAG_DISALLOW_DELETE."); if (systemFlag != (systemFlagVal.ToString())) { isParseSystemFlagsValue = false; } //MS-ADTS-Schema_R465 if (!adAdapter.GetObjectByDN("CN=Inter-Site Transports,CN=Sites," + configNC, out dirPartitions)) { DataSchemaSite.Assume.IsTrue( false, "CN=Inter-Site Transports,CN=Sites," + configNC + " Object is not found in server"); } DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=Sites", dirPartitions.Parent.Name.ToString(), 465, "The Parent of the IP Transport Container must be Inter-Site Transports container."); //MS-ADTS-Schema_R466 DataSchemaSite.CaptureRequirementIfIsTrue( dirPartitions.Properties["objectClass"].Contains((object)"interSiteTransportContainer"), 466, "The ObjectClass attribute of the Inter-Site Transports Container must be interSiteTransportContainer."); //MS-ADTS-Schema_R467 systemFlag = dirPartitions.Properties["systemFlags"].Value.ToString(); systemFlagVal = ParseSystemFlagsValue("FLAG_DISALLOW_DELETE"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( systemFlagVal.ToString(), systemFlag, 467, "The SystemFlags attribute of the Inter-Site Transports Container must be FLAG_DISALLOW_DELETE."); if (systemFlag != (systemFlagVal.ToString())) { isParseSystemFlagsValue = false; } //MS-ADTS-Schema_R468 childEntry = dirPartitions.Children.Find("CN=IP"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=Inter-Site Transports", childEntry.Parent.Name.ToString(), 468, "The Parent of the IP Transport Container must be Inter-Site Transports container."); //MS-ADTS-Schema_R469 DataSchemaSite.CaptureRequirementIfIsTrue( childEntry.Properties["objectClass"].Contains((object)"interSiteTransport"), 469, "The ObjectClass attribute of the IP Transport Container must be interSiteTransport."); List <DirectoryAttribute> atts = new List <DirectoryAttribute>(); string ret = AdLdapClient.Instance().ConnectAndBind( adAdapter.PDCNetbiosName, adAdapter.PDCIPAddr, Convert.ToInt32(adAdapter.ADDSPortNum), adAdapter.DomainAdministratorName, adAdapter.DomainUserPassword, adAdapter.PrimaryDomainNetBiosName, AuthType.Basic | AuthType.Kerberos); if (ret.Equals("Success_STATUS_SUCCESS")) { atts.Add(new DirectoryAttribute("objectClass", new String[] { "top", "site" })); string testDistinguishedName = "CN=test,CN=Sites,CN=Configuration," + adAdapter.rootDomainDN; AdLdapClient.Instance().AddObject(testDistinguishedName, atts, null); atts.Clear(); atts.Add(new DirectoryAttribute("siteList", new String[] { "CN=test,CN=Sites,CN=Configuration," + adAdapter.rootDomainDN })); atts.Add(new DirectoryAttribute("objectClass", new String[] { "top", "siteLink" })); string testLinkDistinguishedName = "CN=testlink,CN=IP,CN=Inter-Site Transports,CN=Sites,CN=Configuration," + adAdapter.rootDomainDN; AdLdapClient.Instance().AddObject(testLinkDistinguishedName, atts, null); atts.Clear(); atts.Add(new DirectoryAttribute("siteLinkList", new String[] { "CN=DEFAULTIPSITELINK,CN=IP,CN=Inter-Site Transports,CN=Sites,CN=Configuration," + adAdapter.rootDomainDN, "CN=testLink,CN=IP,CN=Inter-Site Transports,CN=Sites,CN=Configuration," + adAdapter.rootDomainDN })); atts.Add(new DirectoryAttribute("objectClass", new String[] { "top", "siteLinkBridge" })); string testLinkBridgeDistinguishedName = "CN=testLinkBridge,CN=IP,CN=Inter-Site Transports,CN=Sites,CN=Configuration," + adAdapter.rootDomainDN; string result = AdLdapClient.Instance().AddObject(testLinkBridgeDistinguishedName, atts, null); DataSchemaSite.Assert.AreEqual <string>("Success_STATUS_SUCCESS", result, "create dynamic object {0} succeeded", testLinkBridgeDistinguishedName); if (!adAdapter.GetObjectByDN("CN=Subnets,CN=Sites," + configNC, out dirPartitions)) { DataSchemaSite.Assume.IsTrue( false, "CN=Subnets,CN=Sites," + configNC + " Object is not found in server"); } //MS-ADTS-Schema_R462,MS-ADTS-Schema_R463 and MS-ADTS-Schema_R464 //The Parent of the Subnet Object must be Subnets container. DirectoryEntries subnetChilds; subnetChilds = dirPartitions.Children; foreach (DirectoryEntry child in subnetChilds) { DataSchemaSite.Log.Add(LogEntryKind.Debug, "Subnet name is a valid subnet name if:"); string name = child.Properties["name"].Value.ToString(); int count = name.Split('/').Length - 1; DataSchemaSite.Assert.AreEqual(1, count, "1. There should be only one occurrence of the character \"/\" in subnet name:{0}.", name); int i = name.IndexOf('/'); string s1 = name.Substring(0, i); DataSchemaSite.Assert.AreNotEqual(0, s1.IndexOf('0'), "2. Let i be the index of the character \"/\" in name, the substring name[0, i-1]:{0} does not have any leading zeros.", s1); System.Net.IPAddress subnetIP = null; bool isValid = false; isValid = System.Net.IPAddress.TryParse(s1, out subnetIP); DataSchemaSite.Assert.IsTrue(isValid, "2. The substring name[0, i-1]:{0} should be either a valid IPv4 address in dotted decimal notation or a valid IPv6 address in colon-hexadecimal form or compressed form.", s1); string s2 = name.Substring(i + 1); DataSchemaSite.Assert.AreNotEqual(0, s2.IndexOf('0'), "3. The substring name[i+1, l-1]:{0} does not have any leading zeros.", s2); uint n; isValid = false; isValid = uint.TryParse(s2, out n); DataSchemaSite.Assert.IsTrue(isValid, "3. The substring name[i+1, l-1] should be able to be converted to an unsigned integer n:{0}.", n); isValid = false; if (subnetIP.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { if (n > 0 && n <= 32) { isValid = true; } } else if (subnetIP.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) { if (n > 0 && n <= 128) { isValid = true; } } else { isValid = false; } DataSchemaSite.Assert.IsTrue(isValid, "4. When the address is in IPv4 format, 0 < n:{0} <= 32. When the address is in IPv6 format, 0 < n:{0} <= 128.", n); uint[] bitMask = new uint[] { 0x00000000, 0x00000080, 0x000000C0, 0x000000E0, 0x000000F0, 0x000000F8, 0x000000FC, 0x000000FE, 0x000000FF, 0x000080FF, 0x0000C0FF, 0x0000E0FF, 0x0000F0FF, 0x0000F8FF, 0x0000FCFF, 0x0000FEFF, 0x0000FFFF, 0x0080FFFF, 0x00C0FFFF, 0x00E0FFFF, 0x00F0FFFF, 0x00F8FFFF, 0x00FCFFFF, 0x00FEFFFF, 0x00FFFFFF, 0x80FFFFFF, 0xC0FFFFFF, 0xE0FFFFFF, 0xF0FFFFFF, 0xF8FFFFFF, 0xFCFFFFFF, 0xFEFFFFFF, 0xFFFFFFFF }; if (subnetIP.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { uint ipInt = BitConverter.ToUInt32(subnetIP.GetAddressBytes().Reverse().ToArray(), 0); uint res = ipInt & (~bitMask[n]); DataSchemaSite.Assert.AreEqual <uint>(0, res, "5. Let b be the binary representation of the address, when the address is in IPv4 format, b & (~BitMask[n]) = 0."); DataSchemaSite.Assert.IsTrue(ipInt != bitMask[n], "6. When the address is in IPv4 format, b != BitMask[n]."); } DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=Subnets", child.Parent.Name.ToString(), 462, "The Parent of the Subnet Object must be Subnets container."); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "subnet", child.SchemaClassName, 463, "The ObjectClass attribute of the Subnet Object must be Subnet."); systemFlag = child.Properties["systemFlags"].Value.ToString(); systemFlagVal = ParseSystemFlagsValue("FLAG_CONFIG_ALLOW_RENAME"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( systemFlagVal.ToString(), systemFlag, 464, "The SystemFlags attribute of the Subnet must be FLAG_CONFIG_ALLOW_RENAME."); } //MS-ADTS-Schema_R476,MS-ADTS-Schema_R477 and MS-ADTS-Schema_R478 subnetChilds = childEntry.Children; foreach (DirectoryEntry child in subnetChilds) { if (child.SchemaClassName.ToLower() == "siteLinkBridge".ToLower()) { DataSchemaSite.CaptureRequirementIfIsTrue( child.Properties["objectClass"].Contains("siteLinkBridge"), 476, "The ObjectClass attribute of the Site Link Bridge Object must be siteLinkBridge."); systemFlag = child.Properties["systemFlags"].Value.ToString(); systemFlagVal = ParseSystemFlagsValue("FLAG_CONFIG_ALLOW_RENAME"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( systemFlagVal.ToString(), systemFlag, 477, "The SystemFlags attribute of the Site Link Bridge Object must be FLAG_CONFIG_ALLOW_RENAME."); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=IP", child.Parent.Name.ToString(), 478, @"The Parent of the Site Link Bridge Object must be Either IP Transport container or SMTP Transport container."); } } if (!AdLdapClient.Instance().DeleteObject(testLinkBridgeDistinguishedName, null).Equals("Success_STATUS_SUCCESS")) { DataSchemaSite.Assume.Fail("The created dynamic object" + testLinkBridgeDistinguishedName + " can not be deleted."); } if (!AdLdapClient.Instance().DeleteObject(testLinkDistinguishedName, null).Equals("Success_STATUS_SUCCESS")) { DataSchemaSite.Assume.Fail("The created dynamic object" + testLinkDistinguishedName + " can not be deleted."); } if (!AdLdapClient.Instance().DeleteObject(testDistinguishedName, null).Equals("Success_STATUS_SUCCESS")) { DataSchemaSite.Assume.Fail("The created dynamic object" + testDistinguishedName + " can not be deleted."); } } else { DataSchemaSite.Assume.Fail("It's failed to connect and bind to AD/DS "); } AdLdapClient.Instance().Unbind(); //MS-ADTS-Schema_R472 domainEntry = childEntry.Children.Find("CN=DEFAULTIPSITELINK"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=IP", domainEntry.Parent.Name.ToString(), 472, @"The Parent of the Site Link Bridge Object must be Either IP Transport container or SMTP Transport container."); //MS-ADTS-Schema_R473 DataSchemaSite.CaptureRequirementIfIsTrue( domainEntry.Properties["objectClass"].Contains((object)"siteLink"), 473, "The ObjectClass attribute of the Site Link Object must be siteLink."); //MS-ADTS-Schema_R474 systemFlag = domainEntry.Properties["systemFlags"].Value.ToString(); systemFlagVal = ParseSystemFlagsValue("FLAG_CONFIG_ALLOW_RENAME"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( systemFlagVal.ToString(), systemFlag, 474, "The SystemFlags attribute of the Site Link Object must be FLAG_CONFIG_ALLOW_RENAME."); if (systemFlag != (systemFlagVal.ToString())) { isParseSystemFlagsValue = false; } if (!adAdapter.GetObjectByDN("CN=Inter-Site Transports,CN=Sites," + configNC, out dirPartitions)) { DataSchemaSite.Assume.IsTrue( false, "CN=Inter-Site Transports,CN=Sites," + configNC + " Object is not found in server"); } //MS-ADTS-Schema_R470 childEntry = dirPartitions.Children.Find("CN=SMTP"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=Inter-Site Transports", childEntry.Parent.Name.ToString(), 470, "The Parent of the SMTP Transport Container must be Inter-Site Transports container."); //MS-ADTS-Schema_R471 DataSchemaSite.CaptureRequirementIfIsTrue( childEntry.Properties["objectClass"].Contains((object)"interSiteTransport"), 471, "The ObjectClass attribute of the SMTP Transport Container must be interSiteTransport."); }
/// <summary> /// This method validates the requirements under /// LDSUniqueID Scenario. /// </summary> public void ValidateLDSUniqueID() { ModelObject attributeObject, classObject; HashSet <string> attrIDsForLDS = new HashSet <string>(); HashSet <string> schemaIDsForLDS = new HashSet <string>(); HashSet <string> attrLDAPDisplayNameIDsLDS = new HashSet <string>(); HashSet <string> linkIDsLDS = new HashSet <string>(); bool uniqueLDSAttrID = false, uniqueLDSSchemaID = false, uniqueLDSattrlDAPDisplayName = false, uniqueLDSlinkID = false, uniqueLDSGovernsID = false, uniqueclassLDSlDAPDisplayName = false, flagfANR = false; foreach (IObjectOnServer serverObject in adAdapter.GetAllLdsSchemaAttributes()) { if (!adamModel.TryGetAttribute(serverObject.Name, out attributeObject)) { DataSchemaSite.Log.Add( LogEntryKind.Warning, "schema attribute '{0}' exists on server but not in model", serverObject.Name); continue; } Value attrIDValue = attributeObject["attributeID"]; Value schemaIDGUIDValue = attributeObject["schemaIDGUID"]; Value lDAPDisplayNameValue = attributeObject["lDAPDisplayName"]; Value linkIDValue = attributeObject["linkID"]; if (attrIDsForLDS.Contains(attrIDValue.ToString())) { uniqueLDSAttrID = true; DataSchemaSite.Log.Add( LogEntryKind.Warning, "attributeID of '{0}' is already exists", serverObject.Name); } //The issue here is that since the OS LDIF files don't specify a schemaGuid, one will be generated at random during ADLDS install which is not specified in model. if (schemaIDGUIDValue != null) { if (schemaIDsForLDS.Contains(schemaIDGUIDValue.ToString())) { uniqueLDSSchemaID = true; DataSchemaSite.Log.Add( LogEntryKind.Warning, "schemaIDGUID of '{0}' is already exists", serverObject.Name); } } if (attrLDAPDisplayNameIDsLDS.Contains(lDAPDisplayNameValue.ToString())) { uniqueLDSattrlDAPDisplayName = true; DataSchemaSite.Log.Add( LogEntryKind.Warning, "lDAPDisplayName of '{0}' is already exists", serverObject.Name); } if (linkIDValue != null) { if (linkIDsLDS.Contains(linkIDValue.ToString())) { uniqueLDSlinkID = true; DataSchemaSite.Log.Add( LogEntryKind.Warning, "linkID of '{0}' is already exists", serverObject.Name); } } attrIDsForLDS.Add(attrIDValue.ToString()); schemaIDsForLDS.Add(attrIDValue.ToString()); attrLDAPDisplayNameIDsLDS.Add(lDAPDisplayNameValue.ToString()); if (linkIDValue != null) { linkIDsLDS.Add(linkIDValue.ToString()); } Value valueOfSearchFlag = attributeObject["searchFlags"]; Type flagType = IntegerSymbols.GetSymbolEnumType("SearchFlags"); string searchFlag = Enum.Format(flagType, (uint)((int)valueOfSearchFlag), "g"); if (searchFlag.Contains("fANR")) { if (!searchFlag.Contains("fATTINDEX")) { flagfANR = true; } } } //MS-ADTS-Schema_R77 DataSchemaSite.CaptureRequirementIfIsTrue( !uniqueLDSAttrID, 77, @"The attributeID attribute of the attributeSchema objects described in MS-ADLS is Unique OID's that identifies this attribute."); //MS-ADTS-Schema_R81 DataSchemaSite.CaptureRequirementIfIsTrue( !uniqueLDSSchemaID, 81, @"The schemaIDGUID attribute of the attributeSchema objects described in MS-ADLS is Unique GUID that identifies this attribute."); //MS-ADTS-Schema_R103 DataSchemaSite.CaptureRequirementIfIsTrue( !uniqueLDSattrlDAPDisplayName, 103, @"The lDAPDisplayName attribute of the attributeSchema objects described in MS-ADLS is Unique that identifies this attribute."); //MS-ADTS-Schema_R87 DataSchemaSite.CaptureRequirementIfIsTrue( !uniqueLDSlinkID, 87, @"The value of the linkID attribute of the attributeSchema, is unique among all values of this attribute on objects in MS-ADLS, regardless of forest functional level"); //MS-ADTS-Schema_R125 DataSchemaSite.CaptureRequirementIfIsTrue( !flagfANR, 125, @"If the flag fANR is set on the searchFlags attribute of the attributeSchema, then fATTINDEX must also be set."); HashSet <string> governsIDsLDS = new HashSet <string>(); HashSet <string> classLDAPDisplayNameIDsLDS = new HashSet <string>(); foreach (IObjectOnServer serverObject in adAdapter.GetAllLdsSchemaClasses()) { if (!adamModel.TryGetClass(serverObject.Name, out classObject)) { DataSchemaSite.Log.Add( LogEntryKind.Warning, "schema class '{0}' exists on server but not in model", serverObject.Name); continue; } Value governsIDValue = classObject["governsID"]; Value lDAPDisplayNameValue = classObject["lDAPDisplayName"]; if (governsIDsLDS.Contains(governsIDValue.ToString())) { uniqueLDSGovernsID = true; DataSchemaSite.Log.Add( LogEntryKind.Warning, "governsID of '{0}' is already exists", serverObject.Name); } if (classLDAPDisplayNameIDsLDS.Contains(lDAPDisplayNameValue.ToString())) { uniqueclassLDSlDAPDisplayName = true; DataSchemaSite.Log.Add( LogEntryKind.Warning, "lDAPDisplayName of '{0}' is already exists", serverObject.Name); } governsIDsLDS.Add(governsIDValue.ToString()); classLDAPDisplayNameIDsLDS.Add(lDAPDisplayNameValue.ToString()); } //MS-ADTS-Schema_R161 DataSchemaSite.CaptureRequirementIfIsTrue( !uniqueLDSGovernsID, 161, @"The governsID attribute of the classSchema objects described in MS-ADLS is unique that identifies the class."); //MS-ADTS-Schema_R188 DataSchemaSite.CaptureRequirementIfIsTrue( !uniqueclassLDSlDAPDisplayName, 188, @"The lDAPDisplayName attribute of the classSchema objects described in MS-ADLS is unique name that identifies the class."); }
/// <summary> /// This method validates the requirements under /// WellKnownSecurityPrincipal Scenario. /// </summary> public void ValidateWellKnownSecurityPrincipal() { DirectoryEntry dirEntry = new DirectoryEntry(); DirectoryEntry childEntry = new DirectoryEntry(); string currDomain = adAdapter.rootDomainDN; string configNC = "CN=Configuration," + currDomain; string schemaNC = "CN=Schema," + configNC; //MS-ADTS-Schema_R499 if (!adAdapter.GetObjectByDN("CN=WellKnown Security Principals," + configNC, out dirEntry)) { DataSchemaSite.Assume.IsTrue( false, "CN=WellKnown Security Principals," + configNC + " Object is not found in server"); } DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=Configuration", dirEntry.Parent.Name.ToString(), 499, "For the WellKnownSecurityPrincipals the Parent must be config NC root object"); //MS-ADTS-Schema_R500 DataSchemaSite.CaptureRequirementIfIsTrue (dirEntry.Properties["objectClass"].Contains((object)"container"), 500, "For the WellKnownSecurityPrincipals the objectClass must be container"); //MS-ADTS-Schema_R501 string systemFlag = dirEntry.Properties["systemFlags"].Value.ToString(); int systemFlagVal = ParseSystemFlagsValue("FLAG_DISALLOW_DELETE"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( systemFlagVal.ToString(), systemFlag, 501, "For the WellKnownSecurityPrincipals the systemFlags must be FLAG_DISALLOW_DELETE"); if (systemFlag != (systemFlagVal.ToString())) { isParseSystemFlagsValue = false; } //MS-ADTS-Schema_R502 childEntry = dirEntry.Children.Find("CN=Anonymous Logon"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 502, "For the Anonymous Logon WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R503 byte[] objSid = (byte[])childEntry.Properties["objectSid"].Value; SecurityIdentifier sid = new SecurityIdentifier(objSid, 0); string objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-5-7", objectSid, 503, "For the Anonymous Logon WellKnownSecurityPrincipal the objectSid must be S-1-5-7"); //MS-ADTS-Schema_R504 childEntry = dirEntry.Children.Find("CN=Authenticated Users"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 504, @"For the Authenticated Users WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R505 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-5-11", objectSid, 505, "For the Authenticated Users WellKnownSecurityPrincipal the objectSid must be S-1-5-11"); //MS-ADTS-Schema_R506 childEntry = dirEntry.Children.Find("CN=Batch"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 506, "For the Batch WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R507 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-5-3", objectSid, 507, "For the Batch WellKnownSecurityPrincipal the objectSid must be S-1-5-3"); //MS-ADTS-Schema_R508 childEntry = dirEntry.Children.Find("CN=Creator Group"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 508, "For the Creator Group WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R509 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-3-1", objectSid, 509, "For the Creator Group WellKnownSecurityPrincipal the objectSid must be S-1-3-1"); //MS-ADTS-Schema_R510 childEntry = dirEntry.Children.Find("CN=Creator Owner"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 510, "For the Creator Owner WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R511 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-3-0", objectSid, 511, "For the Creator Owner WellKnownSecurityPrincipal the objectSid must be S-1-3-0"); //MS-ADTS-Schema_R512 childEntry = dirEntry.Children.Find("CN=Dialup"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 512, "For the Dialup WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R513 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-5-1", objectSid, 513, "For the Dialup WellKnownSecurityPrincipal the objectSid must be S-1-5-1"); //MS-ADTS-Schema_R514 childEntry = dirEntry.Children.Find("CN=Digest Authentication"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 514, @"For the Digest Authentication WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R515 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-5-64-21", objectSid, 515, "For the Digest Authentication WellKnownSecurityPrincipal the objectSid must be S-1-5-64-21"); //MS-ADTS-Schema_R516 childEntry = dirEntry.Children.Find("CN=Enterprise Domain Controllers"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 516, @"For the Enterprise Domain Controllers WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R517 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-5-9", objectSid, 517, "For the Enterprise Domain Controllers WellKnownSecurityPrincipal the objectSid must be S-1-5-9"); //MS-ADTS-Schema_R764 DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-5-9", objectSid, 764, "The member attribute of Windows Authorization Access Group Group Object " + "must be NT AUTHORITY/ENTERPRISE DOMAIN CONTROLLERS well-known security principal (SID S-1-5-9)."); //MS-ADTS-Schema_R518 childEntry = dirEntry.Children.Find("CN=Everyone"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 518, "For the Everyone WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R519 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-1-0", objectSid, 519, "For the Everyone WellKnownSecurityPrincipal the objectSid must be S-1-1-0"); //MS-ADTS-Schema_R520 childEntry = dirEntry.Children.Find("CN=Interactive"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 520, "For the Interactive WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R521 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-5-4", objectSid, 521, "For the Interactive WellKnownSecurityPrincipal the objectSid must be S-1-5-4"); //MS-ADTS-Schema_R524 childEntry = dirEntry.Children.Find("CN=Local Service"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 524, "For the Local Service WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R525 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-5-19", objectSid, 525, "For the Local Service WellKnownSecurityPrincipal the objectSid must be S-1-5-19"); //MS-ADTS-Schema_R526 childEntry = dirEntry.Children.Find("CN=Network"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 526, "For the Network WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R527 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-5-2", objectSid, 527, "For the Network WellKnownSecurityPrincipal the objectSid must be S-1-5-2"); //MS-ADTS-Schema_R528 childEntry = dirEntry.Children.Find("CN=Network Service"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 528, "For the Network Service WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R529 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-5-20", objectSid, 529, "For the Network Service WellKnownSecurityPrincipal the objectSid must be S-1-5-20"); //MS-ADTS-Schema_R530 childEntry = dirEntry.Children.Find("CN=NTLM Authentication"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 530, @"For the NTLM Authentication WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R531 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-5-64-10", objectSid, 531, "For the NTLM Authentication WellKnownSecurityPrincipal the objectSid must be S-1-5-64-10"); //MS-ADTS-Schema_R532 childEntry = dirEntry.Children.Find("CN=Other Organization"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 532, "For the Other Organization WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R533 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-5-1000", objectSid, 533, "For the Other Organization WellKnownSecurityPrincipal the objectSid must be S-1-5-1000"); //MS-ADTS-Schema_R536 childEntry = dirEntry.Children.Find("CN=Proxy"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 536, "For the Proxy WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R537 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-5-8", objectSid, 537, "For the Proxy WellKnownSecurityPrincipal the objectSid must be S-1-5-8"); //MS-ADTS-Schema_R538 childEntry = dirEntry.Children.Find("CN=Remote Interactive Logon"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 538, "For the Interactive Logon WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R539 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-5-14", objectSid, 539, "For the Remote Interactive Logon WellKnownSecurityPrincipal the objectSid must be S-1-5-14"); //MS-ADTS-Schema_R540 childEntry = dirEntry.Children.Find("CN=Restricted"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 540, "For the Restricted WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R541 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-5-12", objectSid, 541, "For the Restricted WellKnownSecurityPrincipal the objectSid must be S-1-5-12"); //MS-ADTS-Schema_R542 childEntry = dirEntry.Children.Find("CN=SChannel Authentication"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 542, "For SChannel Authentication WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R543 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-5-64-14", objectSid, 543, "For the SChannel Authentication WellKnownSecurityPrincipal the objectSid must be S-1-5-64-14"); //MS-ADTS-Schema_R544 childEntry = dirEntry.Children.Find("CN=Self"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 544, "For the Self WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R545 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-5-10", objectSid, 545, "For the Self WellKnownSecurityPrincipal the objectSid must be S-1-5-10"); //MS-ADTS-Schema_R546 childEntry = dirEntry.Children.Find("CN=Service"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 546, "For the Service WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R547 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-5-6", objectSid, 547, "For the Service WellKnownSecurityPrincipal the objectSid must be S-1-5-6"); //MS-ADTS-Schema_R550 childEntry = dirEntry.Children.Find("CN=Terminal Server User"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 550, @"For the Terminal Server User WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R551 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-5-13", objectSid, 551, "For the Terminal Server User WellKnownSecurityPrincipal the objectSid must be S-1-5-13"); //MS-ADTS-Schema_R552 childEntry = dirEntry.Children.Find("CN=This Organization"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 552, "For the This Organization WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R553 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-5-15", objectSid, 553, "For the This Organization WellKnownSecurityPrincipal the objectSid must be S-1-5-15"); if (serverOS >= OSVersion.WinSvr2008) { //MS-ADTS-Schema_R522 childEntry = dirEntry.Children.Find("CN=IUSR"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 522, "For the IUSR WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R523 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-5-17", objectSid, 523, "For the IUSR WellKnownSecurityPrincipal the objectSid must be S-1-5-17"); //MS-ADTS-Schema_R763 DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-5-17", objectSid, 763, "The member attribute of IIS_IUSRS Group Object " + "must be NT AUTHORITY/IUSR well-known security principal (SID S-1-5-17)."); //MS-ADTS-Schema_R534 childEntry = dirEntry.Children.Find("CN=Owner Rights"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 534, "For the Owner Rights WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R535 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-3-4", objectSid, 535, "For the Owner Rights WellKnownSecurityPrincipal the objectSid must be S-1-3-4"); //MS-ADTS-Schema_R548 childEntry = dirEntry.Children.Find("CN=System"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=WellKnown Security Principals", childEntry.Parent.Name.ToString(), 548, "For the System WellKnownSecurityPrincipal the Parent must be WellKnown Security Principals"); //MS-ADTS-Schema_R549 objSid = (byte[])childEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objSid, 0); objectSid = sid.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "S-1-5-18", objectSid, 549, "For the System WellKnownSecurityPrincipal the objectSid must be S-1-5-18"); } }
/// <summary> /// Method validates the requirements under CrossRefContainer Scenario. /// </summary> public void ValidateCrossRefContainer() { //Variables required for Directory Entries. DirectoryEntry dirPartitions = new DirectoryEntry(); DirectoryEntry domainEntry = new DirectoryEntry(); DirectoryEntry childEntry = new DirectoryEntry(); if (!Utilities.IsObjectExist(adAdapter.PartitionPath + "," + adAdapter.rootDomainDN, adAdapter.PDCNetbiosName, adAdapter.ADDSPortNum, adAdapter.DomainAdministratorName, adAdapter.DomainUserPassword)) { //To create the Application NC in the Active Directory. AdLdapClient.Instance().ConnectAndBind(adAdapter.PDCNetbiosName, adAdapter.PDCIPAddr, Convert.ToInt32(adAdapter.ADDSPortNum), adAdapter.DomainAdministratorName, adAdapter.DomainUserPassword, adAdapter.PrimaryDomainDnsName, AuthType.Basic | AuthType.Kerberos); List <DirectoryAttribute> attrs = new List <DirectoryAttribute>(); attrs.Add(new DirectoryAttribute("instancetype:5")); attrs.Add(new DirectoryAttribute("objectclass:domainDNS")); AdLdapClient.Instance().AddObject(adAdapter.PartitionPath + "," + adAdapter.rootDomainDN, attrs, null); AdLdapClient.Instance().Unbind(); } string configNC = "CN=Configuration," + adAdapter.rootDomainDN; string SchemaNC = "CN=Schema," + configNC; //Returns Fully Qualified DNS Name for the Current Domain. string strReturn = adAdapter.PrimaryDomainDnsName; if (!adAdapter.GetObjectByDN("CN=Partitions," + configNC, out dirPartitions)) { DataSchemaSite.Assume.IsTrue(false, "CN=Partitions," + configNC + " Object is not found in server"); } string parent = dirPartitions.Parent.Name, systemFlag; bool isPresent = false; int systemFlagVal; //MS-ADTS-Schema_R402 DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=Configuration", parent, 402, "The Parent of the Cross-Ref-Container Container must be Config NC root."); //MS-ADTS-Schema_R403 DataSchemaSite.CaptureRequirementIfAreEqual <string>( "Partitions", dirPartitions.Properties["name"].Value.ToString(), 403, @"The name attribute of the Cross-Ref-Container Container must be Partitions."); //MS-ADTS-Schema_R404 PropertyValueCollection objectClass = dirPartitions.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"crossRefContainer"), 404, "The objectClass attribute of the Cross-Ref-Container Container must be crossRefContainer."); string fsmoRoleOwner = dirPartitions.Properties["fSMORoleOwner"].Value.ToString(); //MS-ADTS-Schema_R406 systemFlag = dirPartitions.Properties["systemFlags"].Value.ToString(); systemFlagVal = ParseSystemFlagsValue("FLAG_DISALLOW_DELETE"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( systemFlagVal.ToString(), systemFlag, 406, "The systemFlags attribute of the Cross-Ref-Container Container must be FLAG_DISALLOW_DELETE."); //MS-ADTS-Schema_R405 if (!adAdapter.GetObjectByDN(adAdapter.rootDomainDN, out domainEntry)) { DataSchemaSite.Assume.IsTrue(false, adAdapter.rootDomainDN + " Object is not found in server"); } string domainFSMO = domainEntry.Properties["fSMORoleOwner"].Value.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( fsmoRoleOwner, domainFSMO, 405, "The fSMORoleOwner attribute of the Cross-Ref-Container Container must references the Domain " + "Naming Master FSMO role owner."); //MS-ADTS-Schema_R408 //Query the Partitions for CrossRef container get the childrens and validate the requirments as such. bool isCrossRef = true; bool isObjectClassCrossRef = true; DirectoryEntries Childs = dirPartitions.Children; foreach (DirectoryEntry child in Childs) { if (!child.Parent.Name.Equals("CN=Partitions")) { isCrossRef = false; } PropertyValueCollection objClass = child.Properties["objectClass"]; objClass.RemoveAt(0); if (objClass.Count != 1 || !objClass.Contains((object)"crossRef")) { isObjectClassCrossRef = false; } if (dirPartitions.Parent.Name.ToString().Equals("CN=Configuration")) { isPresent = true; } } //Validate the parent of the crossref objects,objectClass,nCName and //dnsRoot for all childs and crossRef container in the configNC. DataSchemaSite.CaptureRequirementIfIsTrue( isCrossRef, 408, "The parent of the Cross-Ref Objects must be crossRefContainer object."); //MS-ADTS-Schema_R851 DataSchemaSite.CaptureRequirementIfIsTrue( isPresent & isCrossRef, 851, "For any NC in the forest crossRef,NC root objects must be exist."); // MS-ADTS-Schema_R409 DataSchemaSite.CaptureRequirementIfIsTrue( isObjectClassCrossRef, 409, "The objectClass attribute of the Cross-Ref Objects must be crossRef."); //This is the crossRef container or crossRefObject //MS-ADTS-Schema_R410 childEntry = dirPartitions.Children.Find("CN=Enterprise Configuration"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( configNC.ToLower(), childEntry.Properties["nCName"].Value.ToString().ToLower(), 410, "The nCName attribute of the Configuration crossRef Object must equal to the config NC root."); //MS-ADTS-Schema_R411 string dnsRoot = childEntry.Properties["dnsRoot"].Value.ToString().ToLower(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( strReturn.ToLower(), dnsRoot.ToLower(), 411, "In AD/DS the dnsroot attribute of the Configuration crossRef Object must be the forest " + "root's fully qualified DNS name."); //This is the crossRef child or crossRefObject //MS-ADTS-Schema_R413 childEntry = dirPartitions.Children.Find("CN=Enterprise Schema"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( SchemaNC.ToLower(), childEntry.Properties["nCName"].Value.ToString().ToLower(), 413, "The nCName attribute of the Schema crossRef Object must equal to the Schema NC root."); //MS-ADTS-Schema_R414 dnsRoot = childEntry.Properties["dnsRoot"].Value.ToString().ToLower(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( strReturn.ToLower(), dnsRoot.ToLower(), 414, "In AD/DS the dnsroot attribute of the Schema crossRef Object must be the forest " + "root's fully qualified DNS name."); //MS-ADTS-Schema_R852 if (!adAdapter.GetObjectByDN(SchemaNC, out dirPartitions)) { DataSchemaSite.Assume.IsTrue(false, SchemaNC + " Object is not found in server"); } DataSchemaSite.CaptureRequirementIfAreEqual <string>( childEntry.Properties["nCName"].Value.ToString(), dirPartitions.Properties["distinguishedName"].Value.ToString(), 852, "The nCName attribute of the crossRef object must equal the dsname of the NC root object."); if (!adAdapter.GetObjectByDN("CN=Partitions," + configNC, out dirPartitions)) { DataSchemaSite.Assume.IsTrue(false, "CN=Partitions," + configNC + " Object is not found in server"); } foreach (DirectoryEntry partitionEntry in dirPartitions.Children) { if (partitionEntry.Properties["objectCategory"].Value.ToString().ToLower().Contains("cn=cross-ref")) { if (partitionEntry.Properties["nCName"].Value.ToString().Contains(adAdapter.PartitionPath)) { partitionEntry.RefreshCache(new string[] { "msDS-SDReferenceDomain" }); if (partitionEntry.Properties.Contains("msDS-SDReferenceDomain") && partitionEntry.Properties["msDS-SDReferenceDomain"].Value != null) { //MS-ADTS-Schema_R422 DataSchemaSite.CaptureRequirementIfAreEqual <string>( adAdapter.rootDomainDN.ToLower(), partitionEntry.Properties["msDS-SDReferenceDomain"].Value.ToString().ToLower(), 422, "In AD/DS msDS-SDReferenceDomain attribute of the Application NC crossRef object," + "references an NC root object for a domain. All security descriptors in this application NC " + "must use the NC represented as the reference domain for resolution."); } else { DataSchemaSite.Log.Add(LogEntryKind.Warning, "The value of msDS-SDReferenceDomain attribute of the Application NC crossRef object is null"); } } if (partitionEntry.Properties["nCName"].Value.ToString().Equals(adAdapter.rootDomainDN)) { //MS-ADTS-Schema_R416 DataSchemaSite.CaptureRequirementIfAreEqual <string>( partitionEntry.Properties["name"].Value.ToString(), partitionEntry.Properties["nETBIOSName"].Value.ToString(), 416, "The name attribute of the Domain crossRef Object must be the Netbios name of the domain."); //MS-ADTS-Schema_R417 DataSchemaSite.CaptureRequirementIfAreEqual <string>( adAdapter.rootDomainDN, partitionEntry.Properties["nCName"].Value.ToString(), 417, "The nCName attribute of the Domain crossRef Object must be reference to the Domain NC root."); //MS-ADTS-Schema_R418 if (!adAdapter.GetObjectByDN(adAdapter.rootDomainDN, out domainEntry)) { DataSchemaSite.Assume.IsTrue(false, adAdapter.rootDomainDN + " Object is not found in server"); } DirectoryEntry domainChildEntry = new DirectoryEntry(); DataSchemaSite.CaptureRequirementIfIsTrue( adAdapter.rootDomainDN.ToLower().Contains(partitionEntry.Properties["nETBIOSName"].Value.ToString().ToLower()), 418, "The nETBIOSName attribute of the Domain crossRef Object must be the Netbios name of the domain."); //MS-ADTS-Schema trustParent DataSchemaSite.Assert.IsNull( partitionEntry.Properties["trustParent"].Value, "The trustParent attribute is not present on the root domain NC's crossRef object."); //MS-ADTS-Schema_R419 systemFlag = partitionEntry.Properties["systemFlags"].Value.ToString(); systemFlagVal = ParseSystemFlagsValue("FLAG_ATTR_NOT_REPLICATED|FLAG_ATTR_REQ_PARTIAL_SET_MEMBER"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( systemFlagVal.ToString(), systemFlag, 419, @"The systemFlags attribute of the Domain crossRef Object must be FLAG_CR_NTDS_NC | FLAG_CR_NTDS_DOMAIN."); } if (partitionEntry.Properties["nCName"].Value.ToString().Equals(adAdapter.childDomainDN)) { //MS-ADTS-Schema_R416 DataSchemaSite.CaptureRequirementIfAreEqual <string>( partitionEntry.Properties["name"].Value.ToString(), partitionEntry.Properties["nETBIOSName"].Value.ToString(), 416, "The name attribute of the Domain crossRef Object must be the Netbios name of the domain."); //MS-ADTS-Schema_R417 DataSchemaSite.CaptureRequirementIfAreEqual <string>( adAdapter.childDomainDN, partitionEntry.Properties["nCName"].Value.ToString(), 417, "The nCName attribute of the Domain crossRef Object must be reference to the Domain NC root."); //MS-ADTS-Schema_R418 if (!adAdapter.GetObjectByDN(adAdapter.childDomainDN, out domainEntry)) { DataSchemaSite.Assume.IsTrue(false, adAdapter.childDomainDN + " Object is not found in server"); } DirectoryEntry domainChildEntry = new DirectoryEntry(); DataSchemaSite.CaptureRequirementIfIsTrue( adAdapter.childDomainDN.ToLower().Contains(partitionEntry.Properties["nETBIOSName"].Value.ToString().ToLower()), 418, "The nETBIOSName attribute of the Domain crossRef Object must be the Netbios name of the domain."); //MS-ADTS-Schema trustParent DirectoryEntry parentEntry = new DirectoryEntry(); string netbiosDomain = adAdapter.PrimaryDomainNetBiosName; parentEntry = dirPartitions.Children.Find(string.Format("CN={0}", netbiosDomain)); DataSchemaSite.Assert.AreEqual <string>( parentEntry.Properties["distinguishedName"].Value.ToString(), partitionEntry.Properties["trustParent"].Value.ToString(), "For child NCs, the trustParent attribute value references the parent NC's crossRef object."); //MS-ADTS-Schema_R419 systemFlag = partitionEntry.Properties["systemFlags"].Value.ToString(); systemFlagVal = ParseSystemFlagsValue("FLAG_ATTR_NOT_REPLICATED|FLAG_ATTR_REQ_PARTIAL_SET_MEMBER"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( systemFlagVal.ToString(), systemFlag, 419, @"The systemFlags attribute of the Domain crossRef Object must be FLAG_CR_NTDS_NC | FLAG_CR_NTDS_DOMAIN."); } } } //MS-ADTS-Schema_R420 dnsRoot = childEntry.Properties["dnsRoot"].Value.ToString().ToLower(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( strReturn.ToLower(), dnsRoot.ToLower(), 420, "In AD/DS the the value for dnsRoot for an application NC crossRef is derived by syntactically " + "converting the DN portion of the crossRef's nCName into a fully qualified DNS name."); }
/// <summary> /// TestCase30 method validates the requirements under /// LDSWellKnownSecurityDomainPrincipal Scenario. /// </summary> public void ValidateLDSWellKnownSecurityDomainPrincipal() { DirectoryEntry dirEntry = new DirectoryEntry(); string currDomain = adAdapter.rootDomainDN; string configNCForLDS = "CN=Configuration," + adAdapter.LDSRootObjectName; if (!adAdapter.GetLdsObjectByDN( "CN=NTDS Settings,CN=" + adAdapter.LDSServerInstance + ",CN=Servers,CN=Default-First-Site-Name,CN=Sites," + configNCForLDS, out dirEntry)) { DataSchemaSite.Assume.IsTrue( false, "CN=NTDS Settings,CN=" + adAdapter.LDSServerInstance + ",CN=Servers,CN=Default-First-Site-Name,CN=Sites," + configNCForLDS + " Object is not found in server"); } //MS-ADTS-Schema_R446 dirEntry.RefreshCache(new string[] { "msDS-PortLDAP" }); PropertyValueCollection msDSLDAP = dirEntry.Properties["msDS-PortLDAP"]; string msLDAPPort = msDSLDAP.Value.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( adAdapter.ADLDSPortNum, msLDAPPort, 446, "In AD/LDS msDS-PortLDAP attribute of the nTDSDSA Object stores the LDAP port for the instance"); //MS-ADTS-Schema_R447 PropertyValueCollection msDSSLPort = dirEntry.Properties["msDS-PortSSL"]; string msSSLPort = msDSSLPort.Value.ToString(); int portNumberValue = int.Parse(adAdapter.ADLDSPortNum) + 1; DataSchemaSite.CaptureRequirementIfAreEqual <int>( portNumberValue, int.Parse(msSSLPort), 447, "In AD/LDS msDS-PortSSL attribute of the nTDSDSA Object stores the SSL port for the instance"); //MS-ADTS-Schema_R448 PropertyValueCollection msDSSerAccount = dirEntry.Properties["msDS-ServiceAccount"]; DataSchemaSite.CaptureRequirementIfIsTrue( msDSSerAccount.Value.ToString().Contains("CN=ForeignSecurityPrincipals"), 448, @"In AD/LDS msDS-ServiceAccount attribute of the nTDSDSA Object stores the foreignSecurityPrincipal object representing the service account running this DC"); //MS-ADTS-Schema_R453 PropertyValueCollection msDSNamingContext = dirEntry.Properties["msDS-DefaultNamingContext"]; //If The value is set DataSchemaSite.CaptureRequirementIfIsNotNull( msDSNamingContext, 453, @"In AD/LDS msDS-DefaultNamingContext attribute of the nTDSDSA object specifies, the NC that should be returned as the default NC by the defaultNamingContext attribute of the root DSE."); //The method to call common requirements for AD/DS and LDS. if (!adAdapter.GetObjectByDN("CN=Users," + currDomain, out dirEntry)) { DataSchemaSite.Assume.IsTrue( false, "CN=Users," + currDomain + " Object is not found in server"); } LDSAndDSCommonCall(dirEntry); }
public void ValidateInheritanceRequirements(IEnumerable <IObjectOnServer> serverObjects, bool isADDS = true) { bool categoryOk = false; //For each server object foreach (IObjectOnServer serverObj in serverObjects) { string superClassName = (string)serverObj.Properties[StandardNames.subClassOf.ToLower()][0]; #region AbstractEx //MS-ADTS-Schema_R129. if (serverObj.Name.ToLower().Equals("applicationsettings")) { //Find super class. DirectoryEntry superClassObj = null; if (isADDS) { adAdapter.GetObjectByDN(string.Format("CN={0},CN=Schema,CN=Configuration,{1}", superClassName, adAdapter.rootDomainDN), out superClassObj); } else { adAdapter.GetLdsObjectByDN(string.Format("CN={0},CN=Schema,CN=Configuration,{1}", superClassName, adAdapter.LDSRootObjectName), out superClassObj); } string superClassObjName = superClassObj.Properties["lDAPDisplayName"].Value.ToString().ToLower(); superClassObj.Close(); DataSchemaSite.CaptureRequirementIfIsTrue( superClassObjName.Equals("top"), 129, @"applicationSettings class (objectClassCategory: 2) is an abstract class," + " is inherited from top class (objectClassCategory: 2) which is also an abstract class."); continue; } //MS-ADTS-Schema_R130. if (serverObj.Name.ToLower().Equals("connectionpoint")) { //Find super class. DirectoryEntry superClassObj = null; if (isADDS) { adAdapter.GetObjectByDN(string.Format("CN={0},CN=Schema,CN=Configuration,{1}", superClassName, adAdapter.rootDomainDN), out superClassObj); } else { adAdapter.GetLdsObjectByDN(string.Format("CN={0},CN=Schema,CN=Configuration,{1}", superClassName, adAdapter.LDSRootObjectName), out superClassObj); } string superClassObjName = superClassObj.Properties["lDAPDisplayName"].Value.ToString().ToLower(); superClassObj.Close(); DataSchemaSite.CaptureRequirementIfIsTrue( superClassObjName.Equals("leaf"), 130, @"connectionPoint class (objectClassCategory: 2) is an abstract class, is" + " inherited from leaf class (objectClassCategory: 2) which is also an abstract class."); continue; } //MS-ADTS-Schema_R131. if (serverObj.Name.ToLower().Equals("leaf")) { //Find super class. DirectoryEntry superClassObj = null; if (isADDS) { adAdapter.GetObjectByDN(string.Format("CN={0},CN=Schema,CN=Configuration,{1}", superClassName, adAdapter.rootDomainDN), out superClassObj); } else { adAdapter.GetLdsObjectByDN(string.Format("CN={0},CN=Schema,CN=Configuration,{1}", superClassName, adAdapter.LDSRootObjectName), out superClassObj); } string superClassObjName = superClassObj.Properties["lDAPDisplayName"].Value.ToString().ToLower(); superClassObj.Close(); DataSchemaSite.CaptureRequirementIfIsTrue( superClassObjName.Equals("top"), 131, @"leaf class (objectClassCategory: 2) is an abstract class, is inherited" + " from top class (objectClassCategory: 2) which is also an abstract class."); continue; } #endregion #region AuxEx //MS-ADTS-Schema_R133. if (serverObj.Name.ToLower().Equals("domainrelatedobject")) { //Find super class. DirectoryEntry superClassObj = null; if (isADDS) { adAdapter.GetObjectByDN(string.Format("CN={0},CN=Schema,CN=Configuration,{1}", superClassName, adAdapter.rootDomainDN), out superClassObj); } else { adAdapter.GetLdsObjectByDN(string.Format("CN={0},CN=Schema,CN=Configuration,{1}", superClassName, adAdapter.LDSRootObjectName), out superClassObj); } string superClassObjName = superClassObj.Properties["lDAPDisplayName"].Value.ToString().ToLower(); superClassObj.Close(); DataSchemaSite.CaptureRequirementIfIsTrue( superClassObjName.Equals("top"), 133, @"domainRelatedObject class (objectClassCategory: 3), bootableDevice class (objectClassCategory: 3) are auxiliary classes, which are inherited from top class (objectClassCategory: 2) which is an abstract class."); continue; } //MS-ADTS-Schema_R133. if (serverObj.Name.ToLower().Equals("bootabledevice")) { //Find super class. DirectoryEntry superClassObj = null; if (isADDS) { adAdapter.GetObjectByDN(string.Format("CN={0},CN=Schema,CN=Configuration,{1}", superClassName, adAdapter.rootDomainDN), out superClassObj); } else { adAdapter.GetLdsObjectByDN(string.Format("CN={0},CN=Schema,CN=Configuration,{1}", superClassName, adAdapter.LDSRootObjectName), out superClassObj); } string superClassObjName = superClassObj.Properties["lDAPDisplayName"].Value.ToString().ToLower(); superClassObj.Close(); DataSchemaSite.CaptureRequirementIfIsTrue( superClassObjName.Equals("top"), 133, @"domainRelatedObject class (objectClassCategory: 3), bootableDevice class (objectClassCategory: 3) are auxiliary classes, which are inherited from top class (objectClassCategory: 2) which is an abstract class."); continue; } //MS-ADTS-Schema_R134. if (serverObj.Name.ToLower().Equals("msds-bindableobject")) { if (superClassName.ToLower().Equals("securityprincipal")) { superClassName = "Security-Principal"; } //Find super class. DirectoryEntry superClassObj = null; if (isADDS) { adAdapter.GetObjectByDN(string.Format("CN={0},CN=Schema,CN=Configuration,{1}", superClassName, adAdapter.rootDomainDN), out superClassObj); } else { adAdapter.GetLdsObjectByDN(string.Format("CN={0},CN=Schema,CN=Configuration,{1}", superClassName, adAdapter.LDSRootObjectName), out superClassObj); } string superClassObjName = superClassObj.Properties["lDAPDisplayName"].Value.ToString().ToLower(); superClassObj.Close(); DataSchemaSite.CaptureRequirementIfIsTrue( superClassObjName.Equals("securityprincipal"), 134, @"msDS-BindableObject class (objectClassCategory: 3), is an auxiliary class, is inherited from securityPrincipal class (objectClassCategory: 3) which is an auxiliary class."); continue; } #endregion #region StructEx //MS-ADTS-Schema_R136. if (serverObj.Name.ToLower().Equals("categoryregistration")) { //Find super class. DirectoryEntry superClassObj = null; if (isADDS) { adAdapter.GetObjectByDN(string.Format("CN={0},CN=Schema,CN=Configuration,{1}", superClassName, adAdapter.rootDomainDN), out superClassObj); } else { adAdapter.GetLdsObjectByDN(string.Format("CN={0},CN=Schema,CN=Configuration,{1}", superClassName, adAdapter.LDSRootObjectName), out superClassObj); } string superClassObjName = superClassObj.Properties["lDAPDisplayName"].Value.ToString().ToLower(); superClassObj.Close(); DataSchemaSite.CaptureRequirementIfIsTrue( superClassObjName.Equals("leaf"), 136, @"categoryRegistration class (objectClassCategory: 1) is a structural class," + " is inherited from leaf class (objectClassCategory: 2) which is an abstract class."); continue; } //MS-ADTS-Schema_R137. if (serverObj.Name.ToLower().Equals("computer")) { //Find super class. DirectoryEntry superClassObj = null; if (isADDS) { adAdapter.GetObjectByDN(string.Format("CN={0},CN=Schema,CN=Configuration,{1}", superClassName, adAdapter.rootDomainDN), out superClassObj); } else { adAdapter.GetLdsObjectByDN(string.Format("CN={0},CN=Schema,CN=Configuration,{1}", superClassName, adAdapter.LDSRootObjectName), out superClassObj); } string superClassObjName = superClassObj.Properties["lDAPDisplayName"].Value.ToString().ToLower(); superClassObj.Close(); DataSchemaSite.CaptureRequirementIfIsTrue( superClassObjName.Equals("user"), 137, @"computer class (objectClassCategory: 1) is a structural class, is inherited from user class" + " (objectClassCategory: 1) which is also a structural class."); continue; } //MS-ADTS-Schema_R138. if (serverObj.Name.ToLower().Equals("msds-quotacontainer")) { //Find super class. DirectoryEntry superClassObj = null; if (isADDS) { adAdapter.GetObjectByDN(string.Format("CN={0},CN=Schema,CN=Configuration,{1}", superClassName, adAdapter.rootDomainDN), out superClassObj); } else { adAdapter.GetLdsObjectByDN(string.Format("CN={0},CN=Schema,CN=Configuration,{1}", superClassName, adAdapter.LDSRootObjectName), out superClassObj); } string superClassObjName = superClassObj.Properties["lDAPDisplayName"].Value.ToString().ToLower(); superClassObj.Close(); DataSchemaSite.CaptureRequirementIfIsTrue( superClassObjName.Equals("top"), 138, @"msDS-QuotaContainer class (objectClassCategory: 1) is a structural class," + " is inherited from top class (objectClassCategory: 2) which is an abstract class."); continue; } #endregion #region 88ClassEx //MS-ADTS-Schema_R140. if (serverObj.Name.ToLower().Equals("organizationalperson")) { //Find super class. DirectoryEntry superClassObj = null; if (isADDS) { adAdapter.GetObjectByDN(string.Format("CN={0},CN=Schema,CN=Configuration,{1}", superClassName, adAdapter.rootDomainDN), out superClassObj); } else { adAdapter.GetLdsObjectByDN(string.Format("CN={0},CN=Schema,CN=Configuration,{1}", superClassName, adAdapter.LDSRootObjectName), out superClassObj); } string superClassObjName = superClassObj.Properties["lDAPDisplayName"].Value.ToString().ToLower(); superClassObj.Close(); DataSchemaSite.CaptureRequirementIfIsTrue( superClassObjName.Equals("person"), 140, @"organizationalPerson class (objectClassCategory: 0) is a 88 class, is inherited from " + "person class (objectClassCategory: 0) which is also a 88 class."); continue; } //MS-ADTS-Schema_R141. if (serverObj.Name.ToLower().Equals("person")) { //Find super class. DirectoryEntry superClassObj = null; if (isADDS) { adAdapter.GetObjectByDN(string.Format("CN={0},CN=Schema,CN=Configuration,{1}", superClassName, adAdapter.rootDomainDN), out superClassObj); } else { adAdapter.GetLdsObjectByDN(string.Format("CN={0},CN=Schema,CN=Configuration,{1}", superClassName, adAdapter.LDSRootObjectName), out superClassObj); } string superClassObjName = superClassObj.Properties["lDAPDisplayName"].Value.ToString().ToLower(); superClassObj.Close(); DataSchemaSite.CaptureRequirementIfIsTrue( superClassObjName.Equals("top"), 141, @"person class (objectClassCategory: 0) is an 88 class, is inherited from top class " + "(objectClassCategory: 2) which is an abstract class."); continue; } //MS-ADTS-Schema_R142. if (serverObj.Name.ToLower().Equals("groupofnames")) { //Find super class. DirectoryEntry superClassObj = null; if (isADDS) { adAdapter.GetObjectByDN(string.Format("CN={0},CN=Schema,CN=Configuration,{1}", superClassName, adAdapter.rootDomainDN), out superClassObj); } else { adAdapter.GetLdsObjectByDN(string.Format("CN={0},CN=Schema,CN=Configuration,{1}", superClassName, adAdapter.LDSRootObjectName), out superClassObj); } string superClassObjName = superClassObj.Properties["lDAPDisplayName"].Value.ToString().ToLower(); superClassObj.Close(); DataSchemaSite.CaptureRequirementIfIsTrue( superClassObjName.Equals("top"), 142, @"groupOfNames class (objectClassCategory: 0) is an 88 class, is inherited from top class" + " (objectClassCategory: 2) which is an abstract class."); continue; } #endregion #region MS-ADTS-Schema_R179 if (serverObj.Name.ToLower().Equals("classschema")) { int category = int.Parse(serverObj.Properties["objectclasscategory"][0].ToString()); if (category >= 0 && category <= 3) { categoryOk = true; } //MS-ADTS-Schema_R179. DataSchemaSite.CaptureRequirementIfIsTrue( categoryOk, 179, "The objectClassCategory attribute of the classSchema object is any of the following. " + "0: 88 Class; 1: Structural class; 2: Abstract class; 3: Auxiliary class."); continue; } #endregion } }
/// <summary> /// This method validates the requirements under /// WellKnownSecurityDomainPrincipal for both AD/DS and LDS Scenario's. /// The common requirements are logged here. /// </summary> public void LDSAndDSCommonCall(DirectoryEntry directEntry) { GroupTypeFlags gType; //Holding Directory entries. DirectoryEntry dirEntry = new DirectoryEntry(); DirectoryEntry childEntry = new DirectoryEntry(); dirEntry = directEntry; //MS-ADTS-Schema_R810 DirectoryEntries rolesChilds = dirEntry.Children; bool isParentRoles = true; foreach (DirectoryEntry child in rolesChilds) { if (!child.Parent.Name.ToString().Equals("CN=Users")) { isParentRoles = false; } } DataSchemaSite.CaptureRequirementIfIsTrue( isParentRoles, 810, "For the Well-Known Domain-Relative Security Principals the Parent must be Users container"); //MS-ADTS-Schema_R813 childEntry = dirEntry.Children.Find("CN=Administrator"); PropertyValueCollection objectClass = childEntry.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"user"), 813, "The objectClass attribute of Administrator Well-Known Domain-Relative Security Principals must be user"); //MS-ADTS-Schema_R814 childEntry = dirEntry.Children.Find("CN=Guest"); objectClass = childEntry.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"user"), 814, "The objectClass attribute of Guest Well-Known Domain-Relative Security Principals must be user"); //MS-ADTS-Schema_R815 childEntry.RefreshCache(new string[] { "primaryGroupID" }); string primary = childEntry.Properties["primaryGroupID"].Value.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "514", primary, 815, @"The primaryGroupID attribute of Guest Well-Known Domain-Relative Security Principals must be 514 (Domain Guests)"); //MS-ADTS-Schema_R816 childEntry = dirEntry.Children.Find("CN=krbtgt"); objectClass = childEntry.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"user"), 816, @"The objectClass attribute of Key Distribution Center Service Account Well-Known Domain-Relative Security Principals must be user"); //MS-ADTS-Schema_R817 childEntry.RefreshCache(new string[] { "primaryGroupID" }); primary = childEntry.Properties["primaryGroupID"].Value.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( "513", primary, 817, @"The primaryGroupID attribute of Key Distribution Center Service Account Well-Known Domain-Relative Security Principals must be 513 (Domain Users)"); //MS-ADTS-Schema_R818 childEntry = dirEntry.Children.Find("CN=Cert Publishers"); objectClass = childEntry.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"group"), 818, @"The objectClass attribute of Key Distribution Center Service Account Well-Known Domain-Relative Security Principals must be user"); //MS-ADTS-Schema_R819 groupType = childEntry.Properties["groupType"]; gType = (GroupTypeFlags)Convert.ToInt32(groupType.Value); DataSchemaSite.CaptureRequirementIfAreEqual <GroupTypeFlags>( GroupTypeFlags.GROUP_TYPE_RESOURCE_GROUP | GroupTypeFlags.GROUP_TYPE_SECURITY_ENABLED, gType, 819, @"The groupType attribute of Cert Publishers Well-Known Domain-Relative Security Principals is {GROUP_TYPE_RESOURCE_GROUP | GROUP_TYPE_SECURITY_ENABLED}.This means that in groupType field the two above bits are set, which means that the groupType is 0x80000004"); //MS-ADTS-Schema_R820 childEntry = dirEntry.Children.Find("CN=Domain Admins"); objectClass = childEntry.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"group"), 820, @"The objectClass attribute of Domain Administrators Well-Known Domain-Relative Security Principals must be group"); //MS-ADTS-Schema_R821 groupType = childEntry.Properties["groupType"]; gType = (GroupTypeFlags)Convert.ToInt32(groupType.Value); DataSchemaSite.CaptureRequirementIfAreEqual <GroupTypeFlags>( GroupTypeFlags.GROUP_TYPE_ACCOUNT_GROUP | GroupTypeFlags.GROUP_TYPE_SECURITY_ENABLED, gType, 821, @"The groupType attribute of Domain Administrators, Well-Known Domain-Relative Security Principals is {GROUP_TYPE_ACCOUNT_GROUP | GROUP_TYPE_SECURITY_ENABLED}.This means that in groupType field the two above bits are set, which means that the groupType is 0x80000002"); //MS-ADTS-Schema_R822 childEntry = dirEntry.Children.Find("CN=Domain Computers"); objectClass = childEntry.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"group"), 822, @"The objectClass attribute of Domain Computers Well-Known Domain-Relative Security Principals must be group"); //MS-ADTS-Schema_R823 groupType = childEntry.Properties["groupType"]; gType = (GroupTypeFlags)Convert.ToInt32(groupType.Value); DataSchemaSite.CaptureRequirementIfAreEqual <GroupTypeFlags>( GroupTypeFlags.GROUP_TYPE_ACCOUNT_GROUP | GroupTypeFlags.GROUP_TYPE_SECURITY_ENABLED, gType, 823, @"The groupType attribute of Domain Computers Well-Known Domain-Relative Security Principals is {GROUP_TYPE_ACCOUNT_GROUP | GROUP_TYPE_SECURITY_ENABLED}.This means that in groupType field the two above bits are set, which means that the groupType is 0x80000002"); //MS-ADTS-Schema_R824 childEntry = dirEntry.Children.Find("CN=Domain Controllers"); objectClass = childEntry.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"group"), 824, @"The objectClass attribute of Domain Controllers, Well-Known Domain-Relative Security Principals must be group"); //MS-ADTS-Schema_R825 groupType = childEntry.Properties["groupType"]; gType = (GroupTypeFlags)Convert.ToInt32(groupType.Value); DataSchemaSite.CaptureRequirementIfAreEqual <GroupTypeFlags>( GroupTypeFlags.GROUP_TYPE_ACCOUNT_GROUP | GroupTypeFlags.GROUP_TYPE_SECURITY_ENABLED, gType, 825, @"The groupType attribute of Domain Controllers Well-Known Domain-Relative Security Principals is {GROUP_TYPE_ACCOUNT_GROUP | GROUP_TYPE_SECURITY_ENABLED}.This means that in groupType field the two above bits are set, which means that the groupType is 0x80000002"); //MS-ADTS-Schema_R826 childEntry = dirEntry.Children.Find("CN=Domain Guests"); objectClass = childEntry.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"group"), 826, @"The objectClass attribute of Domain Guests Well-Known Domain-Relative Security Principals must be group"); //MS-ADTS-Schema_R827 groupType = childEntry.Properties["groupType"]; gType = (GroupTypeFlags)Convert.ToInt32(groupType.Value); DataSchemaSite.CaptureRequirementIfAreEqual <GroupTypeFlags>( GroupTypeFlags.GROUP_TYPE_ACCOUNT_GROUP | GroupTypeFlags.GROUP_TYPE_SECURITY_ENABLED, gType, 827, @"The groupType attribute of Domain Guests Well-Known Domain-Relative Security Principals is {GROUP_TYPE_ACCOUNT_GROUP | GROUP_TYPE_SECURITY_ENABLED}.This means that in groupType field the two above bits are set, which means that the groupType is 0x80000002"); //MS-ADTS-Schema_R828 childEntry = dirEntry.Children.Find("CN=Domain Users"); objectClass = childEntry.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"group"), 828, "The objectClass attribute of Domain Users Well-Known Domain-Relative Security Principals must be group"); //MS-ADTS-Schema_R829 groupType = childEntry.Properties["groupType"]; gType = (GroupTypeFlags)Convert.ToInt32(groupType.Value); DataSchemaSite.CaptureRequirementIfAreEqual <GroupTypeFlags>( GroupTypeFlags.GROUP_TYPE_ACCOUNT_GROUP | GroupTypeFlags.GROUP_TYPE_SECURITY_ENABLED, gType, 829, @"The groupType attribute of Domain Users Well-Known Domain-Relative Security Principals must be either of GROUP_TYPE_ACCOUNT_GROUP | GROUP_TYPE_SECURITY_ENABLED"); //MS-ADTS-Schema_R833 childEntry = dirEntry.Children.Find("CN=Group Policy Creator Owners"); objectClass = childEntry.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"group"), 833, @"The objectClass attribute of Group Policy Creator Owners Well-Known Domain-Relative Security Principals must be group"); //MS-ADTS-Schema_R834 groupType = childEntry.Properties["groupType"]; gType = (GroupTypeFlags)Convert.ToInt32(groupType.Value); DataSchemaSite.CaptureRequirementIfAreEqual <GroupTypeFlags>( GroupTypeFlags.GROUP_TYPE_ACCOUNT_GROUP | GroupTypeFlags.GROUP_TYPE_SECURITY_ENABLED, gType, 834, @"The groupType attribute of Group Policy Creator Owners Well-Known Domain-Relative Security Principals is {GROUP_TYPE_ACCOUNT_GROUP | GROUP_TYPE_SECURITY_ENABLED}.This means that in groupType field the two above bits are set, which means that the groupType is 0x80000002"); //MS-ADTS-Schema_R835 childEntry = dirEntry.Children.Find("CN=RAS and IAS Servers"); objectClass = childEntry.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"group"), 835, @"The objectClass attribute of RAS and IAS Servers Well-Known Domain-Relative Security Principals must be group"); //MS-ADTS-Schema_R836 groupType = childEntry.Properties["groupType"]; gType = (GroupTypeFlags)Convert.ToInt32(groupType.Value); DataSchemaSite.CaptureRequirementIfAreEqual <GroupTypeFlags>( GroupTypeFlags.GROUP_TYPE_RESOURCE_GROUP | GroupTypeFlags.GROUP_TYPE_SECURITY_ENABLED, gType, 836, @"The groupType attribute of RAS and IAS Servers Well-Known Domain-Relative Security Principals is {GROUP_TYPE_RESOURCE_GROUP | GROUP_TYPE_SECURITY_ENABLED}.This means that in groupType field the two above bits are set, which means that the groupType is 0x80000004"); //MS-ADTS-Schema_R841 childEntry = dirEntry.Children.Find("CN=Schema Admins"); objectClass = childEntry.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"group"), 841, @"The objectClass attribute of Schema Admins Well-Known Domain-Relative Security Principals must be group"); if (serverOS >= OSVersion.WinSvr2008) { //MS-ADTS-Schema_R830 childEntry = dirEntry.Children.Find("CN=Enterprise Admins"); objectClass = childEntry.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"group"), 830, @"The objectClass attribute of Enterprise Administrators Well-Known Domain-Relative Security Principals must be group."); //MS-ADTS-Schema_R837 childEntry = dirEntry.Children.Find("CN=Read-only Domain Controllers"); objectClass = childEntry.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"group"), 837, @"The objectClass attribute of Read-Only Domain Controllers Well-Known Domain-Relative Security Principals must be group"); //MS-ADTS-Schema_R838 groupType = childEntry.Properties["groupType"]; gType = (GroupTypeFlags)Convert.ToInt32(groupType.Value); DataSchemaSite.CaptureRequirementIfAreEqual <GroupTypeFlags>( GroupTypeFlags.GROUP_TYPE_ACCOUNT_GROUP | GroupTypeFlags.GROUP_TYPE_SECURITY_ENABLED, gType, 838, @"The groupType attribute of Read-Only Domain Controllers Well-Known Domain-Relative Security Principals is {GROUP_TYPE_ACCOUNT_GROUP|GROUP_TYPE_SECURITY_ENABLED} This means that in groupType field the two above bits are set, which means that the groupType is 0x80000002."); //MS-ADTS-Schema_R839 childEntry = dirEntry.Children.Find("CN=Enterprise Read-only Domain Controllers"); objectClass = childEntry.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"group"), 839, @"The objectClass attribute of Enterprise Read-Only Domain Controllers Well-Known Domain-Relative Security Principals must be group"); //MS-ADTS-Schema_R840 groupType = childEntry.Properties["groupType"]; gType = (GroupTypeFlags)Convert.ToInt32(groupType.Value); DataSchemaSite.CaptureRequirementIfAreEqual <GroupTypeFlags>( GroupTypeFlags.GROUP_TYPE_UNIVERSAL_GROUP | GroupTypeFlags.GROUP_TYPE_SECURITY_ENABLED, gType, 840, @"The groupType attribute of Enterprise Read-Only Domain Controllers Well-Known Domain-Relative Security Principals is {GROUP_TYPE_UNIVERSAL_GROUP|GROUP_TYPE_SECURITY_ENABLED} This means that in groupType field the two above bits are set, which means that the groupType is 0x80000008."); //MS-ADTS-Schema_Allowed RODC Password Replication Group childEntry = dirEntry.Children.Find("CN=Allowed RODC Password Replication Group"); objectClass = childEntry.Properties["objectClass"]; DataSchemaSite.Assert.IsTrue( objectClass.Contains((object)"group"), @"The objectClass attribute of Allowed RODC Password Replication Group Well-Known Domain-Relative Security Principals must be group"); //MS-ADTS-Schema_Allowed RODC Password Replication Group groupType = childEntry.Properties["groupType"]; gType = (GroupTypeFlags)Convert.ToInt32(groupType.Value); DataSchemaSite.Assert.AreEqual <GroupTypeFlags>( GroupTypeFlags.GROUP_TYPE_RESOURCE_GROUP | GroupTypeFlags.GROUP_TYPE_SECURITY_ENABLED, gType, @"The groupType attribute of Allowed RODC Password Replication Group Well-Known Domain-Relative Security Principals is {GROUP_TYPE_RESOURCE_GROUP|GROUP_TYPE_SECURITY_ENABLED} This means that in groupType field the two above bits are set, which means that the groupType is 0x80000004."); //MS-ADTS-Schema_Denied RODC Password Replication Group childEntry = dirEntry.Children.Find("CN=Denied RODC Password Replication Group"); objectClass = childEntry.Properties["objectClass"]; DataSchemaSite.Assert.IsTrue( objectClass.Contains((object)"group"), @"The objectClass attribute of Denied RODC Password Replication Group Well-Known Domain-Relative Security Principals must be group"); //MS-ADTS-Schema_Denied RODC Password Replication Group groupType = childEntry.Properties["groupType"]; gType = (GroupTypeFlags)Convert.ToInt32(groupType.Value); DataSchemaSite.Assert.AreEqual <GroupTypeFlags>( GroupTypeFlags.GROUP_TYPE_RESOURCE_GROUP | GroupTypeFlags.GROUP_TYPE_SECURITY_ENABLED, gType, @"The groupType attribute of Denied RODC Password Replication Group Well-Known Domain-Relative Security Principals is {GROUP_TYPE_RESOURCE_GROUP|GROUP_TYPE_SECURITY_ENABLED} This means that in groupType field the two above bits are set, which means that the groupType is 0x80000004."); } }
public void ValidateStructureRulesRequirements(IEnumerable <IObjectOnServer> serverObjects, bool isADDS) { bool isAllowedParent = false; List <string> sampleClasses = new List <string>(); sampleClasses.Add("organization"); sampleClasses.Add("attributeSchema"); sampleClasses.Add("account"); sampleClasses.Add("classSchema"); foreach (IObjectOnServer serverObj in serverObjects) { if (sampleClasses.Contains(serverObj.Name)) { //Get possSuperior value List <string> possSuperiors = new List <string>(); if (serverObj.Properties.ContainsKey(StandardNames.possSuperiors.ToLower())) { foreach (string element in serverObj.Properties[StandardNames.possSuperiors.ToLower()]) { possSuperiors.Add(element); } } if (serverObj.Properties.ContainsKey(StandardNames.systemPossSuperiors.ToLower())) { foreach (string element in serverObj.Properties[StandardNames.systemPossSuperiors.ToLower()]) { possSuperiors.Add(element); } } //For each possSuperior. foreach (string possSuperior in possSuperiors) { isAllowedParent = false; //Get distinguishedName of this possSuperior from model to get this object from server. ModelObject possSuperiorObject; if (isADDS) { possSuperiorObject = dcModel.GetClass(possSuperior); } else { possSuperiorObject = adamModel.GetClass(possSuperior); } if (possSuperiorObject == null) { DataSchemaSite.Assume.IsNotNull( possSuperiorObject, "Class " + possSuperior + " is not existing in Model"); } string possSuperiorDN = (string)possSuperiorObject[StandardNames.distinguishedName].UnderlyingValues[0]; //Get this possSuperior from Server DirectoryEntry possSuperiorServerObject; if (isADDS) { if (!adAdapter.GetObjectByDN(possSuperiorDN, out possSuperiorServerObject)) { DataSchemaSite.Assume.IsTrue(false, possSuperiorDN + " Object is not found in server"); } } else { if (!adAdapter.GetLdsObjectByDN(possSuperiorDN, out possSuperiorServerObject)) { DataSchemaSite.Assume.IsTrue(false, possSuperiorDN + " Object is not found in server"); } } //Get possibleInfeiror value of possSuperiorClass. possSuperiorServerObject.RefreshCache(new string[] { "possibleinferiors" }); PropertyValueCollection possInferiorVal = possSuperiorServerObject. Properties[StandardNames.possibleInferiors.ToLower()]; //In all possSuperior object, this class name should exist in its possibleInferiors. foreach (string possInfe in possInferiorVal) { if (possInfe.Equals(serverObj.Name)) { isAllowedParent = true; break; } } if (!isAllowedParent) { break; } } if (!isAllowedParent) { break; } } } //MS-ADTS-Schema_R149. DataSchemaSite.CaptureRequirementIfIsTrue( isAllowedParent, 149, "The union of values in possSuperiors and systemPossSuperiors specifies the classes that " + "are allowed to be parents of an object instance of the class in question."); }
/// <summary> /// TestCase29 method validates the requirements under /// WellKnownSecurityDomainPrincipal Scenario. /// </summary> public void ValidateWellKnownSecurityDomainPrincipal() { DirectoryEntry dirEntry = new DirectoryEntry(); DirectoryEntry childEntry = new DirectoryEntry(); DirectoryEntry rootEntry = new DirectoryEntry(); string currDomain = adAdapter.rootDomainDN; string configNC = "CN=Configuration," + currDomain; string schemaNC = "CN=Schema," + configNC; bool isObjectSid = true; SecurityIdentifier sid; PropertyValueCollection rid, ridUser; byte[] objectSid; string expectedValue = String.Empty; string actualValue = String.Empty; if (!adAdapter.GetObjectByDN("CN=Users," + currDomain, out dirEntry)) { DataSchemaSite.Assume.IsTrue(false, "CN=Users," + currDomain + " Object is not found in server"); } // Get the object of Root Domain NC. if (!adAdapter.GetObjectByDN(currDomain, out rootEntry)) { DataSchemaSite.Assume.IsTrue(false, currDomain + " Object is not found in server"); } //Get the objectSid value of the object of root domain NC. objectSid = (byte[])rootEntry.Properties["objectSid"].Value; sid = new SecurityIdentifier(objectSid, 0); expectedValue = sid.ToString(); int length = expectedValue.Length; DirectoryEntries rolesChilds = dirEntry.Children; //For each child, foreach (DirectoryEntry child in rolesChilds) { //Get the sid of the child object. objectSid = (byte[])child.Properties["objectSid"].Value; sid = new SecurityIdentifier(objectSid, 0); //Get the rid of this object. string temp = sid.ToString(); temp = temp.Substring(temp.LastIndexOf('-')); //Add rid with expected value. expectedValue = expectedValue + temp; //Get the actual value. actualValue = sid.ToString(); //Compare. if (actualValue.Equals(expectedValue)) { isObjectSid = true; } else { isObjectSid = false; break; } //Reset the expected value. expectedValue = expectedValue.Substring(0, length); } //MS-ADTS-Schema_R811 DataSchemaSite.CaptureRequirementIfIsTrue( isObjectSid, 811, @"The objectSid attribute of Well-Known Domain-Relative Security Principals must be a SID consisting of the objectSid of the domain NC root followed by the RID specified for each child."); //MS-ADTS-Schema_R812 childEntry = dirEntry.Children.Find("CN=Administrator"); rid = childEntry.Properties["primaryGroupID"]; childEntry = dirEntry.Children.Find("CN=Domain Users"); childEntry.RefreshCache(new string[] { "primaryGroupToken" }); ridUser = childEntry.Properties["primaryGroupToken"]; DataSchemaSite.CaptureRequirementIfAreEqual <int>( (int)ridUser.Value, (int)rid.Value, 812, @"The primaryGroupID attribute of class user Well-Known Domain-Relative Security Principals must be RID, which refers to another Well-Known domain relative security principal, by RID"); //The method to call common requirements for AD/DS and LDS. LDSAndDSCommonCall(dirEntry); if (!adAdapter.GetObjectByDN(currDomain, out childEntry)) { DataSchemaSite.Assume.IsTrue(false, currDomain + " Object is not found in server"); } PropertyValueCollection nTMixedDomain = childEntry.Properties["nTMixedDomain"]; //If nTMixedDomain value is 0 that is not mixed else mixed domain if ((int)nTMixedDomain.Value == 0) { //MS-ADTS-Schema_R843 childEntry = dirEntry.Children.Find("CN=Schema Admins"); PropertyValueCollection groupType = childEntry.Properties["groupType"]; gType = (GroupTypeFlags)Convert.ToInt32(groupType.Value); DataSchemaSite.CaptureRequirementIfAreEqual <GroupTypeFlags>( GroupTypeFlags.GROUP_TYPE_UNIVERSAL_GROUP | GroupTypeFlags.GROUP_TYPE_SECURITY_ENABLED, gType, 843, @"If the forest root domain is not mixed :The groupType attribute of Schema Admins Well-Known Domain-Relative Security Principals is {GROUP_TYPE_UNIVERSAL_GROUP | GROUP_TYPE_SECURITY_ENABLED} This means that in groupType field the two above bits are set, which means that the groupType is 0x80000008."); if (serverOS >= OSVersion.WinSvr2008) { //MS-ADTS-Schema_R832 childEntry = dirEntry.Children.Find("CN=Enterprise Admins"); groupType = childEntry.Properties["groupType"]; gType = (GroupTypeFlags)Convert.ToInt32(groupType.Value); DataSchemaSite.CaptureRequirementIfAreEqual <GroupTypeFlags>( GroupTypeFlags.GROUP_TYPE_UNIVERSAL_GROUP | GroupTypeFlags.GROUP_TYPE_SECURITY_ENABLED, gType, 832, @"If the forest root domain is not mixed :The groupType attribute of Enterprise Administrators Well-Known Domain-Relative Security Principals is {GROUP_TYPE_UNIVERSAL_GROUP | GROUP_TYPE_SECURITY_ENABLED} This means that in groupType field the two above bits are set, which means that the groupType is 0x80000008."); } } else { //MS-ADTS-Schema_R842, MS-ADTS-Schema_R831 childEntry = dirEntry.Children.Find("CN=Schema Admins"); PropertyValueCollection groupType = childEntry.Properties["groupType"]; gType = (GroupTypeFlags)Convert.ToInt32(groupType.Value); DataSchemaSite.CaptureRequirementIfAreEqual <GroupTypeFlags>( GroupTypeFlags.GROUP_TYPE_ACCOUNT_GROUP | GroupTypeFlags.GROUP_TYPE_SECURITY_ENABLED, gType, 842, @"If the forest root domain is not mixed :The groupType attribute of Schema Admins Well-Known Domain-Relative Security Principals is {GROUP_TYPE_ACCOUNT_GROUP | GROUP_TYPE_SECURITY_ENABLED} This means that in groupType field the two above bits are set, which means that the groupType is 0x80000002."); if (serverOS == OSVersion.WinSvr2008) { //MS-ADTS-Schema_R831 childEntry = dirEntry.Children.Find("CN=Enterprise Admins"); groupType = childEntry.Properties["groupType"]; gType = (GroupTypeFlags)Convert.ToInt32(groupType.Value); DataSchemaSite.CaptureRequirementIfAreEqual <GroupTypeFlags>( GroupTypeFlags.GROUP_TYPE_ACCOUNT_GROUP | GroupTypeFlags.GROUP_TYPE_SECURITY_ENABLED, gType, 831, @"If the forest root domain is not mixed :The groupType attribute of Enterprise Administrators Well-Known Domain-Relative Security Principals is {GROUP_TYPE_ACCOUNT_GROUP | GROUP_TYPE_SECURITY_ENABLED} This means that in groupType field the two above bits are set, which means that the groupType is 0x80000002."); } } }
/// <summary> /// This method validates the requirements under /// QueryNC Scenario. /// </summary> public void ValidateQueryNC() { //Variables holding the directory entries required. DirectoryEntry dirEntry = new DirectoryEntry(); DirectoryEntry schemaEntry = new DirectoryEntry(); DirectoryEntry serverDirEntry = new DirectoryEntry(); DirectoryEntry partitionsDirEntry = new DirectoryEntry(); if (!adAdapter.GetObjectByDN(adAdapter.rootDomainDN, out dirEntry)) { DataSchemaSite.Assert.IsTrue(false, adAdapter.rootDomainDN + " Object is not found in server"); } //MS-ADTS-Schema_R853 DataSchemaSite.CaptureRequirementIfIsTrue( dirEntry.Properties.Contains("nTMixedDomain"), 853, "The attribute nTMixedDomain is present on each domain NC root object."); if (!adAdapter.GetObjectByDN("CN=Configuration," + adAdapter.rootDomainDN, out dirEntry)) { DataSchemaSite.Assert.IsTrue( false, "CN=Configuration," + adAdapter.rootDomainDN + " Object is not found in server"); } if (!adAdapter.GetObjectByDN("CN=Schema,CN=Configuration," + adAdapter.rootDomainDN, out schemaEntry)) { DataSchemaSite.Assert.IsTrue( false, "CN=Schema,CN=Configuration," + adAdapter.rootDomainDN + " Object is not found in server"); } if (!adAdapter.GetObjectByDN("CN=" + adAdapter.PDCNetbiosName + ",OU=Domain Controllers," + adAdapter.rootDomainDN, out dirEntry)) { DataSchemaSite.Assert.IsTrue( false, "CN=" + adAdapter.PDCNetbiosName + ",OU=Domain Controllers," + adAdapter.rootDomainDN + " Object is not found in server"); } if (!adAdapter.GetObjectByDN( "CN=" + adAdapter.PDCNetbiosName + ",CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration," + adAdapter.rootDomainDN, out serverDirEntry)) { DataSchemaSite.Assert.IsTrue( false, "CN=" + adAdapter.PDCNetbiosName + ",CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration," + adAdapter.rootDomainDN + " Object is not found in server"); } //Validate the objectVersion of Schema NC if (serverOS == OSVersion.WinSvr2008) { DataSchemaSite.Assert.AreEqual <string>("44", schemaEntry.Properties["objectVersion"].Value.ToString(), "The objectVersion of {0} should be 44.", serverOS); } else if (serverOS == OSVersion.WinSvr2008R2) { DataSchemaSite.Assert.AreEqual <string>("47", schemaEntry.Properties["objectVersion"].Value.ToString(), "The objectVersion of {0} should be 47.", serverOS); } else if (serverOS == OSVersion.WinSvr2012) { DataSchemaSite.Assert.AreEqual <string>("56", schemaEntry.Properties["objectVersion"].Value.ToString(), "The objectVersion of {0} should be 56.", serverOS); } else if (serverOS == OSVersion.WinSvr2012R2) { DataSchemaSite.Assert.AreEqual <string>("69", schemaEntry.Properties["objectVersion"].Value.ToString(), "The objectVersion of {0} should be 69.", serverOS); } else if (serverOS == OSVersion.Win2016) { DataSchemaSite.Assert.AreEqual <string>("87", schemaEntry.Properties["objectVersion"].Value.ToString(), "The objectVersion of {0} should be 87.", serverOS); } else if (serverOS >= OSVersion.Winv1803) { DataSchemaSite.Assert.AreEqual <string>("88", schemaEntry.Properties["objectVersion"].Value.ToString(), "The objectVersion of {0} should be 88.", serverOS); } //MS-ADTS-Schema_R848 DataSchemaSite.CaptureRequirementIfAreEqual <string>( dirEntry.Properties["dNSHostName"].Value.ToString(), serverDirEntry.Properties["dNSHostName"].Value.ToString(), 848, @"On AD/DS, the dNSHostName attribute of the domain controller object must equal the dNSHostName attribute of the server object."); //MS-ADTS-Schema_R847 DataSchemaSite.CaptureRequirementIfAreEqual <string>( dirEntry.Properties["distinguishedName"].Value.ToString(), serverDirEntry.Properties["serverReference"].Value.ToString(), 847, @"On AD/DS, the attribute serverReference on the server object must equal the dsname of the domain controller object."); //MS-ADTS-Schema_R845 DataSchemaSite.CaptureRequirementIfAreEqual <string>( adAdapter.PDCNetbiosName.ToLower(), serverDirEntry.Properties["cn"].Value.ToString().ToLower(), 845, "On AD/DS, the name of the server object is the computer name of the DC."); //MS-ADTS-Schema_R849 DataSchemaSite.CaptureRequirementIfAreEqual <string>( dirEntry.Properties["dNSHostName"].Value.ToString(), serverDirEntry.Properties["dNSHostName"].Value.ToString(), 849, @"The dNSHostName attribute of the server object must equal the DNS Hostname of the computer that is physically the DC."); //MS-ADTS-Schema_R850 PropertyValueCollection val = dirEntry.Properties["servicePrincipalName"]; foreach (string value in val) { // Extract the hostname string partvar = value.Substring(value.IndexOf('/') + 1); string hostname = (partvar.IndexOf('/') == -1) ? partvar : partvar.Substring(0, partvar.IndexOf('/')); // Ignore the port number if (hostname.Contains(":")) { hostname = hostname.Substring(0, hostname.IndexOf(':')); } // If it is a DNS hostname if (hostname.Contains(".") && !hostname.Contains("_msdcs")) { DataSchemaSite.CaptureRequirementIfIsTrue( hostname.ToLower().Equals(dirEntry.Properties["dNSHostName"].Value.ToString().ToLower()), 850, @"On AD/DS, every value of the servicePrincipalName attribute of the domain controller object, which has a DNS Hostname as the instance name should have instance name equal to the dNSHostName of the domain controller object."); } } if (!adAdapter.GetObjectByDN(adAdapter.rootDomainDN, out dirEntry)) { DataSchemaSite.Assume.IsTrue(false, adAdapter.rootDomainDN + " Object is not found in server"); } DirectoryEntry entry = new DirectoryEntry("LDAP://" + adAdapter.PDCNetbiosName + "/rootDSE"); DirectoryEntry applicationEntry = new DirectoryEntry(); DirectoryEntry ncEntry = new DirectoryEntry(); PropertyValueCollection allNCs = entry.Properties["namingContexts"]; HashSet <string> collectionOfNCs = new HashSet <string>(); bool rootDomainNCAsChild = false, domainOfApplicationNC = false; foreach (string eachNC in allNCs) { if (collectionOfNCs.Contains(eachNC)) { collectionOfNCs.Add(eachNC); } collectionOfNCs.Add(eachNC); } if (!Utilities.IsObjectExist(adAdapter.PartitionPath + "," + adAdapter.rootDomainDN, adAdapter.PDCNetbiosName, adAdapter.ADDSPortNum, adAdapter.DomainAdministratorName, adAdapter.DomainUserPassword)) { //To create the Application NC in the Active Directory. AdLdapClient.Instance().ConnectAndBind(adAdapter.PDCNetbiosName, adAdapter.PDCIPAddr, Convert.ToInt32(adAdapter.ADDSPortNum), adAdapter.DomainAdministratorName, adAdapter.DomainUserPassword, adAdapter.PrimaryDomainDnsName, AuthType.Basic | AuthType.Kerberos); List <DirectoryAttribute> attrs = new List <DirectoryAttribute>(); attrs.Add(new DirectoryAttribute("instancetype:5")); attrs.Add(new DirectoryAttribute("objectclass:domainDNS")); AdLdapClient.Instance().AddObject(adAdapter.PartitionPath + "," + adAdapter.rootDomainDN, attrs, null); AdLdapClient.Instance().Unbind(); } if (!adAdapter.GetObjectByDN( adAdapter.PartitionPath + "," + adAdapter.rootDomainDN, out applicationEntry)) { DataSchemaSite.Assume.IsTrue( false, adAdapter.PartitionPath + "," + adAdapter.rootDomainDN + " Object is not found in server"); } foreach (DirectoryEntry eachChild in applicationEntry.Children) { if (eachChild.Name == adAdapter.rootDomainDN) { domainOfApplicationNC = true; } } //MS-ADTS-Schema_R8 DataSchemaSite.CaptureRequirementIfIsTrue( !domainOfApplicationNC, 8, "In a forest, the Domain NC must not be a child of application NC."); bool sidofdomainNCnotnull = false; bool sidofcongNcnull = false; bool sidofschemaNcnull = false; bool sidofapplicationNcnull = false; bool isDomainNc = false; bool isConfigurationNc = false; bool isSchemaNc = false; bool isApplicationNc = false; //Get all NC objects foreach (string singleNC in collectionOfNCs) { if (adAdapter.GetObjectByDN(singleNC, out ncEntry)) { //Get SID of this NC object objectSid = ncEntry.Properties["objectSid"].Value; if (objectSid != null) { System.Security.Principal.SecurityIdentifier sid = new System.Security.Principal.SecurityIdentifier((byte[])objectSid, 0); sidofdomainNCnotnull = true; } if (ncEntry.Properties["distinguishedName"].Value.ToString().Equals(adAdapter.rootDomainDN, StringComparison.OrdinalIgnoreCase)) { isDomainNc = true; } else if (ncEntry.Name == "CN=Configuration") { isConfigurationNc = true; if (objectSid == null) { sidofcongNcnull = true; } } else if (ncEntry.Name == "CN=Schema") { isSchemaNc = true; if (objectSid == null) { sidofschemaNcnull = true; } } else { isApplicationNc = true; if (objectSid == null) { sidofapplicationNcnull = true; } } } } //Verify MS-AD_Schema requirement: MS-AD_Schema_R4557. DataSchemaSite.CaptureRequirementIfIsTrue( isDomainNc, 4557, @"[NC, NC Replica]Active Directory supports four NC types: Domain NC."); //Verify MS-AD_Schema requirement: MS-AD_Schema_R4558. DataSchemaSite.CaptureRequirementIfIsTrue( sidofdomainNCnotnull, 4558, @"[NC, NC Replica]The sid field of a domain NC is not NULL."); //Verify MS-AD_Schema requirement: MS-AD_Schema_R4559. DataSchemaSite.CaptureRequirementIfIsTrue( isConfigurationNc, 4559, @"[NC, NC Replica]Active Directory supports four NC types: Config NC."); //Verify MS-AD_Schema requirement: MS-AD_Schema_R4560. DataSchemaSite.CaptureRequirementIfIsTrue( sidofcongNcnull, 4560, @"[NC, NC Replica]The sid field of a config NC is NULL."); //Verify MS-AD_Schema requirement: MS-AD_Schema_R4561. DataSchemaSite.CaptureRequirementIfIsTrue( isSchemaNc, 4561, @"[NC, NC Replica]Active Directory supports four NC types: Schema NC."); //Verify MS-AD_Schema requirement: MS-AD_Schema_R4562. DataSchemaSite.CaptureRequirementIfIsTrue( sidofschemaNcnull, 4562, @"[NC, NC Replica]The sid field of a schema NC is NULL."); //Verify MS-AD_Schema requirement: MS-AD_Schema_R4564. DataSchemaSite.CaptureRequirementIfIsTrue( sidofapplicationNcnull, 4564, @"[NC, NC Replica]The sid field of an application NC is NULL."); // //Verify MS-AD_Schema requirement: MS-AD_Schema_R4563. // DataSchemaSite.CaptureRequirementIfIsTrue( isApplicationNc, 4563, @"[NC, NC Replica]Active Directory supports four NC types: Application NC."); if (!adAdapter.GetObjectByDN( "CN=Partitions,CN=Configuration," + adAdapter.rootDomainDN, out partitionsDirEntry)) { DataSchemaSite.Assume.IsTrue( false, "CN=Partitions,CN=Configuration," + adAdapter.rootDomainDN + " Object is not found in server"); } foreach (DirectoryEntry eachNC in partitionsDirEntry.Children) { if (eachNC.Properties["msDS-SDReferenceDomain"].Value != null) { if (dirEntry.Properties["distinguishedName"].Value.ToString() == eachNC.Properties["distinguishedName"].Value.ToString()) { rootDomainNCAsChild = true; } } } //MS-ADTS-Schema_R9 DataSchemaSite.CaptureRequirementIfIsTrue( !rootDomainNCAsChild, 9, "In a forest, the root domain NC must not be a child of another domain NC in the forest."); }
/// <summary> /// This method validates the requirements under /// ServiceAndQueryPolicyContainer for both AD/DS and LDS Scenario's /// </summary> public void LDSAndDSCommonCallForServices(DirectoryEntry reqEntry) { PropertyValueCollection objectClass; DirectoryEntry requiredEntry = new DirectoryEntry(); DirectoryEntry childEntry = new DirectoryEntry(); requiredEntry = reqEntry; //MS-ADTS-Schema_R482 string parentAttribute = requiredEntry.Parent.Name.ToString(); DataSchemaSite.CaptureRequirementIfIsTrue( parentAttribute.Equals("CN=Configuration"), 482, "The parent of the Services Container must be Config NC root object."); //MS-ADTS-Schema_R483 objectClass = requiredEntry.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"container"), 483, "The ObjectClass attribute of the Services Container must be container."); //MS-ADTS-Schema_R484 childEntry = requiredEntry.Children.Find("CN=Windows NT"); parentAttribute = childEntry.Parent.Name.ToString(); DataSchemaSite.CaptureRequirementIfIsTrue( parentAttribute.Equals("CN=Services"), 484, "The Parent of the Windows NT Service must be Services."); //MS-ADTS-Schema_R485 PropertyValueCollection objectClassForWinNT = childEntry.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClassForWinNT.Contains((object)"container"), 485, "The ObjectClass attribute of the Windows NT Service must be container."); //MS-ADTS-Schema_R486 childEntry = childEntry.Children.Find("CN=Directory Service"); requiredEntry = childEntry; string parentAttributeDirectory = childEntry.Parent.Name.ToString(); DataSchemaSite.CaptureRequirementIfIsTrue( parentAttributeDirectory.Equals("CN=Windows NT"), 486, "The Parent of the Directory Service which is a type of Windows NT Service must be Windows NT."); //MS-ADTS-Schema_R487 PropertyValueCollection objectClassForDirService = childEntry.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClassForDirService.Contains((object)"nTDSService"), 487, @"The ObjectClass attribute of the Directory Service which is a type of Windows NT Service must be nTDSService."); //MS-ADTS-Schema_R102689 PropertyValueCollection dSHeuristicsForDirService = childEntry.Properties["dSHeuristics"]; if (dSHeuristicsForDirService.Value == null) { DataSchemaSite.CaptureRequirementIfIsNull( dSHeuristicsForDirService.Value, 102689, "[In Directory Service] dSHeuristics: By default, this attribute is not set."); } else { DataSchemaSite.Log.Add(LogEntryKind.Comment, "dSHeuristics has been changed by other test suites, the value is: {0}", dSHeuristicsForDirService.Value); } //MS-ADTS-Schema_R490 childEntry = childEntry.Children.Find("CN=Query-Policies"); parentAttribute = childEntry.Parent.Name.ToString(); DataSchemaSite.CaptureRequirementIfIsTrue( parentAttribute.Equals("CN=Directory Service"), 490, "The Parent of the Query-Policies which is a type of Windows NT Service must be Directory Service."); //MS-ADTS-Schema_R491 PropertyValueCollection objectClassQueryPolicy = childEntry.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClassQueryPolicy.Contains((object)"container"), 491, "The ObjectClass attribute of the Query-Policies which is a type of Windows NT Service must be container."); //MS-ADTS-Schema_R492 childEntry = childEntry.Children.Find("CN=Default Query Policy"); parentAttribute = childEntry.Parent.Name.ToString(); DataSchemaSite.CaptureRequirementIfIsTrue( parentAttribute.Equals("CN=Query-Policies"), 492, "The Parent of the Default Query Policy must be Query-Policies."); //MS-ADTS-Schema_R493 objectClassQueryPolicy = childEntry.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClassQueryPolicy.Contains((object)"queryPolicy"), 493, "The ObjectClass attribute of the Default Query Policy must be queryPolicy."); }
/// <summary> /// CaptureServerContainer is a Common method for Both AD/DS and AD/LDS Server Container Requirements Validation /// Retrieves the required Directory Entry for a specified DN and its attributes. /// </summary> public void CaptureServerContainer() { if (isDS) { if (!adAdapter.GetObjectByDN("CN=Sites,CN=Configuration," + adAdapter.rootDomainDN, out sitesEntry)) { DataSchemaSite.Assume.IsTrue( false, "CN=Sites,CN=Configuration," + adAdapter.rootDomainDN + " Object is not found in server"); } } else { if (!adAdapter.GetLdsObjectByDN("CN=Sites,CN=Configuration," + adAdapter.LDSRootObjectName, out sitesEntry)) { DataSchemaSite.Assume.IsTrue( false, "CN=Sites,CN=Configuration," + adAdapter.LDSRootObjectName + " Object is not found in server"); } } DirectoryEntries sitesChildern = sitesEntry.Children; foreach (DirectoryEntry child in sitesChildern) { if (child.Properties["objectClass"].Contains((object)"site") && child.Name.Equals("CN=Default-First-Site-Name")) { serverParentEntry = child.Children.Find("CN=Servers"); //MS-ADTS-Schema_R433 // [Since objectClass of the child is a site object, R433 is captured.] DataSchemaSite.CaptureRequirement( 433, "The parent of the Servers Container must be site object."); } } if (isDS) { string dnServers = serverParentEntry.Properties["distinguishedName"].Value.ToString(); if (!adAdapter.GetObjectByDN(dnServers, out dirPartitions)) { DataSchemaSite.Assume.IsTrue(false, dnServers + " Object is not found in server"); } } parent = serverParentEntry.Parent.Name; objectClass = serverParentEntry.Properties["objectClass"]; //MS-ADTS-Schema_R434 DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"serversContainer"), 434, "The ObjectClass Attribute of the Servers Container must be serversContainer."); systemFlag = serverParentEntry.Properties["systemFlags"].Value.ToString(); systemFlagVal = ParseSystemFlagsValue("FLAG_DISALLOW_MOVE_ON_DELETE"); //MS-ADTS-Schema_R435 DataSchemaSite.CaptureRequirementIfAreEqual <string>( systemFlagVal.ToString(), systemFlag, 435, "The systemFlags Attribute of the Servers Container must be FLAG_DISALLOW_MOVE_ON_DELETE."); DirectoryEntries serverChildren = null; foreach (DirectoryEntry sitechild in sitesChildern) { if (sitechild.Properties["objectClass"].Contains((object)"site") && sitechild.Name.Equals("CN=Default-First-Site-Name")) { serverParentEntry = sitechild.Children.Find("CN=Servers"); serverChildren = serverParentEntry.Children; foreach (DirectoryEntry child in serverChildren) { if (!child.Parent.Name.Equals("CN=Servers")) { isParent = false; } objectClass = child.Properties["objectClass"]; if (!objectClass.Contains((object)"server")) { isObjectClass = false; } systemFlag = child.Properties["systemFlags"].Value.ToString(); systemFlagVal = ParseSystemFlagsValue("FLAG_CONFIG_ALLOW_RENAME|FLAG_CONFIG_ALLOW_LIMITED_MOVE|FLAG_DISALLOW_MOVE_ON_DELETE"); if (systemFlag != (systemFlagVal.ToString())) { isParseSystemFlagsValue = false; } } } } //MS-ADTS-Schema_R436 DataSchemaSite.CaptureRequirementIfIsTrue( isParent, 436, "The parent of the Server Object must be servers Container object."); //MS-ADTS-Schema_R437 DataSchemaSite.CaptureRequirementIfIsTrue( isObjectClass, 437, "The ObjectClass Attribute of the Server Object must be Server."); //MS-ADTS-Schema_R438 DataSchemaSite.CaptureRequirementIfIsTrue( isParseSystemFlagsValue, 438, "The systemFlags Attribute of the Server Object must be either of" + "FLAG_CONFIG_ALLOW_RENAME | FLAG_CONFIG_ALLOW_LIMITED_MOVE | FLAG_DISALLOW_MOVE_ON_DELETE."); if (isDS) { if (!adAdapter.GetObjectByDN("OU=Domain Controllers," + adAdapter.rootDomainDN, out sitesEntry)) { DataSchemaSite.Assume.IsTrue( false, "OU=Domain Controllers," + adAdapter.rootDomainDN + " Object is not found in server"); } DirectoryEntries domainChildren = sitesEntry.Children; isObjectClass = true; foreach (DirectoryEntry childDomain in domainChildren) { string cnName = childDomain.Properties["cn"].Value.ToString(); foreach (DirectoryEntry sitechild in sitesChildern) { if (sitechild.Properties["objectClass"].Contains((object)"site")) { if (sitechild.Name.Equals("CN=Default-First-Site-Name")) { serverParentEntry = sitechild.Children.Find("CN=Servers"); serverChildren = serverParentEntry.Children; foreach (DirectoryEntry child in serverChildren) { serverEntry = serverParentEntry.Children.Find("CN=" + cnName); DirectoryEntries serverEntryChildern = serverEntry.Children; foreach (DirectoryEntry serverEntryChild in serverEntryChildern) { PropertyValueCollection objClass = serverEntryChild.Properties["objectClass"]; dnName = serverEntryChild.Properties["distinguishedName"].Value.ToString(); if (dnName.StartsWith("CN=NTDS Settings")) { if (dnName.Contains(adAdapter.PDCNetbiosName)) { nTDSName = dnName; } if (!objClass.Contains((object)"nTDSDSA")) { isObjectClass = false; } } } } } } } } bool hasDNSHostName = false; string dnsHostName = null; string[] hostName = null; string domainStr = null; foreach (DirectoryEntry child in serverChildren) { dnsHostName = child.Properties["dnsHostName"].Value.ToString().ToLower(); hostName = dnsHostName.Split('.'); domainStr = dnsHostName.Substring(hostName[0].Length + 1, dnsHostName.Length - (hostName[0].Length + 1)); if (hostName[0].Equals(adAdapter.PDCNetbiosName.ToLower())) { hasDNSHostName = true; break; } } //MS-ADTS-Schema_R439 DataSchemaSite.CaptureRequirementIfIsTrue( hasDNSHostName && (domainStr.ToLower().Equals(adAdapter.PrimaryDomainDnsName.ToLower())), 439, "The dNSHostName Attribute of the Server Object must be fully qualified DNS name of the DC."); //MS-ADTS-Schema_R440 DataSchemaSite.CaptureRequirementIfIsTrue( isObjectClass, 440, "Each DC in a domain has an nTDSDSA object in the config NC."); if (!adAdapter.GetObjectByDN(nTDSName, out dirPartitions)) { DataSchemaSite.Assume.IsTrue(false, nTDSName + " Object is not found in server"); } string dMDLocation = dirPartitions.Properties["dMDLocation"].Value.ToString(); //MS-ADTS-Schema_R444 DataSchemaSite.CaptureRequirementIfAreEqual <string>( ("CN=Schema,CN=Configuration," + adAdapter.rootDomainDN).ToLower(), dMDLocation.ToLower(), 444, "The dMDLocation Attribute of the nTDSDSA Object must be dsname of the schema NC root."); } else { foreach (DirectoryEntry serverEntryChild in serverChildren) { DirectoryEntries serverEntryChildsChild = serverEntryChild.Children; foreach (DirectoryEntry serverChild in serverEntryChildsChild) { string dnsHostName = serverEntryChild.Properties["dNSHostName"].Value.ToString().ToLower(); string[] hostName = dnsHostName.Split('.'); string domainStr = dnsHostName.Substring(hostName[0].Length + 1, dnsHostName.Length - (hostName[0].Length + 1)); if ((hostName[0].ToLower().Equals(adAdapter.PDCNetbiosName.ToLower())) && (domainStr.ToLower().Equals(adAdapter.PrimaryDomainDnsName.ToLower()))) { isTrue = true; } dnName = serverChild.Properties["distinguishedName"].Value.ToString(); if (dnName.StartsWith("CN=NTDS Settings")) { nTDSName = dnName; } } } //MS-ADTS-Schema_R439 DataSchemaSite.CaptureRequirementIfIsTrue( isTrue, 439, "The dNSHostName Attribute of the Server Object must be fully qualified DNS name of the DC."); if (!adAdapter.GetLdsObjectByDN(nTDSName, out dirPartitions)) { DataSchemaSite.Assume.IsTrue(false, nTDSName + " Object is not found in server"); } string dMDLocation = dirPartitions.Properties["dMDLocation"].Value.ToString(); //MS-ADTS-Schema_R444 DataSchemaSite.CaptureRequirementIfAreEqual <string>( "CN=Schema,CN=Configuration," + adAdapter.LDSRootObjectName, dMDLocation, 444, "The dMDLocation Attribute of the nTDSDSA Object must be dsname of the schema NC root."); } string name = dirPartitions.Properties["name"].Value.ToString(); //MS-ADTS-Schema_R441 DataSchemaSite.CaptureRequirementIfAreEqual <string>( "NTDS Settings", name, 441, "The name Attribute of the nTDSDSA Object must be NTDS Settings."); objectClass = dirPartitions.Parent.Properties["objectClass"]; //MS-ADTS-Schema_R442 DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"server"), 442, "The parent of the nTDSDSA Object must be an object with objectClass server."); objectClass = dirPartitions.Properties["objectClass"]; //MS-ADTS-Schema_R443 DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"nTDSDSA"), 443, "The ObjectClass Attribute of the nTDSDSA Object must be nTDSDSA."); //MS-ADTS-Schema_R445 PropertyValueCollection allNCs = null; systemFlag = dirPartitions.Properties["systemFlags"].Value.ToString(); systemFlagVal = ParseSystemFlagsValue("FLAG_DISALLOW_MOVE_ON_DELETE"); DataSchemaSite.CaptureRequirementIfAreEqual <string>( systemFlagVal.ToString(), systemFlag, 445, "The SystemFlags attribute of the nTDSDSA Object must be FLAG_DISALLOW_MOVE_ON_DELETE."); if (isDS) { entry = new DirectoryEntry("LDAP://" + adAdapter.PDCNetbiosName + "/rootDSE"); } else { entry = new DirectoryEntry("LDAP://" + adAdapter.adamServerPort + "/rootDSE"); try { allNCs = entry.Properties["namingContexts"]; } catch (Exception) { entry = new DirectoryEntry("LDAP://" + adAdapter.adamServerPort + "/rootDSE"); } } allNCs = entry.Properties["namingContexts"];//namingContexts PropertyValueCollection hasMasterNCs = dirPartitions.Properties["hasMasterNCs"]; PropertyValueCollection msDSHasMasterNCs = dirPartitions.Properties["msDS-hasMasterNCs"]; PropertyValueCollection msDSHasFullReplicasNCs; bool isHasMasterNCs = true, ismsDSHasMasterNCs = true, ismsDSHasFullReplicasNCs = true; for (int index = 0; index < hasMasterNCs.Count; index++) { if (!allNCs.Contains(hasMasterNCs[index])) { isHasMasterNCs = false; } } for (int index = 0; index < msDSHasMasterNCs.Count; index++) { if (!allNCs.Contains(msDSHasMasterNCs[index])) { ismsDSHasMasterNCs = false; } } //MS-ADTS-Schema_R449 DataSchemaSite.CaptureRequirementIfIsTrue( isHasMasterNCs, 449, @"hasMasterNCs attribute in nTDSDSA Object Contains the dsnames of the NC root objects representing the schema NC, config NC,and domain NC for the default domain of the DC. This attribute always contains these three values, and only these three values."); //MS-ADTS-Schema_R451 DataSchemaSite.CaptureRequirementIfIsTrue( ismsDSHasMasterNCs, 451, @"msDS-hasMasterNCs attribute in nTDSDSA Object Contains the dsnames of the root objects of all writable NC replicas hosted by the DC."); if (isDS) { if (!adAdapter.GetObjectByDN(adAdapter.rootDomainDN, out entry)) { DataSchemaSite.Assume.IsTrue(false, adAdapter.rootDomainDN + " Object is not found in server"); } PropertyValueCollection msds = entry.Properties["distinguishedName"]; PropertyValueCollection msDSHasDomainNCs = dirPartitions.Properties["msDS-HasDomainNCs"]; //MS-ADTS-Schema_R450 DataSchemaSite.CaptureRequirementIfIsTrue( msds.Value.ToString() == msDSHasDomainNCs.Value.ToString(), 450, @"msDS-HasDomainNCs attribute in nTDSDSA Object Equals to the dsname of the NC root object for which the DC is hosting a regular NC replica. This attribute must have only one value. "); } if (isDS) { isParseSystemFlagsValue = true; isParent = true; isObjectClass = true; bool isNotExistingRODC = true; //The value optionsvalue=0x41 can be got from TD [MS-ADTS] 7.1.1.2.2.1.2.1.3 const int optionsvalue = 0x41; foreach (DirectoryEntry serverEntryChild in serverChildren) { if (serverEntryChild.Name.ToLower() == ("CN=" + adAdapter.RODCNetbiosName).ToLower()) { DirectoryEntries nTDSEntries = serverEntryChild.Children; foreach (DirectoryEntry nTDSEntry in nTDSEntries) { msDSHasFullReplicasNCs = nTDSEntry.Properties["msDS-hasFullReplicaNCs"]; for (int index = 0; index < hasMasterNCs.Count; index++) { if (!allNCs.Contains(msDSHasFullReplicasNCs[index])) { ismsDSHasFullReplicasNCs = false; } } //Checking For the Parent equal to Servers if (!nTDSEntry.Properties["objectClass"].Contains((object)"nTDSDSA")) { isParent = false; } foreach (DirectoryEntry nTDSConnectionObjects in nTDSEntry.Children) { //Check schedule attribute if (nTDSConnectionObjects.Properties["schedule"].Value != null) { bool verifySuccessed = VerifyScheduleStructure((byte[])nTDSConnectionObjects.Properties["schedule"].Value); if (verifySuccessed != true) { isSchedule = false; } } objectClass = nTDSConnectionObjects.Properties["objectClass"]; if (!objectClass.Contains((object)"nTDSConnection")) { isObjectClass = false; } string s = (string)nTDSConnectionObjects.Properties["fromServer"].Value; if (!s.Contains("CN=NTDS Settings")) { isRefertontdsdsa = false; } //Checking For the attribute options. if (optionsvalue != ((int)(nTDSConnectionObjects.Properties["options"].Value))) { isOptions = false; } //Checking For the name equals to RODC Connection. name = nTDSConnectionObjects.Properties["name"].Value.ToString(); if ((bool)(nTDSConnectionObjects.Properties["enabledConnection"].Value) != true) { isEnabledconnection = false; } systemFlag = nTDSConnectionObjects.Properties["systemFlags"].Value.ToString(); systemFlagVal = ParseSystemFlagsValue("FLAG_CONFIG_ALLOW_RENAME"); if (systemFlag != (systemFlagVal.ToString())) { isParseSystemFlagsValue = false; } } } } if (serverEntryChild.Name.ToLower() == ("CN=" + adAdapter.PDCNetbiosName.ToLower())) { DirectoryEntries nTDSDCEntries = serverEntryChild.Children; foreach (DirectoryEntry nTDSDCEntry in nTDSDCEntries) { foreach (DirectoryEntry nTDSConnectionDCObjects in nTDSDCEntry.Children) { nonRODCConnection = nTDSConnectionDCObjects.Properties["name"].Value.ToString(); if ((serverOS == OSVersion.WinSvr2012 || serverOS == OSVersion.WinSvr2012R2) && nonRODCConnection.Equals("RODC Connection (SYSVOL)")) { isNotExistingRODC = false; } else if ((serverOS == OSVersion.WinSvr2008 || serverOS == OSVersion.WinSvr2008R2) && nonRODCConnection.Equals("RODC Connection (FRS)")) { isNotExistingRODC = false; } } } } } //Verify MS-AD_Schema requirement:MS-AD_Schema_R4511 DataSchemaSite.CaptureRequirementIfIsTrue( isRefertontdsdsa, 4511, @"[Each RODC NTFRS connection object has the following attributes:]fromServer: A reference to the nTDSDSA object of the source DC."); //Verify MS-AD_Schema requirement:MS-AD_Schema_R4512 DataSchemaSite.CaptureRequirementIfIsTrue( isSchedule, 4512, @"[Each RODC NTFRS connection object has the following attributes:]schedule: Contains a SCHEDULE structure that specifies the time intervals when replication can be performed between the source and the destination DCs."); //Verify MS-AD_Schema requirement:MS-AD_Schema_R4504 DataSchemaSite.CaptureRequirementIfIsTrue( isNotExistingRODC, 4504, @"RODC NTFRS connection objects do not exist for DCs."); //Verify MS-AD_Schema requirement:MS-AD_Schema_R4503 if (serverOS >= OSVersion.WinSvr2012) { DataSchemaSite.CaptureRequirementIfAreEqual <string>( "RODC Connection (SYSVOL)", name, 4503, @"An RODC NTFRS connection object exists for each RODC in the forest."); } else { DataSchemaSite.CaptureRequirementIfAreEqual <string>( "RODC Connection (FRS)", name, 4503, @"An RODC NTFRS connection object exists for each RODC in the forest."); } //Verify MS-AD_Schema requirement:MS-AD_Schema_R4508 DataSchemaSite.CaptureRequirementIfIsTrue( isParent, 4508, @"[Each RODC NTFRS connection object has the following attributes:]parent: nTDSDSA object."); //Verify MS-AD_Schema requirement:MS-AD_Schema_R4506 DataSchemaSite.CaptureRequirementIfIsTrue( isParent, 4506, @"This object[RODC NTFRS Connection Object] is a child of the nTDSDSA object of the destination RODC."); //MS-ADTS-Schema_R455 DataSchemaSite.CaptureRequirementIfIsTrue( isObjectClass, 455, "The objectClass attribute of the Connection object must be nTDSConnection."); //Verify MS-AD_Schema requirement:MS-AD_Schema_R4510 DataSchemaSite.CaptureRequirementIfIsTrue( isEnabledconnection, 4510, @"[Each RODC NTFRS connection object has the following attributes:]enabledConnection: true."); // //Verify MS-AD_Schema requirement:MS-AD_Schema_R4513 // DataSchemaSite.CaptureRequirementIfIsTrue( isParseSystemFlagsValue, 4513, @"[Each RODC NTFRS connection object has the following attributes:]systemFlags: {FLAG_CONFIG_ALLOW_RENAME}."); //Verify MS-AD_Schema requirement:MS-AD_Schema_R4509 DataSchemaSite.CaptureRequirementIfIsTrue( isObjectClass, 4509, @"[Each RODC NTFRS connection object has the following attributes:]objectClass: nTDSConnection."); //Verify MS-AD_Schema requirement:MS-AD_Schema_R4507 if (serverOS >= OSVersion.WinSvr2012) { DataSchemaSite.CaptureRequirementIfAreEqual <string>( "RODC Connection (SYSVOL)", name, 4507, @"[Each RODC NTFRS connection object has the following attributes:]name: RODC Connection (SYSVOL)."); } else { DataSchemaSite.CaptureRequirementIfAreEqual <string>( "RODC Connection (FRS)", name, 4507, @"[Each RODC NTFRS connection object has the following attributes:]name: RODC Connection (FRS)."); } //Verify MS-AD_Schema requirement:MS-AD_Schema_R4514 DataSchemaSite.CaptureRequirementIfIsTrue( isOptions, 4514, @"[Each RODC NTFRS connection object has the following attributes:]options: Both of the bits from the following diagram[The 26th bit is RT, the last bit is IG, and the rest are X]. "); //Verify MS-AD_Schema requirement:MS-AD_Schema_R4517 DataSchemaSite.CaptureRequirementIfIsTrue( isOptions, 4517, @"[In RODC NTFRS connection object, options attribute]X: Must be zero and ignored."); } //MS-ADTS-Schema_R452 DataSchemaSite.CaptureRequirementIfIsTrue( ismsDSHasFullReplicasNCs, 452, @"msDS-hasFullReplicaNCs attribute in nTDSDSA Object Contains the dsnames of the root objects of all writable NC replicas hosted by the DC."); //MS-ADTS-Schema_R454 DataSchemaSite.CaptureRequirementIfIsTrue( isParent, 454, "The parent of the Connection object must be nTDSDSA object."); //MS-ADTS-Schema_R456 DataSchemaSite.CaptureRequirementIfIsTrue( isParseSystemFlagsValue, 456, @"The SystemFlags attribute of the Connection object must be FLAG_CONFIG_ALLOW_RENAME | FLAG_CONFIG_ALLOW_MOVE."); }
// <summary> /// This method validates the requirements under /// ServiceAndQueryPolicyContainer Scenario. /// </summary> public void ValidateServiceAndQueryPolicyContainer() { // For AD/DS ; //This for holding DirectroyEntry. DirectoryEntry requiredEntry = new DirectoryEntry(); string rootDomain = adAdapter.rootDomainDN; string schemaNC = "CN=Schema," + rootDomain; string ConfigNC = "CN=Configuration," + rootDomain; string parentAttribute; PropertyValueCollection objectClass; //The following requirements are present in AD/DS only. //MS-ADTS-Schema_R480 if (!adAdapter.GetObjectByDN("CN=DisplaySpecifiers," + ConfigNC, out requiredEntry)) { DataSchemaSite.Assume.IsTrue( false, "CN=DisplaySpecifiers," + ConfigNC + " Object is not found in server"); } parentAttribute = requiredEntry.Parent.Name.ToString(); DataSchemaSite.CaptureRequirementIfIsTrue( parentAttribute.Equals("CN=Configuration"), 480, "The parent of the Display Specifiers Container must be Config NC root."); //MS-ADTS-Schema_R481 objectClass = requiredEntry.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"container"), 481, "The ObjectClass attribute of the Display Specifier Container must be container."); //MS-ADTS-Schema_R497 if (!adAdapter.GetObjectByDN("CN=Physical Locations," + ConfigNC, out requiredEntry)) { DataSchemaSite.Assume.IsTrue( false, "CN=Physical Locations," + ConfigNC + " Object is not found in server"); } parentAttribute = requiredEntry.Parent.Name.ToString(); DataSchemaSite.CaptureRequirementIfIsTrue( parentAttribute.Equals("CN=Configuration"), 497, "The Parent of the Physical Locations must be config NC root object."); //MS-ADTS-Schema_R498 objectClass = requiredEntry.Properties["objectClass"]; DataSchemaSite.CaptureRequirementIfIsTrue( objectClass.Contains((object)"physicalLocation"), 498, "The objectClass attribute of the Physical Locations must be physicalLocation."); if (!adAdapter.GetObjectByDN("CN=Services," + ConfigNC, out requiredEntry)) { DataSchemaSite.Assume.IsTrue( false, "CN=Services," + ConfigNC + " Object is not found in server"); } //This method is for DS/LDS common requirement call for Services and QueryPolicy Container. LDSAndDSCommonCallForServices(requiredEntry); }
/// <summary> /// This method validates the requirements under /// ReadOnlyDomainController. /// </summary> public void ValidateReadOnlyDomainController() { SearchResponse rodcEntries = null; bool isRodcEntry = false; string distinguishedName = "CN=" + adAdapter.RODCNetbiosName + ",OU=Domain Controllers," + adAdapter.rootDomainDN; //System.DirectoryServices.Protocols.SearchScope GetLDAPObject( distinguishedName, adAdapter.PDCNetbiosName, "objectclass=computer", System.DirectoryServices.Protocols.SearchScope.Base, new string[] { "objectclass", "userAccountControl", "primaryGroupId", "servicePrincipalName", "dNSHostName", "msDS-RevealedUsers", "msDS-NeverRevealGroup", "msDS-RevealOnDemandGroup", "msDS-KrbTgtLink", "managedBy" }, out rodcEntries); if (rodcEntries != null) { isRodcEntry = true; SearchResultEntry rodcEntry = rodcEntries.Entries[0]; SearchResultAttributeCollection attributeCollection = rodcEntry.Attributes; string expected = String.Empty, actual = String.Empty; foreach (DirectoryAttribute attribute in attributeCollection.Values) { #region Capturing MS-AD_Schema_R913 if (attribute.Name.ToLower().Equals("objectclass")) { string[] values = (string[])attribute.GetValues(expected.GetType()); expected = "computer"; actual = values[values.Length - 1]; DataSchemaSite.CaptureRequirementIfAreEqual <string>( expected, actual, 913, @"Read-Only Domain controller object's objectClass is computer."); DataSchemaSite.CaptureRequirementIfIsTrue( expected == actual && isRodcEntry, 912, @"Each RODC in a domain has a read-only domain controller object in its default NC. The DC's RODC object is the DC's computer object with additional requirements as described in this section. "); continue; } #endregion #region Capturing MS-AD_Schema_R914 if (attribute.Name.ToLower().Equals("useraccountcontrol")) { int value = int.Parse(attribute[0].ToString()); int userAccControlFlag = ParseUserAccountControlValue("ADS_UF_PARTIAL_SECRETS_ACCOUNT|ADS_UF_WORKSTATION_TRUST_ACCOUNT"); bool isR914Satisfied = ((value & userAccControlFlag) == userAccControlFlag); DataSchemaSite.CaptureRequirementIfIsTrue( isR914Satisfied, 914, @"Read-Only Domain controller object's userAccountControl is {ADS_UF_PARTIAL_SECRETS_ACCOUNT | ADS_UF_WORKSTATION_TRUST_ACCOUNT}"); continue; } #endregion #region Capturing MS-AD_Schema_R915, MS-AD_Schema_R916 if (attribute.Name.ToLower().Equals("primarygroupid")) { int value = int.Parse(attribute[0].ToString()); expected = "521"; actual = value.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( expected, actual, 915, @"Read-Only Domain controller object's primaryGroupId is 521."); if (serverOS >= OSVersion.WinSvr2008) { string dn = "CN=Read-only Domain Controllers,CN=Users," + adAdapter.rootDomainDN; DirectoryEntry rodcGroupEntry = null; adAdapter.GetObjectByDN(dn, out rodcGroupEntry); SecurityIdentifier sid = new SecurityIdentifier((byte[])rodcGroupEntry.Properties["objectsid"].Value, 0); expected = sid.ToString().Substring(sid.ToString().LastIndexOf('-') + 1); actual = value.ToString(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( expected, actual, 916, @"primaryGroupId attribute is populated during creation of the RODC corresponding to the RODC object. The primary group of an RODC object is the domain relative well-known Read-Only Domain Controllers security group. So the primaryGroupID attribute of an RODC object equals the RID of the Read-Only Domain Controllers security group, 521."); } continue; } #endregion #region Capturing MS-AD_Schema_R917 if (attribute.Name.ToLower().Equals("serviceprincipalname")) { string[] values = (string[])attribute.GetValues(expected.GetType()); //For windows 2008 SP1, it's same with windows server 2008 r2 expected = "host/" + adAdapter.RODCNetbiosName + "." + adAdapter.PrimaryDomainDnsName + "/" + adAdapter.PrimaryDomainDnsName; expected = expected.ToLower(); for (int i = 0; i < values.Length; i++) { if (expected.Equals(values[i].ToLower())) { actual = values[i].ToLower(); break; } } DataSchemaSite.CaptureRequirementIfAreEqual <string>( expected, actual, 917, @"Read-Only Domain Controllers servicePrincipalName is contains all of the SPNs for a normal (not read-only) DC."); continue; } #endregion #region Capturing MS-AD_Schema_R918 if (attribute.Name.ToLower().Equals("dnshostname")) { expected = adAdapter.RODCNetbiosName.ToLower() + "." + adAdapter.PrimaryDomainDnsName.ToLower(); actual = attribute[0].ToString().ToLower(); DataSchemaSite.CaptureRequirementIfAreEqual <string>( expected, actual, 918, @"Read-Only Domain Controller object's dNSHostName equals fully qualified DNS name of the RODC."); continue; } #endregion #region Capturing MS-AD_Schema_R920 if (attribute.Name.ToLower().Equals("msds-revealedusers")) { SearchResponse userResponse = null; GetLDAPObject( "CN=Users," + adAdapter.rootDomainDN, adAdapter.PDCNetbiosName, "objectclass=user", System.DirectoryServices.Protocols.SearchScope.OneLevel, new string[] { "distinguishedname" }, out userResponse); foreach (SearchResultEntry ent in userResponse.Entries) { if (ent.DistinguishedName.Contains("krbtgt_")) { expected = ent.DistinguishedName; break; } } actual = attribute[0].ToString(); bool isR920Satisfied = actual.Contains(expected); DataSchemaSite.CaptureRequirementIfIsTrue( isR920Satisfied, 920, @"Read-Only Domain Controller object's msDS-RevealedUsers attribute Contains information about the user objects whose secret attributes are cached at this RODC. This attribute is maintained by the system; see procedure UpdateRevealedList.A more usable form of this attribute is the constructed attribute msDS-RevealedList."); continue; } #endregion #region Capturing MS-AD_Schema_R922 if (attribute.Name.ToLower().Equals("msds-neverrevealgroup")) { string[] values = (string[])attribute.GetValues(expected.GetType()); SearchResponse groupResponse = null; GetLDAPObject( "CN=Users," + adAdapter.rootDomainDN, adAdapter.PDCNetbiosName, "objectclass=group", System.DirectoryServices.Protocols.SearchScope.OneLevel, new string[] { "distinguishedname" }, out groupResponse); foreach (SearchResultEntry ent in groupResponse.Entries) { if (ent.DistinguishedName.Contains("Denied RODC Password")) { expected = ent.DistinguishedName; break; } } bool isR922Satisfied = false; for (int i = 0; i < values.Length; i++) { if (values[i].Equals(expected)) { isR922Satisfied = true; break; } } DataSchemaSite.CaptureRequirementIfIsTrue( isR922Satisfied, 922, @"Read-Only Domain Controller object's msDS-NeverRevealGroup attribute is maintained by an administrator. It contains a set of user and security-enabled group objects. A user in this set, or reachable from this set by traversing any number of member links from a group in this set, will not change state from not being cached to being cached at this RODC. If a user is added to this attribute (directly or indirectly) while one of its secret attributes is already cached, the secret attribute remains cached until the secret attribute changes, at which time the caching stops. For the use of this attribute, see procedure RevealSecretsForUserAllowed."); continue; } #endregion #region Capturing MS-AD_Schema_R923 if (attribute.Name.ToLower().Equals("msds-revealondemandgroup")) { string[] values = (string[])attribute.GetValues(expected.GetType()); SearchResponse groupResponse = null; GetLDAPObject( "CN=Users," + adAdapter.rootDomainDN, adAdapter.PDCNetbiosName, "objectclass=group", System.DirectoryServices.Protocols.SearchScope.OneLevel, new string[] { "distinguishedname" }, out groupResponse); foreach (SearchResultEntry ent in groupResponse.Entries) { if (ent.DistinguishedName.Contains("Allowed RODC Password")) { expected = ent.DistinguishedName; break; } } bool isR923Satisfied = false; for (int i = 0; i < values.Length; i++) { if (values[i].Equals(expected)) { isR923Satisfied = true; break; } } DataSchemaSite.CaptureRequirementIfIsTrue( isR923Satisfied, 923, @"Read-Only Domain Controller object's msDS-RevealOnDemandGroup attribute is maintained by an administrator. It contains a set of user and security-enabled group objects. A user in this set, or reachable from this set by traversing any number of member links from a group in this set, and not excluded by membership in msDS-NeverRevealGroup can change state from not being cached to being cached at this RODC. For the use of this attribute see procedure RevealSecretsForUserAllowed."); continue; } #endregion #region Capturing MS-AD_Schema_R924 if (attribute.Name.ToLower().Equals("msds-krbtgtlink")) { string[] values = (string[])attribute.GetValues(expected.GetType()); SearchResponse userResponse = null; GetLDAPObject( "CN=Users," + adAdapter.rootDomainDN, adAdapter.PDCNetbiosName, "objectclass=user", System.DirectoryServices.Protocols.SearchScope.OneLevel, new string[] { "distinguishedname" }, out userResponse); foreach (SearchResultEntry ent in userResponse.Entries) { if (ent.DistinguishedName.Contains("krbtgt_")) { expected = ent.DistinguishedName; break; } } bool isR924Satisfied = false; for (int i = 0; i < values.Length; i++) { if (values[i].Equals(expected)) { isR924Satisfied = true; break; } } DataSchemaSite.CaptureRequirementIfIsTrue( isR924Satisfied, 924, @"Read-Only Domain Controllers objects msDS-KrbTgtLink attribute is populated during creation of the RODC object. It contains a reference to the RODC's secondary Kerberos ticket-granting ticket account."); continue; } #endregion #region Capturing MS-AD_Schema_R925 if (attribute.Name.ToLower().Equals("managedby")) { actual = (string)attribute[0]; SearchResponse userResponse = null; GetLDAPObject( "CN=Users," + adAdapter.rootDomainDN, adAdapter.PDCNetbiosName, "(|(objectclass=user)(objectclass=group))", System.DirectoryServices.Protocols.SearchScope.OneLevel, new string[] { "distinguishedname" }, out userResponse); bool isR925Satisfied = false; foreach (SearchResultEntry ent in userResponse.Entries) { if (ent.DistinguishedName.Contains("Admin") && ent.DistinguishedName.Equals(actual)) { isR925Satisfied = true; break; } } DataSchemaSite.CaptureRequirementIfIsTrue( isR925Satisfied, 925, @"Read-Only Domain Controller object's managedBy attribute If the value of this attribute points to a valid security principal, that security principal will be an implicit member of the administrators group of this RODC. This applies to this RODC only."); continue; } #endregion } } }
/// <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 }