Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members

LDAPSynchConnection.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *  filename  : LDAPSynchConnection.h
00003  *  authors   : Salvatore Monforte <salvatore.monforte@ct.infn.it>
00004  *  copyright : (C) 2001, 2002 by INFN
00005  ***************************************************************************/
00006 
00007 // $Id:
00008 
00016 #ifndef _LDAPSYNCHCONNECTION_
00017 #define _LDAPSYNCHCONNECTION_ 
00018 
00019 #include <map>
00020 #include <string>
00021 #include <vector>
00022 #include <sys/time.h>
00023 #include <ldap.h>
00024 #include <lber.h>
00025 
00026 #ifdef WITH_LDAP_EXCEPTIONS
00027 #include "edg/workload/common/ldif2classad/exceptions.h"
00028 #endif 
00029 
00031 #include "edg/workload/common/ldif2classad/LDAPConnection.h"
00032 #include "edg/workload/common/ldif2classad/LDIFObject.h"
00033 
00034 namespace edg {
00035 namespace workload {
00036 namespace common {
00037 namespace ldif2classad {
00038 
00039 typedef std::pair<std::string,std::string > UnknownAttrPair;
00040 typedef std::map<std::string, std::vector<UnknownAttrPair> > UnknownAttrMap;
00041 typedef std::map<std::string, LDIFObject> LDIFObjectMap;
00042 typedef std::vector<std::string> DNVector;
00043 typedef DNVector::const_iterator DNIterator;
00044 
00050 class ldap_result_entry_t : public generic_result_entry_t
00051 {
00052 public:
00058   ldap_result_entry_t(const DNVector& dns,
00059                       const UnknownAttrMap& undefined_attrs,
00060                       const LDIFObjectMap& objects)
00061   {
00062     m_dns = &dns;
00063     m_undefined_attrs = &undefined_attrs;
00064     m_objects = &objects;
00065 
00066     m_itr = m_dns->begin();
00067   }  
00068 
00073   bool next()
00074   {
00075     if( good() ) {
00076       m_itr++;
00077       return ( m_itr != m_dns->end() );
00078     }
00079     return false;
00080   }
00085   bool good () const 
00086   {
00087     return ( m_itr != m_dns->end() );
00088   }
00093   std::string distinguished_name() const 
00094   {
00095     if (good())
00096       return *m_itr;
00097 
00098     return std::string();
00099   }
00104   LDIFObject* value() 
00105   {
00106     object = LDIFObject();
00107 
00108     if (!good()) return &object;
00109 
00110     UnknownAttrMap::const_iterator it = m_undefined_attrs->find(*m_itr);
00111     if (it != m_undefined_attrs->end()) {
00112 #ifdef WITH_LDAP_EXCEPTIONS
00113       const std::vector<UnknownAttrPair>& undefined_pairs = it->second;
00114 
00115       if (undefined_pairs.size() > 0) {
00116         // report first error message
00117         const std::string& error_str = undefined_pairs.begin()->first;
00118         throw UndefinedValueException(std::string("LDIFObject::value()"),
00119                             std::string("ldap_get_values()"), error_str);
00120       }
00121 #endif
00122     }
00123 
00124     LDIFObjectMap::const_iterator it2 = m_objects->find(*m_itr);
00125     if (it2 != m_objects->end()) {
00126       object = it2->second;
00127     }
00128 
00129     return &object;
00130   }
00131 
00132 private:
00133 
00134   /* DN vector iterator */
00135   DNIterator m_itr;
00136 
00137   /* Vector of DN strings */
00138   const DNVector *m_dns;
00139 
00140   /* Map of DNs to pairs of undefined attributes found in that DN, along with the ldap error */
00141   const UnknownAttrMap *m_undefined_attrs;
00142 
00143   /* Map of DNs to LDIFObjects */
00144   const LDIFObjectMap *m_objects;
00145 
00146   /* LDIF object that holds a copy of current object for return to the user */
00147   LDIFObject object;
00148 };
00149 
00155 class ldap_search_result_t : public generic_search_result_t 
00156 {
00157 public:
00161   ldap_search_result_t(LDAPMessage* ldresult, LDAP* ld) 
00162   {
00163     m_good = (ldresult != NULL && ld != NULL);
00164     if (good()) {
00165       m_nresults = ldap_count_entries(ld, ldresult);
00166       if (empty()) {
00167         ldap_msgfree(ldresult);
00168         return;
00169       }
00170     } else {
00171       return;
00172     }
00173         
00174     LDAPMessage* ldap_1st_entry = ldap_first_entry( ld, ldresult );
00175     if( ldap_1st_entry == NULL ) {
00176       m_good = false;
00177 #ifdef WITH_LDAP_EXCEPTIONS
00178       std::string error_msg( ldap_err2string( ldap_result2error(ld, ldresult, 0) ) );
00179       throw QueryException(std::string("ldap_search_result_t"),
00180                            std::string("ldap_first_entry()"), error_msg);
00181 #endif
00182       return;
00183     }
00184 
00185     LDAPMessage *lne = ldap_1st_entry;
00186     do {
00187       char *dn_ptr = ldap_get_dn( ld, lne );
00188       std::string dn(dn_ptr);
00189       ldap_memfree(dn_ptr);
00190 
00191       BerElement *ber = NULL;
00192       LDIFObject this_object;
00193       char *attribute = NULL;
00194 
00195       for(attribute = ldap_first_attribute(ld, lne, &ber); 
00196           attribute; attribute = ldap_next_attribute(ld, lne, ber) ) {
00197       
00198         char **values = ldap_get_values(ld, lne, attribute);
00199         if( values ) {
00200           for(int i=0; values[i]!=NULL; i++)
00201             this_object.add( (std::string)attribute, (std::string)values[i] );
00202           ldap_value_free(values);
00203         } else {
00204           std::string error_msg( ldap_err2string( ldap_result2error(ld, lne, 0) ) );
00205           std::string attr_name(attribute);
00206 
00207           m_undefined_attrs[dn].push_back(std::make_pair(error_msg,attr_name));
00208         }
00209         ldap_memfree(attribute);
00210       }
00211       if( ber != NULL ) ber_free( ber, 0 );
00212       m_dns.push_back(dn);
00213       m_objects[dn] = this_object;
00214     } while(good() && (lne = ldap_next_entry(ld, lne)) != NULL);
00215     ldap_msgfree(ldresult);
00216   } 
00217           
00218   ~ldap_search_result_t() 
00219   {
00220   }
00221 
00225   bool good() const { return m_good; }
00226   bool empty() const { return ( good() && (m_nresults == 0) ); }
00231   generic_result_entry_t* make_first_entry() const
00232   {
00233     if (!good()) return NULL;
00234 
00235     ldap_result_entry_t *r = new ldap_result_entry_t( m_dns, m_undefined_attrs, m_objects );
00236     return (r);
00237   }
00238   
00239 private:
00240   /* Indicates whether the ldap_search_result_t object contains a valid result */
00241   bool m_good;
00242 
00243   /* Is the object is good, contains the number of entries in the result */
00244   int m_nresults;
00245 
00246   /* Vector of DN strings */
00247   DNVector m_dns;
00248   
00249   /* Map of DNs to pairs of undefined attributes found in that DN, along with the ldap error */
00250   UnknownAttrMap m_undefined_attrs;
00251 
00252   /* Map of DNs to LDIFObjects */
00253   LDIFObjectMap m_objects;
00254 };
00255 
00263 class LDAPSynchConnection : public LDAPConnection
00264 {
00265 public:
00269   LDAPSynchConnection(const std::string&, const std::string&, int, long = 15);
00270   
00274   virtual ~LDAPSynchConnection();
00275   
00281   bool open();
00287   bool close();
00294   generic_search_result_t* execute(LDAPQuery* q); 
00299   bool is_established() const;
00300   std::string error() const { return (saved_error) ? std::string( ldap_err2string(ldap_last_error) ) : std::string("No error available"); }
00301 
00302 private:
00303   char** make_topics( const std::vector<std::string>& );
00304   bool l_open(int&, bool&, bool&);
00305   void l_note_failure();
00306 
00307 private:
00309   struct timeval timeout;
00310   int source_port;
00311   std::string source_name;
00312   std::string base_dn;
00313   LDAP* handle;
00314 
00316   int ldap_last_error;
00317 
00319   bool saved_error;
00320   
00322   int max_retries;
00323 
00325   int failures;
00326 };
00327 
00328 } // namespace ldif2classad 
00329 } // namespace common
00330 } // namespace workload
00331 } // namespace edg 
00332 
00333 #endif
00334 
00335 /*
00336   Local Variables:
00337   mode: c++
00338   End:
00339 */

Generated on Wed Mar 1 00:37:55 2006 for COMMON API - configuration, jobid, ldif2classadi, logger, process, requestad, socket++i, task, utilities by doxygen 1.3.5