/// <summary> /// Get a list of all groups of a certain user. /// </summary> /// <param name="adInfo">The user to query the groups from.</param> /// <returns> /// Returns an array of all groups the given user is /// member of. /// </returns> /// <remarks> /// From: /// http://72.14.221.104/search?q=cache:sywXEEFvZiYJ:www.411asp.net/func/goto%3Fid%3D5863210+memberOf+ad&hl=de&gl=de&ct=clnk&cd=2&client=firefox-a /// The property "MemberOf" does not supply the "Primary Group". /// See: /// http://dunnry.com/blog/EnumeratingTokenGroupsTokenGroupsInNET.aspx /// </remarks> public ADGroupInfo[] GetUserParentGroupsEx( ADUserInfo adInfo ) { byte[] guidBytes = adInfo.Guid.ToByteArray(); string guidString = HexEscape( guidBytes ); DirectoryEntry entry = GetDirectoryEntry( LdapBaseString ); DirectorySearcher searcher = new DirectorySearcher( entry ); searcher.Filter = string.Format( @"(&(objectCategory=person)(objectGUID={0}))", guidString ); searcher.PropertiesToLoad.Add( @"memberOf" ); searcher.SizeLimit = adSizeReturn; SearchResult result = searcher.FindOne(); if ( result == null ) { LogCentral.Current.LogDebug( string.Format( @"GetUserGroups(): (B) searcher.FindOne() returned NULL, exiting with return value NULL." ) ); return null; } else { StringBuilder sb = new StringBuilder(); //we are building an '|' clause sb.Append( @"(|" ); using ( DirectoryEntry user = result.GetDirectoryEntry() ) { //we must ask for this one first user.RefreshCache( new string[] { @"tokenGroups" } ); PropertyValueCollection tokenGroups = user.Properties[@"tokenGroups"]; if ( tokenGroups == null || tokenGroups.Count <= 0 ) { LogCentral.Current.LogDebug( string.Format( @"GetUserGroups(): (C) No token groups for user '{0}' found, exiting with return value NULL.", adInfo.SamName ) ); return null; } foreach ( byte[] sid in tokenGroups ) { //append each member into the filter sb.AppendFormat( @"(objectSid={0})", HexEscape( sid ) ); } } //end our initial filter sb.Append( @")" ); // -- List<ADGroupInfo> list = new List<ADGroupInfo>(); //now create and pull in one search using ( DirectorySearcher ds = new DirectorySearcher( GetDirectoryEntry( LdapBaseString ), sb.ToString(), new string[] { @"distinguishedName" } ) ) { using ( SearchResultCollection srcs = ds.FindAll() ) { foreach ( SearchResult src in srcs ) { object val = src.Properties[@"distinguishedName"][0]; ADGroupInfo info = GetGroupInfoByDN( Convert.ToString( val ) ); Debug.Assert( info != null ); if ( info != null ) { list.Add( info ); } } } } return list.ToArray(); } }
/// <summary> /// Get a list of all groups of a certain user. /// </summary> /// <param name="adInfo">The user to query the groups from.</param> /// <returns> /// Returns an array of all groups the given user is /// member of. /// </returns> /// <remarks> /// From: /// http://72.14.221.104/search?q=cache:sywXEEFvZiYJ:www.411asp.net/func/goto%3Fid%3D5863210+memberOf+ad&hl=de&gl=de&ct=clnk&cd=2&client=firefox-a /// The property "MemberOf" does not supply the "Primary Group". /// </remarks> public ADGroupInfo[] GetUserParentGroups( ADUserInfo adInfo ) { byte[] guidBytes = adInfo.Guid.ToByteArray(); string guidString = HexEscape( guidBytes ); DirectoryEntry entry = GetDirectoryEntry( LdapBaseString ); DirectorySearcher searcher = new DirectorySearcher( entry ); searcher.Filter = string.Format( @"(&(objectCategory=person)(objectGUID={0}))", guidString ); searcher.PropertiesToLoad.Add( @"memberOf" ); searcher.SizeLimit = adSizeReturn; SearchResult result = searcher.FindOne(); if ( result == null ) { LogCentral.Current.LogDebug( string.Format( @"GetUserGroups(): (B) searcher.FindOne() returned NULL, exiting with return value NULL." ) ); return null; } else if ( result.Properties[@"memberOf"] == null ) { return null; } else { List<ADGroupInfo> list = new List<ADGroupInfo>(); foreach ( object val in result.Properties[@"memberOf"] ) { ADGroupInfo info = GetGroupInfoByDN( Convert.ToString( val ) ); Debug.Assert( info != null ); if ( info != null ) { list.Add( info ); } } return list.ToArray(); } }
/// <summary> /// Modifies the information of an EXISTING user in /// the ActiveDirectory. /// </summary> /// <param name="info">The information of the existing user. /// The Guid field must be valid.</param> /// <param name="oldPassword">The old password.</param> /// <param name="newPassword">The new password.</param> public void ChangePassword( ADUserInfo info, string oldPassword, string newPassword ) { try { Impersonator impersonator = null; if ( configuration.DoImpersonate ) { LogCentral.Current.LogDebug( string.Format( @"ChangePassword(): About to impersonate with domain name '{0}' and user name '{1}'.", configuration.ImpersonationDomainName, configuration.ImpersonationUserName ) ); impersonator = new Impersonator( configuration.ImpersonationUserName, configuration.ImpersonationDomainName, configuration.ImpersonationPassword ); LogCentral.Current.LogDebug( string.Format( @"ChangePassword(): Impersonation succeeded." ) ); } try { byte[] guidBytes = info.Guid.ToByteArray(); string guidString = HexEscape( guidBytes ); string ldapString = LdapBaseString; string ldapFilter = string.Format( @"(&(objectCategory=person)(objectGUID={0}))", guidString ); LogCentral.Current.LogDebug( string.Format( @"ChangePassword(): About to query LDAP server with LDAP string '{0}' and filter string '{1}'.", ldapString, ldapFilter ) ); DirectoryEntry entry = GetDirectoryEntry( ldapString ); DirectorySearcher searcher = new DirectorySearcher( entry ); searcher.Filter = ldapFilter; searcher.SizeLimit = adSizeReturn; // -- // Use this call only to fill the req. fields. ADUserInfo currentInfo = GetUserInfoBySearcher( searcher ); SearchResult result = searcher.FindOne(); DirectoryEntry e = result.GetDirectoryEntry(); // -- e.Invoke( @"setPassword", new object[] { newPassword } ); //e.Invoke( "changePassword", new object[] { oldPassword, newPassword } ); // -- // Actually store back. e.CommitChanges(); } finally { if ( impersonator != null ) { impersonator.Dispose(); impersonator = null; } } } catch ( Exception x ) { LogCentral.Current.LogError( string.Format( @"ActiveDirectory.ChangePassword(): Exception occured for putting the user infos. The following values were set through SetWP(): '{0}'.", debugSettedWPValues ), x ); throw; } }
/// <summary> /// Add to the cache. /// </summary> /// <param name="item">The item.</param> public void Add( ADUserInfo item ) { cachedItems.Add( item ); }
/// <summary> /// Write back to AD, but only certain information, since not all /// is modifiable or intented to be so. /// </summary> /// <param name="e">The e.</param> /// <param name="curInfo">The cur info.</param> /// <param name="newInfo">The new info.</param> private void PutUserInfo( DirectoryEntry e, ADUserInfo curInfo, ADUserInfo newInfo ) { // Reset for accumulating. debugSettedWPValues = string.Empty; if ( curInfo.CN != newInfo.CN ) { SetWP( e.Properties, @"cn", newInfo.CN ); } if ( curInfo.CN != newInfo.Name ) { SetWP( e.Properties, @"name", newInfo.Name ); } if ( curInfo.FirstName != newInfo.FirstName ) { SetWP( e.Properties, @"givenName", newInfo.FirstName ); } if ( curInfo.LastName != newInfo.LastName ) { SetWP( e.Properties, @"sn", newInfo.LastName ); } if ( curInfo.Initials != newInfo.Initials ) { SetWP( e.Properties, @"initials", newInfo.Initials ); } if ( curInfo.Description != newInfo.Description ) { SetWP( e.Properties, @"description", newInfo.Description ); } if ( curInfo.StreetAddress != newInfo.StreetAddress ) { SetWP( e.Properties, @"streetAddress", newInfo.StreetAddress ); } if ( curInfo.PostOfficeBox != newInfo.PostOfficeBox ) { SetWP( e.Properties, @"postOfficeBox", newInfo.PostOfficeBox ); } if ( curInfo.Zip != newInfo.Zip ) { SetWP( e.Properties, @"postalCode", newInfo.Zip ); } if ( curInfo.City != newInfo.City ) { SetWP( e.Properties, @"l", newInfo.City ); } if ( curInfo.State != newInfo.State ) { SetWP( e.Properties, @"st", newInfo.State ); } if ( curInfo.CountryCode != newInfo.CountryCode ) { SetWP( e.Properties, @"c", newInfo.CountryCode ); } if ( curInfo.TelephoneNumber != newInfo.TelephoneNumber ) { SetWP( e.Properties, @"telephoneNumber", newInfo.TelephoneNumber ); } if ( curInfo.MobileNumber != newInfo.MobileNumber ) { SetWP( e.Properties, @"mobile", newInfo.MobileNumber ); } if ( curInfo.FaxNumber != newInfo.FaxNumber ) { SetWP( e.Properties, @"facsimileTelephoneNumber", newInfo.FaxNumber ); } if ( curInfo.EMail != newInfo.EMail ) { SetWP( e.Properties, @"mail", newInfo.EMail ); } if ( curInfo.WwwHomePage != newInfo.WwwHomePage ) { SetWP( e.Properties, @"wwwHomePage", newInfo.WwwHomePage ); } if ( curInfo.Title != newInfo.Title ) { SetWP( e.Properties, @"title", newInfo.Title ); } if ( curInfo.Department != newInfo.Department ) { SetWP( e.Properties, @"department", newInfo.Department ); } if ( curInfo.Company != newInfo.Company ) { SetWP( e.Properties, @"company", newInfo.Company ); } if ( curInfo.PrimaryGroupID != newInfo.PrimaryGroupID ) { SetWP( e.Properties, @"primaryGroupID", newInfo.PrimaryGroupID ); } if ( curInfo.Manager != newInfo.Manager ) { SetWP( e.Properties, @"manager", newInfo.Manager ); } }
/// <summary> /// Gets the user info by searcher. /// </summary> /// <param name="searcher">The searcher.</param> /// <returns></returns> private ADUserInfo GetUserInfoBySearcher( DirectorySearcher searcher ) { searcher.SizeLimit = adSizeReturn; searcher.PropertiesToLoad.Add( @"userAccountControl" ); searcher.PropertiesToLoad.Add( @"objectGUID" ); searcher.PropertiesToLoad.Add( @"objectSid" ); searcher.PropertiesToLoad.Add( @"sAMAccountName" ); searcher.PropertiesToLoad.Add( @"cn" ); searcher.PropertiesToLoad.Add( @"name" ); searcher.PropertiesToLoad.Add( @"givenName" ); searcher.PropertiesToLoad.Add( @"sn" ); searcher.PropertiesToLoad.Add( @"initials" ); searcher.PropertiesToLoad.Add( @"description" ); searcher.PropertiesToLoad.Add( @"streetAddress" ); searcher.PropertiesToLoad.Add( @"postOfficeBox" ); searcher.PropertiesToLoad.Add( @"postalCode" ); searcher.PropertiesToLoad.Add( @"c" ); searcher.PropertiesToLoad.Add( @"st" ); searcher.PropertiesToLoad.Add( @"l" ); searcher.PropertiesToLoad.Add( @"telephoneNumber" ); searcher.PropertiesToLoad.Add( @"mobile" ); searcher.PropertiesToLoad.Add( @"facsimileTelephoneNumber" ); searcher.PropertiesToLoad.Add( @"mail" ); searcher.PropertiesToLoad.Add( @"wwwHomePage" ); searcher.PropertiesToLoad.Add( @"title" ); searcher.PropertiesToLoad.Add( @"department" ); searcher.PropertiesToLoad.Add( @"company" ); searcher.PropertiesToLoad.Add( @"manager" ); searcher.PropertiesToLoad.Add( @"primaryGroupID" ); // -- SearchResult result = searcher.FindOne(); if ( result == null ) { LogCentral.Current.LogDebug( string.Format( @"GetUserInfo(): (A) searcher.FindOne() returned NULL, exiting with return value NULL (The LDAP query was '{0}').", searcher.Filter ) ); return null; } else { ADUserInfo info = new ADUserInfo( this ); // Add relative DN. string dn = result.Path; string basePath = string.Format( @"LDAP://{0}", configuration.LdapServer ); if ( dn.StartsWith( basePath, StringComparison.InvariantCultureIgnoreCase ) ) { dn = dn.Substring( basePath.Length ).Trim( '/' ); } info.DN = dn; // -- byte[] guidBytes = GetPropertyValueByteArray( result.Properties[@"objectGUID"] ); byte[] sidBytes = GetPropertyValueByteArray( result.Properties[@"objectSid"] ); info.Guid = new Guid( guidBytes ); info.Sid = ConvertByteToStringSid( sidBytes ); info.AccountControlFlags = (ADUserFlags)Convert.ToUInt32( GetRP( result.Properties[@"userAccountControl"] ) ); info.SamName = ReadFieldString( GetRP( result.Properties[@"sAMAccountName"] ) ); info.CN = ReadFieldString( GetRP( result.Properties[@"cn"] ) ); info.Name = ReadFieldString( GetRP( result.Properties[@"name"] ) ); info.FirstName = ReadFieldString( GetRP( result.Properties[@"givenName"] ) ); info.LastName = ReadFieldString( GetRP( result.Properties[@"sn"] ) ); info.Initials = ReadFieldString( GetRP( result.Properties[@"initials"] ) ); info.Description = ReadFieldString( GetRP( result.Properties[@"description"] ) ); info.StreetAddress = ReadFieldString( GetRP( result.Properties[@"streetAddress"] ) ); info.PostOfficeBox = ReadFieldString( GetRP( result.Properties[@"postOfficeBox"] ) ); info.Zip = ReadFieldString( GetRP( result.Properties[@"postalCode"] ) ); info.City = ReadFieldString( GetRP( result.Properties[@"l"] ) ); info.State = ReadFieldString( GetRP( result.Properties[@"st"] ) ); info.CountryCode = ReadFieldString( GetRP( result.Properties[@"c"] ) ); info.TelephoneNumber = ReadFieldString( GetRP( result.Properties[@"telephoneNumber"] ) ); info.MobileNumber = ReadFieldString( GetRP( result.Properties[@"mobile"] ) ); info.FaxNumber = ReadFieldString( GetRP( result.Properties[@"facsimileTelephoneNumber"] ) ); info.EMail = ReadFieldString( GetRP( result.Properties[@"mail"] ) ); info.WwwHomePage = ReadFieldString( GetRP( result.Properties[@"wwwHomePage"] ) ); info.Title = ReadFieldString( GetRP( result.Properties[@"title"] ) ); info.Department = ReadFieldString( GetRP( result.Properties[@"department"] ) ); info.Company = ReadFieldString( GetRP( result.Properties[@"company"] ) ); info.Manager = ReadFieldString( GetRP( result.Properties[@"manager"] ) ); info.PrimaryGroupID = ReadFieldLong( GetRP( result.Properties[@"primaryGroupID"] ) ); // -- return info; } }