websitepanel/WebsitePanel/Sources/WebsitePanel.Providers.Base/HostedSolution/ActiveDirectoryUtils.cs
robvde 50f2c43315 Significant amount of changes to hosted organizations and exchange:
Exchange 2010 SP2 provisioning separated through a new provider
Exchange 2010 SP2 now compliant with product group guidelines
Support for Database Availability Group
Fixed Distribution List view scope to only tenant
Consumer support (individual mailboxes as hotmail) added
Mailbox configuration moved to mailbox plans concept
CN creation is now based on UPN
sAMAccountName generation revised and decoupled from tenant name
2007 (ACL Based), 2010 (ACL Bases), 2010 SP2 (ABP) supported
Automated Hosted Organization provisioning added to create hosting space
Enterprise Server webservice extended with ImportMethod
Mobile tab fixed
Added more information to users listview
2012-07-09 12:03:24 +04:00

416 lines
14 KiB
C#

// Copyright (c) 2011, Outercurve Foundation.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// - Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// - Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// - Neither the name of the Outercurve Foundation nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using System;
using System.Collections.Generic;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using System.Globalization;
using System.Text;
namespace WebsitePanel.Providers.HostedSolution
{
public class ActiveDirectoryUtils
{
public static DirectoryEntry GetADObject(string path)
{
DirectoryEntry de = new DirectoryEntry(path);
de.RefreshCache();
return de;
}
public static bool IsUserInGroup(string samAccountName, string group)
{
bool res = false;
DirectorySearcher deSearch = new DirectorySearcher
{
Filter =
("(&(objectClass=user)(samaccountname=" + samAccountName + "))")
};
//get the group result
SearchResult results = deSearch.FindOne();
DirectoryEntry de = results.GetDirectoryEntry();
PropertyValueCollection props = de.Properties["memberOf"];
foreach (string str in props)
{
if (str.IndexOf(group) != -1)
{
res = true;
break;
}
}
return res;
}
public static string CreateOrganizationalUnit(string name, string parentPath)
{
string ret;
DirectoryEntry ou = null;
DirectoryEntry parent = null;
try
{
parent = GetADObject(parentPath);
ou = parent.Children.Add(
string.Format("OU={0}", name),
parent.SchemaClassName);
ret = ou.Path;
ou.CommitChanges();
}
finally
{
if (ou != null)
ou.Close();
if (parent != null)
parent.Close();
}
return ret;
}
public static void DeleteADObject(string path, bool removeChild)
{
DirectoryEntry entry = GetADObject(path);
if (removeChild && entry.Children != null)
foreach (DirectoryEntry child in entry.Children)
{
entry.Children.Remove(child);
}
DirectoryEntry parent = entry.Parent;
if (parent != null)
{
parent.Children.Remove(entry);
parent.CommitChanges();
}
}
public static void DeleteADObject(string path)
{
DirectoryEntry entry = GetADObject(path);
DirectoryEntry parent = entry.Parent;
if (parent != null)
{
parent.Children.Remove(entry);
parent.CommitChanges();
}
}
public static void SetADObjectProperty(DirectoryEntry oDE, string name, string value)
{
if (!string.IsNullOrEmpty(value))
{
if (oDE.Properties.Contains(name))
{
oDE.Properties[name][0] = value;
}
else
{
oDE.Properties[name].Add(value);
}
}
else
{
if (oDE.Properties.Contains(name))
{
oDE.Properties[name].Remove(oDE.Properties[name][0]);
}
}
}
public static void SetADObjectPropertyValue(DirectoryEntry oDE, string name, string value)
{
PropertyValueCollection collection = oDE.Properties[name];
collection.Value = value;
}
public static void SetADObjectPropertyValue(DirectoryEntry oDE, string name, Guid value)
{
PropertyValueCollection collection = oDE.Properties[name];
collection.Value = value.ToByteArray();
}
public static void ClearADObjectPropertyValue(DirectoryEntry oDE, string name)
{
PropertyValueCollection collection = oDE.Properties[name];
collection.Clear();
}
public static object GetADObjectProperty(DirectoryEntry entry, string name)
{
return entry.Properties.Contains(name) ? entry.Properties[name][0] : null;
}
public static string GetADObjectStringProperty(DirectoryEntry entry, string name)
{
object ret = GetADObjectProperty(entry, name);
return ret != null ? ret.ToString() : string.Empty;
}
public static string ConvertADPathToCanonicalName(string name)
{
if (string.IsNullOrEmpty(name))
return null;
StringBuilder ret = new StringBuilder();
List<string> cn = new List<string>();
List<string> dc = new List<string>();
name = RemoveADPrefix(name);
string[] parts = name.Split(',');
for (int i = 0; i < parts.Length; i++)
{
if (parts[i].StartsWith("DC="))
{
dc.Add(parts[i].Substring(3));
}
else if (parts[i].StartsWith("OU=") || parts[i].StartsWith("CN="))
{
cn.Add(parts[i].Substring(3));
}
}
for (int i = 0; i < dc.Count; i++)
{
ret.Append(dc[i]);
if (i < dc.Count - 1)
ret.Append(".");
}
for (int i = cn.Count - 1; i != -1; i--)
{
ret.Append("/");
ret.Append(cn[i]);
}
return ret.ToString();
}
public static string ConvertDomainName(string name)
{
if (string.IsNullOrEmpty(name))
return null;
StringBuilder ret = new StringBuilder("LDAP://");
string[] parts = name.Split('.');
for (int i = 0; i < parts.Length; i++)
{
ret.Append("DC=");
ret.Append(parts[i]);
if (i < parts.Length - 1)
ret.Append(",");
}
return ret.ToString();
}
public static string GetNETBIOSDomainName(string rootDomain)
{
string ret = string.Empty;
string path = string.Format("LDAP://{0}/RootDSE", rootDomain);
DirectoryEntry rootDSE = GetADObject(path);
string contextPath = GetADObjectProperty(rootDSE, "ConfigurationNamingContext").ToString();
string defaultContext = GetADObjectProperty(rootDSE, "defaultNamingContext").ToString();
DirectoryEntry partitions = GetADObject("LDAP://cn=Partitions," + contextPath);
DirectorySearcher searcher = new DirectorySearcher();
searcher.SearchRoot = partitions;
searcher.Filter = string.Format("(&(objectCategory=crossRef)(nCName={0}))", defaultContext);
searcher.SearchScope = SearchScope.OneLevel;
//find the first instance
SearchResult result = searcher.FindOne();
if (result != null)
{
DirectoryEntry partition = GetADObject(result.Path);
ret = GetADObjectProperty(partition, "nETBIOSName").ToString();
partition.Close();
}
partitions.Close();
rootDSE.Close();
return ret;
}
public static string CreateUser(string path, string user, string displayName, string password, bool enabled)
{
return CreateUser(path, "", user, displayName, password, enabled);
}
public static string CreateUser(string path, string upn, string user, string displayName, string password, bool enabled)
{
DirectoryEntry currentADObject = new DirectoryEntry(path);
string cn = string.Empty;
if (string.IsNullOrEmpty(upn)) cn = user; else cn = upn;
DirectoryEntry newUserObject = currentADObject.Children.Add("CN=" + cn, "User");
newUserObject.Properties[ADAttributes.SAMAccountName].Add(user);
SetADObjectProperty(newUserObject, ADAttributes.DisplayName, displayName);
newUserObject.CommitChanges();
newUserObject.Invoke(ADAttributes.SetPassword, password);
newUserObject.InvokeSet(ADAttributes.AccountDisabled, !enabled);
newUserObject.CommitChanges();
return newUserObject.Path;
}
public static void CreateGroup(string path, string group)
{
DirectoryEntry currentADObject = new DirectoryEntry(path);
DirectoryEntry newGroupObject = currentADObject.Children.Add("CN=" + group, "Group");
newGroupObject.Properties[ADAttributes.SAMAccountName].Add(group);
newGroupObject.Properties[ADAttributes.GroupType].Add(-2147483640);
newGroupObject.CommitChanges();
}
public static void AddUserToGroup(string userPath, string groupPath)
{
DirectoryEntry user = new DirectoryEntry(userPath);
DirectoryEntry group = new DirectoryEntry(groupPath);
group.Invoke("Add", user.Path);
}
public static bool AdObjectExists(string path)
{
return DirectoryEntry.Exists(path);
}
public static string RemoveADPrefix(string path)
{
string dn = path;
if (dn.ToUpper().StartsWith("LDAP://"))
{
dn = dn.Substring(7);
}
int index = dn.IndexOf("/");
if (index != -1)
{
dn = dn.Substring(index + 1);
}
return dn;
}
public static string AddADPrefix(string path, string primaryDomainController)
{
string dn = path;
if (!dn.ToUpper().StartsWith("LDAP://"))
{
if (string.IsNullOrEmpty(primaryDomainController))
{
dn = string.Format("LDAP://{0}", dn);
}
else
dn = string.Format("LDAP://{0}/{1}", primaryDomainController, dn);
}
return dn;
}
public static string AddADPrefix(string path)
{
return AddADPrefix(path, null);
}
private static void AddADObjectProperty(DirectoryEntry oDE, string name, string value)
{
if (!string.IsNullOrEmpty(value))
{
oDE.Properties[name].Add(value);
}
}
public static void AddUPNSuffix(string ouPath, string suffix)
{
//Add UPN Suffix to the OU
DirectoryEntry ou = GetADObject(ouPath);
AddADObjectProperty(ou, "uPNSuffixes", suffix);
ou.CommitChanges();
ou.Close();
}
public static void RemoveUPNSuffix(string ouPath, string suffix)
{
if (DirectoryEntry.Exists(ouPath))
{
DirectoryEntry ou = GetADObject(ouPath);
PropertyValueCollection prop = null;
prop = ou.Properties["uPNSuffixes"];
if (prop != null)
{
if (ou.Properties["uPNSuffixes"].Contains(suffix))
{
ou.Properties["uPNSuffixes"].Remove(suffix);
ou.CommitChanges();
}
ou.Close();
}
}
}
public static string GetDomainName(string userName)
{
string str4;
string filter = string.Format(CultureInfo.InvariantCulture, "(&(objectClass=user)(Name={0}))", new object[] { userName });
using (DirectoryEntry entry = Domain.GetComputerDomain().GetDirectoryEntry())
{
using (DirectorySearcher searcher = new DirectorySearcher(entry, filter))
{
searcher.PropertiesToLoad.Add("sAMAccountName");
string str2 = searcher.FindOne().Properties["sAMAccountName"][0] as string;
str4 = string.Format(CultureInfo.InvariantCulture, @"{0}\{1}", new object[] { entry.Properties["Name"].Value as string, str2 });
}
}
return str4;
}
}
}