public void ModifyDNOperation()

in TestSuites/ADFamily/src/Adapter/MS-ADTS-LDAP/AD_LDAPModelAdapter.cs [5112:5920]


        public void ModifyDNOperation(
            IList<string> oldDN_newDN_deleteOldRDN,
            RightsOnObjects rightsOnOldObject, //rightsOnObject
            RightsOnParentObjects rightsOnNewObjectParent, //accessRights
            RightOnOldParentObject rightsOnOldObjectParent, //ParentRights
            bool isLDAPBindWithDelegationEnabled,
            string control,
            ServerVersion dcLevel,
            bool isRODC,
            out ConstrOnModDNOpErrs errorStatus)
        {

            #region Variables

            errorStatus = ConstrOnModDNOpErrs.Success;

            ICollection<AdtsSearchResultEntryPacket> searchResponse;
            string[] searchAttrVals = null;

            string oldObjectDN = string.Empty;
            SecurityIdentifier oldObjectSid = null;
            string oldObjectParentDn = string.Empty;

            string newObjectDN = string.Empty;
            SecurityIdentifier newObjectSid = null;
            string newObjectRDN = string.Empty;
            string newObjectParentDN = string.Empty;

            string newContainerCN = string.Empty;
            string newContainerName = string.Empty;

            bool deleteOldObjectRDN;
            int index;
            SearchResult tombStoneResult = null;
            string tombStoneName = string.Empty;

            #endregion

            #region Connect and Bind

            if (isConnected == false)
            {
                if (isRODC)
                {
                    SetConnectAndBind(ADImplementations.AD_DS, RODCNetbiosName);
                }
                else
                {
                    SetConnectAndBind(ADImplementations.AD_DS, PDCNetbiosName);
                }
            }

            #endregion

            #region Tombstone Requirements (the modifyDN operations on tombstone objects MUST fail)

            #region Create a new tombstone object

            //Add a new object into AD.
            List<DirectoryAttribute> atts = new List<DirectoryAttribute>();
            atts.Add(new DirectoryAttribute("objectClass:user"));
            atts.Add(new DirectoryAttribute("samAccountName: TempObj"));
            adLdapClient.AddObject("CN=TempObj,CN=Users," + rootDomainNC, atts, null);
            //Delete the new object
            adLdapClient.DeleteObject("CN=TempObj,CN=Users," + rootDomainNC, null);
            //Search for deleted object
            tombStoneResult = Utilities.GetTombstone(
                Utilities.BuildDeletedEntry(
                string.Format("{0}:{1}", currentWorkingDC.FQDN, currentPort),
                DELETED_OBJECTS_CONTAINER_GUID,
                rootDomainNC),
                "TempObj");
            if (tombStoneResult != null)
            {
                foreach (string key in tombStoneResult.Properties.PropertyNames)
                {
                    foreach (object value in tombStoneResult.Properties[key])
                    {
                        if (key.ToLower(CultureInfo.InvariantCulture) == "distinguishedname")
                        {
                            tombStoneName = value.ToString();
                            break;
                        }
                    }
                }
            }

            #endregion

            if (!(string.IsNullOrEmpty(tombStoneName)))
            {
                tombStoneName = tombStoneName.Replace("\0", "\\0");
                index = tombStoneName.IndexOf('\\');

                #region IntraDomainModifyDN on the new tombstone object

                if (string.IsNullOrEmpty(control))
                {
                    result = adLdapClient.IntraDomainModifyDn(
                        tombStoneName,
                        "CN=Users," + rootDomainNC,
                        tombStoneName.Remove(index),
                        true,
                        null,
                        isWindows);
                    if (currentWorkingDC.OSVersion.Equals(ServerVersion.NonWin))
                    {
                        Site.CaptureRequirementIfAreEqual<string>(
                            ConstrOnModDNOpErrs.UnwillingToPerform_UnKnownError.ToString(),
                            result + "_UnKnownError",
                            812,
                            @"For the Modify DN operation, if O!isDeleted = true, then the server returns error unwillingToPerform / ERROR_DS_ILLEGAL_MOD_OPERATION.");
                    }
                    else
                    {
                        Site.CaptureRequirementIfAreEqual<string>(
                            ConstrOnModDNOpErrs.UnwillingToPerform_ERROR_DS_ILLEGAL_MOD_OPERATION.ToString(),
                            result,
                            812,
                            @"For the Modify DN operation, if O!isDeleted = true, then the server returns error unwillingToPerform / ERROR_DS_ILLEGAL_MOD_OPERATION.");
                    }
                }

                #endregion

                #region CrossDomainModifyDN on the new tombstone object

                else if (control == ExtendedControl.LDAP_SERVER_CROSSDOM_MOVE_TARGET_OID)
                {
                    if (currentWorkingDC.OSVersion >= ServerVersion.Win2003)
                    {
                        result = adLdapClient.CrossDomainModifyDN(
                            tombStoneName,
                            "CN=Users," + rootDomainNC,
                            tombStoneName.Remove(index),
                            true,
                            CDCNetbiosName + '.' + ChildDomainDnsName,
                            null,
                            isWindows);
                        if (currentWorkingDC.OSVersion.Equals(ServerVersion.NonWin))
                        {
                            Site.CaptureRequirementIfAreEqual<string>(
                                ConstrOnModDNOpErrs.UnwillingToPerform_UnKnownError.ToString(),
                                result + "_UnKnownError",
                                862,
                                @"During cross-domain move operation, if (O!isDeleted = true), then the server returns error unwillingToPerform / ERROR_DS_CANT_MOVE_DELETED_OBJECT.");
                        }
                        else
                        {
                            Site.CaptureRequirementIfAreEqual<string>(
                                ConstrOnModDNOpErrs.UnwillingToPerform_ERROR_DS_CANT_MOVE_DELETED_OBJECT.ToString(),
                                result,
                                862,
                                @"During cross-domain move operation, if (O!isDeleted = true), then the server returns error unwillingToPerform / ERROR_DS_CANT_MOVE_DELETED_OBJECT.");
                        }
                        Site.CaptureRequirement(
                            1205,
                            @"The LDAP extended control LDAP_SERVER_CROSSDOM_MOVE_TARGET_OID is supported in Windows 2000, Windows Server 2003,
                            Windows Server 2003 SP1 and Windows Server 2008, Windows Server 2008 R2.");
                    }
                }

                #endregion
            }

            #endregion

            #region Get oldObjectDN, oldObjectParentDN and newObjectDN, newObjectRDN, newObjectParentDN

            // distinguishedNames[0] => old object DN, old object ParentDN
            // distinguishedNames[1] => new object DN, new object ParentDN
            // distinguishedNames[2] => whether to deleted old RDN
            string[] distinguishedNames = oldDN_newDN_deleteOldRDN.ToArray();
            string childDomainNetbios = string.Format("{0}$", ChildDomainNetBiosName.ToUpper());

            if (control == ExtendedControl.LDAP_SERVER_CROSSDOM_MOVE_TARGET_OID)
            {
                distinguishedNames[0] = distinguishedNames[0].Replace("LDAPCHILD$", childDomainNetbios);
                distinguishedNames[1] = distinguishedNames[1].Replace("LDAPCHILD$", childDomainNetbios);
            }

            // oldObjectDN
            // for example, null => old object is already at the top of the nc tree, no parent
            if (distinguishedNames[0].ToLower(CultureInfo.InvariantCulture).Contains("null"))
            {
                oldObjectDN = null;
                oldObjectParentDn = null;
            }
            // for example, CN=Sample,DC=adts88
            else
            {
                if (string.IsNullOrEmpty(control))
                {
                    oldObjectDN = distinguishedNames[0].Replace("DC=adts88", rootDomainNC);
                    index = distinguishedNames[0].IndexOf(',');
                    oldObjectParentDn = distinguishedNames[0].Remove(0, index + 1).Replace("DC=adts88", rootDomainNC);
                }
                else if (control == ExtendedControl.LDAP_SERVER_CROSSDOM_MOVE_TARGET_OID)
                {
                    oldObjectDN = distinguishedNames[0].Replace("DC=LDAP,DC=com", rootDomainNC);
                    index = distinguishedNames[0].IndexOf(',');
                    oldObjectParentDn = distinguishedNames[0].Remove(0, index + 1).Replace("DC=LDAP,DC=com", rootDomainNC);
                }
            }

            // newObjectDN
            // for example, CN=Sample,null => meaning the object is at the top of the nc tree, no parent
            if (distinguishedNames[1].Split('=')[1].Contains(","))
            {
                if (distinguishedNames[1].Split(',')[1].Trim().Equals("null", StringComparison.OrdinalIgnoreCase))
                {
                    newObjectDN = distinguishedNames[1].Replace("DC=adts88", rootDomainNC);
                    newObjectRDN = newObjectDN.Split(',')[0].Trim();
                    newObjectParentDN = null;
                }
                if (distinguishedNames[1].Split(',')[0].Trim().Equals("null", StringComparison.OrdinalIgnoreCase))
                {
                    newObjectRDN = null;
                    index = distinguishedNames[1].IndexOf(',');
                    newObjectParentDN = distinguishedNames[1].Remove(0, index + 1).Replace("DC=adts88", rootDomainNC);
                }
            }
            // for example, CN=Sample,DC=adts88
            if (!(distinguishedNames[1].ToLower(CultureInfo.InvariantCulture).Contains("null")))
            {
                if (string.IsNullOrEmpty(control))
                {
                    newObjectDN = distinguishedNames[1].Replace("DC=adts88", rootDomainNC);
                    newObjectRDN = newObjectDN.Split(',')[0].Trim();
                    index = distinguishedNames[1].IndexOf(',');
                    newObjectParentDN = distinguishedNames[1].Remove(0, index + 1).Replace("DC=adts88", rootDomainNC);
                }
                if (control == ExtendedControl.LDAP_SERVER_CROSSDOM_MOVE_TARGET_OID)
                {
                    // target domain is child domain
                    if (distinguishedNames[1].ToUpper(CultureInfo.InvariantCulture).Contains("LDAPCHILD"))
                    {
                        newObjectDN = distinguishedNames[1].Replace("DC=LDAPCHILD,DC=LDAP,DC=com", childDomainNC);
                        newObjectRDN = newObjectDN.Split(',')[0].Trim();
                        index = distinguishedNames[1].IndexOf(',');
                        newObjectParentDN = distinguishedNames[1].Remove(0, index + 1).Replace(
                            "DC=LDAPCHILD,DC=LDAP,DC=com",
                            childDomainNC);
                    }
                    else
                    {
                        newObjectDN = distinguishedNames[1].Replace("DC=LDAP,DC=com", rootDomainNC);
                        newObjectRDN = newObjectDN.Split(',')[0].Trim();
                        index = distinguishedNames[1].IndexOf(',');
                        newObjectParentDN = distinguishedNames[1].Remove(0, index + 1).Replace("DC=LDAP,DC=com", rootDomainNC);
                    }
                }
            }
            // true => delete old object RDN, false => do not delete
            if (distinguishedNames[2].ToLower(CultureInfo.InvariantCulture).Equals("true"))
            {
                deleteOldObjectRDN = true;
            }
            else
            {
                deleteOldObjectRDN = false;
            }

            #endregion

            #region Set access rights for testuser on oldObjectDN and newObjectDN and their parentDNs

            if (oldObjectDN != null
                && !newObjectDN.ToLower(CultureInfo.InvariantCulture).Contains("null"))
            {
                if (oldObjectDN.ToLower(CultureInfo.InvariantCulture).Contains("CN=Users".ToLower(CultureInfo.InvariantCulture))
                    && !oldObjectDN.ToLower(CultureInfo.InvariantCulture).Contains("NonExistingObject".ToLower(CultureInfo.InvariantCulture)))
                {
                    #region Remove rights of the requester for the old object DN, will add these rights back after object move

                    if ((rightsOnOldObject == RightsOnObjects.RIGHT_DS_WRITE_PROPERTYWithOutRIGHT_DELETE)
                        || (rightsOnOldObject == RightsOnObjects.INVALID_RIGHT))
                    {
                        // Both IntraDomainModifyDN and CrossDomainModifyDN
                        Utilities.SetAccessRights(
                            oldObjectDN,
                            testUserName,
                            PrimaryDomainDnsName,
                            ActiveDirectoryRights.Delete,
                            AccessControlType.Deny);

                        // IntraDomainModifyDN
                        if (string.IsNullOrEmpty(control))
                        {
                            Utilities.SetAccessRights(
                                oldObjectDN,
                                testUserName,
                                PrimaryDomainDnsName,
                                ActiveDirectoryRights.WriteProperty,
                                AccessControlType.Deny);
                        }
                    }

                    #endregion

                    #region Remove rights of the requester for the old object parent DN and new object parent DN

                    // IntraDomainModifyDN
                    if (string.IsNullOrEmpty(control))
                    {
                        if (!((rightsOnNewObjectParent == RightsOnParentObjects.RIGHT_DS_CREATE_CHILD)
                            && (rightsOnOldObjectParent == RightOnOldParentObject.RIGHT_DS_DELETE_CHILD))
                            && (oldObjectParentDn.ToLower(CultureInfo.InvariantCulture) != newObjectParentDN.ToLower(CultureInfo.InvariantCulture))
                            && !newObjectParentDN.ToLower(CultureInfo.InvariantCulture).Contains("NonExistingParent".ToLower(CultureInfo.InvariantCulture)))
                        {
                            Utilities.SetAccessRights(
                                oldObjectParentDn,
                                testUserName,
                                PrimaryDomainDnsName,
                                ActiveDirectoryRights.DeleteChild,
                                AccessControlType.Deny);
                            Utilities.SetAccessRights(
                                newObjectParentDN,
                                testUserName,
                                PrimaryDomainDnsName,
                                ActiveDirectoryRights.CreateChild,
                                AccessControlType.Deny);
                        }
                    }
                    // CrossDomainModifyDN
                    else if (control == ExtendedControl.LDAP_SERVER_CROSSDOM_MOVE_TARGET_OID)
                    {
                        if (rightsOnOldObjectParent == RightOnOldParentObject.INVALID_RIGHT)
                        {
                            Utilities.SetAccessRights(
                                oldObjectParentDn,
                                testUserName,
                                PrimaryDomainDnsName,
                                ActiveDirectoryRights.DeleteChild,
                                AccessControlType.Deny);
                        }
                    }

                    #endregion
                }
            }

            #endregion

            #region ModifyDN Operations

            #region IntraDomainModifyDN Operation

            // IntraDomainModifyDN
            if (string.IsNullOrEmpty(control))
            {
                #region Get container name before performing IntraDomainModifyDN

                if (!distinguishedNames[0].ToLower(CultureInfo.InvariantCulture).Contains("NonExistingObject".ToLower(CultureInfo.InvariantCulture)))
                {
                    result = adLdapClient.SearchObject(
                        "CN=TestContainerALLOWRENAME," + configurationNC,
                        System.DirectoryServices.Protocols.SearchScope.Subtree,
                        "(objectClass=container)",
                        new string[] { "name" },
                        null,
                        out searchResponse);
                    Site.Assert.IsTrue(result.ToLower().Contains("success"),
                        string.Format("Search operation on {0} should be successful, actual result: {1}", "CN=TestContainerALLOWRENAME," + configurationNC, result));
                    if (searchResponse != null)
                    {
                        foreach (AdtsSearchResultEntryPacket entrypacket in searchResponse)
                        {
                            searchAttrVals = adLdapClient.GetAttributeValuesInString(entrypacket, "name");
                            Site.Log.Add(LogEntryKind.Debug, string.Format("name={0}", searchAttrVals[0]));
                        }
                    }
                }

                #endregion

                result = adLdapClient.IntraDomainModifyDn(
                    oldObjectDN,
                    newObjectParentDN,
                    newObjectRDN,
                    deleteOldObjectRDN,
                    null,
                    isWindows);
            }

            #endregion

            #region CrossDomainModifyDN Operation

            // CrossDomainModifyDN
            else if (control == ExtendedControl.LDAP_SERVER_CROSSDOM_MOVE_TARGET_OID)
            {
                //Search for the object SID

                #region Get old objectSid before performing CrossDomainModifyDN

                if (oldObjectDN != null && newObjectParentDN != null)
                {
                    result = adLdapClient.SearchObject(
                        oldObjectDN,
                        System.DirectoryServices.Protocols.SearchScope.Subtree,
                        "(objectClass=user)",
                        new string[] { "objectSid" },
                        null,
                        out searchResponse,
                        isWindows);
                    Site.Assert.IsTrue(result.ToLower().Contains("success"),
                            string.Format("Search operation on {0} should be successful, actual result: {1}", oldObjectDN, result));
                    if (searchResponse != null)
                    {
                        foreach (AdtsSearchResultEntryPacket entrypacket in searchResponse)
                        {
                            searchAttrVals = adLdapClient.GetAttributeValuesInString(entrypacket, "objectSid");
                            oldObjectSid = new SecurityIdentifier(Encoding.ASCII.GetBytes(searchAttrVals[0]), 0);
                            Site.Log.Add(LogEntryKind.Debug, string.Format("objectSid={0}", oldObjectSid.Value.ToString()));
                        }
                    }
                }

                #endregion

                #region If LDAP binding is not delegation enabled => connect and bind again with basic authentication type

                // Cross-domain move is not supported by AD LDS
                Site.Assert.AreEqual(ADDSPortNum, currentPort, "The currently connected port should be AD DS port {0}. Cross-domain move is not supported by AD LDS.", ADDSPortNum);

                // The requester must have performed a Kerberos LDAP bind with delegation enabled (see [RFC4120] section 2.8).

                if (!isLDAPBindWithDelegationEnabled)
                {
                    // if LDAP bind with delegation is not enabled, should reconnect with no ok-as-delegation flag set
                    // or remove the A2DF on service account
                    adLdapClient.ConnectAndBind(
                        currentWorkingDC.NetbiosName,
                        currentWorkingDC.IPAddress,
                        int.Parse(currentPort),
                        testUserName,
                        testUserPwd,
                        currentWorkingDC.Domain.NetbiosName,
                        AuthType.Ntlm);
                }

                #endregion

                result = adLdapClient.CrossDomainModifyDN(
                    oldObjectDN,
                    newObjectParentDN,
                    newObjectRDN,
                    deleteOldObjectRDN,
                    CDCNetbiosName + '.' + ChildDomainDnsName,
                    null,
                    isWindows);
            }

            #endregion

            if (!isWindows)
            {
                #region Switch ErrorStatus Non-Windows

                switch (result)
                {
                    case "UnwillingToPerform":
                        errorStatus = ConstrOnModDNOpErrs.UnwillingToPerform_UnKnownError;
                        break;
                    case "InsufficientAccessRights":
                        errorStatus = ConstrOnModDNOpErrs.InsufficientAccessRights_UnKnownError;
                        break;
                    case "EntryAlreadyExists":
                        errorStatus = ConstrOnModDNOpErrs.EntryAlreadyExists_UnKnownError;
                        break;
                    case "InvalidDNSyntax":
                        errorStatus = ConstrOnModDNOpErrs.InvalidDNSyntax_UnKnownError;
                        break;
                    case "Other":
                        errorStatus = ConstrOnModDNOpErrs.Other_UnKnownError;
                        break;
                    case "ProtocolError":
                        errorStatus = ConstrOnModDNOpErrs.ProtocolError_UnKnownError;
                        break;
                    case "NoSuchObject":
                        errorStatus = ConstrOnModDNOpErrs.NoSuchObject_UnKnownError;
                        break;
                    case "NotAllowedOnNonLeaf":
                        errorStatus = ConstrOnModDNOpErrs.NotAllowedOnNonLeaf_UnKnownError;
                        break;
                    case "InappropriateAuthentication":
                        errorStatus = ConstrOnModDNOpErrs.InappropriateAuthentication_UnKnownError;
                        break;
                    case "Success":
                        errorStatus = ConstrOnModDNOpErrs.Success;
                        break;
                    default:
                        errorStatus = ConstrOnModDNOpErrs.UnSpecifiedError;
                        break;
                }

                #endregion
            }
            else
            {
                #region Switch ErrorStatus Windows

                switch (result)
                {
                    case "UnwillingToPerform_ERROR_DS_ILLEGAL_MOD_OPERATION":
                        errorStatus = ConstrOnModDNOpErrs.UnwillingToPerform_ERROR_DS_ILLEGAL_MOD_OPERATION;
                        break;
                    case "UnwillingToPerform_ERROR_DS_CANT_DELETE":
                        errorStatus = ConstrOnModDNOpErrs.UnwillingToPerform_ERROR_DS_CANT_DELETE;
                        break;
                    case "InsufficientAccessRights_UnKnownError":
                        errorStatus = ConstrOnModDNOpErrs.InsufficientAccessRights_UnKnownError;
                        break;
                    case "EntryAlreadyExists_UnKnownError":
                        errorStatus = ConstrOnModDNOpErrs.EntryAlreadyExists_UnKnownError;
                        break;
                    case "InvalidDNSyntax_UnKnownError":
                        errorStatus = ConstrOnModDNOpErrs.InvalidDNSyntax_UnKnownError;
                        break;
                    case "Other_ERROR_DS_NO_PARENT_OBJECT":
                        errorStatus = ConstrOnModDNOpErrs.Other_ERROR_DS_NO_PARENT_OBJECT;
                        break;
                    case "ProtocolError_ERROR_INVALID_PARAMETER":
                        errorStatus = ConstrOnModDNOpErrs.ProtocolError_ERROR_INVALID_PARAMETER;
                        break;
                    case "UnwillingToPerform_ERROR_INVALID_PARAMETER":
                        errorStatus = ConstrOnModDNOpErrs.UnwillingToPerform_ERROR_INVALID_PARAMETER;
                        break;
                    case "NoSuchObject_ERROR_DS_OBJ_NOT_FOUND":
                        errorStatus = ConstrOnModDNOpErrs.NoSuchObject_ERROR_DS_OBJ_NOT_FOUND;
                        break;
                    case "Other_ERROR_DS_DISALLOWED_IN_SYSTEM_CONTAINER":
                        errorStatus = ConstrOnModDNOpErrs.Other_ERROR_DS_DISALLOWED_IN_SYSTEM_CONTAINER;
                        break;
                    case "UnwillingToPerform_ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION":
                        errorStatus = ConstrOnModDNOpErrs.UnwillingToPerform_ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION;
                        break;
                    case "UnwillingToPerform_ERROR_DS_CANT_MOVE_ACCOUNT_GROUP":
                        errorStatus = ConstrOnModDNOpErrs.UnwillingToPerform_ERROR_DS_CANT_MOVE_ACCOUNT_GROUP;
                        break;
                    case "UnwillingToPerform_ERROR_DS_CANT_MOVE_RESOURCE_GROUP":
                        errorStatus = ConstrOnModDNOpErrs.UnwillingToPerform_ERROR_DS_CANT_MOVE_RESOURCE_GROUP;
                        break;
                    case "UnwillingToPerform_ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD":
                        errorStatus = ConstrOnModDNOpErrs.UnwillingToPerform_ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD;
                        break;
                    case "UnwillingToPerform_ERROR_DS_CANT_MOVE_APP_QUERY_GROUP":
                        errorStatus = ConstrOnModDNOpErrs.UnwillingToPerform_ERROR_DS_CANT_MOVE_APP_QUERY_GROUP;
                        break;
                    case "InvalidDNSyntax_ERROR_DS_SRC_AND_DST_NC_IDENTICAL":
                        errorStatus = ConstrOnModDNOpErrs.InvalidDNSyntax_ERROR_DS_SRC_AND_DST_NC_IDENTICAL;
                        break;
                    case "NotAllowedOnNonLeaf_ERROR_DS_CHILDREN_EXIST":
                        errorStatus = ConstrOnModDNOpErrs.NotAllowedOnNonLeaf_ERROR_DS_CHILDREN_EXIST;
                        break;
                    case "UnwillingToPerform_ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS":
                        errorStatus = ConstrOnModDNOpErrs.UnwillingToPerform_ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS;
                        break;
                    case "NoSuchObject_ERROR_DS_CANT_FIND_EXPECTED_NC":
                        errorStatus = ConstrOnModDNOpErrs.NoSuchObject_ERROR_DS_CANT_FIND_EXPECTED_NC;
                        break;
                    case "InappropriateAuthentication_UnKnownError":
                        errorStatus = ConstrOnModDNOpErrs.InappropriateAuthentication_UnKnownError;
                        break;
                    case "UnwillingToPerform_ERROR_DS_MODIFYDN_DISALLOWED_BY_FLAG":
                        errorStatus = ConstrOnModDNOpErrs.UnwillingToPerform_ERROR_DS_MODIFYDN_DISALLOWED_BY_FLAG;
                        break;
                    case "Success_STATUS_SUCCESS":
                        errorStatus = ConstrOnModDNOpErrs.Success;
                        break;
                    default:
                        errorStatus = ConstrOnModDNOpErrs.UnSpecifiedError;
                        break;
                }

                #endregion
            }

            if (isRODC
                && result.ToLower(CultureInfo.InvariantCulture).Contains("NoSuchObject".ToLower(CultureInfo.InvariantCulture)))
            {
                errorStatus = ConstrOnModDNOpErrs.NoSuchObject_UnKnownError;
            }
            if ((errorStatus != ConstrOnModDNOpErrs.Success)
                && (oldDN_newDN_deleteOldRDN.Contains("CN=BCKUPKEY_P Secret,CN=System,DC=adts88")
                || oldDN_newDN_deleteOldRDN.Contains("CN=LostAndFound,DC=adts88")
                || oldDN_newDN_deleteOldRDN.Contains("CN=TestContainerWithoutSysFlags,CN=DisplaySpecifiers,CN=Configuration,DC=adts88")))
            {
                errorStatus = ConstrOnModDNOpErrs.UnwillingToPerform_UnKnownError;
            }
            if ((errorStatus != ConstrOnModDNOpErrs.Success)
                && (oldDN_newDN_deleteOldRDN.Contains("CN=TestUser4,CN=Computers,DC=adts88")))
            {
                errorStatus = ConstrOnModDNOpErrs.EntryAlreadyExists_UnKnownError;
            }

            #endregion

            #region Requirements on ModifyDN Operations

            if (errorStatus.Equals(ConstrOnModDNOpErrs.Success))
            {
                // IntraDomainModifyDN
                if (string.IsNullOrEmpty(control))
                {
                    #region Search container name after performing IntraDomainModifyDN

                    result = adLdapClient.SearchObject(
                        "CN=TestContainerALLOWRENAME1," + configurationNC,
                        System.DirectoryServices.Protocols.SearchScope.Subtree,
                        "(objectClass=container)",
                        new string[] { "cn", "name" },
                        null,
                        out searchResponse,
                        isWindows);
                    if (searchResponse != null)
                    {
                        foreach (AdtsSearchResultEntryPacket entrypacket in searchResponse)
                        {
                            searchAttrVals = adLdapClient.GetAttributeValuesInString(entrypacket, "cn");
                            Site.Log.Add(LogEntryKind.Debug, string.Format("cn={0}", searchAttrVals[0]));
                            newContainerCN = searchAttrVals[0];

                            searchAttrVals = adLdapClient.GetAttributeValuesInString(entrypacket, "name");
                            Site.Log.Add(LogEntryKind.Debug, string.Format("name={0}", searchAttrVals[0]));
                            newContainerName = searchAttrVals[0];
                        }
                        if (oldObjectParentDn == newObjectParentDN)
                        {
                            Site.CaptureRequirementIfAreEqual<string>(
                                newContainerCN,
                                newContainerName,
                                35,
                                @"An object's value of name attribute equals the value of the object's RDN attribute.
                                Even if an object is renamed (LDAP Modify DN), the object's name attribute remains equal to the object's RDN attribute.");
                        }
                    }

                    #endregion
                }
                // CrossDomainModifyDN
                else if (control == ExtendedControl.LDAP_SERVER_CROSSDOM_MOVE_TARGET_OID)
                {
                    currentWorkingDC = GetDomainController(CDCNetbiosName);
                    currentPort = ADDSPortNum;
                    adLdapClient.ConnectAndBind(
                        currentWorkingDC.NetbiosName,
                        currentWorkingDC.IPAddress,
                        int.Parse(currentPort),
                        childAdminName,
                        childAdminPwd,
                        ChildDomainDnsName,
                        AuthType.Basic);

                    #region Target domain controller name for LDAP_SERVER_CROSSDOM_MOVE_TARGET_OID control

                    Site.CaptureRequirementIfIsNotNull(
                        CDCNetbiosName + '.' + ChildDomainDnsName,
                        831,
                        @"The controlValue field of LDAP_SERVER_CROSSDOM_MOVE_TARGET_OID control has the DNS hostname of the target DC 
                    that must be used as a helper to perform cross domain move.");

                    #endregion

                    #region Get newObjectSid after performing CrossDomainModifyDN, should not be the same with oldObjectSid

                    if (oldObjectDN != null && newObjectParentDN != null)
                    {
                        result = adLdapClient.SearchObject(
                            newObjectDN,
                            System.DirectoryServices.Protocols.SearchScope.Subtree,
                            "(objectClass=user)",
                            new string[] { "objectSid" },
                            null,
                            out searchResponse,
                            isWindows);
                        Site.Assert.IsTrue(result.ToLower().Contains("success"),
                            string.Format("Search operation on {0} should be successful, actual result: {1}", newObjectDN, result));
                        if (searchResponse != null)
                        {
                            foreach (AdtsSearchResultEntryPacket entrypacket in searchResponse)
                            {
                                searchAttrVals = adLdapClient.GetAttributeValuesInString(entrypacket, "objectSid");
                                newObjectSid = new SecurityIdentifier(Encoding.ASCII.GetBytes(searchAttrVals[0]), 0);
                                Site.Log.Add(LogEntryKind.Debug, string.Format("objectSid={0}", newObjectSid.Value.ToString()));
                                Site.CaptureRequirementIfAreNotEqual<SecurityIdentifier>(
                                    newObjectSid,
                                    oldObjectSid,
                                    30,
                                    @"During LDAP Add operation, once a fresh SID is assigned to the objectSid attribute of a security 
                                principal object, this attribute can be writable, if the object is moved to another NC 
                                (LDAP Modify DN; see section 3.1.1.5 for the specification of such moves).");
                            }
                        }
                    }

                    #endregion
                }
            }

            #endregion

            #region Set access rights back for testuser on old and new objectDN and their parents

            if (!errorStatus.Equals(ConstrOnModDNOpErrs.Success))
            {
                if (oldObjectDN != null
                    && !newObjectDN.ToLower(CultureInfo.InvariantCulture).Contains("null"))
                {
                    if (oldObjectDN.ToLower(CultureInfo.InvariantCulture).Contains("CN=Users".ToLower(CultureInfo.InvariantCulture))
                        && !oldObjectDN.ToLower(CultureInfo.InvariantCulture).Contains("NonExistingObject".ToLower(CultureInfo.InvariantCulture)))
                    {
                        #region Set access rights back for old object DN

                        // Both IntraDomainModifyDN and CrossDomainModifyDN
                        Utilities.RemoveAccessRights(
                            oldObjectDN,
                            testUserName,
                            PrimaryDomainDnsName,
                            ActiveDirectoryRights.Delete,
                            AccessControlType.Deny);
                        Utilities.SetAccessRights(
                            oldObjectDN,
                            testUserName,
                            PrimaryDomainDnsName,
                            ActiveDirectoryRights.Delete,
                            AccessControlType.Allow);

                        // IntraDomainModifyDN
                        if (string.IsNullOrEmpty(control))
                        {
                            Utilities.RemoveAccessRights(
                                oldObjectDN,
                                testUserName,
                                PrimaryDomainDnsName,
                                ActiveDirectoryRights.WriteProperty,
                                AccessControlType.Deny);
                            Utilities.SetAccessRights(
                                oldObjectDN,
                                testUserName,
                                PrimaryDomainDnsName,
                                ActiveDirectoryRights.WriteProperty,
                                AccessControlType.Allow);
                        }

                        #endregion

                        #region Set access rights back for old object parent DN and new object parent DN

                        // IntraDomainModifyDN
                        if (string.IsNullOrEmpty(control))
                        {
                            if (!newObjectParentDN.ToLower(CultureInfo.InvariantCulture).Contains("NonExistingParent".ToLower(CultureInfo.InvariantCulture)))
                            {
                                Utilities.RemoveAccessRights(
                                    oldObjectParentDn,
                                    testUserName,
                                    PrimaryDomainDnsName,
                                    ActiveDirectoryRights.DeleteChild,
                                    AccessControlType.Deny);
                                Utilities.SetAccessRights(
                                    oldObjectParentDn,
                                    testUserName,
                                    PrimaryDomainDnsName,
                                    ActiveDirectoryRights.DeleteChild,
                                    AccessControlType.Allow);
                                Utilities.RemoveAccessRights(
                                    newObjectParentDN,
                                    testUserName,
                                    PrimaryDomainDnsName,
                                    ActiveDirectoryRights.CreateChild,
                                    AccessControlType.Deny);
                                Utilities.SetAccessRights(
                                    newObjectParentDN,
                                    testUserName,
                                    PrimaryDomainDnsName,
                                    ActiveDirectoryRights.CreateChild,
                                    AccessControlType.Allow);
                            }
                        }

                        // CrossDomainModifyDN
                        else if (control == ExtendedControl.LDAP_SERVER_CROSSDOM_MOVE_TARGET_OID)
                        {
                            if (rightsOnOldObjectParent == RightOnOldParentObject.INVALID_RIGHT)
                            {
                                Utilities.RemoveAccessRights(
                                    oldObjectParentDn,
                                    testUserName,
                                    PrimaryDomainDnsName,
                                    ActiveDirectoryRights.DeleteChild,
                                    AccessControlType.Deny);
                                Utilities.SetAccessRights(
                                    oldObjectParentDn,
                                    testUserName,
                                    PrimaryDomainDnsName,
                                    ActiveDirectoryRights.DeleteChild,
                                    AccessControlType.Allow);
                            }
                        }

                        #endregion
                    }
                }
            }

            #endregion
        }