예제 #1
0
        /// <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.");
        }
예제 #2
0
        /// <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
        }
예제 #3
0
        // <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.");
        }