public void LDAP_Add_EnforceSchemaConstrains_rDNAttID()
        {
            #region variables

            // OrganizationalUnit rDNAttID should be "OU=" instead of "CN="
            // Specify wrong rDNAttID to cause expected errorcode
            string userName = "******";
            string userDN   = "CN=" + userName + "," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            int    errorCode;
            bool   failed = false;

            #endregion

            #region connect

            BaseTestSite.Assume.IsTrue(EnvironmentConfig.ServerVer >= ServerVersion.Win2012R2, "Server OS version should be not less than Windows Server 2012");
            LdapConnection con = new LdapConnection(new LdapDirectoryIdentifier(AD_LDAPModelAdapter.Instance(Site).PDCIPAddress),
                                                    new NetworkCredential(AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                                                                          AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                                                                          AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName));
            con.SessionOptions.Sealing = false;
            con.SessionOptions.Signing = false;

            #endregion

            #region Add Enforce Schema Constraints rDNAttID
            try
            {
                System.DirectoryServices.Protocols.DeleteRequest  delReq = new System.DirectoryServices.Protocols.DeleteRequest(userDN);
                System.DirectoryServices.Protocols.DeleteResponse delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);
            }
            catch { }
            ManagedAddRequest addReq = new ManagedAddRequest(userDN, "organizationalUnit");
            System.DirectoryServices.Protocols.AddResponse addRep = null;
            try
            {
                addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            }
            catch (DirectoryOperationException e)
            {
                if (e.Response.ResultCode == ResultCode.NamingViolation)
                {
                    errorCode = int.Parse(e.Response.ErrorMessage.Split(':')[0], System.Globalization.NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                    if ((Win32ErrorCode_32)errorCode == Win32ErrorCode_32.ERROR_DS_RDN_DOESNT_MATCH_SCHEMA)
                    {
                        failed = true;
                    }
                }
            }
            BaseTestSite.Assert.IsTrue(
                failed,
                @"The attributeType of the first label of the object DN matches the rDNAttID of 
                    the structural object class or the 88 object class. Otherwise, 
                    namingViolation / ERROR_DS_RDN_DOESNT_MATCH_SCHEMA is returned. 
                    For example, it is not allowed to create an organizationalUnit with CN=test RDN; 
                    the correct RDN for an organizationalUnit object is OU=test. If there is no class C 
                    for which the attributeType is equal to C!rDNAttID, namingViolation / <unrestricted> 
                    is returned.");
            #endregion
        }
        public void LDAP_Add_EnforceSchemaConstrains_Range()
        {
            #region variables

            //set employeeID attribute out of range, upperRange is 16
            const int upperRange          = 16;
            string    attrName            = "employeeID";
            string    attrValueOutOfRange = new string('1', upperRange + 10);
            string    userName            = "******";
            string    userDN = "CN=" + userName + ",CN=users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            int       errorCode;
            bool      failed = false;

            #endregion

            #region connect

            BaseTestSite.Assume.IsTrue(EnvironmentConfig.ServerVer >= ServerVersion.Win2012, "Server OS version should be not less than Windows Server 2012");
            LdapConnection con = new LdapConnection(new LdapDirectoryIdentifier(AD_LDAPModelAdapter.Instance(Site).PDCIPAddress),
                                                    new NetworkCredential(AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                                                                          AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                                                                          AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName));
            con.SessionOptions.Sealing = false;
            con.SessionOptions.Signing = false;

            #endregion

            #region Add Enforce Schema Constraints RangeUpper
            try
            {
                System.DirectoryServices.Protocols.DeleteRequest  delReq = new System.DirectoryServices.Protocols.DeleteRequest(userDN);
                System.DirectoryServices.Protocols.DeleteResponse delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);
            }
            catch { }
            ManagedAddRequest addReq = new ManagedAddRequest(userDN, "user");
            addReq.Attributes.Add(new DirectoryAttribute(attrName, attrValueOutOfRange));
            System.DirectoryServices.Protocols.AddResponse addRep = null;
            try
            {
                addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            }
            catch (DirectoryOperationException e)
            {
                if (e.Response.ResultCode == ResultCode.ConstraintViolation)
                {
                    errorCode = int.Parse(e.Response.ErrorMessage.Split(':')[0], System.Globalization.NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                    if ((Win32ErrorCode_32)errorCode == Win32ErrorCode_32.ERROR_DS_RANGE_CONSTRAINT)
                    {
                        failed = true;
                    }
                }
            }
            BaseTestSite.Assert.IsTrue(
                failed,
                @"All attribute values must be compliant with the rangeUpper and rangeLower constraints 
                    of the schema (see section 3.1.1.2.3). If a supplied value violates a rangeUpper or rangeLower
                    constraint, then the Add fails with constraintViolation / ERROR_DS_RANGE_CONSTRAINT.");
            #endregion
        }
 /// <summary>
 /// Test initialize
 /// </summary>
 protected override void TestInitialize()
 {
     base.TestInitialize();
     Site.DefaultProtocolDocShortName = "MS-AD_LDAP";
     AD_LDAPModelAdapter.Instance(Site).Initialize();
     Utilities.DomainAdmin         = AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName;
     Utilities.DomainAdminPassword = AD_LDAPModelAdapter.Instance(Site).DomainUserPassword;
     Utilities.TargetServerFqdn    = AD_LDAPModelAdapter.Instance(Site).PDCNetbiosName + "." + AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName + ":" + AD_LDAPModelAdapter.Instance(Site).ADDSPortNum + "/";
 }
        public void LDAP_Search_ConstructedAttributes_isUserCachableAtRodc()
        {
            if (string.IsNullOrWhiteSpace(AD_LDAPModelAdapter.Instance(Site).RODCNetbiosName))
            {
                BaseTestSite.Assert.Fail("Test case requires a RODC but \"RODCName\" ptfconfig property value is invalid");
            }

            #region variables

            string RODCName = AD_LDAPModelAdapter.Instance(Site).RODCNetbiosName;
            string RODCDN   = "CN=" + RODCName + ",OU=Domain Controllers," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            //Let D be the DN of the user principal specified using LDAP Control LDAP_SERVER_DN_INPUT_OID.
            //If the DN of a security principal is not explicitly specified, D is the DN of the current requester.
            string userName   = AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName;
            string userDN     = "CN=" + userName + ",CN=Users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            bool   isCachable = false;

            #endregion

            #region connect

            BaseTestSite.Assume.IsTrue(EnvironmentConfig.ServerVer >= ServerVersion.Win2012, "Server OS version should be not less than Windows Server 2012");
            LdapConnection con = new LdapConnection(new LdapDirectoryIdentifier(AD_LDAPModelAdapter.Instance(Site).PDCIPAddress),
                                                    new NetworkCredential(AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                                                                          AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                                                                          AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName));
            con.SessionOptions.Sealing = false;
            con.SessionOptions.Signing = false;

            #endregion

            #region search with LDAP_SERVER_DN_INPUT_OID

            System.DirectoryServices.Protocols.SearchRequest searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                RODCDN,
                "(objectClass=computer)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "msDS-isUserCachableAtRodc");
            //Let D be the DN of the user principal specified using LDAP Control LDAP_SERVER_DN_INPUT_OID.
            //If the DN of a security principal is not explicitly specified, D is the DN of the current requester.
            System.DirectoryServices.Protocols.SearchResponse searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            DirectoryAttribute attr   = searchRep.Entries[0].Attributes["msDS-isUserCachableAtRodc"];
            object[]           values = attr.GetValues(Type.GetType("System.String"));
            isCachable = Convert.ToBoolean(Convert.ToInt16(values[0].ToString(), CultureInfo.InvariantCulture));

            //Get expected result by GetRevealSecretsPolicyForUser(TO!distinguishedName, D) defined in MS-DRSR section 4.1.10.5.14
            bool expectedCachable = GetRevealSecretsPolicyForUser(RODCDN, userDN);

            BaseTestSite.Assert.AreEqual(
                expectedCachable,
                isCachable,
                @"TO!msDS-IsUserCachableAtRodc = GetRevealSecretsPolicyForUser(TO!distinguishedName, D) (procedure GetRevealSecretsPolicyForUser is defined in [MS-DRSR] section 4.1.10.5.14).");

            #endregion
        }
Ejemplo n.º 5
0
        public static void ClassInitialize(TestContext testContext)
        {
            TestClassBase.Initialize(testContext);

            // Initializing the ITestSite object
            if (null == TestScenarioDeleteWin2012TestSite)
            {
                TestScenarioDeleteWin2012TestSite = TestClassBase.BaseTestSite;
                TestScenarioDeleteWin2012TestSite.DefaultProtocolDocShortName = "MS-ADTS-LDAP";
            }
            adLdapModelAdapter = AD_LDAPModelAdapter.Instance(TestScenarioDeleteWin2012TestSite);
            adLdapModelAdapter.Initialize();
        }
        /// <summary>
        /// Test clean up
        /// </summary>
        protected override void TestCleanup()
        {
            string         addr = AD_LDAPModelAdapter.Instance(Site).PDCIPAddress;
            LdapConnection con  = new LdapConnection(
                new LdapDirectoryIdentifier(addr),
                new NetworkCredential(AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                                      AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                                      AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName));

            con.SessionOptions.Sealing = false;
            con.SessionOptions.Signing = false;

            System.DirectoryServices.Protocols.ModifyRequest mod = new System.DirectoryServices.Protocols.ModifyRequest("",
                                                                                                                        DirectoryAttributeOperation.Add, "schemaupgradeinprogress", "0");
            con.SendRequest(mod);
            base.TestCleanup();
        }
        public void LDAP_Search_SearchFilters()
        {
            #region variables

            string testUser   = "******";
            string testUserDN = "CN=" + testUser + ",CN=Users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            int    errorCode;
            bool   failed = false;

            #endregion

            #region connect

            BaseTestSite.Assume.IsTrue(EnvironmentConfig.ServerVer >= ServerVersion.Win2012, "Server OS version should be not less than Windows Server 2012");
            string         addr = AD_LDAPModelAdapter.Instance(Site).PDCIPAddress;
            string         port = AD_LDAPModelAdapter.Instance(Site).ADDSPortNum;
            LdapConnection con  = new LdapConnection(new LdapDirectoryIdentifier(addr, int.Parse(port)),
                                                     new NetworkCredential(AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                                                                           AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                                                                           AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName));
            con.SessionOptions.Sealing = false;
            con.SessionOptions.Signing = false;

            #endregion

            #region Add a dynamic object for search testing

            if (Utilities.IsObjectExist(testUserDN, addr, port))
            {
                System.DirectoryServices.Protocols.DeleteRequest  req = new System.DirectoryServices.Protocols.DeleteRequest(testUserDN);
                System.DirectoryServices.Protocols.DeleteResponse rep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(req);
            }
            ManagedAddRequest addReq = new ManagedAddRequest(testUserDN);
            addReq.Attributes.Add(new DirectoryAttribute("objectClass", new string[] { "dynamicObject", "user" }));
            addReq.Attributes.Add(new DirectoryAttribute("entryTTL", "1800"));
            addReq.Attributes.Add(new DirectoryAttribute("sAMAccountName", testUser));
            System.DirectoryServices.Protocols.AddResponse addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);

            #endregion

            #region search filter
            //entryTTL is a constructed attribute
            System.DirectoryServices.Protocols.SearchRequest searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                testUserDN,
                "(entryTTL=*)",
                System.DirectoryServices.Protocols.SearchScope.Subtree);
            try
            {
                System.DirectoryServices.Protocols.SearchResponse searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            }
            catch (DirectoryOperationException e)
            {
                if (e.Response.ResultCode == ResultCode.InappropriateMatching)
                {
                    errorCode = int.Parse(e.Response.ErrorMessage.Split(':')[0], System.Globalization.NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                    if ((Win32ErrorCode_32)errorCode == Win32ErrorCode_32.ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS)
                    {
                        failed = true;
                    }
                }
            }
            BaseTestSite.Assert.IsTrue(
                failed,
                @"Active Directory does not support constructed attributes (defined in section 3.1.1.4.5) in search filters.
                When a search operation is performed with such a search filter, Active Directory fails with inappropriateMatching
                ([RFC2251] section 4.1.10).");

            #endregion

            #region clean up
            if (Utilities.IsObjectExist(testUserDN, addr, port))
            {
                System.DirectoryServices.Protocols.DeleteRequest  delReq = new System.DirectoryServices.Protocols.DeleteRequest(testUserDN);
                System.DirectoryServices.Protocols.DeleteResponse delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);
            }
            #endregion
        }
        public void LDAP_Add_Processing_Specifics_SystemFlags()
        {
            #region variables

            string siteObjDN             = "CN=testSite,CN=Sites,CN=Configuration," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            string serversContainerObjDN = "CN=testServers," + siteObjDN;
            string serverObjDN           = "CN=testServer," + serversContainerObjDN;
            string ntdsSettingsObjDN     = "CN=NTDS Settings," + serverObjDN;
            string nTDSConnection        = "CN=testnTDSConnection," + ntdsSettingsObjDN;
            string ipObjDN              = "CN=IP,CN=Inter-Site Transports,CN=Sites,CN=Configuration," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            string siteLinkObjDN        = "CN=testSiteLink," + ipObjDN;
            string siteLinkBridgeDN     = "CN=testSiteLinkBridge," + ipObjDN;
            string subnetContainerObjDN = "CN=Subnets,CN=Sites,CN=Configuration," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            string subnetObjDN          = "CN=192.168.0.0/24," + subnetContainerObjDN;
            #endregion

            #region connect

            BaseTestSite.Assume.IsTrue(EnvironmentConfig.ServerVer >= ServerVersion.Win2012, "Server OS version should be not less than Windows Server 2012");
            LdapConnection con = new LdapConnection(new LdapDirectoryIdentifier(AD_LDAPModelAdapter.Instance(Site).PDCIPAddress),
                                                    new NetworkCredential(AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                                                                          AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                                                                          AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName));
            con.SessionOptions.Sealing = false;
            con.SessionOptions.Signing = false;

            #endregion

            #region Site Object
            ManagedAddRequest addReq = new ManagedAddRequest(siteObjDN, "site");
            System.DirectoryServices.Protocols.AddResponse addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            BaseTestSite.Assert.AreEqual <ResultCode>(
                ResultCode.Success,
                addRep.ResultCode,
                @"Add Site: {0} should succeed.",
                siteObjDN);
            System.DirectoryServices.Protocols.SearchRequest searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                siteObjDN,
                "(objectClass=Site)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "systemFlags");
            System.DirectoryServices.Protocols.SearchResponse searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            DirectoryAttribute attr   = searchRep.Entries[0].Attributes["systemFlags"];
            object[]           values = attr.GetValues(Type.GetType("System.String"));
            int flags = Convert.ToInt32(values[0], CultureInfo.InvariantCulture);
            BaseTestSite.Assert.AreEqual(
                SystemFlags.FLAG_DISALLOW_MOVE_ON_DELETE | SystemFlags.FLAG_CONFIG_ALLOW_RENAME,
                (SystemFlags)flags & (SystemFlags.FLAG_DISALLOW_MOVE_ON_DELETE | SystemFlags.FLAG_CONFIG_ALLOW_RENAME),
                @"The DC sets additional bits in the systemFlags value of the object created:
                site object: FLAG_DISALLOW_MOVE_ON_DELETE and FLAG_CONFIG_ALLOW_RENAME.");
            #endregion

            #region ServersContainer Object
            addReq = new ManagedAddRequest(serversContainerObjDN, "serversContainer");
            addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            BaseTestSite.Assert.AreEqual <ResultCode>(
                ResultCode.Success,
                addRep.ResultCode,
                @"Add ServersContainer: {0} should succeed.",
                serversContainerObjDN);
            searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                serversContainerObjDN,
                "(objectClass=serversContainer)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "systemFlags");
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            attr      = searchRep.Entries[0].Attributes["systemFlags"];
            values    = attr.GetValues(Type.GetType("System.String"));
            flags     = Convert.ToInt32(values[0], CultureInfo.InvariantCulture);
            BaseTestSite.Assert.AreEqual(
                SystemFlags.FLAG_DISALLOW_MOVE_ON_DELETE,
                (SystemFlags)flags & SystemFlags.FLAG_DISALLOW_MOVE_ON_DELETE,
                @"The DC sets additional bits in the systemFlags value of the object created:
                serversContainer object: FLAG_DISALLOW_MOVE_ON_DELETE.");
            #endregion

            #region Server Object
            addReq = new ManagedAddRequest(serverObjDN, "server");
            addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            BaseTestSite.Assert.AreEqual <ResultCode>(
                ResultCode.Success,
                addRep.ResultCode,
                @"Add server: {0} should succeed.",
                serverObjDN);
            searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                serverObjDN,
                "(objectClass=server)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "systemFlags");
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            attr      = searchRep.Entries[0].Attributes["systemFlags"];
            values    = attr.GetValues(Type.GetType("System.String"));
            flags     = Convert.ToInt32(values[0], CultureInfo.InvariantCulture);
            BaseTestSite.Assert.AreEqual(
                SystemFlags.FLAG_DISALLOW_MOVE_ON_DELETE | SystemFlags.FLAG_CONFIG_ALLOW_RENAME | SystemFlags.FLAG_CONFIG_ALLOW_LIMITED_MOVE,
                (SystemFlags)flags & (SystemFlags.FLAG_DISALLOW_MOVE_ON_DELETE | SystemFlags.FLAG_CONFIG_ALLOW_RENAME | SystemFlags.FLAG_CONFIG_ALLOW_LIMITED_MOVE),
                @"The DC sets additional bits in the systemFlags value of the object created:
                server object: FLAG_DISALLOW_MOVE_ON_DELETE, FLAG_CONFIG_ALLOW_RENAME, and FLAG_CONFIG_ALLOW_LIMITED_MOVE.");
            #endregion

            #region nTDSDSA Object
            System.DirectoryServices.Protocols.ModifyRequest modReq = new System.DirectoryServices.Protocols.ModifyRequest("",
                                                                                                                           DirectoryAttributeOperation.Add, "schemaupgradeinprogress", "1");
            System.DirectoryServices.Protocols.ModifyResponse modRep = (System.DirectoryServices.Protocols.ModifyResponse)con.SendRequest(modReq);
            BaseTestSite.Assert.AreEqual <ResultCode>(ResultCode.Success, modRep.ResultCode, "Should return success when set SchemaUpgradeInProgress to 1");
            addReq = new ManagedAddRequest(ntdsSettingsObjDN, "nTDSDSA");
            addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            BaseTestSite.Assert.AreEqual <ResultCode>(
                ResultCode.Success,
                addRep.ResultCode,
                @"Add nTDSDSA: {0} should succeed.",
                ntdsSettingsObjDN);
            searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                ntdsSettingsObjDN,
                "(objectClass=nTDSDSA)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "systemFlags");
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            attr      = searchRep.Entries[0].Attributes["systemFlags"];
            values    = attr.GetValues(Type.GetType("System.String"));
            flags     = Convert.ToInt32(values[0], CultureInfo.InvariantCulture);
            BaseTestSite.Assert.AreEqual(
                SystemFlags.FLAG_DISALLOW_MOVE_ON_DELETE,
                (SystemFlags)flags & (SystemFlags.FLAG_DISALLOW_MOVE_ON_DELETE),
                @"The DC sets additional bits in the systemFlags value of the object created:
                nTDSDSA object: FLAG_DISALLOW_MOVE_ON_DELETE.");
            #endregion

            #region nTDSConnection Object
            addReq = new ManagedAddRequest(nTDSConnection, "nTDSConnection");
            addReq.Attributes.Add(new DirectoryAttribute("options", "1"));
            addReq.Attributes.Add(new DirectoryAttribute("fromServer", ntdsSettingsObjDN));
            addReq.Attributes.Add(new DirectoryAttribute("enabledConnection", "TRUE"));
            addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);

            BaseTestSite.Assert.AreEqual <ResultCode>(
                ResultCode.Success,
                addRep.ResultCode,
                @"Add nTDSConnection: {0} should succeed.",
                nTDSConnection);
            searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                nTDSConnection,
                "(objectClass=nTDSConnection)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "systemFlags");
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            attr      = searchRep.Entries[0].Attributes["systemFlags"];
            values    = attr.GetValues(Type.GetType("System.String"));
            flags     = Convert.ToInt32(values[0], CultureInfo.InvariantCulture);
            BaseTestSite.Assert.AreEqual(
                SystemFlags.FLAG_CONFIG_ALLOW_RENAME,
                (SystemFlags)flags & (SystemFlags.FLAG_CONFIG_ALLOW_RENAME),
                @"The DC sets additional bits in the systemFlags value of the object created:
                nTDSConnection object: FLAG_CONFIG_ALLOW_RENAME.");
            #endregion

            #region SiteLink Object
            addReq = new ManagedAddRequest(siteLinkObjDN, "siteLink");

            addReq.Attributes.Add(new DirectoryAttribute("siteList", siteObjDN));
            addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            BaseTestSite.Assert.AreEqual <ResultCode>(
                ResultCode.Success,
                addRep.ResultCode,
                @"Add SiteLink: {0} should succeed.",
                siteLinkObjDN);
            searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                siteLinkObjDN,
                "(objectClass=SiteLink)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "systemFlags");
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            attr      = searchRep.Entries[0].Attributes["systemFlags"];
            values    = attr.GetValues(Type.GetType("System.String"));
            flags     = Convert.ToInt32(values[0], CultureInfo.InvariantCulture);
            BaseTestSite.Assert.AreEqual(
                SystemFlags.FLAG_CONFIG_ALLOW_RENAME,
                (SystemFlags)flags & SystemFlags.FLAG_CONFIG_ALLOW_RENAME,
                @"The DC sets additional bits in the systemFlags value of the object created:
                siteLink object: FLAG_CONFIG_ALLOW_RENAME.");
            #endregion

            #region SiteLinkBridge Object
            addReq = new ManagedAddRequest(siteLinkBridgeDN, "siteLinkBridge");
            addReq.Attributes.Add(new DirectoryAttribute("siteLinkList", siteLinkObjDN));
            addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            BaseTestSite.Assert.AreEqual <ResultCode>(
                ResultCode.Success,
                addRep.ResultCode,
                @"Add SiteLinkBridge: {0} should succeed.",
                siteLinkBridgeDN);
            searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                siteLinkBridgeDN,
                "(objectClass=SiteLinkBridge)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "systemFlags");
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            attr      = searchRep.Entries[0].Attributes["systemFlags"];
            values    = attr.GetValues(Type.GetType("System.String"));
            flags     = Convert.ToInt32(values[0], CultureInfo.InvariantCulture);
            BaseTestSite.Assert.AreEqual(
                SystemFlags.FLAG_CONFIG_ALLOW_RENAME,
                (SystemFlags)flags & SystemFlags.FLAG_CONFIG_ALLOW_RENAME,
                @"The DC sets additional bits in the systemFlags value of the object created:
                siteLinkBridge object: FLAG_CONFIG_ALLOW_RENAME.");
            #endregion

            #region not above Object with Subnets Container Parent
            addReq = new ManagedAddRequest(subnetObjDN, "subnet");
            addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            BaseTestSite.Assert.AreEqual <ResultCode>(
                ResultCode.Success,
                addRep.ResultCode,
                @"Add subnet: {0} should succeed.",
                subnetObjDN);
            searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                subnetObjDN,
                "(objectClass=Subnet)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "systemFlags");
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            attr      = searchRep.Entries[0].Attributes["systemFlags"];
            values    = attr.GetValues(Type.GetType("System.String"));
            flags     = Convert.ToInt32(values[0], CultureInfo.InvariantCulture);
            BaseTestSite.Assert.AreEqual(
                SystemFlags.FLAG_CONFIG_ALLOW_RENAME,
                (SystemFlags)flags & SystemFlags.FLAG_CONFIG_ALLOW_RENAME,
                @"The DC sets additional bits in the systemFlags value of the object created:
                subnet object: FLAG_CONFIG_ALLOW_RENAME.");
            #endregion

            #region not above Object with Sites Container Parent except the Subnets Container and the Inter-Site-Transports Container
            #endregion

            #region clean up

            System.DirectoryServices.Protocols.DeleteRequest delReq = new System.DirectoryServices.Protocols.DeleteRequest(siteObjDN);
            delReq.Controls.Add(new TreeDeleteControl());
            System.DirectoryServices.Protocols.DeleteResponse delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);
            delReq = new System.DirectoryServices.Protocols.DeleteRequest(siteLinkObjDN);
            delReq.Controls.Add(new TreeDeleteControl());
            delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);
            delReq = new System.DirectoryServices.Protocols.DeleteRequest(siteLinkBridgeDN);
            delReq.Controls.Add(new TreeDeleteControl());
            delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);
            delReq = new System.DirectoryServices.Protocols.DeleteRequest(subnetObjDN);
            delReq.Controls.Add(new TreeDeleteControl());
            delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);

            #endregion
        }
        public void LDAP_AD_DS_Add_Constraints_ComputerObject()
        {
            BaseTestSite.Assume.IsTrue(EnvironmentConfig.ServerVer >= ServerVersion.Win2012, "Server OS version should be not less than Windows Server 2012");

            #region Connect and bind to server

            SocketTransportConfig transportConfig = new SocketTransportConfig();
            transportConfig.RemoteIpAddress = IPAddress.Parse(AD_LDAPModelAdapter.Instance(Site).PDCIPAddress);
            transportConfig.RemoteIpPort    = int.Parse(AD_LDAPModelAdapter.Instance(Site).ADDSPortNum, CultureInfo.InvariantCulture);
            transportConfig.BufferSize      = AD_LDAPModelAdapter.Instance(Site).transportBufferSize;
            transportConfig.Type            = StackTransportType.Tcp;
            transportConfig.Role            = Role.Client;
            AdtsLdapClient ldapClientStack = new AdtsLdapClient(AdtsLdapVersion.V3, transportConfig);
            ldapClientStack.Connect();

            //The user do not have RIGHT_DS_CREATE_CHILD access rights
            String   userName      = AD_LDAPModelAdapter.Instance(Site).testUser7Name;
            String   password      = AD_LDAPModelAdapter.Instance(Site).testUser7Pwd;
            String   netbiosDomain = AD_LDAPModelAdapter.Instance(Site).PrimaryDomainNetBiosName;
            TimeSpan timeout       = AD_LDAPModelAdapter.Instance(Site).timeout;

            //Using SSL binding
            //Microsoft.Protocols.TestTools.StackSdk.Security.Sspi.AccountCredential transportCredential = new Microsoft.Protocols.TestTools.StackSdk.Security.Sspi.AccountCredential(
            //    Site.Properties["FullDomainName"], userName, password);
            //Microsoft.Protocols.TestTools.StackSdk.Security.Sspi.ClientSecurityContextAttribute contextAttributes = Microsoft.Protocols.TestTools.StackSdk.Security.Sspi.ClientSecurityContextAttribute.Connection;
            //Microsoft.Protocols.TestTools.StackSdk.Security.Sspi.SspiClientSecurityContext securityContext = new Microsoft.Protocols.TestTools.StackSdk.Security.Sspi.SspiClientSecurityContext(
            //            Microsoft.Protocols.TestTools.StackSdk.Security.Sspi.SecurityPackageType.Kerberos,
            //            transportCredential,
            //            "LDAP/" + Site.Properties["ServerComputerName"],
            //            contextAttributes,
            //            Microsoft.Protocols.TestTools.StackSdk.Security.Sspi.SecurityTargetDataRepresentation.SecurityNetworkDrep);
            //securityContext.Initialize(null);
            //AdtsBindRequestPacket bindRequest = ldapClientStack.CreateSaslBindRequest(securityContext, false);

            AdtsBindRequestPacket bindRequest = ldapClientStack.CreateSimpleBindRequest(userName, password, netbiosDomain);
            //send bind request
            ldapClientStack.SendPacket(bindRequest);
            AdtsLdapPacket         response     = ldapClientStack.ExpectPacket(timeout);
            AdtsBindResponsePacket bindResponse = (AdtsBindResponsePacket)response;

            //check the connectiong between client and server
            Site.Assert.AreEqual <long>(
                LDAPResult_resultCode.success,
                (long)((BindResponse)bindResponse.GetInnerRequestOrResponse()).resultCode.Value,
                "Bind response result should be LDAPResult_resultCode.success.");

            #endregion

            #region Add a Computer Object

            string computerName     = "testAddConstraints";
            string computerObjectDN = "CN=" + computerName + ",CN=Computers," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            KeyValuePair <string, string[]>[] attrs = new KeyValuePair <string, string[]> [5];
            attrs[0] = new KeyValuePair <string, string[]>("objectClass", new string[] { "computer" });
            attrs[1] = new KeyValuePair <string, string[]>("dNSHostName", new string[] { computerName + "." + AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName });
            attrs[2] = new KeyValuePair <string, string[]>("servicePrincipalName", new string[] { "host/" + computerName + "." + AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName, "host/" + computerName });
            attrs[3] = new KeyValuePair <string, string[]>("sAMAccountName", new string[] { computerName + "$" });
            //attrs[4] = new KeyValuePair<string, string[]>("userAccountControl", new string[]{ "4098" });
            //If the account is created with UF_ACCOUNTDISABLE set in userAccountControl, unicodePwd is not required.
            //attrs[5] = new KeyValuePair<string, string[]>("unicodePwd", new string[] { "Password01!" });

            AdtsAddRequestPacket addRequest = ldapClientStack.CreateAddRequest(computerObjectDN, attrs);
            ldapClientStack.SendPacket(addRequest);
            response = ldapClientStack.ExpectPacket(timeout);
            AdtsAddResponsePacket addResponse = (AdtsAddResponsePacket)response;
            string ldapErrorCode = Enum.GetName(typeof(ResultCode), ((Microsoft.Protocols.TestTools.StackSdk.ActiveDirectory.Adts.Asn1CodecV3.AddResponse)
                                                                     addResponse.GetInnerRequestOrResponse()).resultCode.Value).ToString();
            //BaseTestSite.Assert.AreEqual<string>(
            //         "some error code",
            //         ldapErrorCode,
            //         @"");
            #endregion

            #region Unbind and Disconnect

            AdtsUnbindRequestPacket unbindRequest = ldapClientStack.CreateUnbindRequest();
            ldapClientStack.SendPacket(unbindRequest);
            ldapClientStack.Disconnect();
            ldapClientStack = null;

            #endregion
        }
 public static void ClassInitialize(TestContext testContext)
 {
     TestClassBase.Initialize(testContext);
     EnvironmentConfig.ServerVer = (ServerVersion)AD_LDAPModelAdapter.Instance(BaseTestSite).PDCOSVersion;
 }
        public void LDAP_AD_DS_Add_Constraints_DisallowedAttributes()
        {
            #region variables

            //The values of the attributes are not important, but should be complied with the attribute syntax
            string attrValue = "100";
            int    attrNum;
            int    errorCode;
            bool   failed = false;

            #endregion

            #region connect

            BaseTestSite.Assume.IsTrue(EnvironmentConfig.ServerVer >= ServerVersion.Win2012, "Server OS version should be not less than Windows Server 2012");
            LdapConnection con = new LdapConnection(new LdapDirectoryIdentifier(AD_LDAPModelAdapter.Instance(Site).PDCIPAddress),
                                                    new NetworkCredential(AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                                                                          AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                                                                          AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName));
            con.SessionOptions.Sealing = false;
            con.SessionOptions.Signing = false;

            #endregion

            #region Add constraint for class user
            attrNum = 15;
            System.DirectoryServices.Protocols.DirectoryAttribute[] attr = new DirectoryAttribute[attrNum];
            attr[0]  = new DirectoryAttribute("badPasswordTime", attrValue);
            attr[1]  = new DirectoryAttribute("badPwdCount", attrValue);
            attr[2]  = new DirectoryAttribute("dBCSPwd", attrValue);
            attr[3]  = new DirectoryAttribute("lastLogoff", attrValue);
            attr[4]  = new DirectoryAttribute("lastLogon", attrValue);
            attr[5]  = new DirectoryAttribute("lastLogonTimestamp", attrValue);
            attr[6]  = new DirectoryAttribute("lmPwdHistory", attrValue);
            attr[7]  = new DirectoryAttribute("logonCount", attrValue);
            attr[8]  = new DirectoryAttribute("memberOf", attrValue);
            attr[9]  = new DirectoryAttribute("msDS-User-Account-Control-Computed", attrValue);
            attr[10] = new DirectoryAttribute("ntPwdHistory", attrValue);
            attr[11] = new DirectoryAttribute("rid", attrValue);
            attr[12] = new DirectoryAttribute("sAMAccountType", attrValue);
            attr[13] = new DirectoryAttribute("supplementalCredentials", attrValue);
            attr[14] = new DirectoryAttribute("isCriticalSystemObject", "TRUE");

            for (int i = 0; i < attrNum; i++)
            {
                ManagedAddRequest addReq = new ManagedAddRequest(
                    "CN=testAddConstraints,CN=users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC, "user");
                addReq.Attributes.Add(attr[i]);
                System.DirectoryServices.Protocols.AddResponse addRep = null;
                try
                {
                    addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
                }
                catch (DirectoryOperationException e)
                {
                    if (e.Response.ResultCode == ResultCode.UnwillingToPerform)
                    {
                        errorCode = int.Parse(e.Response.ErrorMessage.Split(':')[0], System.Globalization.NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                        if ((Win32ErrorCode_32)errorCode == Win32ErrorCode_32.ERROR_DS_ATTRIBUTE_OWNED_BY_SAM)
                        {
                            failed = true;
                        }
                    }
                }
                BaseTestSite.Assert.IsTrue(
                    failed,
                    @"In AD DS, the following attributes are disallowed in an Add for objects of class user:
                        badPasswordTime, badPwdCount, dBCSPwd, isCriticalSystemObject, lastLogoff, lastLogon, 
                        lastLogonTimestamp, lmPwdHistory, logonCount, memberOf, msDS-User-Account-Control-Computed, 
                        ntPwdHistory, objectSid, rid, sAMAccountType, and supplementalCredentials. If one of these 
                        attributes is specified in an Add, the Add returns unwillingToPerform / ERROR_DS_ATTRIBUTE_OWNED_BY_SAM.");
                failed = false;
            }

            #endregion

            #region Add constraint for class group

            //The values of the attributes are not important, but should be complied with the attribute syntax
            attrNum = 5;
            System.DirectoryServices.Protocols.DirectoryAttribute[] attr2 = new DirectoryAttribute[attrNum];
            attr[0] = new DirectoryAttribute("memberOf", attrValue);
            attr[1] = new DirectoryAttribute("rid", attrValue);
            attr[2] = new DirectoryAttribute("sAMAccountType", attrValue);
            attr[3] = new DirectoryAttribute("userPassword", attrValue);
            attr[4] = new DirectoryAttribute("isCriticalSystemObject", "TRUE");

            for (int i = 0; i < attrNum; i++)
            {
                ManagedAddRequest addReq = new ManagedAddRequest(
                    "CN=testAddConstraints,CN=users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC, "group");
                addReq.Attributes.Add(attr[i]);
                System.DirectoryServices.Protocols.AddResponse addRep = null;
                try
                {
                    addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
                }
                catch (DirectoryOperationException e)
                {
                    if (e.Response.ResultCode == ResultCode.UnwillingToPerform)
                    {
                        errorCode = int.Parse(e.Response.ErrorMessage.Split(':')[0], System.Globalization.NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                        if ((Win32ErrorCode_32)errorCode == Win32ErrorCode_32.ERROR_DS_ATTRIBUTE_OWNED_BY_SAM)
                        {
                            failed = true;
                        }
                    }
                }
                BaseTestSite.Assert.IsTrue(
                    failed,
                    @"In AD DS, the following attributes are disallowed in an Add for objects of class group:
                        isCriticalSystemObject, memberOf, objectSid, rid, sAMAccountType, and userPassword. 
                        If one of these attributes is specified in an Add, the Add returns unwillingToPerform / ERROR_DS_ATTRIBUTE_OWNED_BY_SAM.");
                failed = false;
            }

            #endregion

            #region Add constraint for class not a SAM-specific object class

            //The values of the attributes are not important, but should be complied with the attribute syntax
            attrNum = 7;
            System.DirectoryServices.Protocols.DirectoryAttribute[] attr3 = new DirectoryAttribute[attrNum];
            attr[0] = new DirectoryAttribute("lmPwdHistory", attrValue);
            attr[1] = new DirectoryAttribute("ntPwdHistory", attrValue);
            attr[2] = new DirectoryAttribute("samAccountName", attrValue);
            attr[3] = new DirectoryAttribute("sAMAccountType", attrValue);
            attr[4] = new DirectoryAttribute("supplementalCredentials", attrValue);
            attr[5] = new DirectoryAttribute("unicodePwd", attrValue);
            attr[6] = new DirectoryAttribute("isCriticalSystemObject", "TRUE");

            for (int i = 0; i < attrNum; i++)
            {
                ManagedAddRequest addReq = new ManagedAddRequest(
                    "CN=testAddConstraints,CN=users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC, "classStore");
                addReq.Attributes.Add(attr[i]);
                System.DirectoryServices.Protocols.AddResponse addRep = null;
                try
                {
                    addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
                }
                catch (DirectoryOperationException e)
                {
                    if (e.Response.ResultCode == ResultCode.UnwillingToPerform)
                    {
                        errorCode = int.Parse(e.Response.ErrorMessage.Split(':')[0], System.Globalization.NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                        if ((Win32ErrorCode_32)errorCode == Win32ErrorCode_32.ERROR_DS_ILLEGAL_MOD_OPERATION)
                        {
                            failed = true;
                        }
                    }
                }
                BaseTestSite.Assert.IsTrue(
                    failed,
                    @"In AD DS, the following attributes are disallowed in an Add for an object whose
                        class is not a SAM-specific object class (see 3.1.1.5.2.3): isCriticalSystemObject,
                        lmPwdHistory, ntPwdHistory, objectSid, samAccountName, sAMAccountType, supplementalCredentials,
                        and unicodePwd. If one of these attributes is specified in an Add, the Add returns
                        unwillingToPerform / ERROR_DS_ILLEGAL_MOD_OPERATION.");
                failed = false;
            }

            #endregion
        }
        private bool GetRevealSecretsPolicyForUser(string rodcObjDN, string userObjDN)
        {
            #region variables

            System.DirectoryServices.Protocols.SearchResultEntry rodcEntry;
            System.DirectoryServices.Protocols.SearchResultEntry userEntry;

            #endregion

            #region connect and get rodc and user object

            LdapConnection con = new LdapConnection(new LdapDirectoryIdentifier(AD_LDAPModelAdapter.Instance(Site).PDCNetbiosName),
                                                    new NetworkCredential(AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                                                                          AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                                                                          AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName));
            con.SessionOptions.Sealing = false;
            con.SessionOptions.Signing = false;
            System.DirectoryServices.Protocols.SearchRequest searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                rodcObjDN,
                "(objectClass=computer)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "msDS-KrbTgtLink",
                "msDS-NeverRevealGroup",
                "msDS-RevealOnDemandGroup");
            System.DirectoryServices.Protocols.SearchResponse searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            rodcEntry = searchRep.Entries[0];
            searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                userObjDN,
                "(objectClass=user)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "userAccountControl",
                "objectSid");
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            userEntry = searchRep.Entries[0];

            #endregion

            #region body
            //An RODC can always cache secrets of its own account
            if (rodcObjDN == userObjDN)
            {
                return(true);
            }

            //An RODC can always cache secrets of its own secondary Kerberos TGT account
            //But not other secondary Kerberos TGT accounts.
            DirectoryAttribute attr   = rodcEntry.Attributes["msDS-KrbTgtLink"];
            object[]           values = attr.GetValues(Type.GetType("System.String"));
            foreach (string value in values)
            {
                if (value.Equals(userObjDN, StringComparison.CurrentCultureIgnoreCase))
                {
                    return(true);
                }
            }
            searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                AD_LDAPModelAdapter.Instance(Site).rootDomainNC,
                "(objectClass=computer)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "msDS-KrbTgtLink");
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            foreach (System.DirectoryServices.Protocols.SearchResultEntry entry in searchRep.Entries)
            {
                if (entry.Attributes["msDS-KrbTgtLink"] != null)
                {
                    values = entry.Attributes["msDS-KrbTgtLink"].GetValues(Type.GetType("System.String"));
                    foreach (string value in values)
                    {
                        if (value.Equals(userObjDN, StringComparison.CurrentCultureIgnoreCase))
                        {
                            return(false);
                        }
                    }
                }
            }

            //Never reveal secrets of inter-domain trust accounts
            attr   = userEntry.Attributes["userAccountControl"];
            values = attr.GetValues(Type.GetType("System.String"));
            foreach (string value in values)
            {
                int userAccountControl = int.Parse(value, CultureInfo.InvariantCulture);
                if (((AdtsUserAccountControl)userAccountControl & AdtsUserAccountControl.ADS_UF_INTERDOMAIN_TRUST_ACCOUNT) != 0)
                {
                    return(false);
                }
            }

            //Never reveal secrets of users reachable from rodcObj!msDS-NeverRevealGroup
            attr   = rodcEntry.Attributes["msDS-NeverRevealGroup"];
            values = attr.GetValues(Type.GetType("System.String"));
            foreach (string groupDN in values)
            {
                if (Utilities.IsGroupMember(
                        AD_LDAPModelAdapter.Instance(Site).PDCNetbiosName,
                        AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName,
                        AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                        AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                        groupDN,
                        userObjDN))
                {
                    return(false);
                }
            }

            //Cache secrets of users reachable from rodcObj!msDS-RevealOnDemandGroup
            attr   = rodcEntry.Attributes["msDS-RevealOnDemandGroup"];
            values = attr.GetValues(Type.GetType("System.String"));
            foreach (string groupDN in values)
            {
                if (Utilities.IsGroupMember(
                        AD_LDAPModelAdapter.Instance(Site).PDCNetbiosName,
                        AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName,
                        AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                        AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                        groupDN,
                        userObjDN))
                {
                    return(true);
                }
            }

            return(false);

            #endregion
        }
        public void LDAP_Add_EnforceSchemaConstrains_isSingleValued()
        {
            #region variables

            // [MS-ADA1] section 2.217 Attibute employeeID
            // isSingleValued: TRUE
            // set employeeID attribute with multiple values, will cause constraint violation
            string attrName   = "employeeID";
            string attrValue1 = "1";
            string attrValue2 = "2";
            string attrValue3 = "3";
            string userName   = "******";
            string userDN     = "CN=" + userName + ",CN=users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            int    errorCode;
            bool   failed = false;

            #endregion

            #region connect

            BaseTestSite.Assume.IsTrue(EnvironmentConfig.ServerVer >= ServerVersion.Win2012R2, "Server OS version should be not less than Windows Server 2012");
            LdapConnection con = new LdapConnection(new LdapDirectoryIdentifier(AD_LDAPModelAdapter.Instance(Site).PDCIPAddress),
                                                    new NetworkCredential(AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                                                                          AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                                                                          AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName));
            con.SessionOptions.Sealing = false;
            con.SessionOptions.Signing = false;

            #endregion

            #region Add Enforce Schema Constraints isSingleValued
            try
            {
                System.DirectoryServices.Protocols.DeleteRequest  delReq = new System.DirectoryServices.Protocols.DeleteRequest(userDN);
                System.DirectoryServices.Protocols.DeleteResponse delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);
            }
            catch { }
            ManagedAddRequest addReq = new ManagedAddRequest(userDN, "user");
            addReq.Attributes.Add(new DirectoryAttribute(attrName, attrValue1, attrValue2, attrValue3));
            System.DirectoryServices.Protocols.AddResponse addRep = null;
            try
            {
                addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            }
            catch (DirectoryOperationException e)
            {
                if (e.Response.ResultCode == ResultCode.ConstraintViolation)
                {
                    errorCode = int.Parse(e.Response.ErrorMessage.Split(':')[0], System.Globalization.NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                    if ((Win32ErrorCode_32)errorCode == Win32ErrorCode_32.ERROR_DS_SINGLE_VALUE_CONSTRAINT)
                    {
                        failed = true;
                    }
                }
            }
            BaseTestSite.Assert.IsTrue(
                failed,
                @"All attribute values must be compliant with the isSingleValued constraint of the schema 
                    (see section 3.1.1.2.3). If multiple values are provided for an attribute that is single-valued, 
                    then the Add fails with constraintViolation / <unrestricted>.");
            #endregion
        }
        public void LDAP_Search_SD_Flags_Control()
        {
            #region variables

            string testUser   = "******";
            string testUserDN = "CN=" + testUser + ",CN=Users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            bool   isExist    = false;

            #endregion

            #region connect

            BaseTestSite.Assume.IsTrue(EnvironmentConfig.ServerVer >= ServerVersion.Win2012, "Server OS version should be not less than Windows Server 2012");
            string         addr = AD_LDAPModelAdapter.Instance(Site).PDCIPAddress;
            string         port = AD_LDAPModelAdapter.Instance(Site).ADDSPortNum;
            LdapConnection con  = new LdapConnection(new LdapDirectoryIdentifier(addr, int.Parse(port)),
                                                     new NetworkCredential(AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                                                                           AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                                                                           AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName));
            con.SessionOptions.Sealing = false;
            con.SessionOptions.Signing = false;

            #endregion

            #region Add an object for search testing

            if (!Utilities.IsObjectExist(testUserDN, addr, port))
            {
                ManagedAddRequest addReq = new ManagedAddRequest(testUserDN, "user");
                System.DirectoryServices.Protocols.AddResponse addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            }

            #endregion

            #region with SD FLags Control

            System.DirectoryServices.Protocols.SearchRequest searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                testUserDN,
                "(objectClass=user)",
                System.DirectoryServices.Protocols.SearchScope.Subtree,
                "ntSecurityDescriptor");
            System.DirectoryServices.Protocols.SecurityDescriptorFlagControl sdFlagsCtrl = new System.DirectoryServices.Protocols.SecurityDescriptorFlagControl(
                System.DirectoryServices.Protocols.SecurityMasks.Owner);
            searchReq.Controls.Add(sdFlagsCtrl);
            System.DirectoryServices.Protocols.SearchResponse searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            DirectoryAttribute attr   = searchRep.Entries[0].Attributes["ntSecurityDescriptor"];
            object[]           values = attr.GetValues(Type.GetType("System.String"));
            if (values != null)
            {
                isExist = true;
            }
            BaseTestSite.Assert.IsTrue(
                isExist,
                @"If the LDAP_SERVER_SD_FLAGS_OID control is present in an LDAP search request, the server returns an SD with the parts specified in the control
                when the SD attribute name is explicitly mentioned in the requested attribute list.");

            isExist = false;
            searchReq.Attributes.Clear();
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            attr      = searchRep.Entries[0].Attributes["ntSecurityDescriptor"];
            values    = attr.GetValues(Type.GetType("System.String"));
            if (values != null)
            {
                isExist = true;
            }
            BaseTestSite.Assert.IsTrue(
                isExist,
                @"If the LDAP_SERVER_SD_FLAGS_OID control is present in an LDAP search request, the server returns an SD with the parts specified in the control
                when the requested attribute list is empty.");

            isExist = false;
            searchReq.Attributes.Add("*");
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            attr      = searchRep.Entries[0].Attributes["ntSecurityDescriptor"];
            values    = attr.GetValues(Type.GetType("System.String"));
            if (values != null)
            {
                isExist = true;
            }
            BaseTestSite.Assert.IsTrue(
                isExist,
                @"If the LDAP_SERVER_SD_FLAGS_OID control is present in an LDAP search request, the server returns an SD with the parts specified in the control
                when all attributes are requested.");

            #endregion

            #region without SD Flags Control

            isExist = false;
            searchReq.Controls.Clear();
            searchReq.Attributes.Clear();
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            attr      = searchRep.Entries[0].Attributes["ntSecurityDescriptor"];
            if (attr == null)
            {
                isExist = false;
            }
            else
            {
                isExist = true;
            }
            BaseTestSite.Assert.IsFalse(
                isExist,
                @"Without the presence of this control, the server returns an SD only when the SD attribute name is explicitly mentioned in the requested attribute list.");

            searchReq.Attributes.Add("ntSecurityDescriptor");
            searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
            BaseTestSite.Assert.AreEqual(
                1,
                searchRep.Entries[0].Attributes.Count,
                @"Without the presence of this control, the server returns an SD only when the SD attribute name is explicitly mentioned in the requested attribute list.");
            attr   = searchRep.Entries[0].Attributes["ntSecurityDescriptor"];
            values = attr.GetValues(Type.GetType("System.String"));
            if (values != null)
            {
                isExist = true;
            }
            BaseTestSite.Assert.IsTrue(
                isExist,
                @"Without the presence of this control, the server returns an SD only when the SD attribute name is explicitly mentioned in the requested attribute list.");

            #endregion
        }
        public void LDAP_Add_EnforceSchemaConstrains_mustContain()
        {
            #region variables

            string userName = "******";
            string userDN   = "CN=" + userName + ",CN=users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            int    errorCode;
            bool   failed = false;

            #endregion

            #region connect

            BaseTestSite.Assume.IsTrue(EnvironmentConfig.ServerVer >= ServerVersion.Win2012R2, "Server OS version should be not less than Windows Server 2012");
            LdapConnection con = new LdapConnection(new LdapDirectoryIdentifier(AD_LDAPModelAdapter.Instance(Site).PDCIPAddress),
                                                    new NetworkCredential(AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                                                                          AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                                                                          AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName));
            con.SessionOptions.Sealing = false;
            con.SessionOptions.Signing = false;

            #endregion

            #region Add Enforce Schema Constraints mustContain
            try
            {
                System.DirectoryServices.Protocols.DeleteRequest  delReq = new System.DirectoryServices.Protocols.DeleteRequest(userDN);
                System.DirectoryServices.Protocols.DeleteResponse delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);
            }
            catch { }
            ManagedAddRequest addReq = new ManagedAddRequest(userDN, "groupOfUniqueNames");
            // classSchema for groupOfUniqueNames mustContain requires a uniqueMember attribtue
            // Not specifying the mustContain attribute when operating LDAP add will cause objectClassViolation error.
            System.DirectoryServices.Protocols.AddResponse addRep = null;
            try
            {
                addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            }
            catch (DirectoryOperationException e)
            {
                if (e.Response.ResultCode == ResultCode.ObjectClassViolation)
                {
                    errorCode = int.Parse(e.Response.ErrorMessage.Split(':')[0], System.Globalization.NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                    if ((Win32ErrorCode_32)errorCode == Win32ErrorCode_32.ERROR_DS_MISSING_REQUIRED_ATT)
                    {
                        failed = true;
                    }
                }
            }
            BaseTestSite.Assert.IsTrue(
                failed,
                @"The mayContain/mustContain constraints that are applicable based on the 
                      selected objectClass values are enforced. The computation of the 
                      mayContain/mustContain set takes into consideration the complete inheritance 
                      chain of the structural objectClass and the 88 object class as well as any 
                      auxiliary classes supplied. If any attributes in the mustContain set are not 
                      provided, the Add fails with objectClassViolation / <unrestricted>. If any 
                      attributes provided are not present in either the mayContain or mustContain 
                      sets, the Add fails with objectClassViolation / <unrestricted>.");
            #endregion
        }
        public void LDAP_Modify_SecurityDescriptor_ProcessingSpecifics()
        {
            #region variables

            string netBIOSName = AD_LDAPModelAdapter.Instance(Site).PrimaryDomainNetBiosName;
            string operUser    = "******";
            string operUserDN  = "CN=" + operUser + ",CN=Users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            string testUser    = "******";
            string testUserDN  = "CN=" + testUser + ",CN=Users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            string userPwd     = "Password01!";
            bool   failed      = false;
            ActiveDirectorySecurity securityDescriptor = new ActiveDirectorySecurity();
            string testUserOwner = null;

            #endregion

            BaseTestSite.Assume.IsTrue(EnvironmentConfig.ServerVer >= ServerVersion.Win2012, "Server OS version should be not less then Windows Server 2012");
            string addr = AD_LDAPModelAdapter.Instance(Site).PDCIPAddress;
            string port = AD_LDAPModelAdapter.Instance(Site).ADDSPortNum;

            try
            {
                using (LdapConnection con = new LdapConnection(
                           new LdapDirectoryIdentifier(addr, int.Parse(port)),
                           new NetworkCredential(AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                                                 AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                                                 AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName)))
                {
                    con.SessionOptions.Sealing = false;
                    con.SessionOptions.Signing = false;

                    #region add a user object for operating the ntSecurityDescriptor modify

                    if (!Utilities.IsObjectExist(operUserDN, addr, port))
                    {
                        Utilities.NewUser(addr, port, "CN=Users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC, operUser, userPwd);
                    }

                    #endregion

                    #region add a test user object to be modified

                    if (!Utilities.IsObjectExist(testUserDN, addr, port))
                    {
                        Utilities.NewUser(addr, port, "CN=Users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC, testUser, userPwd);
                    }

                    #endregion

                    #region get ntSecurityDescriptor for the test user object to be modified

                    System.DirectoryServices.Protocols.SearchRequest searchReq = new System.DirectoryServices.Protocols.SearchRequest(
                        testUserDN,
                        "(objectClass=user)",
                        System.DirectoryServices.Protocols.SearchScope.Subtree,
                        "ntSecurityDescriptor");
                    System.DirectoryServices.Protocols.SearchResponse searchRep = (System.DirectoryServices.Protocols.SearchResponse)con.SendRequest(searchReq);
                    BaseTestSite.Assert.AreEqual(
                        1,
                        searchRep.Entries[0].Attributes.Count,
                        @"Without the presence of this control, the server returns an SD only when the SD attribute name is explicitly mentioned in the requested attribute list.");
                    DirectoryAttribute attr   = searchRep.Entries[0].Attributes["ntSecurityDescriptor"];
                    object[]           values = attr.GetValues(Type.GetType("System.Byte[]"));
                    byte[]             value  = (byte[])values[0];
                    securityDescriptor.SetSecurityDescriptorBinaryForm(value);

                    //GetsSecurityDescriptorOwner method will return the owner part of Secuirty Descriptor
                    testUserOwner = Utilities.GetSecurityDescriptorOwner(securityDescriptor);

                    #endregion
                }

                using (LdapConnection con = new LdapConnection(
                           new LdapDirectoryIdentifier(addr, int.Parse(port)),
                           new NetworkCredential(operUser, userPwd, AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName)))
                {
                    #region modify the test user

                    IdentityReference testUserId = new NTAccount(testUserOwner);
                    securityDescriptor.SetOwner(testUserId);
                    byte[] value = securityDescriptor.GetSecurityDescriptorBinaryForm();

                    DirectoryAttributeModification mod = new DirectoryAttributeModification();
                    mod.Name      = "ntSecurityDescriptor";
                    mod.Operation = DirectoryAttributeOperation.Replace;
                    mod.Add(value);
                    System.DirectoryServices.Protocols.ModifyRequest modReq = new System.DirectoryServices.Protocols.ModifyRequest(testUserDN, mod);
                    try
                    {
                        System.DirectoryServices.Protocols.ModifyResponse modRep = (System.DirectoryServices.Protocols.ModifyResponse)con.SendRequest(modReq);
                        if (modRep.ResultCode == ResultCode.Success)
                        {
                            failed = false;
                        }
                    }
                    catch (DirectoryOperationException e)
                    {
                        if (e.Response.ResultCode == ResultCode.ConstraintViolation)
                        {
                            int errorCode = int.Parse(e.Response.ErrorMessage.Split(':')[0], System.Globalization.NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                            if ((Win32ErrorCode_32)errorCode == Win32ErrorCode_32.ERROR_INVALID_OWNER)
                            {
                                failed = true;
                            }
                        }
                    }

                    BaseTestSite.Assert.IsTrue(
                        failed,
                        @"Microsoft Windows Server 2008 R2 operating system and above impose a restriction on modifying the OWNER field.
                    If a modify operation attempts to set the OWNER SID to a value to which it is currently set, the operation will 
                    fail with a constraintViolation / ERROR_INVALID_OWNER unless at least one of the following conditions applies.
                    Let U be the user performing the modify operation:
                    §	U.SID equals OWNER SID.
                    §	Let G be a group in U.Groups whose SID is being set in the OWNER field. G.Attributes contains SE_GROUP_OWNER but not SE_GROUP_USE_FOR_DENY_ONLY.
                    §	U.Privileges contains SE_RESTORE_PRIVILEGE.
                    This restriction is processed before the security checks described in section 6.1.3.4.");

                    #endregion
                }
            }
            finally
            {
                using (LdapConnection con = new LdapConnection(
                           new LdapDirectoryIdentifier(addr, int.Parse(port)),
                           new NetworkCredential(AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                                                 AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                                                 AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName)))
                {
                    #region clean up

                    System.DirectoryServices.Protocols.DeleteRequest  delReq = new System.DirectoryServices.Protocols.DeleteRequest(testUserDN);
                    System.DirectoryServices.Protocols.DeleteResponse delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);
                    delReq = new System.DirectoryServices.Protocols.DeleteRequest(operUserDN);
                    delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);

                    #endregion
                }
            }
        }
        public void LDAP_AD_DS_Modify_msDS_AdditionalDNSHostName()
        {
            BaseTestSite.Assume.IsTrue(EnvironmentConfig.ServerVer >= ServerVersion.Win2012, "Server OS version should be not less than Windows Server 2012");

            AD_LDAPModelAdapter.Instance(Site).SetConnectAndBind(
                ADImplementations.AD_DS,
                AD_LDAPModelAdapter.Instance(Site).PDCNetbiosName);

            string dn = "cn=" + AD_LDAPModelAdapter.Instance(Site).testComputer1Name + ",cn=Computers," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;

            Utilities.SetAccessRights(
                dn,
                AD_LDAPModelAdapter.Instance(Site).testUserName,
                AD_LDAPModelAdapter.Instance(Site).currentWorkingDC.Domain.NetbiosName,
                ActiveDirectoryRights.WriteProperty,
                AccessControlType.Allow);
            Utilities.RemoveControlAcessRights(
                dn,
                AD_LDAPModelAdapter.Instance(Site).testUserName,
                AD_LDAPModelAdapter.Instance(Site).currentWorkingDC.Domain.NetbiosName,
                ValidatedWrite.Validated_MS_DS_Additional_DNS_Host_Name,
                ActiveDirectoryRights.Self,
                AccessControlType.Deny);
            Utilities.SetControlAcessRights(
                dn,
                AD_LDAPModelAdapter.Instance(Site).testUserName,
                AD_LDAPModelAdapter.Instance(Site).currentWorkingDC.Domain.NetbiosName,
                ValidatedWrite.Validated_MS_DS_Additional_DNS_Host_Name,
                ActiveDirectoryRights.Self,
                AccessControlType.Allow);

            DirectoryEntry entry = new DirectoryEntry(string.Format("LDAP://{0}:{1}/{2}",
                                                                    AD_LDAPModelAdapter.Instance(Site).currentWorkingDC.NetbiosName,
                                                                    AD_LDAPModelAdapter.Instance(Site).currentPort,
                                                                    dn),
                                                      AD_LDAPModelAdapter.Instance(Site).testUserName,
                                                      AD_LDAPModelAdapter.Instance(Site).testUserPwd);

            string testDNS = AD_LDAPModelAdapter.Instance(Site).testComputer1Name + "." + AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName;

            entry.Properties["msds-additionaldnshostname"].Value = testDNS;
            entry.CommitChanges();
            entry.RefreshCache();
            BaseTestSite.Assert.Pass("Should success when requestor {0} has Validated-msDS-Additional-DNS-Host-Name Extended Right on computer object {1}", AD_LDAPModelAdapter.Instance(Site).testUserName, dn);

            Utilities.RemoveControlAcessRights(
                dn,
                AD_LDAPModelAdapter.Instance(Site).testUserName,
                AD_LDAPModelAdapter.Instance(Site).currentWorkingDC.Domain.NetbiosName,
                ValidatedWrite.Validated_MS_DS_Additional_DNS_Host_Name,
                ActiveDirectoryRights.Self,
                AccessControlType.Allow);
            Utilities.SetControlAcessRights(
                dn,
                AD_LDAPModelAdapter.Instance(Site).testUserName,
                AD_LDAPModelAdapter.Instance(Site).currentWorkingDC.Domain.NetbiosName,
                ValidatedWrite.Validated_MS_DS_Additional_DNS_Host_Name,
                ActiveDirectoryRights.Self,
                AccessControlType.Deny);

            entry = new DirectoryEntry(string.Format("LDAP://{0}:{1}/{2}",
                                                     AD_LDAPModelAdapter.Instance(Site).currentWorkingDC.NetbiosName,
                                                     AD_LDAPModelAdapter.Instance(Site).currentPort,
                                                     dn),
                                       AD_LDAPModelAdapter.Instance(Site).testUserName,
                                       AD_LDAPModelAdapter.Instance(Site).testUserPwd);
            entry.Properties["msds-additionaldnshostname"].Value = testDNS;
            try
            {
                entry.CommitChanges();
                BaseTestSite.Assert.Fail("Should fail when requestor {0} does not have Validated-msDS-Additional-DNS-Host-Name Extended Right on computer object {1}", AD_LDAPModelAdapter.Instance(Site).testUser7Name, dn);
            }
            catch
            {
                BaseTestSite.Assert.Pass("Should fail when requestor {0} does not have Validated-msDS-Additional-DNS-Host-Name Extended Right on computer object {1}", AD_LDAPModelAdapter.Instance(Site).testUser7Name, dn);
            }
        }
        public void LDAP_Modify_ObjectClass_Updates()
        {
            #region variables

            bool   failed = false;
            string userDN = "CN=" + AD_LDAPModelAdapter.Instance(Site).testUser7Name + ",CN=Users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            int    errorCode;

            #endregion

            #region connect

            BaseTestSite.Assume.IsTrue(EnvironmentConfig.ServerVer >= ServerVersion.Win2003, "Server OS version should be not less than Windows Server 2003");
            LdapConnection con = new LdapConnection(new LdapDirectoryIdentifier(AD_LDAPModelAdapter.Instance(Site).PDCIPAddress),
                                                    new NetworkCredential(AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                                                                          AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                                                                          AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName));

            #endregion

            #region Modify Object Class Update for class user

            System.DirectoryServices.Protocols.ModifyRequest modReq = new System.DirectoryServices.Protocols.ModifyRequest(
                userDN,
                DirectoryAttributeOperation.Replace,
                "objectClass",
                "computer");
            System.DirectoryServices.Protocols.ModifyResponse modRep = null;
            try
            {
                modRep = (System.DirectoryServices.Protocols.ModifyResponse)con.SendRequest(modReq);
            }
            catch (DirectoryOperationException e)
            {
                if (EnvironmentConfig.ServerVer == ServerVersion.Win2003)
                {
                    if (e.Response.ResultCode == ResultCode.UnwillingToPerform)
                    {
                        errorCode = int.Parse(e.Response.ErrorMessage.Split(':')[0], System.Globalization.NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                        if ((Win32ErrorCode_32)errorCode == Win32ErrorCode_32.ERROR_DS_ILLEGAL_MOD_OPERATION)
                        {
                            failed = true;
                        }
                    }
                }
                else if (EnvironmentConfig.ServerVer >= ServerVersion.Win2008)
                {
                    if (e.Response.ResultCode == ResultCode.ObjectClassViolation)
                    {
                        errorCode = int.Parse(e.Response.ErrorMessage.Split(':')[0], System.Globalization.NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                        if ((Win32ErrorCode_32)errorCode == Win32ErrorCode_32.ERROR_DS_ILLEGAL_MOD_OPERATION)
                        {
                            failed = true;
                        }
                    }
                }
                else
                {
                    failed = false;
                }
            }
            BaseTestSite.Assert.IsTrue(
                failed,
                @"If the DC functional level is DS_BEHAVIOR_WIN2003, unwillingToPerform / ERROR_DS_ILLEGAL_MOD_OPERATION is returned.
                If the DC functional level is DS_BEHAVIOR_WIN2008 or greater, objectClassViolation / ERROR_DS_ILLEGAL_MOD_OPERATION is returned.");

            #endregion
        }
        public void LDAP_AD_DS_Modify_Constraints_DisallowedAttributes()
        {
            #region variables

            //The values of the attributes are not important, but should be complied with the attribute syntax
            string attrValue = "100";
            int    attrNum;
            int    errorCode;
            bool   failed      = false;
            string userName    = "******";
            string userDN      = "CN=" + userName + ",CN=Users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            string groupName   = "tempGroup";
            string groupDN     = "CN=" + groupName + ",CN=Users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            string testObjName = "tempObj";
            string testObjDN   = "CN=" + testObjName + ",CN=Users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;

            #endregion

            #region connect

            BaseTestSite.Assume.IsTrue(EnvironmentConfig.ServerVer >= ServerVersion.Win2012, "Server OS version should be not less than Windows Server 2012");
            string         addr = AD_LDAPModelAdapter.Instance(Site).PDCIPAddress;
            string         port = AD_LDAPModelAdapter.Instance(Site).ADDSPortNum;
            LdapConnection con  = new LdapConnection(
                new LdapDirectoryIdentifier(addr, int.Parse(port)),
                new NetworkCredential(AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                                      AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                                      AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName));
            con.SessionOptions.Sealing = false;
            con.SessionOptions.Signing = false;

            #endregion

            #region Add a user, a group and a non SAM-specific object(classStore) to test modify constraints

            if (!Utilities.IsObjectExist(userDN, addr, port))
            {
                ManagedAddRequest addReq = new ManagedAddRequest(userDN, "user");
                System.DirectoryServices.Protocols.AddResponse addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            }
            if (!Utilities.IsObjectExist(groupDN, addr, port))
            {
                ManagedAddRequest addReq = new ManagedAddRequest(groupDN, "group");
                System.DirectoryServices.Protocols.AddResponse addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            }
            if (!Utilities.IsObjectExist(testObjDN, addr, port))
            {
                ManagedAddRequest addReq = new ManagedAddRequest(testObjDN, "classStore");
                System.DirectoryServices.Protocols.AddResponse addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            }

            #endregion

            #region Modify constraint for class user
            attrNum = 15;
            System.DirectoryServices.Protocols.DirectoryAttributeModification[] modAttr1 = new DirectoryAttributeModification[attrNum];
            for (int i = 0; i < attrNum; i++)
            {
                modAttr1[i]           = new DirectoryAttributeModification();
                modAttr1[i].Operation = DirectoryAttributeOperation.Replace;
                modAttr1[i].Add(attrValue);
            }
            modAttr1[0].Name  = "badPasswordTime";
            modAttr1[1].Name  = "badPwdCount";
            modAttr1[2].Name  = "dBCSPwd";
            modAttr1[3].Name  = "lastLogoff";
            modAttr1[4].Name  = "lastLogon";
            modAttr1[5].Name  = "lastLogonTimestamp";
            modAttr1[6].Name  = "lmPwdHistory";
            modAttr1[7].Name  = "logonCount";
            modAttr1[8].Name  = "memberOf";
            modAttr1[9].Name  = "msDS-User-Account-Control-Computed";
            modAttr1[10].Name = "ntPwdHistory";
            modAttr1[11].Name = "rid";
            modAttr1[12].Name = "sAMAccountType";
            modAttr1[13].Name = "supplementalCredentials";
            modAttr1[14].Name = "isCriticalSystemObject";
            modAttr1[14].Clear();
            modAttr1[14].Add("TRUE");

            for (int i = 0; i < attrNum; i++)
            {
                System.DirectoryServices.Protocols.ModifyRequest  modReq = new System.DirectoryServices.Protocols.ModifyRequest(userDN, modAttr1[i]);
                System.DirectoryServices.Protocols.ModifyResponse modRep = null;
                try
                {
                    modRep = (System.DirectoryServices.Protocols.ModifyResponse)con.SendRequest(modReq);
                }
                catch (DirectoryOperationException e)
                {
                    if (e.Response.ResultCode == ResultCode.UnwillingToPerform)
                    {
                        errorCode = int.Parse(e.Response.ErrorMessage.Split(':')[0], System.Globalization.NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                        if ((Win32ErrorCode_32)errorCode == Win32ErrorCode_32.ERROR_DS_ATTRIBUTE_OWNED_BY_SAM)
                        {
                            failed = true;
                        }
                    }
                }
                BaseTestSite.Assert.IsTrue(
                    failed,
                    @"In AD DS, the following attributes are disallowed in a Modify for an object of class user:
                    badPasswordTime, badPwdCount, dBCSPwd, isCriticalSystemObject, lastLogoff, lastLogon, 
                    lastLogonTimestamp, lmPwdHistory, logonCount, memberOf, msDS-User-Account-Control-Computed, 
                    ntPwdHistory, objectSid, rid, sAMAccountType, and supplementalCredentials. If one of these 
                    attributes is specified in an Add, the Add returns unwillingToPerform / ERROR_DS_ATTRIBUTE_OWNED_BY_SAM.");
                failed = false;
            }

            #endregion

            #region Modify constraint for class group
            attrNum = 5;
            System.DirectoryServices.Protocols.DirectoryAttributeModification[] modAttr2 = new DirectoryAttributeModification[attrNum];
            for (int i = 0; i < attrNum; i++)
            {
                modAttr2[i]           = new DirectoryAttributeModification();
                modAttr2[i].Operation = DirectoryAttributeOperation.Replace;
                modAttr2[i].Add(attrValue);
            }
            modAttr2[0].Name = "memberOf";
            modAttr2[1].Name = "rid";
            modAttr2[1].Clear();
            modAttr2[1].Add("512");
            modAttr2[2].Name = "sAMAccountType";
            modAttr2[2].Clear();
            modAttr2[2].Add("805306370");
            modAttr2[3].Name = "userPassword";
            modAttr2[4].Name = "isCriticalSystemObject";
            modAttr2[4].Clear();
            modAttr2[4].Add("TRUE");

            for (int i = 0; i < attrNum; i++)
            {
                System.DirectoryServices.Protocols.ModifyRequest  modReq = new System.DirectoryServices.Protocols.ModifyRequest(groupDN, modAttr2[i]);
                System.DirectoryServices.Protocols.ModifyResponse modRep = null;
                try
                {
                    modRep = (System.DirectoryServices.Protocols.ModifyResponse)con.SendRequest(modReq);
                }
                catch (DirectoryOperationException e)
                {
                    if (e.Response.ResultCode == ResultCode.UnwillingToPerform)
                    {
                        errorCode = int.Parse(e.Response.ErrorMessage.Split(':')[0], System.Globalization.NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                        if ((Win32ErrorCode_32)errorCode == Win32ErrorCode_32.ERROR_DS_ATTRIBUTE_OWNED_BY_SAM)
                        {
                            failed = true;
                        }
                    }
                }
                BaseTestSite.Assert.IsTrue(
                    failed,
                    @"In AD DS, the following attributes are disallowed in a Modify for an object of class group:
                    isCriticalSystemObject, memberOf, objectSid, rid, sAMAccountType, and userPassword. 
                    If one of these attributes is specified in an Add, the Add returns unwillingToPerform / ERROR_DS_ATTRIBUTE_OWNED_BY_SAM.");
                failed = false;
            }

            #endregion

            #region Modify constraint for class not a SAM-specific object class

            attrNum = 7;
            System.DirectoryServices.Protocols.DirectoryAttributeModification[] modAttr3 = new DirectoryAttributeModification[attrNum];
            for (int i = 0; i < attrNum; i++)
            {
                modAttr3[i]           = new DirectoryAttributeModification();
                modAttr3[i].Operation = DirectoryAttributeOperation.Replace;
                modAttr3[i].Add(attrValue);
            }
            modAttr3[0].Name = "lmPwdHistory";
            modAttr3[1].Name = "ntPwdHistory";
            modAttr3[2].Name = "samAccountName";
            modAttr3[3].Name = "sAMAccountType";
            modAttr3[3].Clear();
            modAttr3[3].Add("805306370");
            modAttr3[4].Name = "supplementalCredentials";
            modAttr3[5].Name = "unicodePwd";
            modAttr3[6].Name = "isCriticalSystemObject";
            modAttr3[6].Clear();
            modAttr3[6].Add("TRUE");

            for (int i = 0; i < attrNum; i++)
            {
                System.DirectoryServices.Protocols.ModifyRequest  modReq = new System.DirectoryServices.Protocols.ModifyRequest(testObjDN, modAttr3[i]);
                System.DirectoryServices.Protocols.ModifyResponse modRep = null;
                try
                {
                    modRep = (System.DirectoryServices.Protocols.ModifyResponse)con.SendRequest(modReq);
                }
                catch (DirectoryOperationException e)
                {
                    if (e.Response.ResultCode == ResultCode.UnwillingToPerform)
                    {
                        errorCode = int.Parse(e.Response.ErrorMessage.Split(':')[0], System.Globalization.NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                        if ((Win32ErrorCode_32)errorCode == Win32ErrorCode_32.ERROR_DS_ILLEGAL_MOD_OPERATION)
                        {
                            failed = true;
                        }
                    }
                }
                BaseTestSite.Assert.IsTrue(
                    failed,
                    @"In AD DS, the following attributes are disallowed in an Add for an object whose
                    class is not a SAM-specific object class (see 3.1.1.5.2.3): isCriticalSystemObject,
                    lmPwdHistory, ntPwdHistory, objectSid, samAccountName, sAMAccountType, supplementalCredentials,
                    and unicodePwd. If one of these attributes is specified in an Add, the Add returns
                    unwillingToPerform / ERROR_DS_ILLEGAL_MOD_OPERATION.");
                failed = false;
            }

            #endregion

            #region Delete all the test user, groups and not SAM-specific objects

            System.DirectoryServices.Protocols.DeleteRequest  delReq = new System.DirectoryServices.Protocols.DeleteRequest(userDN);
            System.DirectoryServices.Protocols.DeleteResponse delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);

            delReq = new System.DirectoryServices.Protocols.DeleteRequest(groupDN);
            delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);

            delReq = new System.DirectoryServices.Protocols.DeleteRequest(testObjDN);
            delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);

            #endregion
        }
        public void LDAP_AD_DS_Modify_Constraints_MultipleDescriptions()
        {
            #region variables

            string userName = "******";
            string userDN   = "CN=" + userName + ",CN=users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC;
            int    errorCode;
            bool   failed = false;

            #endregion

            #region connect

            BaseTestSite.Assume.IsTrue(EnvironmentConfig.ServerVer >= ServerVersion.Win2012, "Server OS version should be not less than Windows Server 2012");
            string         addr = AD_LDAPModelAdapter.Instance(Site).PDCIPAddress;
            string         port = AD_LDAPModelAdapter.Instance(Site).ADDSPortNum;
            LdapConnection con  = new LdapConnection(new LdapDirectoryIdentifier(addr, int.Parse(port)),
                                                     new NetworkCredential(AD_LDAPModelAdapter.Instance(Site).DomainAdministratorName,
                                                                           AD_LDAPModelAdapter.Instance(Site).DomainUserPassword,
                                                                           AD_LDAPModelAdapter.Instance(Site).PrimaryDomainDnsName));
            con.SessionOptions.Sealing = false;
            con.SessionOptions.Signing = false;

            #endregion

            #region Add an object for modify constraint test

            if (!Utilities.IsObjectExist(userDN, addr, port))
            {
                ManagedAddRequest addReq = new ManagedAddRequest(userDN, "user");
                System.DirectoryServices.Protocols.AddResponse addRep = (System.DirectoryServices.Protocols.AddResponse)con.SendRequest(addReq);
            }

            #endregion

            #region Modify constraint for class user

            System.DirectoryServices.Protocols.ModifyRequest modReq = new System.DirectoryServices.Protocols.ModifyRequest(
                userDN,
                DirectoryAttributeOperation.Add,
                "description",
                new string[] { "aaa", "bbb" });
            System.DirectoryServices.Protocols.ModifyResponse modRep = null;
            try
            {
                modRep = (System.DirectoryServices.Protocols.ModifyResponse)con.SendRequest(modReq);
            }
            catch (DirectoryOperationException e)
            {
                if (e.Response.ResultCode == ResultCode.AttributeOrValueExists)
                {
                    errorCode = int.Parse(e.Response.ErrorMessage.Split(':')[0], System.Globalization.NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                    if ((Win32ErrorCode_32)errorCode == Win32ErrorCode_32.ERROR_DS_SINGLE_VALUE_CONSTRAINT)
                    {
                        failed = true;
                    }
                }
            }
            BaseTestSite.Assert.IsTrue(
                failed,
                @"If the modify operation adds or replaces values of the description attribute on a SAM-specific object
                    (section 3.1.1.5.2.3), and results in more than one value in the attribute, then the modification fails 
                    with attributeOrValueExists / ERROR_DS_SINGLE_VALUE_CONSTRAINT.");

            #endregion

            #region Delete the user for modify test

            System.DirectoryServices.Protocols.DeleteRequest delReq = new System.DirectoryServices.Protocols.DeleteRequest(
                "CN=testModifyConstraints,CN=users," + AD_LDAPModelAdapter.Instance(Site).rootDomainNC);
            System.DirectoryServices.Protocols.DeleteResponse delRep = (System.DirectoryServices.Protocols.DeleteResponse)con.SendRequest(delReq);

            #endregion
        }