Lines 38-44
Link Here
|
38 |
#include <unistd.h> |
38 |
#include <unistd.h> |
39 |
#endif |
39 |
#endif |
40 |
|
40 |
|
41 |
#ifndef APU_HAS_LDAP |
41 |
#if !APR_HAS_LDAP |
42 |
#error mod_ldap requires APR-util to have LDAP support built in |
42 |
#error mod_ldap requires APR-util to have LDAP support built in |
43 |
#endif |
43 |
#endif |
44 |
|
44 |
|
Lines 88-93
Link Here
|
88 |
"\"http://www.w3.org/TR/REC-html40/frameset.dtd\">\n" |
88 |
"\"http://www.w3.org/TR/REC-html40/frameset.dtd\">\n" |
89 |
#endif |
89 |
#endif |
90 |
|
90 |
|
|
|
91 |
|
92 |
static void util_ldap_strdup (char **str, const char *newstr) |
93 |
{ |
94 |
if (*str) { |
95 |
free(*str); |
96 |
*str = NULL; |
97 |
} |
98 |
|
99 |
if (newstr) { |
100 |
*str = calloc(1, strlen(newstr)+1); |
101 |
strcpy (*str, newstr); |
102 |
} |
103 |
} |
104 |
|
91 |
/* |
105 |
/* |
92 |
* Status Handler |
106 |
* Status Handler |
93 |
* -------------- |
107 |
* -------------- |
Lines 171-202
Link Here
|
171 |
|
185 |
|
172 |
|
186 |
|
173 |
/* |
187 |
/* |
174 |
* Destroys an LDAP connection by unbinding. This function is registered |
188 |
* Destroys an LDAP connection by unbinding and closing the connection to |
175 |
* with the pool cleanup function - causing the LDAP connections to be |
189 |
* the LDAP server. It is used to bring the connection back to a known |
176 |
* shut down cleanly on graceful restart. |
190 |
* state after an error, and during pool cleanup. |
177 |
*/ |
191 |
*/ |
178 |
LDAP_DECLARE_NONSTD(apr_status_t) util_ldap_connection_destroy(void *param) |
192 |
LDAP_DECLARE_NONSTD(apr_status_t) util_ldap_connection_unbind(void *param) |
179 |
{ |
193 |
{ |
180 |
util_ldap_connection_t *ldc = param; |
194 |
util_ldap_connection_t *ldc = param; |
181 |
|
195 |
|
182 |
/* unbinding from the LDAP server */ |
196 |
if (ldc) { |
183 |
if (ldc->ldap) { |
197 |
if (ldc->ldap) { |
184 |
ldap_unbind_s(ldc->ldap); |
198 |
ldap_unbind_s(ldc->ldap); |
|
|
199 |
ldc->ldap = NULL; |
200 |
} |
185 |
ldc->bound = 0; |
201 |
ldc->bound = 0; |
186 |
ldc->ldap = NULL; |
|
|
187 |
} |
202 |
} |
188 |
|
203 |
|
189 |
/* release the lock we were using. The lock should have |
204 |
return APR_SUCCESS; |
190 |
already been released in the close connection call. |
205 |
} |
191 |
But just in case it wasn't, we first try to get the lock |
206 |
|
192 |
before unlocking it to avoid unlocking an unheld lock. |
207 |
|
193 |
Unlocking an unheld lock causes problems on NetWare. The |
208 |
/* |
194 |
other option would be to assume that close connection did |
209 |
* Clean up an LDAP connection by unbinding and unlocking the connection. |
195 |
its job. */ |
210 |
* This function is registered with the pool cleanup function - causing |
196 |
#if APR_HAS_THREADS |
211 |
* the LDAP connections to be shut down cleanly on graceful restart. |
197 |
apr_thread_mutex_trylock(ldc->lock); |
212 |
*/ |
198 |
apr_thread_mutex_unlock(ldc->lock); |
213 |
LDAP_DECLARE_NONSTD(apr_status_t) util_ldap_connection_cleanup(void *param) |
199 |
#endif |
214 |
{ |
|
|
215 |
util_ldap_connection_t *ldc = param; |
216 |
|
217 |
if (ldc) { |
218 |
|
219 |
/* unbind and disconnect from the LDAP server */ |
220 |
util_ldap_connection_unbind(ldc); |
221 |
|
222 |
/* free the username and password */ |
223 |
if (ldc->bindpw) { |
224 |
free((void*)ldc->bindpw); |
225 |
} |
226 |
if (ldc->binddn) { |
227 |
free((void*)ldc->binddn); |
228 |
} |
229 |
|
230 |
/* unlock this entry */ |
231 |
util_ldap_connection_close(ldc); |
232 |
|
233 |
} |
200 |
|
234 |
|
201 |
return APR_SUCCESS; |
235 |
return APR_SUCCESS; |
202 |
} |
236 |
} |
Lines 290-300
Link Here
|
290 |
/* always default to LDAP V3 */ |
324 |
/* always default to LDAP V3 */ |
291 |
ldap_set_option(ldc->ldap, LDAP_OPT_PROTOCOL_VERSION, &version); |
325 |
ldap_set_option(ldc->ldap, LDAP_OPT_PROTOCOL_VERSION, &version); |
292 |
|
326 |
|
293 |
|
|
|
294 |
/* add the cleanup to the pool */ |
295 |
apr_pool_cleanup_register(ldc->pool, ldc, |
296 |
util_ldap_connection_destroy, |
297 |
apr_pool_cleanup_null); |
298 |
} |
327 |
} |
299 |
|
328 |
|
300 |
|
329 |
|
Lines 313-321
Link Here
|
313 |
break; |
342 |
break; |
314 |
} |
343 |
} |
315 |
|
344 |
|
316 |
ldc->bound = 1; |
|
|
317 |
ldc->reason = "LDAP: connection open successful"; |
318 |
|
319 |
/* free the handle if there was an error |
345 |
/* free the handle if there was an error |
320 |
*/ |
346 |
*/ |
321 |
if (LDAP_SUCCESS != result) |
347 |
if (LDAP_SUCCESS != result) |
Lines 325-330
Link Here
|
325 |
ldc->bound = 0; |
351 |
ldc->bound = 0; |
326 |
ldc->reason = "LDAP: ldap_simple_bind_s() failed"; |
352 |
ldc->reason = "LDAP: ldap_simple_bind_s() failed"; |
327 |
} |
353 |
} |
|
|
354 |
else { |
355 |
ldc->bound = 1; |
356 |
ldc->reason = "LDAP: connection open successful"; |
357 |
} |
328 |
|
358 |
|
329 |
return(result); |
359 |
return(result); |
330 |
} |
360 |
} |
Lines 362-379
Link Here
|
362 |
*/ |
392 |
*/ |
363 |
for (l=st->connections,p=NULL; l; l=l->next) { |
393 |
for (l=st->connections,p=NULL; l; l=l->next) { |
364 |
#if APR_HAS_THREADS |
394 |
#if APR_HAS_THREADS |
365 |
if ( (APR_SUCCESS == apr_thread_mutex_trylock(l->lock)) && |
395 |
if (APR_SUCCESS == apr_thread_mutex_trylock(l->lock)) { |
366 |
#else |
|
|
367 |
if ( |
368 |
#endif |
396 |
#endif |
369 |
l->port == port |
397 |
if ((l->port == port) && (strcmp(l->host, host) == 0) && |
370 |
&& strcmp(l->host, host) == 0 |
398 |
((!l->binddn && !binddn) || (l->binddn && binddn && !strcmp(l->binddn, binddn))) && |
371 |
&& ( (!l->binddn && !binddn) || (l->binddn && binddn && !strcmp(l->binddn, binddn)) ) |
399 |
((!l->bindpw && !bindpw) || (l->bindpw && bindpw && !strcmp(l->bindpw, bindpw))) && |
372 |
&& ( (!l->bindpw && !bindpw) || (l->bindpw && bindpw && !strcmp(l->bindpw, bindpw)) ) |
400 |
(l->deref == deref) && (l->secure == secure)) { |
373 |
&& l->deref == deref |
401 |
|
374 |
&& l->secure == secure |
|
|
375 |
) |
376 |
break; |
402 |
break; |
|
|
403 |
} |
404 |
#if APR_HAS_THREADS |
405 |
/* If this connection didn't match the criteria, then we |
406 |
* need to unlock the mutex so it is available to be reused. |
407 |
*/ |
408 |
apr_thread_mutex_unlock(l->lock); |
409 |
} |
410 |
#endif |
377 |
p = l; |
411 |
p = l; |
378 |
} |
412 |
} |
379 |
|
413 |
|
Lines 383-403
Link Here
|
383 |
if (!l) { |
417 |
if (!l) { |
384 |
for (l=st->connections,p=NULL; l; l=l->next) { |
418 |
for (l=st->connections,p=NULL; l; l=l->next) { |
385 |
#if APR_HAS_THREADS |
419 |
#if APR_HAS_THREADS |
386 |
if ( (APR_SUCCESS == apr_thread_mutex_trylock(l->lock)) && |
420 |
if (APR_SUCCESS == apr_thread_mutex_trylock(l->lock)) { |
387 |
#else |
421 |
|
388 |
if ( |
|
|
389 |
#endif |
422 |
#endif |
390 |
l->port == port |
423 |
if ((l->port == port) && (strcmp(l->host, host) == 0) && |
391 |
&& strcmp(l->host, host) == 0 |
424 |
(l->deref == deref) && (l->secure == secure)) { |
392 |
&& l->deref == deref |
425 |
|
393 |
&& l->secure == secure |
|
|
394 |
) { |
395 |
/* the bind credentials have changed */ |
426 |
/* the bind credentials have changed */ |
396 |
l->bound = 0; |
427 |
l->bound = 0; |
397 |
l->binddn = apr_pstrdup(st->pool, binddn); |
428 |
util_ldap_strdup((char**)&(l->binddn), binddn); |
398 |
l->bindpw = apr_pstrdup(st->pool, bindpw); |
429 |
util_ldap_strdup((char**)&(l->bindpw), bindpw); |
399 |
break; |
430 |
break; |
400 |
} |
431 |
} |
|
|
432 |
#if APR_HAS_THREADS |
433 |
/* If this connection didn't match the criteria, then we |
434 |
* need to unlock the mutex so it is available to be reused. |
435 |
*/ |
436 |
apr_thread_mutex_unlock(l->lock); |
437 |
} |
438 |
#endif |
401 |
p = l; |
439 |
p = l; |
402 |
} |
440 |
} |
403 |
} |
441 |
} |
Lines 426-435
Link Here
|
426 |
l->host = apr_pstrdup(st->pool, host); |
464 |
l->host = apr_pstrdup(st->pool, host); |
427 |
l->port = port; |
465 |
l->port = port; |
428 |
l->deref = deref; |
466 |
l->deref = deref; |
429 |
l->binddn = apr_pstrdup(st->pool, binddn); |
467 |
util_ldap_strdup((char**)&(l->binddn), binddn); |
430 |
l->bindpw = apr_pstrdup(st->pool, bindpw); |
468 |
util_ldap_strdup((char**)&(l->bindpw), bindpw); |
431 |
l->secure = secure; |
469 |
l->secure = secure; |
432 |
|
470 |
|
|
|
471 |
/* add the cleanup to the pool */ |
472 |
apr_pool_cleanup_register(l->pool, l, |
473 |
util_ldap_connection_cleanup, |
474 |
apr_pool_cleanup_null); |
475 |
|
433 |
if (p) { |
476 |
if (p) { |
434 |
p->next = l; |
477 |
p->next = l; |
435 |
} |
478 |
} |
Lines 531-538
Link Here
|
531 |
if ((result = ldap_search_ext_s(ldc->ldap, const_cast(reqdn), LDAP_SCOPE_BASE, |
574 |
if ((result = ldap_search_ext_s(ldc->ldap, const_cast(reqdn), LDAP_SCOPE_BASE, |
532 |
"(objectclass=*)", NULL, 1, |
575 |
"(objectclass=*)", NULL, 1, |
533 |
NULL, NULL, NULL, -1, &res)) == LDAP_SERVER_DOWN) { |
576 |
NULL, NULL, NULL, -1, &res)) == LDAP_SERVER_DOWN) { |
534 |
util_ldap_connection_close(ldc); |
|
|
535 |
ldc->reason = "DN Comparison ldap_search_ext_s() failed with server down"; |
577 |
ldc->reason = "DN Comparison ldap_search_ext_s() failed with server down"; |
|
|
578 |
util_ldap_connection_unbind(ldc); |
536 |
goto start_over; |
579 |
goto start_over; |
537 |
} |
580 |
} |
538 |
if (result != LDAP_SUCCESS) { |
581 |
if (result != LDAP_SUCCESS) { |
Lines 584-590
Link Here
|
584 |
util_url_node_t curnode; |
627 |
util_url_node_t curnode; |
585 |
util_compare_node_t *compare_nodep; |
628 |
util_compare_node_t *compare_nodep; |
586 |
util_compare_node_t the_compare_node; |
629 |
util_compare_node_t the_compare_node; |
587 |
apr_time_t curtime; |
630 |
apr_time_t curtime = 0; /* silence gcc -Wall */ |
588 |
int failures = 0; |
631 |
int failures = 0; |
589 |
|
632 |
|
590 |
util_ldap_state_t *st = |
633 |
util_ldap_state_t *st = |
Lines 660-667
Link Here
|
660 |
if ((result = ldap_compare_s(ldc->ldap, const_cast(dn), const_cast(attrib), const_cast(value))) |
703 |
if ((result = ldap_compare_s(ldc->ldap, const_cast(dn), const_cast(attrib), const_cast(value))) |
661 |
== LDAP_SERVER_DOWN) { |
704 |
== LDAP_SERVER_DOWN) { |
662 |
/* connection failed - try again */ |
705 |
/* connection failed - try again */ |
663 |
util_ldap_connection_close(ldc); |
|
|
664 |
ldc->reason = "ldap_compare_s() failed with server down"; |
706 |
ldc->reason = "ldap_compare_s() failed with server down"; |
|
|
707 |
util_ldap_connection_unbind(ldc); |
665 |
goto start_over; |
708 |
goto start_over; |
666 |
} |
709 |
} |
667 |
|
710 |
|
Lines 781-786
Link Here
|
781 |
const_cast(filter), attrs, 0, |
824 |
const_cast(filter), attrs, 0, |
782 |
NULL, NULL, NULL, -1, &res)) == LDAP_SERVER_DOWN) { |
825 |
NULL, NULL, NULL, -1, &res)) == LDAP_SERVER_DOWN) { |
783 |
ldc->reason = "ldap_search_ext_s() for user failed with server down"; |
826 |
ldc->reason = "ldap_search_ext_s() for user failed with server down"; |
|
|
827 |
util_ldap_connection_unbind(ldc); |
784 |
goto start_over; |
828 |
goto start_over; |
785 |
} |
829 |
} |
786 |
|
830 |
|
Lines 809-815
Link Here
|
809 |
|
853 |
|
810 |
/* Grab the dn, copy it into the pool, and free it again */ |
854 |
/* Grab the dn, copy it into the pool, and free it again */ |
811 |
dn = ldap_get_dn(ldc->ldap, entry); |
855 |
dn = ldap_get_dn(ldc->ldap, entry); |
812 |
*binddn = apr_pstrdup(st->pool, dn); |
856 |
*binddn = apr_pstrdup(r->pool, dn); |
813 |
ldap_memfree(dn); |
857 |
ldap_memfree(dn); |
814 |
|
858 |
|
815 |
/* |
859 |
/* |
Lines 835-840
Link Here
|
835 |
LDAP_SERVER_DOWN) { |
879 |
LDAP_SERVER_DOWN) { |
836 |
ldc->reason = "ldap_simple_bind_s() to check user credentials failed with server down"; |
880 |
ldc->reason = "ldap_simple_bind_s() to check user credentials failed with server down"; |
837 |
ldap_msgfree(res); |
881 |
ldap_msgfree(res); |
|
|
882 |
util_ldap_connection_unbind(ldc); |
838 |
goto start_over; |
883 |
goto start_over; |
839 |
} |
884 |
} |
840 |
|
885 |
|
Lines 842-849
Link Here
|
842 |
if (result != LDAP_SUCCESS) { |
887 |
if (result != LDAP_SUCCESS) { |
843 |
ldc->reason = "ldap_simple_bind_s() to check user credentials failed"; |
888 |
ldc->reason = "ldap_simple_bind_s() to check user credentials failed"; |
844 |
ldap_msgfree(res); |
889 |
ldap_msgfree(res); |
|
|
890 |
util_ldap_connection_unbind(ldc); |
845 |
return result; |
891 |
return result; |
846 |
} |
892 |
} |
|
|
893 |
else { |
894 |
/* |
895 |
* We have just bound the connection to a different user and password |
896 |
* combination, which might be reused unintentionally next time this |
897 |
* connection is used from the connection pool. To ensure no confusion, |
898 |
* we mark the connection as unbound. |
899 |
*/ |
900 |
ldc->bound = 0; |
901 |
} |
847 |
|
902 |
|
848 |
/* |
903 |
/* |
849 |
* Get values for the provided attributes. |
904 |
* Get values for the provided attributes. |
Lines 873-894
Link Here
|
873 |
/* |
928 |
/* |
874 |
* Add the new username to the search cache. |
929 |
* Add the new username to the search cache. |
875 |
*/ |
930 |
*/ |
876 |
LDAP_CACHE_WRLOCK(); |
|
|
877 |
the_search_node.username = filter; |
878 |
the_search_node.dn = *binddn; |
879 |
the_search_node.bindpw = bindpw; |
880 |
the_search_node.lastbind = apr_time_now(); |
881 |
the_search_node.vals = vals; |
882 |
if (curl) { |
931 |
if (curl) { |
|
|
932 |
LDAP_CACHE_WRLOCK(); |
933 |
the_search_node.username = filter; |
934 |
the_search_node.dn = *binddn; |
935 |
the_search_node.bindpw = bindpw; |
936 |
the_search_node.lastbind = apr_time_now(); |
937 |
the_search_node.vals = vals; |
883 |
util_ald_cache_insert(curl->search_cache, &the_search_node); |
938 |
util_ald_cache_insert(curl->search_cache, &the_search_node); |
|
|
939 |
LDAP_CACHE_UNLOCK(); |
884 |
} |
940 |
} |
885 |
ldap_msgfree(res); |
941 |
ldap_msgfree(res); |
886 |
LDAP_CACHE_UNLOCK(); |
|
|
887 |
|
942 |
|
888 |
ldc->reason = "Authentication successful"; |
943 |
ldc->reason = "Authentication successful"; |
889 |
return LDAP_SUCCESS; |
944 |
return LDAP_SUCCESS; |
890 |
} |
945 |
} |
891 |
|
946 |
|
|
|
947 |
|
892 |
/* |
948 |
/* |
893 |
* Reports if ssl support is enabled |
949 |
* Reports if ssl support is enabled |
894 |
* |
950 |
* |
Lines 916-923
Link Here
|
916 |
st->cache_bytes = atol(bytes); |
972 |
st->cache_bytes = atol(bytes); |
917 |
|
973 |
|
918 |
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, |
974 |
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, |
919 |
"[%d] ldap cache: Setting shared memory cache size to %d bytes.", |
975 |
"[%" APR_PID_T_FMT "] ldap cache: Setting shared memory " |
920 |
getpid(), st->cache_bytes); |
976 |
" cache size to %" APR_SIZE_T_FMT " bytes.", |
|
|
977 |
getpid(), st->cache_bytes); |
921 |
|
978 |
|
922 |
return NULL; |
979 |
return NULL; |
923 |
} |
980 |
} |
Lines 1025-1031
Link Here
|
1025 |
} |
1082 |
} |
1026 |
|
1083 |
|
1027 |
|
1084 |
|
1028 |
const char *util_ldap_set_cert_type(cmd_parms *cmd, void *dummy, const char *Type) |
1085 |
static const char *util_ldap_set_cert_type(cmd_parms *cmd, void *dummy, const char *Type) |
1029 |
{ |
1086 |
{ |
1030 |
util_ldap_state_t *st = |
1087 |
util_ldap_state_t *st = |
1031 |
(util_ldap_state_t *)ap_get_module_config(cmd->server->module_config, |
1088 |
(util_ldap_state_t *)ap_get_module_config(cmd->server->module_config, |
Lines 1073-1091
Link Here
|
1073 |
|
1130 |
|
1074 |
static apr_status_t util_ldap_cleanup_module(void *data) |
1131 |
static apr_status_t util_ldap_cleanup_module(void *data) |
1075 |
{ |
1132 |
{ |
|
|
1133 |
#if APR_HAS_LDAP_SSL && APR_HAS_NOVELL_LDAPSDK |
1076 |
server_rec *s = data; |
1134 |
server_rec *s = data; |
1077 |
|
|
|
1078 |
util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config( |
1135 |
util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config( |
1079 |
s->module_config, &ldap_module); |
1136 |
s->module_config, &ldap_module); |
|
|
1137 |
|
1138 |
if (st->ssl_support) |
1139 |
ldapssl_client_deinit(); |
1080 |
|
1140 |
|
1081 |
#if APR_HAS_LDAP_SSL |
1141 |
#endif |
1082 |
#if APR_HAS_NOVELL_LDAPSDK |
1142 |
return APR_SUCCESS; |
1083 |
if (st->ssl_support) |
|
|
1084 |
ldapssl_client_deinit(); |
1085 |
#endif |
1086 |
#endif |
1087 |
|
1088 |
return(APR_SUCCESS); |
1089 |
} |
1143 |
} |
1090 |
|
1144 |
|
1091 |
static int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog, |
1145 |
static int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog, |
Lines 1115-1121
Link Here
|
1115 |
s_vhost = s->next; |
1169 |
s_vhost = s->next; |
1116 |
while (s_vhost) { |
1170 |
while (s_vhost) { |
1117 |
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, result, s, |
1171 |
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, result, s, |
1118 |
"LDAP merging Shared Cache conf: shm=0x%x rmm=0x%x for VHOST: %s", |
1172 |
"LDAP merging Shared Cache conf: shm=0x%pp rmm=0x%pp for VHOST: %s", |
1119 |
st->cache_shm, st->cache_rmm, s_vhost->server_hostname); |
1173 |
st->cache_shm, st->cache_rmm, s_vhost->server_hostname); |
1120 |
|
1174 |
|
1121 |
st_vhost = (util_ldap_state_t *)ap_get_module_config(s_vhost->module_config, &ldap_module); |
1175 |
st_vhost = (util_ldap_state_t *)ap_get_module_config(s_vhost->module_config, &ldap_module); |