bug: AD ignore foreign security principals
This commit is contained in:
@@ -143,7 +143,7 @@ namespace Disco.Services.Interop.ActiveDirectory
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Machine Accounts
|
#region Machine Accounts
|
||||||
public ADMachineAccount RetrieveADMachineAccount(string Id, System.Guid? UUIDNetbootGUID, System.Guid? MacAddressNetbootGUID, string[] AdditionalProperties = null)
|
public ADMachineAccount RetrieveADMachineAccount(string Id, Guid? UUIDNetbootGUID, Guid? MacAddressNetbootGUID, string[] AdditionalProperties = null)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(Id))
|
if (string.IsNullOrWhiteSpace(Id))
|
||||||
throw new ArgumentNullException("Id");
|
throw new ArgumentNullException("Id");
|
||||||
@@ -186,7 +186,7 @@ namespace Disco.Services.Interop.ActiveDirectory
|
|||||||
{
|
{
|
||||||
return RetrieveADMachineAccount(Id, null, null, AdditionalProperties);
|
return RetrieveADMachineAccount(Id, null, null, AdditionalProperties);
|
||||||
}
|
}
|
||||||
public ADMachineAccount RetrieveADMachineAccount(string Id, System.Guid? NetbootGUID, string[] AdditionalProperties = null)
|
public ADMachineAccount RetrieveADMachineAccount(string Id, Guid? NetbootGUID, string[] AdditionalProperties = null)
|
||||||
{
|
{
|
||||||
return RetrieveADMachineAccount(Id, NetbootGUID, null, AdditionalProperties);
|
return RetrieveADMachineAccount(Id, NetbootGUID, null, AdditionalProperties);
|
||||||
}
|
}
|
||||||
@@ -256,23 +256,31 @@ namespace Disco.Services.Interop.ActiveDirectory
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var objectCategory = result.Value<string>("objectCategory");
|
var objectCategory = result.Value<string>("objectCategory");
|
||||||
objectCategory = objectCategory.Substring(0, objectCategory.IndexOf(',')).ToLower();
|
|
||||||
switch (objectCategory)
|
if (objectCategory == null || objectCategory.Length == 0)
|
||||||
{
|
throw new InvalidOperationException("objectCategory is null or empty");
|
||||||
case "cn=person":
|
|
||||||
|
if (objectCategory.StartsWith("CN=Person,", StringComparison.OrdinalIgnoreCase))
|
||||||
return result.AsADUserAccount(Quick, AdditionalProperties);
|
return result.AsADUserAccount(Quick, AdditionalProperties);
|
||||||
case "cn=computer":
|
else if (objectCategory.StartsWith("CN=Computer,", StringComparison.OrdinalIgnoreCase))
|
||||||
return result.AsADMachineAccount(AdditionalProperties);
|
return result.AsADMachineAccount(AdditionalProperties);
|
||||||
case "cn=group":
|
else if (objectCategory.StartsWith("CN=Group,", StringComparison.OrdinalIgnoreCase))
|
||||||
return result.AsADGroup(AdditionalProperties);
|
return result.AsADGroup(AdditionalProperties);
|
||||||
default:
|
else if (objectCategory.StartsWith("CN=Foreign-Security-Principal,", StringComparison.OrdinalIgnoreCase))
|
||||||
|
return null;
|
||||||
|
else
|
||||||
throw new InvalidOperationException("Unexpected objectCategory");
|
throw new InvalidOperationException("Unexpected objectCategory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public IADObject RetrieveADObjectByDistinguishedName(string distinguishedName, bool quick, string[] additionalProperties = null)
|
public IADObject RetrieveADObjectByDistinguishedName(string distinguishedName, bool quick, string[] additionalProperties = null)
|
||||||
{
|
{
|
||||||
|
// ignore foreign security principals
|
||||||
|
var containerIndex = distinguishedName.IndexOf(',') + 1;
|
||||||
|
var container = distinguishedName.Substring(containerIndex, distinguishedName.IndexOf(',', containerIndex) - containerIndex);
|
||||||
|
if (string.Equals("CN=ForeignSecurityPrincipals", container, StringComparison.OrdinalIgnoreCase))
|
||||||
|
return null;
|
||||||
|
|
||||||
using (var entry = RetrieveDirectoryEntry(distinguishedName, additionalProperties))
|
using (var entry = RetrieveDirectoryEntry(distinguishedName, additionalProperties))
|
||||||
{
|
{
|
||||||
if (entry == null)
|
if (entry == null)
|
||||||
@@ -319,7 +327,7 @@ namespace Disco.Services.Interop.ActiveDirectory
|
|||||||
var slashIndex = Id.IndexOf('\\');
|
var slashIndex = Id.IndexOf('\\');
|
||||||
|
|
||||||
if (!Domain.NetBiosName.Equals(Id.Substring(0, slashIndex), StringComparison.OrdinalIgnoreCase))
|
if (!Domain.NetBiosName.Equals(Id.Substring(0, slashIndex), StringComparison.OrdinalIgnoreCase))
|
||||||
throw new ArgumentException(string.Format("The Id [{0}] is invalid for this domain [{1}]", Id, Domain.Name), "Id");
|
throw new ArgumentException($"The Id [{Id}] is invalid for this domain [{Domain.Name}]", "Id");
|
||||||
|
|
||||||
var ldapFilter = string.Format(LdapFilterTemplate, Id.Substring(slashIndex + 1));
|
var ldapFilter = string.Format(LdapFilterTemplate, Id.Substring(slashIndex + 1));
|
||||||
|
|
||||||
@@ -340,10 +348,10 @@ namespace Disco.Services.Interop.ActiveDirectory
|
|||||||
public string OfflineDomainJoinProvision(string ComputerSamAccountName, string OrganisationalUnit, ref ADMachineAccount MachineAccount, out string DiagnosticInformation)
|
public string OfflineDomainJoinProvision(string ComputerSamAccountName, string OrganisationalUnit, ref ADMachineAccount MachineAccount, out string DiagnosticInformation)
|
||||||
{
|
{
|
||||||
if (MachineAccount != null && MachineAccount.IsCriticalSystemObject)
|
if (MachineAccount != null && MachineAccount.IsCriticalSystemObject)
|
||||||
throw new InvalidOperationException(string.Format("This account {0} is a Critical System Active Directory Object and Disco ICT refuses to modify it", MachineAccount.DistinguishedName));
|
throw new InvalidOperationException($"This account {MachineAccount.DistinguishedName} is a Critical System Active Directory Object and Disco ICT refuses to modify it");
|
||||||
|
|
||||||
if (!IsWritable)
|
if (!IsWritable)
|
||||||
throw new InvalidOperationException(string.Format("The domain controller [{0}] is not writable. This action (Offline Domain Join Provision) requires a writable domain controller.", Name));
|
throw new InvalidOperationException($"The domain controller [{Name}] is not writable. This action (Offline Domain Join Provision) requires a writable domain controller.");
|
||||||
|
|
||||||
StringBuilder diagnosticInfo = new StringBuilder();
|
StringBuilder diagnosticInfo = new StringBuilder();
|
||||||
string DJoinResult = null;
|
string DJoinResult = null;
|
||||||
@@ -355,7 +363,7 @@ namespace Disco.Services.Interop.ActiveDirectory
|
|||||||
|
|
||||||
// NetBIOS Limit (16 characters; "{ComputerName}$"; 15 characters allowed)
|
// NetBIOS Limit (16 characters; "{ComputerName}$"; 15 characters allowed)
|
||||||
if (string.IsNullOrWhiteSpace(ComputerSamAccountName) || ComputerSamAccountName.Length > 15)
|
if (string.IsNullOrWhiteSpace(ComputerSamAccountName) || ComputerSamAccountName.Length > 15)
|
||||||
throw new System.ArgumentException("Invalid Computer Name; > 0 and <= 15", "ComputerName");
|
throw new ArgumentException("Invalid Computer Name; > 0 and <= 15", "ComputerName");
|
||||||
|
|
||||||
// Ensure Specified OU Exists
|
// Ensure Specified OU Exists
|
||||||
if (!string.IsNullOrEmpty(OrganisationalUnit))
|
if (!string.IsNullOrEmpty(OrganisationalUnit))
|
||||||
@@ -417,12 +425,15 @@ namespace Disco.Services.Interop.ActiveDirectory
|
|||||||
System.IO.File.Delete(tempFileName);
|
System.IO.File.Delete(tempFileName);
|
||||||
}
|
}
|
||||||
if (string.IsNullOrWhiteSpace(DJoinResult))
|
if (string.IsNullOrWhiteSpace(DJoinResult))
|
||||||
throw new System.InvalidOperationException(string.Format("Domain Join Unsuccessful{0}Error: {1}{0}Output: {2}", System.Environment.NewLine, stdError, stdOutput));
|
throw new InvalidOperationException(
|
||||||
|
$@"Domain Join Unsuccessful
|
||||||
|
Error: {stdError}
|
||||||
|
Output: {stdOutput}");
|
||||||
|
|
||||||
DiagnosticInformation = diagnosticInfo.ToString();
|
DiagnosticInformation = diagnosticInfo.ToString();
|
||||||
|
|
||||||
// Reload Machine Account
|
// Reload Machine Account
|
||||||
MachineAccount = RetrieveADMachineAccount(string.Format(@"{0}\{1}", Domain.NetBiosName, ComputerSamAccountName), (MachineAccount == null ? null : MachineAccount.LoadedProperties.Keys.ToArray()));
|
MachineAccount = RetrieveADMachineAccount($@"{Domain.NetBiosName}\{ComputerSamAccountName}", (MachineAccount == null ? null : MachineAccount.LoadedProperties.Keys.ToArray()));
|
||||||
|
|
||||||
return DJoinResult;
|
return DJoinResult;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,21 +98,22 @@ namespace Disco.Services
|
|||||||
|
|
||||||
public static IADObject AsADObject(this ADDirectoryEntry directoryEntry, bool quick, string[] additionalProperties)
|
public static IADObject AsADObject(this ADDirectoryEntry directoryEntry, bool quick, string[] additionalProperties)
|
||||||
{
|
{
|
||||||
var properties = directoryEntry.Entry.Properties;
|
var objectCategory = directoryEntry.Entry.Properties.Value<string>("objectCategory");
|
||||||
var objectCategory = properties.Value<string>("objectCategory");
|
|
||||||
objectCategory = objectCategory.Substring(0, objectCategory.IndexOf(',')).ToLower();
|
if (objectCategory == null || objectCategory.Length == 0)
|
||||||
switch (objectCategory)
|
throw new InvalidOperationException("objectCategory is null or empty");
|
||||||
{
|
|
||||||
case "cn=person":
|
if (objectCategory.StartsWith("CN=Person,", StringComparison.OrdinalIgnoreCase))
|
||||||
return ADUserAccount.FromDirectoryEntry(directoryEntry, quick, additionalProperties);
|
return ADUserAccount.FromDirectoryEntry(directoryEntry, quick, additionalProperties);
|
||||||
case "cn=computer":
|
else if (objectCategory.StartsWith("CN=Computer,", StringComparison.OrdinalIgnoreCase))
|
||||||
return ADMachineAccount.FromDirectoryEntry(directoryEntry, additionalProperties);
|
return ADMachineAccount.FromDirectoryEntry(directoryEntry, additionalProperties);
|
||||||
case "cn=group":
|
else if (objectCategory.StartsWith("CN=Group,", StringComparison.OrdinalIgnoreCase))
|
||||||
return ADGroup.FromDirectoryEntry(directoryEntry, additionalProperties);
|
return ADGroup.FromDirectoryEntry(directoryEntry, additionalProperties);
|
||||||
default:
|
else if (objectCategory.StartsWith("CN=Foreign-Security-Principal,", StringComparison.OrdinalIgnoreCase))
|
||||||
|
return null;
|
||||||
|
else
|
||||||
throw new InvalidOperationException("Unexpected objectCategory");
|
throw new InvalidOperationException("Unexpected objectCategory");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user