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
}