#region
using System;
using System.Collections.Generic;
using System.DirectoryServices;
using System.Linq;
#endregion
namespace Framework.Net.LDAP
{
/// <summary>
/// Class for helping with AD
/// </summary>
public sealed class Directory : IDisposable
{
#region Constructors
/// <summary>
/// Constructor
/// </summary>
/// <param name = "userName">User name used to log in</param>
/// <param name = "password">Password used to log in</param>
/// <param name = "path">Path of the LDAP server</param>
/// <param name = "query">Query to use in the search</param>
public Directory(string query, string userName, string password, string path)
{
Entry = new DirectoryEntry(path, userName, password, AuthenticationTypes.Secure);
Path = path;
UserName = userName;
Password = password;
Query = query;
Searcher = new DirectorySearcher(Entry) { Filter = query, PageSize = 1000 };
}
#endregion
#region Public Functions
#region Authenticate
/// <summary>
/// Checks to see if the person was authenticated
/// </summary>
/// <returns>true if they were authenticated properly, false otherwise</returns>
public bool Authenticate()
{
try
{
if (!Entry.Guid.ToString().ToLower().Trim().Equals(""))
return true;
}
catch
{
}
return false;
}
#endregion
#region Close
/// <summary>
/// Closes the directory
/// </summary>
public void Close()
{
Entry.Close();
}
#endregion
#region FindActiveGroupMembers
/// <summary>
/// Returns a group's list of members
/// </summary>
/// <param name = "GroupName">The group's name</param>
/// <returns>A list of the members</returns>
public List<Entry> FindActiveGroupMembers(string GroupName)
{
try
{
List<Entry> entries = FindGroups("cn=" + GroupName);
return entries.Count < 1 ? new List<Entry>() : FindActiveUsersAndGroups("memberOf=" + entries[0].DistinguishedName);
}
catch
{
return new List<Entry>();
}
}
#endregion
#region FindActiveGroups
/// <summary>
/// Finds all active groups
/// </summary>
/// <param name = "Filter">Filter used to modify the query</param>
/// <param name = "args">Additional arguments (used in string formatting</param>
/// <returns>A list of all active groups' entries</returns>
public List<Entry> FindActiveGroups(string Filter, params object[] args)
{
Filter = string.Format(Filter, args);
Filter =
string.Format(
"(&((userAccountControl:1.2.840.113556.1.4.803:=512)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(cn=*$)))({0}))",
Filter);
return FindGroups(Filter);
}
#endregion
#region FindActiveUsers
/// <summary>
/// Finds all active users
/// </summary>
/// <param name = "Filter">Filter used to modify the query</param>
/// <param name = "args">Additional arguments (used in string formatting</param>
/// <returns>A list of all active users' entries</returns>
public List<Entry> FindActiveUsers(string Filter, params object[] args)
{
Filter = string.Format(Filter, args);
Filter =
string.Format(
"(&((userAccountControl:1.2.840.113556.1.4.803:=512)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(cn=*$)))({0}))",
Filter);
return FindUsers(Filter);
}
#endregion
#region FindActiveUsersAndGroups
/// <summary>
/// Finds all active users and groups
/// </summary>
/// <param name = "Filter">Filter used to modify the query</param>
/// <param name = "args">Additional arguments (used in string formatting</param>
/// <returns>A list of all active groups' entries</returns>
public List<Entry> FindActiveUsersAndGroups(string Filter, params object[] args)
{
Filter = string.Format(Filter, args);
Filter =
string.Format(
"(&((userAccountControl:1.2.840.113556.1.4.803:=512)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(cn=*$)))({0}))",
Filter);
return FindUsersAndGroups(Filter);
}
#endregion
#region FindAll
/// <summary>
/// Finds all entries that match the query
/// </summary>
/// <returns>A list of all entries that match the query</returns>
public List<Entry> FindAll()
{
List<Entry> returnedResults = new List<Entry>();
using (SearchResultCollection results = Searcher.FindAll())
{
returnedResults.AddRange(from SearchResult result in results select new Entry(result.GetDirectoryEntry()));
}
return returnedResults;
}
#endregion
#region FindComputers
/// <summary>
/// Finds all computers
/// </summary>
/// <param name = "Filter">Filter used to modify the query</param>
/// <param name = "args">Additional arguments (used in string formatting</param>
/// <returns>A list of all computers meeting the specified Filter</returns>
public List<Entry> FindComputers(string Filter, params object[] args)
{
Filter = string.Format(Filter, args);
Filter = string.Format("(&(objectClass=computer)({0}))", Filter);
Searcher.Filter = Filter;
return FindAll();
}
#endregion
#region FindGroups
/// <summary>
/// Finds all groups
/// </summary>
/// <param name = "Filter">Filter used to modify the query</param>
/// <param name = "args">Additional arguments (used in string formatting</param>
/// <returns>A list of all groups meeting the specified Filter</returns>
public List<Entry> FindGroups(string Filter, params object[] args)
{
Filter = string.Format(Filter, args);
Filter = string.Format("(&(objectClass=Group)(objectCategory=Group)({0}))", Filter);
Searcher.Filter = Filter;
return FindAll();
}
#endregion
#region FindOne
/// <summary>
/// Finds one entry that matches the query
/// </summary>
/// <returns>A single entry matching the query</returns>
public Entry FindOne()
{
return new Entry(Searcher.FindOne().GetDirectoryEntry());
}
#endregion
#region FindUsersAndGroups
/// <summary>
/// Finds all users and groups
/// </summary>
/// <param name = "Filter">Filter used to modify the query</param>
/// <param name = "args">Additional arguments (used in string formatting</param>
/// <returns>A list of all users and groups meeting the specified Filter</returns>
public List<Entry> FindUsersAndGroups(string Filter, params object[] args)
{
Filter = string.Format(Filter, args);
Filter =
string.Format(
"(&(|(&(objectClass=Group)(objectCategory=Group))(&(objectClass=User)(objectCategory=Person)))({0}))",
Filter);
Searcher.Filter = Filter;
return FindAll();
}
#endregion
#region FindUserByUserName
/// <summary>
/// Finds a user by his user name
/// </summary>
/// <param name = "userName">User name to search by</param>
/// <returns>The user's entry</returns>
public Entry FindUserByUserName(string userName)
{
if (string.IsNullOrEmpty(userName))
{
throw new ArgumentNullException("userName");
}
List<Entry> entries = FindUsers("samAccountName=" + userName);
return entries.Count > 0 ? entries[0] : null;
}
#endregion
#region FindUsers
/// <summary>
/// Finds all users
/// </summary>
/// <param name = "filter">Filter used to modify the query</param>
/// <param name = "args">Additional arguments (used in string formatting</param>
/// <returns>A list of all users meeting the specified Filter</returns>
public List<Entry> FindUsers(string filter, params object[] args)
{
filter = string.Format(filter, args);
filter = string.Format("(&(objectClass=User)(objectCategory=Person)({0}))", filter);
Searcher.Filter = filter;
return FindAll();
}
#endregion
#endregion
#region Properties
/// <summary>
/// Path of the server
/// </summary>
public string Path
{
get { return _Path; }
set
{
_Path = value;
if (Entry != null)
{
Entry.Close();
Entry.Dispose();
Entry = null;
}
if (Searcher != null)
{
Searcher.Dispose();
Searcher = null;
}
Entry = new DirectoryEntry(_Path, _UserName, _Password, AuthenticationTypes.Secure);
Searcher = new DirectorySearcher(Entry) { Filter = Query, PageSize = 1000 };
}
}
/// <summary>
/// User name used to log in
/// </summary>
public string UserName
{
get { return _UserName; }
set
{
_UserName = value;
if (Entry != null)
{
Entry.Close();
Entry.Dispose();
Entry = null;
}
if (Searcher != null)
{
Searcher.Dispose();
Searcher = null;
}
Entry = new DirectoryEntry(_Path, _UserName, _Password, AuthenticationTypes.Secure);
Searcher = new DirectorySearcher(Entry) { Filter = Query, PageSize = 1000 };
}
}
/// <summary>
/// Password used to log in
/// </summary>
public string Password
{
get { return _Password; }
set
{
_Password = value;
if (Entry != null)
{
Entry.Close();
Entry.Dispose();
Entry = null;
}
if (Searcher != null)
{
Searcher.Dispose();
Searcher = null;
}
Entry = new DirectoryEntry(_Path, _UserName, _Password, AuthenticationTypes.Secure);
Searcher = new DirectorySearcher(Entry) { Filter = Query, PageSize = 1000 };
}
}
/// <summary>
/// The query that is being made
/// </summary>
public string Query
{
get { return _Query; }
set
{
_Query = value;
Searcher.Filter = _Query;
}
}
/// <summary>
/// Decides what to sort the information by
/// </summary>
public string SortBy
{
get { return _SortBy; }
set
{
_SortBy = value;
Searcher.Sort.PropertyName = _SortBy;
Searcher.Sort.Direction = SortDirection.Ascending;
}
}
#endregion
#region Private Variables
private DirectoryEntry Entry;
private DirectorySearcher Searcher;
private string _Password = "";
private string _Path = "";
private string _Query = "";
private string _SortBy = "";
private string _UserName = "";
#endregion
#region IDisposable Members
public void Dispose()
{
if (Entry != null)
{
Entry.Close();
Entry.Dispose();
Entry = null;
}
if (Searcher != null)
{
Searcher.Dispose();
Searcher = null;
}
}
#endregion
}
}
#region
using System;
using System.Collections.Generic;
using System.DirectoryServices;
using System.Linq;
#endregion
namespace Framework.Net.LDAP
{
/// <summary>
/// Directory entry class
/// </summary>
public sealed class Entry : IDisposable
{
#region Constructors
/// <summary>
/// Constructor
/// </summary>
/// <param name = "directoryEntry">Directory entry for the item</param>
public Entry(DirectoryEntry directoryEntry)
{
DirectoryEntry = directoryEntry;
}
#endregion
#region Properties
/// <summary>
/// Actual base directory entry
/// </summary>
public DirectoryEntry DirectoryEntry { get; set; }
/// <summary>
/// Email property for this entry
/// </summary>
public string Email
{
get { return (string)GetValue("mail"); }
set { SetValue("mail", value); }
}
/// <summary>
/// distinguished name property for this entry
/// </summary>
public string DistinguishedName
{
get { return (string)GetValue("distinguishedname"); }
set { SetValue("distinguishedname", value); }
}
/// <summary>
/// country code property for this entry
/// </summary>
public string CountryCode
{
get { return (string)GetValue("countrycode"); }
set { SetValue("countrycode", value); }
}
/// <summary>
/// company property for this entry
/// </summary>
public string Company
{
get { return (string)GetValue("company"); }
set { SetValue("company", value); }
}
/// <summary>
/// MemberOf property for this entry
/// </summary>
public List<string> MemberOf
{
get
{
PropertyValueCollection collection = DirectoryEntry.Properties["memberof"];
return collection.Cast<string>().ToList();
}
}
/// <summary>
/// display name property for this entry
/// </summary>
public string DisplayName
{
get { return (string)GetValue("displayname"); }
set { SetValue("displayname", value); }
}
/// <summary>
/// initials property for this entry
/// </summary>
public string Initials
{
get { return (string)GetValue("initials"); }
set { SetValue("initials", value); }
}
/// <summary>
/// title property for this entry
/// </summary>
public string Title
{
get { return (string)GetValue("title"); }
set { SetValue("title", value); }
}
/// <summary>
/// samaccountname property for this entry
/// </summary>
public string SamAccountName
{
get { return (string)GetValue("samaccountname"); }
set { SetValue("samaccountname", value); }
}
/// <summary>
/// givenname property for this entry
/// </summary>
public string GivenName
{
get { return (string)GetValue("givenname"); }
set { SetValue("givenname", value); }
}
/// <summary>
/// cn property for this entry
/// </summary>
public string CN
{
get { return (string)GetValue("cn"); }
set { SetValue("cn", value); }
}
/// <summary>
/// name property for this entry
/// </summary>
public string Name
{
get { return (string)GetValue("name"); }
set { SetValue("name", value); }
}
/// <summary>
/// office property for this entry
/// </summary>
public string Office
{
get { return (string)GetValue("physicaldeliveryofficename"); }
set { SetValue("physicaldeliveryofficename", value); }
}
/// <summary>
/// telephone number property for this entry
/// </summary>
public string TelephoneNumber
{
get { return (string)GetValue("telephonenumber"); }
set { SetValue("telephonenumber", value); }
}
#endregion
#region Public Functions
/// <summary>
/// Saves any changes that have been made
/// </summary>
public void Save()
{
if (DirectoryEntry == null)
throw new NullReferenceException("DirectoryEntry shouldn't be null");
DirectoryEntry.CommitChanges();
}
/// <summary>
/// Gets a value from the entry
/// </summary>
/// <param name = "Property">Property you want the information about</param>
/// <returns>an object containing the property's information</returns>
public object GetValue(string Property)
{
PropertyValueCollection Collection = DirectoryEntry.Properties[Property];
return Collection != null ? Collection.Value : null;
}
/// <summary>
/// Gets a value from the entry
/// </summary>
/// <param name = "Property">Property you want the information about</param>
/// <param name = "Index">Index of the property to return</param>
/// <returns>an object containing the property's information</returns>
public object GetValue(string Property, int Index)
{
PropertyValueCollection Collection = DirectoryEntry.Properties[Property];
return Collection != null ? Collection[Index] : null;
}
/// <summary>
/// Sets a property of the entry to a specific value
/// </summary>
/// <param name = "Property">Property of the entry to set</param>
/// <param name = "Value">Value to set the property to</param>
public void SetValue(string Property, object Value)
{
PropertyValueCollection Collection = DirectoryEntry.Properties[Property];
if (Collection != null)
Collection.Value = Value;
}
/// <summary>
/// Sets a property of the entry to a specific value
/// </summary>
/// <param name = "Property">Property of the entry to set</param>
/// <param name = "Index">Index of the property to set</param>
/// <param name = "Value">Value to set the property to</param>
public void SetValue(string Property, int Index, object Value)
{
PropertyValueCollection Collection = DirectoryEntry.Properties[Property];
if (Collection != null)
Collection[Index] = Value;
}
#endregion
#region IDisposable Members
public void Dispose()
{
if (DirectoryEntry != null)
{
DirectoryEntry.Dispose();
DirectoryEntry = null;
}
}
#endregion
}
}