2022-05-05 13:23:05 +00:00
// (c) Copyright Ascensio System SIA 2010-2022
//
// This program is a free software product.
// You can redistribute it and/or modify it under the terms
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
// any third-party rights.
//
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
//
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// The interactive user interfaces in modified source and object code versions of the Program must
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
//
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
// trademark law for use of our trademarks.
//
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
namespace ASC.ActiveDirectory.Novell ;
2022-05-05 13:23:05 +00:00
2022-03-17 19:44:34 +00:00
[Scope]
public class NovellLdapSearcher : IDisposable
2022-03-08 05:37:20 +00:00
{
2022-06-08 09:42:49 +00:00
protected readonly ILogger < NovellLdapSearcher > _logger ;
2022-03-17 19:44:34 +00:00
private LdapCertificateConfirmRequest _certificateConfirmRequest ;
private static readonly object _rootSync = new object ( ) ;
private readonly IConfiguration _configuration ;
private readonly NovellLdapEntryExtension _novellLdapEntryExtension ;
private LdapConnection _ldapConnection ;
public string Login { get ; private set ; }
public string Password { get ; private set ; }
public string Server { get ; private set ; }
public int PortNumber { get ; private set ; }
public bool StartTls { get ; private set ; }
public bool Ssl { get ; private set ; }
public bool AcceptCertificate { get ; private set ; }
public string AcceptCertificateHash { get ; private set ; }
public string LdapUniqueIdAttribute { get ; set ; }
private Dictionary < string , string [ ] > _capabilities ;
public bool IsConnected
2022-03-08 05:37:20 +00:00
{
2022-03-17 19:44:34 +00:00
get { return _ldapConnection ! = null & & _ldapConnection . Connected ; }
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
public NovellLdapSearcher (
IConfiguration configuration ,
2022-06-08 09:42:49 +00:00
ILogger < NovellLdapSearcher > logger ,
2022-03-17 19:44:34 +00:00
NovellLdapEntryExtension novellLdapEntryExtension )
{
2022-06-08 09:42:49 +00:00
_logger = logger ;
2022-03-17 19:44:34 +00:00
_configuration = configuration ;
_novellLdapEntryExtension = novellLdapEntryExtension ;
LdapUniqueIdAttribute = configuration [ "ldap:unique:id" ] ;
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
public void Init ( string login ,
string password ,
string server ,
int portNumber ,
bool startTls ,
bool ssl ,
bool acceptCertificate ,
string acceptCertificateHash = null )
{
Login = login ;
Password = password ;
Server = server ;
PortNumber = portNumber ;
StartTls = startTls ;
Ssl = ssl ;
AcceptCertificate = acceptCertificate ;
AcceptCertificateHash = acceptCertificateHash ;
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
public void Connect ( )
{
if ( Server . StartsWith ( "LDAP://" ) )
2022-06-15 12:39:37 +00:00
{
2022-03-17 19:44:34 +00:00
Server = Server . Substring ( "LDAP://" . Length ) ;
2022-06-15 12:39:37 +00:00
}
2022-03-08 05:37:20 +00:00
2022-05-23 20:44:45 +00:00
LdapConnection ldapConnection ;
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
if ( StartTls | | Ssl )
2022-05-23 20:44:45 +00:00
{
var ldapConnectionOptions = new LdapConnectionOptions ( ) ;
ldapConnectionOptions . ConfigureRemoteCertificateValidationCallback ( ServerCertValidationHandler ) ;
ldapConnection = new LdapConnection ( ldapConnectionOptions ) ;
}
else
{
ldapConnection = new LdapConnection ( ) ;
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
if ( Ssl )
2022-06-15 12:39:37 +00:00
{
2022-03-17 19:44:34 +00:00
ldapConnection . SecureSocketLayer = true ;
2022-06-15 12:39:37 +00:00
}
2022-03-17 19:44:34 +00:00
try
2022-03-10 11:41:46 +00:00
{
2022-03-17 19:44:34 +00:00
ldapConnection . ConnectionTimeout = 30000 ; // 30 seconds
2022-06-08 09:42:49 +00:00
_logger . DebugldapConnection ( Server , PortNumber ) ;
2022-03-17 19:44:34 +00:00
ldapConnection . Connect ( Server , PortNumber ) ;
2022-03-10 11:41:46 +00:00
2022-03-17 19:44:34 +00:00
if ( StartTls )
{
2022-06-08 09:42:49 +00:00
_logger . DebugStartTls ( ) ;
2022-03-17 19:44:34 +00:00
ldapConnection . StartTls ( ) ;
}
}
catch ( Exception ex )
2022-03-08 05:37:20 +00:00
{
2022-03-17 19:44:34 +00:00
if ( _certificateConfirmRequest = = null )
{
if ( ex . Message . StartsWith ( "Connect Error" ) )
{
throw new SocketException ( ) ;
}
if ( ex . Message . StartsWith ( "Unavailable" ) )
{
throw new NotSupportedException ( ex . Message ) ;
}
throw ;
}
2022-06-08 09:42:49 +00:00
_logger . DebugLdapCertificateConfirmationRequested ( ) ;
2022-03-17 19:44:34 +00:00
ldapConnection . Disconnect ( ) ;
var exception = new NovellLdapTlsCertificateRequestedException
{
CertificateConfirmRequest = _certificateConfirmRequest
} ;
throw exception ;
2022-03-08 05:37:20 +00:00
}
2022-03-17 19:44:34 +00:00
if ( string . IsNullOrEmpty ( Login ) | | string . IsNullOrEmpty ( Password ) )
2022-03-08 05:37:20 +00:00
{
2022-06-08 09:42:49 +00:00
_logger . DebugBindAnonymous ( ) ;
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
ldapConnection . Bind ( null , null ) ;
}
else
{
2022-06-08 09:42:49 +00:00
_logger . DebugBind ( Login ) ;
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
ldapConnection . Bind ( Login , Password ) ;
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
if ( ! ldapConnection . Bound )
{
throw new Exception ( "Bind operation wasn't completed successfully." ) ;
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
_ldapConnection = ldapConnection ;
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
private bool ServerCertValidationHandler ( object sender , X509Certificate certificate ,
X509Chain chain , SslPolicyErrors sslPolicyErrors )
{
if ( sslPolicyErrors = = SslPolicyErrors . None )
2022-06-15 12:39:37 +00:00
{
2022-03-17 19:44:34 +00:00
return true ;
2022-06-15 12:39:37 +00:00
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
lock ( _rootSync )
{
var certHash = certificate . GetCertHashString ( ) ;
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
if ( AcceptCertificate )
{
if ( AcceptCertificateHash = = null | | AcceptCertificateHash . Equals ( certHash ) )
2022-03-08 05:37:20 +00:00
{
2022-03-17 19:44:34 +00:00
return true ;
2022-03-08 05:37:20 +00:00
}
2022-03-17 19:44:34 +00:00
AcceptCertificate = false ;
AcceptCertificateHash = null ;
2022-03-08 05:37:20 +00:00
}
2022-06-08 09:42:49 +00:00
_logger . WarnSslPolicyErrors ( sslPolicyErrors ) ;
2022-03-08 05:37:20 +00:00
2022-06-08 09:42:49 +00:00
_certificateConfirmRequest = LdapCertificateConfirmRequest . FromCert ( certificate , chain , sslPolicyErrors , false , true , _logger ) ;
2022-03-17 19:44:34 +00:00
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
return false ;
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
public enum LdapScope
{
Base = LdapConnection . ScopeBase ,
One = LdapConnection . ScopeOne ,
Sub = LdapConnection . ScopeSub
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
public List < LdapObject > Search ( LdapScope scope , string searchFilter ,
string [ ] attributes = null , int limit = - 1 , LdapSearchConstraints searchConstraints = null )
{
return Search ( "" , scope , searchFilter , attributes , limit , searchConstraints ) ;
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
public List < LdapObject > Search ( string searchBase , LdapScope scope , string searchFilter ,
string [ ] attributes = null , int limit = - 1 , LdapSearchConstraints searchConstraints = null )
{
if ( ! IsConnected )
2022-06-15 12:39:37 +00:00
{
2022-03-17 19:44:34 +00:00
Connect ( ) ;
2022-06-15 12:39:37 +00:00
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
if ( searchBase = = null )
2022-06-15 12:39:37 +00:00
{
2022-03-17 19:44:34 +00:00
searchBase = "" ;
2022-06-15 12:39:37 +00:00
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
var entries = new List < LdapEntry > ( ) ;
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
if ( string . IsNullOrEmpty ( searchFilter ) )
2022-06-15 12:39:37 +00:00
{
2022-03-17 19:44:34 +00:00
return new List < LdapObject > ( ) ;
2022-06-15 12:39:37 +00:00
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
if ( attributes = = null )
{
if ( string . IsNullOrEmpty ( LdapUniqueIdAttribute ) )
2022-03-08 05:37:20 +00:00
{
2022-03-17 19:44:34 +00:00
attributes = new [ ]
{
"*" , LdapConstants . RfcLDAPAttributes . ENTRY_DN , LdapConstants . RfcLDAPAttributes . ENTRY_UUID ,
LdapConstants . RfcLDAPAttributes . NS_UNIQUE_ID , LdapConstants . RfcLDAPAttributes . GUID
} ;
}
else
{
attributes = new [ ] { "*" , LdapUniqueIdAttribute } ;
2022-03-08 05:37:20 +00:00
}
}
2022-03-17 19:44:34 +00:00
var ldapSearchConstraints = searchConstraints ? ? new LdapSearchConstraints
2022-03-08 05:37:20 +00:00
{
2022-03-17 19:44:34 +00:00
// Maximum number of search results to return.
// The value 0 means no limit. The default is 1000.
MaxResults = limit = = - 1 ? 0 : limit ,
// Returns the number of results to block on during receipt of search results.
// This should be 0 if intermediate results are not needed, and 1 if results are to be processed as they come in.
//BatchSize = 0,
// The maximum number of referrals to follow in a sequence during automatic referral following.
// The default value is 10. A value of 0 means no limit.
HopLimit = 0 ,
// Specifies whether referrals are followed automatically
// Referrals of any type other than to an LDAP server (for example, a referral URL other than ldap://something) are ignored on automatic referral following.
// The default is false.
ReferralFollowing = true ,
// The number of seconds to wait for search results.
// Sets the maximum number of seconds that the server is to wait when returning search results.
//ServerTimeLimit = 600000, // 10 minutes
// Sets the maximum number of milliseconds the client waits for any operation under these constraints to complete.
// If the value is 0, there is no maximum time limit enforced by the API on waiting for the operation results.
//TimeLimit = 600000 // 10 minutes
} ;
var queue = _ldapConnection . Search ( searchBase ,
( int ) scope , searchFilter , attributes , false , ldapSearchConstraints ) ;
while ( queue . HasMore ( ) )
{
LdapEntry nextEntry ;
try
2022-03-08 05:37:20 +00:00
{
2022-03-17 19:44:34 +00:00
nextEntry = queue . Next ( ) ;
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
if ( nextEntry = = null )
2022-06-15 12:39:37 +00:00
{
2022-03-17 19:44:34 +00:00
continue ;
2022-06-15 12:39:37 +00:00
}
2022-03-17 19:44:34 +00:00
}
catch ( LdapException ex )
{
if ( ! string . IsNullOrEmpty ( ex . Message ) & & ex . Message . Contains ( "Sizelimit Exceeded" ) )
2022-03-08 05:37:20 +00:00
{
2022-03-17 19:44:34 +00:00
if ( ! string . IsNullOrEmpty ( Login ) & & ! string . IsNullOrEmpty ( Password ) & & limit = = - 1 )
2022-03-08 05:37:20 +00:00
{
2022-06-08 09:42:49 +00:00
_logger . WarnStartTrySearchSimple ( ) ;
2022-03-17 19:44:34 +00:00
List < LdapObject > simpleResults ;
if ( TrySearchSimple ( searchBase , scope , searchFilter , out simpleResults , attributes , limit ,
searchConstraints ) )
{
if ( entries . Count > = simpleResults . Count )
2022-06-15 12:39:37 +00:00
{
2022-03-17 19:44:34 +00:00
break ;
2022-06-15 12:39:37 +00:00
}
2022-03-17 19:44:34 +00:00
return simpleResults ;
}
2022-03-08 05:37:20 +00:00
}
2022-03-17 19:44:34 +00:00
break ;
2022-03-08 05:37:20 +00:00
}
2022-06-08 09:42:49 +00:00
_logger . ErrorSearch ( searchFilter , ex ) ;
2022-03-17 19:44:34 +00:00
continue ;
2022-03-08 05:37:20 +00:00
}
2022-03-17 19:44:34 +00:00
entries . Add ( nextEntry ) ;
if ( string . IsNullOrEmpty ( LdapUniqueIdAttribute ) )
{
LdapUniqueIdAttribute = GetLdapUniqueId ( nextEntry ) ;
}
2022-03-08 05:37:20 +00:00
}
2022-03-17 19:44:34 +00:00
var result = _novellLdapEntryExtension . ToLdapObjects ( entries , LdapUniqueIdAttribute ) ;
return result ;
}
private bool TrySearchSimple ( string searchBase , LdapScope scope , string searchFilter , out List < LdapObject > results ,
string [ ] attributes = null , int limit = - 1 , LdapSearchConstraints searchConstraints = null )
{
try
2022-03-08 05:37:20 +00:00
{
2022-03-17 19:44:34 +00:00
results = SearchSimple ( searchBase , scope , searchFilter , attributes , limit , searchConstraints ) ;
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
return true ;
}
catch ( Exception ex )
2022-03-08 05:37:20 +00:00
{
2022-06-08 09:42:49 +00:00
_logger . ErrorTrySearchSimple ( ex ) ;
2022-03-08 05:37:20 +00:00
}
2022-03-17 19:44:34 +00:00
results = null ;
return false ;
}
public List < LdapObject > SearchSimple ( string searchBase , LdapScope scope , string searchFilter ,
string [ ] attributes = null , int limit = - 1 , LdapSearchConstraints searchConstraints = null )
{
if ( ! IsConnected )
2022-06-15 12:39:37 +00:00
{
2022-03-17 19:44:34 +00:00
Connect ( ) ;
2022-06-15 12:39:37 +00:00
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
if ( searchBase = = null )
2022-06-15 12:39:37 +00:00
{
2022-03-17 19:44:34 +00:00
searchBase = "" ;
2022-06-15 12:39:37 +00:00
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
var entries = new List < LdapEntry > ( ) ;
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
if ( string . IsNullOrEmpty ( searchFilter ) )
2022-06-15 12:39:37 +00:00
{
2022-03-17 19:44:34 +00:00
return new List < LdapObject > ( ) ;
2022-06-15 12:39:37 +00:00
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
if ( attributes = = null )
{
if ( string . IsNullOrEmpty ( LdapUniqueIdAttribute ) )
2022-03-08 05:37:20 +00:00
{
2022-03-17 19:44:34 +00:00
attributes = new [ ]
2022-03-08 05:37:20 +00:00
{
"*" , LdapConstants . RfcLDAPAttributes . ENTRY_DN , LdapConstants . RfcLDAPAttributes . ENTRY_UUID ,
LdapConstants . RfcLDAPAttributes . NS_UNIQUE_ID , LdapConstants . RfcLDAPAttributes . GUID
} ;
}
2022-03-17 19:44:34 +00:00
else
2022-03-08 05:37:20 +00:00
{
2022-03-17 19:44:34 +00:00
attributes = new [ ] { "*" , LdapUniqueIdAttribute } ;
}
}
var ldapSearchConstraints = searchConstraints ? ? new LdapSearchConstraints
{
// Maximum number of search results to return.
// The value 0 means no limit. The default is 1000.
MaxResults = limit = = - 1 ? 0 : limit ,
// Returns the number of results to block on during receipt of search results.
// This should be 0 if intermediate results are not needed, and 1 if results are to be processed as they come in.
//BatchSize = 0,
// The maximum number of referrals to follow in a sequence during automatic referral following.
// The default value is 10. A value of 0 means no limit.
HopLimit = 0 ,
// Specifies whether referrals are followed automatically
// Referrals of any type other than to an LDAP server (for example, a referral URL other than ldap://something) are ignored on automatic referral following.
// The default is false.
ReferralFollowing = true ,
// The number of seconds to wait for search results.
// Sets the maximum number of seconds that the server is to wait when returning search results.
//ServerTimeLimit = 600000, // 10 minutes
// Sets the maximum number of milliseconds the client waits for any operation under these constraints to complete.
// If the value is 0, there is no maximum time limit enforced by the API on waiting for the operation results.
//TimeLimit = 600000 // 10 minutes
} ;
// initially, cookie must be set to an empty string
var pageSize = 2 ;
2022-06-15 12:39:37 +00:00
var cookie = Array . ConvertAll ( Encoding . ASCII . GetBytes ( "" ) , b = > unchecked ( b ) ) ;
2022-03-17 19:44:34 +00:00
var i = 0 ;
do
{
var requestControls = new LdapControl [ 1 ] ;
requestControls [ 0 ] = new SimplePagedResultsControl ( pageSize , cookie ) ;
ldapSearchConstraints . SetControls ( requestControls ) ;
_ldapConnection . Constraints = ldapSearchConstraints ;
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
var res = _ldapConnection . Search ( searchBase ,
( int ) scope , searchFilter , attributes , false , ( LdapSearchConstraints ) null ) ;
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
while ( res . HasMore ( ) )
2022-03-08 05:37:20 +00:00
{
LdapEntry nextEntry ;
try
{
2022-03-17 19:44:34 +00:00
nextEntry = res . Next ( ) ;
2022-03-08 05:37:20 +00:00
if ( nextEntry = = null )
2022-06-15 12:39:37 +00:00
{
2022-03-08 05:37:20 +00:00
continue ;
2022-06-15 12:39:37 +00:00
}
2022-03-08 05:37:20 +00:00
}
catch ( LdapException ex )
{
2022-03-17 19:44:34 +00:00
if ( ex is LdapReferralException )
2022-06-15 12:39:37 +00:00
{
2022-03-17 19:44:34 +00:00
continue ;
2022-06-15 12:39:37 +00:00
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
if ( ! string . IsNullOrEmpty ( ex . Message ) & & ex . Message . Contains ( "Sizelimit Exceeded" ) )
2022-06-15 12:39:37 +00:00
{
2022-03-08 05:37:20 +00:00
break ;
2022-06-15 12:39:37 +00:00
}
2022-03-08 05:37:20 +00:00
2022-06-08 09:42:49 +00:00
_logger . ErrorSearchSimple ( searchFilter , ex ) ;
2022-03-08 05:37:20 +00:00
continue ;
}
2022-06-08 09:42:49 +00:00
_logger . DebugDnEnumeration ( + + i , nextEntry . Dn ) ;
2022-03-17 19:44:34 +00:00
2022-03-08 05:37:20 +00:00
entries . Add ( nextEntry ) ;
if ( string . IsNullOrEmpty ( LdapUniqueIdAttribute ) )
{
LdapUniqueIdAttribute = GetLdapUniqueId ( nextEntry ) ;
}
}
2022-03-17 19:44:34 +00:00
// Server should send back a control irrespective of the
// status of the search request
var controls = res . ResponseControls ;
if ( controls = = null )
2022-03-08 05:37:20 +00:00
{
2022-06-08 09:42:49 +00:00
_logger . DebugNoControlsReturned ( ) ;
2022-03-17 19:44:34 +00:00
cookie = null ;
2022-03-08 05:37:20 +00:00
}
2022-03-17 19:44:34 +00:00
else
2022-03-08 05:37:20 +00:00
{
2022-03-17 19:44:34 +00:00
// Multiple controls could have been returned
2022-05-18 10:50:39 +00:00
foreach ( var control in controls )
2022-03-17 19:44:34 +00:00
{
/* Is this the LdapPagedResultsResponse control? */
if ( ! ( control is SimplePagedResultsControl ) )
2022-06-15 12:39:37 +00:00
{
2022-03-17 19:44:34 +00:00
continue ;
2022-06-15 12:39:37 +00:00
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
var response = new SimplePagedResultsControl ( control . Id ,
control . Critical , control . GetValue ( ) ) ;
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
cookie = response . Cookie ;
}
}
// if cookie is empty, we are done.
} while ( cookie ! = null & & cookie . Length > 0 ) ;
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
var result = _novellLdapEntryExtension . ToLdapObjects ( entries , LdapUniqueIdAttribute ) ;
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
return result ;
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
public Dictionary < string , string [ ] > GetCapabilities ( )
{
if ( _capabilities ! = null )
2022-06-15 12:39:37 +00:00
{
2022-03-17 19:44:34 +00:00
return _capabilities ;
2022-06-15 12:39:37 +00:00
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
_capabilities = new Dictionary < string , string [ ] > ( ) ;
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
try
{
var ldapSearchConstraints = new LdapSearchConstraints
2022-03-08 05:37:20 +00:00
{
2022-03-17 19:44:34 +00:00
MaxResults = int . MaxValue ,
2022-03-08 05:37:20 +00:00
HopLimit = 0 ,
2022-03-17 19:44:34 +00:00
ReferralFollowing = true
2022-03-08 05:37:20 +00:00
} ;
2022-03-17 19:44:34 +00:00
var ldapSearchResults = _ldapConnection . Search ( "" , LdapConnection . ScopeBase , LdapConstants . OBJECT_FILTER ,
new [ ] { "*" , "supportedControls" , "supportedCapabilities" } , false , ldapSearchConstraints ) ;
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
while ( ldapSearchResults . HasMore ( ) )
2022-03-08 05:37:20 +00:00
{
2022-03-17 19:44:34 +00:00
LdapEntry nextEntry ;
try
2022-03-08 05:37:20 +00:00
{
2022-03-17 19:44:34 +00:00
nextEntry = ldapSearchResults . Next ( ) ;
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
if ( nextEntry = = null )
2022-06-15 12:39:37 +00:00
{
2022-03-08 05:37:20 +00:00
continue ;
2022-06-15 12:39:37 +00:00
}
2022-03-08 05:37:20 +00:00
}
2022-03-17 19:44:34 +00:00
catch ( LdapException ex )
2022-03-08 05:37:20 +00:00
{
2022-06-08 09:42:49 +00:00
_logger . ErrorGetCapabilitiesLoopResultsFailed ( ex ) ;
2022-03-17 19:44:34 +00:00
continue ;
2022-03-08 05:37:20 +00:00
}
2022-03-17 19:44:34 +00:00
var attributeSet = nextEntry . GetAttributeSet ( ) ;
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
var ienum = attributeSet . GetEnumerator ( ) ;
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
while ( ienum . MoveNext ( ) )
2022-03-08 05:37:20 +00:00
{
2022-03-17 19:44:34 +00:00
var attribute = ( LdapAttribute ) ienum . Current ;
if ( attribute = = null )
2022-06-15 12:39:37 +00:00
{
2022-03-08 05:37:20 +00:00
continue ;
2022-06-15 12:39:37 +00:00
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
var attributeName = attribute . Name ;
var attributeVals = attribute . StringValueArray
. ToList ( )
. Select ( s = >
{
2022-06-15 12:39:37 +00:00
if ( Base64 . IsLdifSafe ( s ) )
{
return s ;
}
2022-03-17 19:44:34 +00:00
s = Base64 . Encode ( s ) ;
return s ;
} ) . ToArray ( ) ;
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
_capabilities . Add ( attributeName , attributeVals ) ;
2022-03-08 05:37:20 +00:00
}
}
}
2022-03-17 19:44:34 +00:00
catch ( Exception ex )
2022-03-08 05:37:20 +00:00
{
2022-06-08 09:42:49 +00:00
_logger . ErrorGetCapabilitiesFailed ( ex ) ;
2022-03-17 19:44:34 +00:00
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
return _capabilities ;
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
private string GetLdapUniqueId ( LdapEntry ldapEntry )
{
try
{
var ldapUniqueIdAttribute = _configuration [ "ldap:unique:id" ] ;
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
if ( ldapUniqueIdAttribute ! = null )
2022-06-15 12:39:37 +00:00
{
2022-03-08 05:37:20 +00:00
return ldapUniqueIdAttribute ;
2022-06-15 12:39:37 +00:00
}
2022-03-17 19:44:34 +00:00
if ( ! string . IsNullOrEmpty (
_novellLdapEntryExtension . GetAttributeValue ( ldapEntry , LdapConstants . ADSchemaAttributes . OBJECT_SID ) as string ) )
{
ldapUniqueIdAttribute = LdapConstants . ADSchemaAttributes . OBJECT_SID ;
}
else if ( ! string . IsNullOrEmpty (
_novellLdapEntryExtension . GetAttributeValue ( ldapEntry , LdapConstants . RfcLDAPAttributes . ENTRY_UUID ) as string ) )
{
ldapUniqueIdAttribute = LdapConstants . RfcLDAPAttributes . ENTRY_UUID ;
2022-03-08 05:37:20 +00:00
}
2022-03-17 19:44:34 +00:00
else if ( ! string . IsNullOrEmpty (
_novellLdapEntryExtension . GetAttributeValue ( ldapEntry , LdapConstants . RfcLDAPAttributes . NS_UNIQUE_ID ) as string ) )
2022-03-08 05:37:20 +00:00
{
2022-03-17 19:44:34 +00:00
ldapUniqueIdAttribute = LdapConstants . RfcLDAPAttributes . NS_UNIQUE_ID ;
}
else if ( ! string . IsNullOrEmpty (
_novellLdapEntryExtension . GetAttributeValue ( ldapEntry , LdapConstants . RfcLDAPAttributes . GUID ) as string ) )
{
ldapUniqueIdAttribute = LdapConstants . RfcLDAPAttributes . GUID ;
2022-03-08 05:37:20 +00:00
}
2022-03-17 19:44:34 +00:00
return ldapUniqueIdAttribute ;
2022-03-08 05:37:20 +00:00
}
2022-03-17 19:44:34 +00:00
catch ( Exception ex )
2022-03-08 05:37:20 +00:00
{
2022-06-08 09:42:49 +00:00
_logger . ErrorGetLdapUniqueId ( ex ) ;
2022-03-17 19:44:34 +00:00
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
return null ;
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
public void Dispose ( )
{
if ( ! IsConnected )
2022-06-15 12:39:37 +00:00
{
2022-03-17 19:44:34 +00:00
return ;
2022-06-15 12:39:37 +00:00
}
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
try
{
_ldapConnection . Constraints . TimeLimit = 10000 ;
_ldapConnection . SearchConstraints . ServerTimeLimit = 10000 ;
_ldapConnection . SearchConstraints . TimeLimit = 10000 ;
_ldapConnection . ConnectionTimeout = 10000 ;
2022-03-08 05:37:20 +00:00
2022-03-17 19:44:34 +00:00
if ( _ldapConnection . Tls )
2022-03-08 05:37:20 +00:00
{
2022-06-08 09:42:49 +00:00
_logger . DebugLdapConnectionStopTls ( ) ;
2022-03-17 19:44:34 +00:00
_ldapConnection . StopTls ( ) ;
2022-03-08 05:37:20 +00:00
}
2022-03-17 19:44:34 +00:00
2022-06-08 09:42:49 +00:00
_logger . DebugLdapConnectionDisconnect ( ) ;
2022-03-17 19:44:34 +00:00
_ldapConnection . Disconnect ( ) ;
2022-06-08 09:42:49 +00:00
_logger . DebugLdapConnectionDispose ( ) ;
2022-03-17 19:44:34 +00:00
_ldapConnection . Dispose ( ) ;
_ldapConnection = null ;
}
catch ( Exception ex )
{
2022-06-08 09:42:49 +00:00
_logger . ErrorLdapDisposeFailed ( ex ) ;
2022-03-08 05:37:20 +00:00
}
}
}