Reputation: 1278
Is there any way of finding out if a domain is available in ActiveDirectory before using GetDomain? I have an app where users should be able to add domains by themselves, and if they enter an invalid domain there should be an error. Right now it is handled by catching the exception below, but a user entering an invalid domain is hardly an exceptional happening, and the exception also can take a really long time to get thrown, especially if an ip adress is entered (it seems like). Is there a better solution to this?
public Domain RegisterUserDirectory(string domainId) {
DirectoryContext context = new DirectoryContext(DirectoryContextType.Domain, domainId);
System.DirectoryServices.ActiveDirectory.Domain domain;
try {
domain = System.DirectoryServices.ActiveDirectory.Domain.GetDomain(context);
}
catch (ActiveDirectoryNotFoundException adne) {
// handle
}
catch (Exception e) {
Log.Warning("Failed to contact domain {0}: {1}", domainId, e.Message);
throw;
}
...
...
}
Upvotes: 4
Views: 11919
Reputation: 787
Here's the way I do it, without using a Forest. Some read-only servers have issues using the Forest class, so if I get an exception with my regular DomainExists method, I try this one instead.
public static bool DomainExistsNoForests(string domain, string server)
{
try {
DirectoryContext directoryContext = new DirectoryContext(DirectoryContextType.DirectoryServer, server);
Domain d = Domain.GetDomain(directoryContext);
if (d.Name.Trim().Equals(domain.Trim(), StringComparison.CurrentCultureIgnoreCase)) return true;
return false;
}
catch (Exception e) {
return false;
}
}
This is far, far faster than the way you posted. This code doesn't attempt to resolve the domain, but you do need to know the directory server you're using.
I also have some code in there to check for null arguments, but I trimmed it out for this reply.
Charles.
Upvotes: 3
Reputation: 11873
We need more information to give you a good answer. Active Directory does store information about all the trusted domains. So, it's possible to find out all the trusted domain information just by looking at the Global Catalog and without really binding to the domain controller.
However, you need to be aware that even if the domain information exists on the Active Directory, it doesn't mean you can bind to it. You may not have permissions to bind to it or the firewall settings in your environment may have blocked your access to some domains.
I am assuming the following things here.
You can use the following code to check whether the domain exists in your current forest. If yes, then continue to call Domain.GetDomain(context) to get your Domain object. If for some reasons, you cannot bind to it, you still need to wait for the timeout happen.
private bool DomainExist(string domain)
{
HashSet<string> domains = new HashSet<string>();
foreach (Domain d in Forest.GetCurrentForest().Domains)
{
domains.Add(d.Name.ToLower());
}
return domains.Contains(domain.ToLower());
}
Upvotes: 1
Reputation: 6834
The only other option I can think of is using the forest to enumerate the domains. i.e.
var myDomain = Domain.GetCurrentDomain(); //or .GetComputerDomain();
var forestDomains = myDomain.Forest.Domains;
This assumes all the domains you want are in the same forest. You'd then need to test your user inputed domainId
against this collection, probably testing against each domains .Name
property.
Upvotes: 5
Reputation: 45101
Unfortunately i think there is no real other way. Just think about how you verify that an ip address is reachable. All you can do is try a connection or send an ping request. After this you just have to wait if someone will answer and due to the fact that the connection could be slow the timeouts are high and you have to wait all the time.
All you can do for a better user experience is to put this job into another tread (or background worker) so that your GUI is still responsive and showing some progress or marquee bar to the user. Then you could also add the possibility for the user to cancel the connection tryout by simply aborting this thread.
So this wouldn't make it any faster but give a better responsive to the user and so it feels faster at last.
Upvotes: 3