]>
Commit | Line | Data |
---|---|---|
3dd1babb | 1 | diff -Nur pdns-2.9.21.1.orig/modules/ldapbackend/ldapbackend.cc pdns-2.9.21.1.int16/modules/ldapbackend/ldapbackend.cc |
2 | --- pdns-2.9.21.1.orig/modules/ldapbackend/ldapbackend.cc 2007-04-21 07:56:36.000000000 -0600 | |
3 | +++ pdns-2.9.21.1.int16/modules/ldapbackend/ldapbackend.cc 2008-10-06 10:08:55.000000000 -0600 | |
4 | @@ -433,7 +433,7 @@ | |
313ceca8 MW |
5 | continue; |
6 | } | |
7 | ||
8 | - rr.priority = (uint16_t) strtoul( (content.substr( 0, first )).c_str(), &endptr, 10 ); | |
9 | + rr.priority = (u_int16_t) strtoul( (content.substr( 0, first )).c_str(), &endptr, 10 ); | |
10 | if( *endptr != '\0' ) | |
11 | { | |
12 | L << Logger::Warning << m_myname << " Invalid " << attrname << " without priority for " << m_qname << ": " << content << endl; | |
3dd1babb | 13 | diff -Nur pdns-2.9.21.1.orig/modules/ldapbackend/ldapbackend.cc.orig pdns-2.9.21.1.int16/modules/ldapbackend/ldapbackend.cc.orig |
14 | --- pdns-2.9.21.1.orig/modules/ldapbackend/ldapbackend.cc.orig 1969-12-31 17:00:00.000000000 -0700 | |
15 | +++ pdns-2.9.21.1.int16/modules/ldapbackend/ldapbackend.cc.orig 2007-04-21 07:56:36.000000000 -0600 | |
16 | @@ -0,0 +1,566 @@ | |
17 | +#include "ldapbackend.hh" | |
18 | + | |
19 | + | |
20 | + | |
21 | +unsigned int ldap_host_index = 0; | |
22 | + | |
23 | + | |
24 | + | |
25 | +LdapBackend::LdapBackend( const string &suffix ) | |
26 | +{ | |
27 | + string hoststr; | |
28 | + unsigned int i, idx; | |
29 | + vector<string> hosts; | |
30 | + | |
31 | + | |
32 | + try | |
33 | + { | |
34 | + m_msgid = 0; | |
35 | + m_qname = ""; | |
36 | + m_pldap = NULL; | |
37 | + m_qlog = arg().mustDo( "query-logging" ); | |
38 | + m_default_ttl = arg().asNum( "default-ttl" ); | |
39 | + m_myname = "[LdapBackend]"; | |
40 | + | |
41 | + // we need UTC time for timestamps | |
42 | + setenv( "TZ", "", 1 ); tzset(); | |
43 | + | |
44 | + setArgPrefix( "ldap" + suffix ); | |
45 | + | |
46 | + m_getdn = false; | |
47 | + m_list_fcnt = &LdapBackend::list_simple; | |
48 | + m_lookup_fcnt = &LdapBackend::lookup_simple; | |
49 | + m_prepare_fcnt = &LdapBackend::prepare_simple; | |
50 | + | |
51 | + if( getArg( "method" ) == "tree" ) | |
52 | + { | |
53 | + m_lookup_fcnt = &LdapBackend::lookup_tree; | |
54 | + } | |
55 | + | |
56 | + if( getArg( "method" ) == "strict" || mustDo( "disable-ptrrecord" ) ) | |
57 | + { | |
58 | + m_list_fcnt = &LdapBackend::list_strict; | |
59 | + m_lookup_fcnt = &LdapBackend::lookup_strict; | |
60 | + m_prepare_fcnt = &LdapBackend::prepare_strict; | |
61 | + } | |
62 | + | |
63 | + stringtok( hosts, getArg( "host" ), ", " ); | |
64 | + idx = ldap_host_index++ % hosts.size(); | |
65 | + hoststr = hosts[idx]; | |
66 | + | |
67 | + for( i = 1; i < hosts.size(); i++ ) | |
68 | + { | |
69 | + hoststr += " " + hosts[ ( idx + i ) % hosts.size() ]; | |
70 | + } | |
71 | + | |
72 | + L << Logger::Info << m_myname << " LDAP servers = " << hoststr << endl; | |
73 | + | |
74 | + m_pldap = new PowerLDAP( hoststr.c_str(), LDAP_PORT, mustDo( "starttls" ) ); | |
75 | + m_pldap->setOption( LDAP_OPT_DEREF, LDAP_DEREF_ALWAYS ); | |
76 | + m_pldap->simpleBind( getArg( "binddn" ), getArg( "secret" ) ); | |
77 | + } | |
78 | + catch( LDAPException &le ) | |
79 | + { | |
80 | + if( m_pldap != NULL ) { delete( m_pldap ); } | |
81 | + L << Logger::Error << m_myname << " Ldap connection to server failed: " << le.what() << endl; | |
82 | + throw( AhuException( "Unable to connect to ldap server" ) ); | |
83 | + } | |
84 | + catch( exception &e ) | |
85 | + { | |
86 | + if( m_pldap != NULL ) { delete( m_pldap ); } | |
87 | + L << Logger::Error << m_myname << " Caught STL exception: " << e.what() << endl; | |
88 | + throw( AhuException( "Unable to connect to ldap server" ) ); | |
89 | + } | |
90 | + | |
91 | + L << Logger::Notice << m_myname << " Ldap connection succeeded" << endl; | |
92 | +} | |
93 | + | |
94 | + | |
95 | + | |
96 | +LdapBackend::~LdapBackend() | |
97 | +{ | |
98 | + if( m_pldap != NULL ) { delete( m_pldap ); } | |
99 | + L << Logger::Notice << m_myname << " Ldap connection closed" << endl; | |
100 | +} | |
101 | + | |
102 | + | |
103 | + | |
104 | +bool LdapBackend::list( const string& target, int domain_id ) | |
105 | +{ | |
106 | + try | |
107 | + { | |
108 | + m_qname = target; | |
109 | + m_axfrqlen = target.length(); | |
110 | + m_adomain = m_adomains.end(); // skip loops in get() first time | |
111 | + | |
112 | + return (this->*m_list_fcnt)( target, domain_id ); | |
113 | + } | |
114 | + catch( LDAPTimeout < ) | |
115 | + { | |
116 | + L << Logger::Warning << m_myname << " Unable to get zone " + target + " from LDAP directory: " << lt.what() << endl; | |
117 | + throw( DBException( "LDAP server timeout" ) ); | |
118 | + } | |
119 | + catch( LDAPException &le ) | |
120 | + { | |
121 | + L << Logger::Error << m_myname << " Unable to get zone " + target + " from LDAP directory: " << le.what() << endl; | |
122 | + throw( AhuException( "LDAP server unreachable" ) ); // try to reconnect to another server | |
123 | + } | |
124 | + catch( exception &e ) | |
125 | + { | |
126 | + L << Logger::Error << m_myname << " Caught STL exception for target " << target << ": " << e.what() << endl; | |
127 | + throw( DBException( "STL exception" ) ); | |
128 | + } | |
129 | + | |
130 | + return false; | |
131 | +} | |
132 | + | |
133 | + | |
134 | + | |
135 | +inline bool LdapBackend::list_simple( const string& target, int domain_id ) | |
136 | +{ | |
137 | + string dn; | |
138 | + string filter; | |
139 | + string qesc; | |
140 | + | |
141 | + | |
142 | + dn = getArg( "basedn" ); | |
143 | + qesc = toLower( m_pldap->escape( target ) ); | |
144 | + | |
145 | + // search for SOARecord of target | |
146 | + filter = strbind( ":target:", "associatedDomain=" + qesc, getArg( "filter-axfr" ) ); | |
147 | + m_msgid = m_pldap->search( dn, LDAP_SCOPE_SUBTREE, filter, (const char**) ldap_attrany ); | |
148 | + m_pldap->getSearchEntry( m_msgid, m_result, true ); | |
149 | + | |
150 | + if( m_result.count( "dn" ) && !m_result["dn"].empty() ) | |
151 | + { | |
152 | + dn = m_result["dn"][0]; | |
153 | + m_result.erase( "dn" ); | |
154 | + } | |
155 | + | |
156 | + prepare(); | |
157 | + filter = strbind( ":target:", "associatedDomain=*." + qesc, getArg( "filter-axfr" ) ); | |
158 | + DLOG( L << Logger::Debug << m_myname << " Search = basedn: " << dn << ", filter: " << filter << endl ); | |
159 | + m_msgid = m_pldap->search( dn, LDAP_SCOPE_SUBTREE, filter, (const char**) ldap_attrany ); | |
160 | + | |
161 | + return true; | |
162 | +} | |
163 | + | |
164 | + | |
165 | + | |
166 | +inline bool LdapBackend::list_strict( const string& target, int domain_id ) | |
167 | +{ | |
168 | + if( target.size() > 13 && target.substr( target.size() - 13, 13 ) == ".in-addr.arpa" || | |
169 | + target.size() > 9 && target.substr( target.size() - 9, 9 ) == ".ip6.arpa" ) | |
170 | + { | |
171 | + L << Logger::Warning << m_myname << " Request for reverse zone AXFR, but this is not supported in strict mode" << endl; | |
172 | + return false; // AXFR isn't supported in strict mode. Use simple mode and additional PTR records | |
173 | + } | |
174 | + | |
175 | + return list_simple( target, domain_id ); | |
176 | +} | |
177 | + | |
178 | + | |
179 | + | |
180 | +void LdapBackend::lookup( const QType &qtype, const string &qname, DNSPacket *dnspkt, int zoneid ) | |
181 | +{ | |
182 | + try | |
183 | + { | |
184 | + m_axfrqlen = 0; | |
185 | + m_qname = qname; | |
186 | + m_adomain = m_adomains.end(); // skip loops in get() first time | |
187 | + | |
188 | + if( m_qlog ) { L.log( "Query: '" + qname + "|" + qtype.getName() + "'", Logger::Error ); } | |
189 | + (this->*m_lookup_fcnt)( qtype, qname, dnspkt, zoneid ); | |
190 | + } | |
191 | + catch( LDAPTimeout < ) | |
192 | + { | |
193 | + L << Logger::Warning << m_myname << " Unable to search LDAP directory: " << lt.what() << endl; | |
194 | + throw( DBException( "LDAP server timeout" ) ); | |
195 | + } | |
196 | + catch( LDAPException &le ) | |
197 | + { | |
198 | + L << Logger::Error << m_myname << " Unable to search LDAP directory: " << le.what() << endl; | |
199 | + throw( AhuException( "LDAP server unreachable" ) ); // try to reconnect to another server | |
200 | + } | |
201 | + catch( exception &e ) | |
202 | + { | |
203 | + L << Logger::Error << m_myname << " Caught STL exception for qname " << qname << ": " << e.what() << endl; | |
204 | + throw( DBException( "STL exception" ) ); | |
205 | + } | |
206 | +} | |
207 | + | |
208 | + | |
209 | + | |
210 | +void LdapBackend::lookup_simple( const QType &qtype, const string &qname, DNSPacket *dnspkt, int zoneid ) | |
211 | +{ | |
212 | + string filter, attr, qesc; | |
213 | + char** attributes = ldap_attrany + 1; // skip associatedDomain | |
214 | + char* attronly[] = { NULL, "dNSTTL", "modifyTimestamp", NULL }; | |
215 | + | |
216 | + | |
217 | + qesc = toLower( m_pldap->escape( qname ) ); | |
218 | + filter = "associatedDomain=" + qesc; | |
219 | + | |
220 | + if( qtype.getCode() != QType::ANY ) | |
221 | + { | |
222 | + attr = qtype.getName() + "Record"; | |
223 | + filter = "&(" + filter + ")(" + attr + "=*)"; | |
224 | + attronly[0] = (char*) attr.c_str(); | |
225 | + attributes = attronly; | |
226 | + } | |
227 | + | |
228 | + filter = strbind( ":target:", filter, getArg( "filter-lookup" ) ); | |
229 | + | |
230 | + DLOG( L << Logger::Debug << m_myname << " Search = basedn: " << getArg( "basedn" ) << ", filter: " << filter << ", qtype: " << qtype.getName() << endl ); | |
231 | + m_msgid = m_pldap->search( getArg( "basedn" ), LDAP_SCOPE_SUBTREE, filter, (const char**) attributes ); | |
232 | +} | |
233 | + | |
234 | + | |
235 | + | |
236 | +void LdapBackend::lookup_strict( const QType &qtype, const string &qname, DNSPacket *dnspkt, int zoneid ) | |
237 | +{ | |
238 | + int len; | |
239 | + vector<string> parts; | |
240 | + string filter, attr, qesc; | |
241 | + char** attributes = ldap_attrany + 1; // skip associatedDomain | |
242 | + char* attronly[] = { NULL, "dNSTTL", "modifyTimestamp", NULL }; | |
243 | + | |
244 | + | |
245 | + qesc = toLower( m_pldap->escape( qname ) ); | |
246 | + stringtok( parts, qesc, "." ); | |
247 | + len = qesc.length(); | |
248 | + | |
249 | + if( parts.size() == 6 && len > 13 && qesc.substr( len - 13, 13 ) == ".in-addr.arpa" ) // IPv4 reverse lookups | |
250 | + { | |
251 | + filter = "aRecord=" + ptr2ip4( parts ); | |
252 | + attronly[0] = "associatedDomain"; | |
253 | + attributes = attronly; | |
254 | + } | |
255 | + else if( parts.size() == 34 && len > 9 && ( qesc.substr( len - 9, 9 ) == ".ip6.arpa" ) ) // IPv6 reverse lookups | |
256 | + { | |
257 | + filter = "aAAARecord=" + ptr2ip6( parts ); | |
258 | + attronly[0] = "associatedDomain"; | |
259 | + attributes = attronly; | |
260 | + } | |
261 | + else // IPv4 and IPv6 lookups | |
262 | + { | |
263 | + filter = "associatedDomain=" + qesc; | |
264 | + if( qtype.getCode() != QType::ANY ) | |
265 | + { | |
266 | + attr = qtype.getName() + "Record"; | |
267 | + filter = "&(" + filter + ")(" + attr + "=*)"; | |
268 | + attronly[0] = (char*) attr.c_str(); | |
269 | + attributes = attronly; | |
270 | + } | |
271 | + } | |
272 | + | |
273 | + filter = strbind( ":target:", filter, getArg( "filter-lookup" ) ); | |
274 | + | |
275 | + DLOG( L << Logger::Debug << m_myname << " Search = basedn: " << getArg( "basedn" ) << ", filter: " << filter << ", qtype: " << qtype.getName() << endl ); | |
276 | + m_msgid = m_pldap->search( getArg( "basedn" ), LDAP_SCOPE_SUBTREE, filter, (const char**) attributes ); | |
277 | +} | |
278 | + | |
279 | + | |
280 | + | |
281 | +void LdapBackend::lookup_tree( const QType &qtype, const string &qname, DNSPacket *dnspkt, int zoneid ) | |
282 | +{ | |
283 | + string filter, attr, qesc, dn; | |
284 | + char** attributes = ldap_attrany + 1; // skip associatedDomain | |
285 | + char* attronly[] = { NULL, "dNSTTL", "modifyTimestamp", NULL }; | |
286 | + vector<string>::reverse_iterator i; | |
287 | + vector<string> parts; | |
288 | + | |
289 | + | |
290 | + qesc = toLower( m_pldap->escape( qname ) ); | |
291 | + filter = "associatedDomain=" + qesc; | |
292 | + | |
293 | + if( qtype.getCode() != QType::ANY ) | |
294 | + { | |
295 | + attr = qtype.getName() + "Record"; | |
296 | + filter = "&(" + filter + ")(" + attr + "=*)"; | |
297 | + attronly[0] = (char*) attr.c_str(); | |
298 | + attributes = attronly; | |
299 | + } | |
300 | + | |
301 | + filter = strbind( ":target:", filter, getArg( "filter-lookup" ) ); | |
302 | + | |
303 | + stringtok( parts, toLower( qname ), "." ); | |
304 | + for( i = parts.rbegin(); i != parts.rend(); i++ ) | |
305 | + { | |
306 | + dn = "dc=" + *i + "," + dn; | |
307 | + } | |
308 | + | |
309 | + DLOG( L << Logger::Debug << m_myname << " Search = basedn: " << dn + getArg( "basedn" ) << ", filter: " << filter << ", qtype: " << qtype.getName() << endl ); | |
310 | + m_msgid = m_pldap->search( dn + getArg( "basedn" ), LDAP_SCOPE_BASE, filter, (const char**) attributes ); | |
311 | +} | |
312 | + | |
313 | + | |
314 | +inline bool LdapBackend::prepare() | |
315 | +{ | |
316 | + m_adomains.clear(); | |
317 | + m_ttl = m_default_ttl; | |
318 | + m_last_modified = 0; | |
319 | + | |
320 | + if( m_result.count( "dNSTTL" ) && !m_result["dNSTTL"].empty() ) | |
321 | + { | |
322 | + char* endptr; | |
323 | + | |
324 | + m_ttl = (uint32_t) strtol( m_result["dNSTTL"][0].c_str(), &endptr, 10 ); | |
325 | + if( *endptr != '\0' ) | |
326 | + { | |
327 | + L << Logger::Warning << m_myname << " Invalid time to life for " << m_qname << ": " << m_result["dNSTTL"][0] << endl; | |
328 | + m_ttl = m_default_ttl; | |
329 | + } | |
330 | + m_result.erase( "dNSTTL" ); | |
331 | + } | |
332 | + | |
333 | + if( m_result.count( "modifyTimestamp" ) && !m_result["modifyTimestamp"].empty() ) | |
334 | + { | |
335 | + if( ( m_last_modified = str2tstamp( m_result["modifyTimestamp"][0] ) ) == 0 ) | |
336 | + { | |
337 | + L << Logger::Warning << m_myname << " Invalid modifyTimestamp for " << m_qname << ": " << m_result["modifyTimestamp"][0] << endl; | |
338 | + } | |
339 | + m_result.erase( "modifyTimestamp" ); | |
340 | + } | |
341 | + | |
342 | + if( !(this->*m_prepare_fcnt)() ) | |
343 | + { | |
344 | + return false; | |
345 | + } | |
346 | + | |
347 | + m_adomain = m_adomains.begin(); | |
348 | + m_attribute = m_result.begin(); | |
349 | + m_value = m_attribute->second.begin(); | |
350 | + | |
351 | + return true; | |
352 | +} | |
353 | + | |
354 | + | |
355 | + | |
356 | +inline bool LdapBackend::prepare_simple() | |
357 | +{ | |
358 | + if( !m_axfrqlen ) // request was a normal lookup() | |
359 | + { | |
360 | + m_adomains.push_back( m_qname ); | |
361 | + } | |
362 | + else // request was a list() for AXFR | |
363 | + { | |
364 | + if( m_result.count( "associatedDomain" ) ) | |
365 | + { | |
366 | + vector<string>::iterator i; | |
367 | + for( i = m_result["associatedDomain"].begin(); i != m_result["associatedDomain"].end(); i++ ) { | |
368 | + if( i->size() >= m_axfrqlen && i->substr( i->size() - m_axfrqlen, m_axfrqlen ) == m_qname ) { | |
369 | + m_adomains.push_back( *i ); | |
370 | + } | |
371 | + } | |
372 | + m_result.erase( "associatedDomain" ); | |
373 | + } | |
374 | + } | |
375 | + | |
376 | + return true; | |
377 | +} | |
378 | + | |
379 | + | |
380 | + | |
381 | +inline bool LdapBackend::prepare_strict() | |
382 | +{ | |
383 | + if( !m_axfrqlen ) // request was a normal lookup() | |
384 | + { | |
385 | + m_adomains.push_back( m_qname ); | |
386 | + if( m_result.count( "associatedDomain" ) ) | |
387 | + { | |
388 | + m_result["PTRRecord"] = m_result["associatedDomain"]; | |
389 | + m_result.erase( "associatedDomain" ); | |
390 | + } | |
391 | + } | |
392 | + else // request was a list() for AXFR | |
393 | + { | |
394 | + if( m_result.count( "associatedDomain" ) ) | |
395 | + { | |
396 | + vector<string>::iterator i; | |
397 | + for( i = m_result["associatedDomain"].begin(); i != m_result["associatedDomain"].end(); i++ ) { | |
398 | + if( i->size() >= m_axfrqlen && i->substr( i->size() - m_axfrqlen, m_axfrqlen ) == m_qname ) { | |
399 | + m_adomains.push_back( *i ); | |
400 | + } | |
401 | + } | |
402 | + m_result.erase( "associatedDomain" ); | |
403 | + } | |
404 | + } | |
405 | + | |
406 | + return true; | |
407 | +} | |
408 | + | |
409 | + | |
410 | + | |
411 | +bool LdapBackend::get( DNSResourceRecord &rr ) | |
412 | +{ | |
413 | + QType qt; | |
414 | + vector<string> parts; | |
415 | + string attrname, content, qstr; | |
416 | + | |
417 | + | |
418 | + try | |
419 | + { | |
420 | + do | |
421 | + { | |
422 | + while( m_adomain != m_adomains.end() ) | |
423 | + { | |
424 | + while( m_attribute != m_result.end() ) | |
425 | + { | |
426 | + attrname = m_attribute->first; | |
427 | + qstr = attrname.substr( 0, attrname.length() - 6 ); // extract qtype string from ldap attribute name | |
428 | + qt = QType( const_cast<char*>(toUpper( qstr ).c_str()) ); | |
429 | + | |
430 | + while( m_value != m_attribute->second.end() ) | |
431 | + { | |
432 | + content = *m_value; | |
433 | + | |
434 | + rr.qtype = qt; | |
435 | + rr.qname = *m_adomain; | |
436 | + rr.priority = 0; | |
437 | + rr.ttl = m_ttl; | |
438 | + rr.last_modified = m_last_modified; | |
439 | + | |
440 | + if( qt.getCode() == QType::MX || qt.getCode() == QType::SRV ) // Priority, e.g. 10 smtp.example.com | |
441 | + { | |
442 | + char* endptr; | |
443 | + string::size_type first = content.find_first_of( " " ); | |
444 | + | |
445 | + if( first == string::npos ) | |
446 | + { | |
447 | + L << Logger::Warning << m_myname << " Invalid " << attrname << " without priority for " << m_qname << ": " << content << endl; | |
448 | + m_value++; | |
449 | + continue; | |
450 | + } | |
451 | + | |
452 | + rr.priority = (uint16_t) strtoul( (content.substr( 0, first )).c_str(), &endptr, 10 ); | |
453 | + if( *endptr != '\0' ) | |
454 | + { | |
455 | + L << Logger::Warning << m_myname << " Invalid " << attrname << " without priority for " << m_qname << ": " << content << endl; | |
456 | + m_value++; | |
457 | + continue; | |
458 | + } | |
459 | + | |
460 | + content = content.substr( first + 1, content.length() - first - 1 ); | |
461 | + } | |
462 | + | |
463 | + rr.content = content; | |
464 | + m_value++; | |
465 | + | |
466 | + DLOG( L << Logger::Debug << m_myname << " Record = qname: " << rr.qname << ", qtype: " << (rr.qtype).getName() << ", priority: " << rr.priority << ", ttl: " << rr.ttl << ", content: " << rr.content << endl ); | |
467 | + return true; | |
468 | + } | |
469 | + | |
470 | + m_attribute++; | |
471 | + m_value = m_attribute->second.begin(); | |
472 | + } | |
473 | + m_adomain++; | |
474 | + m_attribute = m_result.begin(); | |
475 | + m_value = m_attribute->second.begin(); | |
476 | + } | |
477 | + } | |
478 | + while( m_pldap->getSearchEntry( m_msgid, m_result, m_getdn ) && prepare() ); | |
479 | + | |
480 | + } | |
481 | + catch( LDAPTimeout < ) | |
482 | + { | |
483 | + L << Logger::Warning << m_myname << " Search failed: " << lt.what() << endl; | |
484 | + throw( DBException( "LDAP server timeout" ) ); | |
485 | + } | |
486 | + catch( LDAPException &le ) | |
487 | + { | |
488 | + L << Logger::Error << m_myname << " Search failed: " << le.what() << endl; | |
489 | + throw( AhuException( "LDAP server unreachable" ) ); // try to reconnect to another server | |
490 | + } | |
491 | + catch( exception &e ) | |
492 | + { | |
493 | + L << Logger::Error << m_myname << " Caught STL exception for " << m_qname << ": " << e.what() << endl; | |
494 | + throw( DBException( "STL exception" ) ); | |
495 | + } | |
496 | + | |
497 | + return false; | |
498 | +} | |
499 | + | |
500 | + | |
501 | + | |
502 | + bool LdapBackend::getDomainInfo( const string& domain, DomainInfo& di ) | |
503 | +{ | |
504 | + string filter; | |
505 | + SOAData sd; | |
506 | + char* attronly[] = { "sOARecord", NULL }; | |
507 | + | |
508 | + | |
509 | + // search for SOARecord of domain | |
510 | + filter = "(&(associatedDomain=" + toLower( m_pldap->escape( domain ) ) + ")(SOARecord=*))"; | |
511 | + m_msgid = m_pldap->search( getArg( "basedn" ), LDAP_SCOPE_SUBTREE, filter, (const char**) attronly ); | |
512 | + m_pldap->getSearchEntry( m_msgid, m_result ); | |
513 | + | |
514 | + if( m_result.count( "sOARecord" ) && !m_result["sOARecord"].empty() ) | |
515 | + { | |
516 | + sd.serial = 0; | |
517 | + fillSOAData( m_result["sOARecord"][0], sd ); | |
518 | + | |
519 | + di.id = 0; | |
520 | + di.serial = sd.serial; | |
521 | + di.zone = domain; | |
522 | + di.last_check = 0; | |
523 | + di.backend = this; | |
524 | + di.kind = DomainInfo::Master; | |
525 | + | |
526 | + return true; | |
527 | + } | |
528 | + | |
529 | + return false; | |
530 | +} | |
531 | + | |
532 | + | |
533 | + | |
534 | + | |
535 | + | |
536 | +class LdapFactory : public BackendFactory | |
537 | +{ | |
538 | + | |
539 | +public: | |
540 | + | |
541 | + LdapFactory() : BackendFactory( "ldap" ) {} | |
542 | + | |
543 | + | |
544 | + void declareArguments( const string &suffix="" ) | |
545 | + { | |
546 | + declare( suffix, "host", "One or more LDAP server with ports or LDAP URIs (separated by spaces)","ldap://127.0.0.1:389/" ); | |
547 | + declare( suffix, "starttls", "Use TLS to encrypt connection (unused for LDAP URIs)", "no" ); | |
548 | + declare( suffix, "basedn", "Search root in ldap tree (must be set)","" ); | |
549 | + declare( suffix, "binddn", "User dn for non anonymous binds","" ); | |
550 | + declare( suffix, "secret", "User password for non anonymous binds", "" ); | |
551 | + declare( suffix, "method", "How to search entries (simple, strict or tree)", "simple" ); | |
552 | + declare( suffix, "filter-axfr", "LDAP filter for limiting AXFR results", "(:target:)" ); | |
553 | + declare( suffix, "filter-lookup", "LDAP filter for limiting IP or name lookups", "(:target:)" ); | |
554 | + declare( suffix, "disable-ptrrecord", "Deprecated, use ldap-method=strict instead", "no" ); | |
555 | + } | |
556 | + | |
557 | + | |
558 | + DNSBackend* make( const string &suffix="" ) | |
559 | + { | |
560 | + return new LdapBackend( suffix ); | |
561 | + } | |
562 | +}; | |
563 | + | |
564 | + | |
565 | + | |
566 | + | |
567 | + | |
568 | +class LdapLoader | |
569 | +{ | |
570 | + LdapFactory factory; | |
571 | + | |
572 | +public: | |
573 | + | |
574 | + LdapLoader() | |
575 | + { | |
576 | + BackendMakers().report( &factory ); | |
577 | + L << Logger::Info << " [LdapBackend] This is the ldap module version "VERSION" ("__DATE__", "__TIME__") reporting" << endl; | |
578 | + } | |
579 | +}; | |
580 | + | |
581 | + | |
582 | +static LdapLoader ldaploader; | |
583 | diff -Nur pdns-2.9.21.1.orig/modules/ldapbackend/powerldap.cc pdns-2.9.21.1.int16/modules/ldapbackend/powerldap.cc | |
584 | --- pdns-2.9.21.1.orig/modules/ldapbackend/powerldap.cc 2007-04-21 07:56:36.000000000 -0600 | |
585 | +++ pdns-2.9.21.1.int16/modules/ldapbackend/powerldap.cc 2008-10-06 10:08:55.000000000 -0600 | |
313ceca8 MW |
586 | @@ -2,7 +2,7 @@ |
587 | ||
588 | ||
589 | ||
196f0df9 | 590 | -PowerLDAP::PowerLDAP( const string& hosts, uint16_t port, bool tls ) |
591 | +PowerLDAP::PowerLDAP( const string& hosts, u_int16_t port, bool tls ) | |
313ceca8 MW |
592 | { |
593 | int protocol = LDAP_VERSION3; | |
594 | ||
3dd1babb | 595 | diff -Nur pdns-2.9.21.1.orig/modules/ldapbackend/powerldap.hh pdns-2.9.21.1.int16/modules/ldapbackend/powerldap.hh |
596 | --- pdns-2.9.21.1.orig/modules/ldapbackend/powerldap.hh 2007-04-21 07:56:36.000000000 -0600 | |
597 | +++ pdns-2.9.21.1.int16/modules/ldapbackend/powerldap.hh 2008-10-06 10:11:53.000000000 -0600 | |
598 | @@ -32,12 +32,8 @@ | |
599 | #include <config.h> | |
600 | #endif | |
601 | ||
602 | -#ifdef HAVE_STDINT_H | |
603 | #include <stdint.h> | |
604 | -#else | |
605 | #include <sys/types.h> | |
606 | -#endif | |
607 | - | |
608 | ||
609 | ||
610 | #ifndef POWERLDAP_HH | |
611 | @@ -78,7 +74,7 @@ | |
313ceca8 MW |
612 | typedef map<string, vector<string> > sentry_t; |
613 | typedef vector<sentry_t> sresult_t; | |
614 | ||
196f0df9 | 615 | - PowerLDAP( const string& hosts = "ldap://127.0.0.1/", uint16_t port = LDAP_PORT, bool tls = false ); |
616 | + PowerLDAP( const string& hosts = "ldap://127.0.0.1/", u_int16_t port = LDAP_PORT, bool tls = false ); | |
313ceca8 MW |
617 | ~PowerLDAP(); |
618 | ||
619 | void getOption( int option, int* value ); | |
3dd1babb | 620 | diff -Nur pdns-2.9.21.1.orig/modules/ldapbackend/powerldap.hh.orig pdns-2.9.21.1.int16/modules/ldapbackend/powerldap.hh.orig |
621 | --- pdns-2.9.21.1.orig/modules/ldapbackend/powerldap.hh.orig 1969-12-31 17:00:00.000000000 -0700 | |
622 | +++ pdns-2.9.21.1.int16/modules/ldapbackend/powerldap.hh.orig 2007-04-21 07:56:36.000000000 -0600 | |
623 | @@ -0,0 +1,98 @@ | |
624 | +/* | |
625 | + * PowerDNS LDAP Connector | |
626 | + * By PowerDNS.COM BV | |
627 | + * By Norbert Sendetzky <norbert@linuxnetworks.de> (2003-2007) | |
628 | + * | |
629 | + * This program is free software; you can redistribute it and/or modify | |
630 | + * it under the terms of the GNU General Public License version 2 | |
631 | + * as published by the Free Software Foundation. | |
632 | + * | |
633 | + * This program is distributed in the hope that it will be useful, | |
634 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
635 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
636 | + * GNU General Public License for more details. | |
637 | + * | |
638 | + * You should have received a copy of the GNU General Public License | |
639 | + * along with this program; if not, write to the Free Software | |
640 | + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
641 | + */ | |
642 | + | |
643 | + | |
644 | + | |
645 | +#include <map> | |
646 | +#include <string> | |
647 | +#include <vector> | |
648 | +#include <exception> | |
649 | +#include <stdexcept> | |
650 | +#include <errno.h> | |
651 | +#include <lber.h> | |
652 | +#include <ldap.h> | |
653 | + | |
654 | +#ifdef HAVE_CONFIG_H | |
655 | +#include <config.h> | |
656 | +#endif | |
657 | + | |
658 | +#ifdef HAVE_STDINT_H | |
659 | +#include <stdint.h> | |
660 | +#else | |
661 | +#include <sys/types.h> | |
662 | +#endif | |
663 | + | |
664 | + | |
665 | + | |
666 | +#ifndef POWERLDAP_HH | |
667 | +#define POWERLDAP_HH | |
668 | + | |
669 | + | |
670 | + | |
671 | +using std::map; | |
672 | +using std::string; | |
673 | +using std::vector; | |
674 | + | |
675 | + | |
676 | + | |
677 | +class LDAPException : public std::runtime_error | |
678 | +{ | |
679 | +public: | |
680 | + explicit LDAPException( const string &str ) : std::runtime_error( str ) {} | |
681 | +}; | |
682 | + | |
683 | + | |
684 | + | |
685 | +class LDAPTimeout : public LDAPException | |
686 | +{ | |
687 | +public: | |
688 | + explicit LDAPTimeout() : LDAPException( "Timeout" ) {} | |
689 | +}; | |
690 | + | |
691 | + | |
692 | + | |
693 | +class PowerLDAP | |
694 | +{ | |
695 | + LDAP* d_ld; | |
696 | + | |
697 | + const string getError( int rc = -1 ); | |
698 | + int waitResult( int msgid = LDAP_RES_ANY, int timeout = 0, LDAPMessage** result = NULL ); | |
699 | + | |
700 | +public: | |
701 | + typedef map<string, vector<string> > sentry_t; | |
702 | + typedef vector<sentry_t> sresult_t; | |
703 | + | |
704 | + PowerLDAP( const string& hosts = "ldap://127.0.0.1/", uint16_t port = LDAP_PORT, bool tls = false ); | |
705 | + ~PowerLDAP(); | |
706 | + | |
707 | + void getOption( int option, int* value ); | |
708 | + void setOption( int option, int value ); | |
709 | + | |
710 | + void simpleBind( const string& ldapbinddn = "", const string& ldapsecret = "" ); | |
711 | + int search( const string& base, int scope, const string& filter, const char** attr = 0 ); | |
712 | + | |
713 | + bool getSearchEntry( int msgid, sentry_t& entry, bool dn = false, int timeout = 5 ); | |
714 | + void getSearchResults( int msgid, sresult_t& result, bool dn = false, int timeout = 5 ); | |
715 | + | |
716 | + static const string escape( const string& tobe ); | |
717 | +}; | |
718 | + | |
719 | + | |
720 | + | |
721 | +#endif |