/* Copyright (C) 2003 Frédéric Giudicelli (contact_nos@yahoo.com). All rights reserved. This product includes cryptographic software written by Eric Young (eay@cryptsoft.com) This program is released under the GPL with the additional exemption that compiling, linking, and/or using OpenSSL is allowed. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // AutoSynchLDAP.cpp: implementation of the AutoSynchLDAP class. // ////////////////////////////////////////////////////////////////////// #include "AutoSynchLDAP.h" #include #include "svintl.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// AutoSynchLDAP::AutoSynchLDAP() { m_Logging = NULL; m_event = NULL; m_group_id = 0; hThreadSynchLdap.Create(ThreadSynchLdap, this); } AutoSynchLDAP::~AutoSynchLDAP() { Stop(); } bool AutoSynchLDAP::Start(const mString & ldap_server, unsigned long ldap_port, const mString & ldap_username, const mString & ldap_password, const mString & ldap_base, const mString & ldap_attr_name, unsigned long utf8) { Stop(); ConfAccessLock.EnterCS(); m_ldap_attr_name = ldap_attr_name; if(ldap_username.size()) m_ldap_username = ldap_username; else m_ldap_username = "anonymous"; if(!m_LdapClient.Connect(ldap_server, ldap_port, ldap_username, ldap_password, ldap_base, ldap_attr_name, utf8)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.LeaveCS(); return false; } if(!hThreadSynchLdap.Start()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_UNKNOWN); ConfAccessLock.LeaveCS(); return false; } ConfAccessLock.LeaveCS(); return true; } void AutoSynchLDAP::Stop() { MustNotProcessUIDs.clear(); hThreadSynchLdap.Stop(); } void AutoSynchLDAP::SetEventHandler(AutoSynchLDAPEvent *event) { m_event = event; } bool AutoSynchLDAP::DoSynch() { mString Filters; mVector Results; mString err; unsigned long ferr; mVector KnownUIDs; bool retval; size_t i; KnownUIDs = MustNotProcessUIDs; ERR_clear_error(); // Get known profiles if(!m_event->GetKnownUIDs(KnownUIDs)) { ERR_to_mstring(err); NewpkiDebug(LOG_LEVEL_ERROR, _sv("LDAP Synchronization"), _sv("Failed to get known ids: %s"), err.c_str()); return false; } // Set up the filters Filters = "(&"; Filters += m_ldap_filters; for(i=0; iShouldStop() && ( !me_this->m_LdapClient || !me_this->m_event || !me_this->m_group_id || !me_this->m_DnSpecs.size() || !me_this->m_Policies.EntriesCount())) { NewpkiThread::Sleep(500); } if(Thread->ShouldStop()) { NewpkiDebug(LOG_LEVEL_DEBUG, _sv("LDAP Synchronization"), _sv("LDAP Synchronization Stopped")); return; } NewpkiDebug(LOG_LEVEL_DEBUG, _sv("LDAP Synchronization"), _sv("LDAP Synchronization Initialized")); do { me_this->ConfAccessLock.EnterCS(); if(me_this->DoSynch()) { waitTime = 0; } else { waitTime = LDAP_SYNCH_WAIT_TIME; } me_this->ConfAccessLock.LeaveCS(); time(&lastTime); do { NewpkiThread::Sleep(500); time(&currTime); } while( ((currTime - lastTime) < waitTime) && !Thread->ShouldStop()); } while(!Thread->ShouldStop()); NewpkiDebug(LOG_LEVEL_DEBUG, _sv("LDAP Synchronization"), _sv("LDAP Synchronization Stopped")); } bool AutoSynchLDAP::SetOptions(bool RemoveUnknownFields, const mVector & DnSpecs, const HashTable_String & Policies, unsigned long group_id, const mString & ldap_filters) { ConfAccessLock.EnterCS(); m_ldap_filters = ldap_filters; m_group_id = group_id; m_RemoveUnknownFields = RemoveUnknownFields; m_DnSpecs = DnSpecs; if( !(m_Policies = Policies) ) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.LeaveCS(); return false; } ConfAccessLock.LeaveCS(); return true; } bool AutoSynchLDAP::ProcessResult(const LdapResult & Result) { HashTable_Dn Dn; HashTable_Dn IndexDn; size_t i; long j; unsigned long Min; unsigned long Max; const char * Name; size_t ValueLen; const char * Value; // We need to have it ! if(!Result.get_uid().size()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_DATAS); ERR_add_error_data(1, _sv("Profile has no UID")); return false; } for(i=0; i= Min) { if(!Max || ValueLen <= Max) { IndexDn.Add(m_DnSpecs[i].get_name().c_str(), Value); } } if(j != HASHTABLE_NOT_FOUND) Dn.Delete(j); } } // Are we allowed to have some fields that are not // present in the DN specs ? if(!m_RemoveUnknownFields) { for(i=0; (long)iOnNewProfile(newProfile)) { if(m_Logging) { m_Logging->LogMessage(LOG_STATUS_TYPE_SUCCESS, LOG_MESSAGE_TYPE_LDAP_AUTO_SYNCH_IMPRT, 0, m_ldap_username.c_str(), LOG_NO_OBJECTID, newProfile.get_ldapUid().c_str()); } } else { return false; } return true; } void AutoSynchLDAP::SetLogging(EntityLog *Logging) { m_Logging = Logging; }