00001
00002
00003
00004
00005
00006
00007
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
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
00135 DNIterator m_itr;
00136
00137
00138 const DNVector *m_dns;
00139
00140
00141 const UnknownAttrMap *m_undefined_attrs;
00142
00143
00144 const LDIFObjectMap *m_objects;
00145
00146
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
00241 bool m_good;
00242
00243
00244 int m_nresults;
00245
00246
00247 DNVector m_dns;
00248
00249
00250 UnknownAttrMap m_undefined_attrs;
00251
00252
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 }
00329 }
00330 }
00331 }
00332
00333 #endif
00334
00335
00336
00337
00338
00339