Changeset 2062
- Timestamp:
- 01/27/2008 12:00:24 AM (4 months ago)
- Files:
-
- trunk/NEWS (modified) (1 diff)
- trunk/src/http_auth.c (modified) (8 diffs)
- trunk/src/http_auth.h (modified) (3 diffs)
- trunk/src/mod_auth.c (modified) (18 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/NEWS
r2059 r2062 15 15 * add IdleServers and Scoreboard directives in ?auto mode for mod_status (#1507) 16 16 * support letterhomes in mod_userdir (#1473) 17 * mod_auth ldap rework, most important change is being able to startup if ldap server is down (#1535) 17 18 18 19 - 1.5.0-r19.. - trunk/src/http_auth.c
r2048 r2062 55 55 56 56 handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s); 57 void auth_ldap_cleanup(ldap_plugin_config *p); 57 58 58 59 static const char base64_pad = '='; … … 698 699 } else if (p->conf.auth_backend == AUTH_BACKEND_LDAP) { 699 700 #ifdef USE_LDAP 700 LDAP *ldap; 701 LDAPMessage *lm, *first; 702 char *dn; 703 int ret; 701 LDAP *ldap = NULL; 702 LDAPMessage *lm = NULL, *first = NULL; 703 struct berval credentials; 704 char *dn = NULL; 705 int ret = 0; 704 706 char *attrs[] = { LDAP_NO_ATTRS, NULL }; 705 size_t i ;707 size_t i = 0; 706 708 707 709 /* for now we stay synchronous */ … … 738 740 return -1; 739 741 742 /* 2. */ 743 744 if (p->conf.ldap->ldap == NULL) { 745 if(auth_ldap_init(srv, &p->conf) != HANDLER_GO_ON) 746 return -1; 747 } 748 740 749 /* build filter */ 741 buffer_copy_string_buffer(p->ldap_filter, p->conf.ldap _filter_pre);750 buffer_copy_string_buffer(p->ldap_filter, p->conf.ldap->ldap_filter_pre); 742 751 buffer_append_string_buffer(p->ldap_filter, username); 743 buffer_append_string_buffer(p->ldap_filter, p->conf.ldap_filter_post); 744 745 746 /* 2. */ 747 if (p->conf.ldap == NULL || 748 LDAP_SUCCESS != (ret = ldap_search_s(p->conf.ldap, p->conf.auth_ldap_basedn->ptr, LDAP_SCOPE_SUBTREE, p->ldap_filter->ptr, attrs, 0, &lm))) { 749 if (auth_ldap_init(srv, &p->conf) != HANDLER_GO_ON) 752 buffer_append_string_buffer(p->ldap_filter, p->conf.ldap->ldap_filter_post); 753 754 ret = ldap_search_ext_s(p->conf.ldap->ldap, p->conf.auth_ldap_basedn->ptr, LDAP_SCOPE_SUBTREE, p->ldap_filter->ptr, attrs, 0, NULL, NULL, NULL, 0, &lm); 755 756 if (ret == LDAP_SERVER_DOWN) { 757 log_error_write(srv, __FILE__, __LINE__, "s", 758 "ldap: server down, try to reconnect"); 759 760 auth_ldap_cleanup(p->conf.ldap); 761 762 if(auth_ldap_init(srv, &p->conf) != HANDLER_GO_ON) 750 763 return -1; 751 if (LDAP_SUCCESS != (ret = ldap_search_s(p->conf.ldap, p->conf.auth_ldap_basedn->ptr, LDAP_SCOPE_SUBTREE, p->ldap_filter->ptr, attrs, 0, &lm))) { 752 764 765 log_error_write(srv, __FILE__, __LINE__, "s", 766 "ldap: successfully reconnected"); 767 } 768 769 if (ret != LDAP_SUCCESS) { 753 770 log_error_write(srv, __FILE__, __LINE__, "sssb", 754 "ldap:", ldap_err2string(ret), "filter:", p->ldap_filter); 755 756 return -1; 757 } 758 } 759 760 if (NULL == (first = ldap_first_entry(p->conf.ldap, lm))) { 761 log_error_write(srv, __FILE__, __LINE__, "s", "ldap ..."); 771 "ldap:", ldap_err2string(ret), ", filter:", p->ldap_filter); 772 773 return -1; 774 } 775 776 if (ldap_count_entries(p->conf.ldap->ldap, lm) > 1) { 777 log_error_write(srv, __FILE__, __LINE__, "ssb", 778 "ldap:", "more than one record returned, you might have to refine the filter:", p->ldap_filter); 779 } 780 781 first = ldap_first_entry(p->conf.ldap->ldap, lm); 782 if (first == NULL) { 783 ldap_get_option(p->conf.ldap->ldap, LDAP_OPT_ERROR_NUMBER, &ret); 784 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); 762 785 763 786 ldap_msgfree(lm); … … 766 789 } 767 790 768 if (NULL == (dn = ldap_get_dn(p->conf.ldap, first))) { 769 log_error_write(srv, __FILE__, __LINE__, "s", "ldap ..."); 791 dn = ldap_get_dn(p->conf.ldap->ldap, first); 792 if (dn == NULL) { 793 ldap_get_option(p->conf.ldap->ldap, LDAP_OPT_ERROR_NUMBER, &ret); 794 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); 770 795 771 796 ldap_msgfree(lm); … … 776 801 ldap_msgfree(lm); 777 802 778 779 803 /* 3. */ 780 if (NULL == (ldap = ldap_init(p->conf.auth_ldap_hostname->ptr, LDAP_PORT))) { 781 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap ...", strerror(errno)); 782 return -1; 783 } 784 785 ret = LDAP_VERSION3; 786 if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ret))) { 804 ret = ldap_initialize(&ldap, p->conf.auth_ldap_url->ptr); 805 if (ret) { 787 806 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); 788 807 789 ldap_unbind_s(ldap); 808 ldap_memfree(dn); 809 810 return -1; 811 } 812 813 const int ldap_version = LDAP_VERSION3; 814 ret = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ldap_version); 815 if (ret != LDAP_OPT_SUCCESS) { 816 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); 817 818 ldap_memfree(ldap); 819 ldap_memfree(dn); 790 820 791 821 return -1; … … 793 823 794 824 if (p->conf.auth_ldap_starttls == 1) { 795 if (LDAP_OPT_SUCCESS != (ret = ldap_start_tls_s(ldap, NULL, NULL))) { 825 ret = ldap_start_tls_s(ldap, NULL, NULL); 826 if (ret != LDAP_OPT_SUCCESS) { 796 827 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap startTLS failed:", ldap_err2string(ret)); 797 828 798 ldap_unbind_s(ldap); 829 ldap_memfree(ldap); 830 ldap_memfree(dn); 799 831 800 832 return -1; … … 802 834 } 803 835 804 805 if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(ldap, dn, pw))) { 836 /* Don't initialize it using " = {...}" since upstream doesn't 837 * guarantee an order and the compiler only issues a warning when 838 * passing an int as the pointer and vice-versa. 839 * We have to cast away the const since berval is a general struct, 840 * but ldap_sasl_bind_s doesn't write to the *pw location 841 */ 842 credentials.bv_val = (char*)pw; 843 credentials.bv_len = strlen(pw); 844 845 /* TODO: add funtionality to specify LDAP_SASL_EXTERNAL (or GSS-SPNEGO, etc.) */ 846 ret = ldap_sasl_bind_s(ldap, dn, LDAP_SASL_SIMPLE, &credentials, NULL, NULL, NULL); 847 if (ret != LDAP_SUCCESS) { 806 848 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); 807 849 808 ldap_unbind_s(ldap); 850 ldap_memfree(ldap); 851 ldap_memfree(dn); 809 852 810 853 return -1; … … 812 855 813 856 /* 5. */ 814 ldap_unbind_s(ldap); 857 ldap_unbind_ext_s(ldap, NULL, NULL); 858 ldap_memfree(dn); 815 859 816 860 /* everything worked, good, access granted */ trunk/src/http_auth.h
r1675 r2062 18 18 } auth_backend_t; 19 19 20 #ifdef USE_LDAP 21 typedef struct { 22 LDAP *ldap; 23 24 buffer *ldap_filter_pre; 25 buffer *ldap_filter_post; 26 } ldap_plugin_config; 27 #endif 28 20 29 typedef struct { 21 30 /* auth */ … … 30 39 buffer *auth_backend_conf; 31 40 32 buffer *auth_ldap_ hostname;41 buffer *auth_ldap_url; 33 42 buffer *auth_ldap_basedn; 34 43 buffer *auth_ldap_binddn; … … 47 56 48 57 #ifdef USE_LDAP 49 LDAP *ldap; 50 51 buffer *ldap_filter_pre; 52 buffer *ldap_filter_post; 58 ldap_plugin_config *ldap; 53 59 #endif 54 60 } mod_auth_plugin_config; trunk/src/mod_auth.c
r1939 r2062 17 17 18 18 handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s); 19 19 void auth_ldap_cleanup(ldap_plugin_config* p); 20 20 21 21 /** … … 75 75 buffer_free(s->auth_backend_conf); 76 76 77 buffer_free(s->auth_ldap_ hostname);77 buffer_free(s->auth_ldap_url); 78 78 buffer_free(s->auth_ldap_basedn); 79 79 buffer_free(s->auth_ldap_binddn); … … 85 85 86 86 #ifdef USE_LDAP 87 buffer_free(s->ldap_filter_pre); 88 buffer_free(s->ldap_filter_post); 89 90 if (s->ldap) ldap_unbind_s(s->ldap); 87 buffer_free(s->ldap->ldap_filter_pre); 88 buffer_free(s->ldap->ldap_filter_post); 89 90 auth_ldap_cleanup(s->ldap); 91 free(s->ldap); 91 92 #endif 92 93 … … 112 113 PATCH_OPTION(auth_require); 113 114 PATCH_OPTION(auth_debug); 114 PATCH_OPTION(auth_ldap_ hostname);115 PATCH_OPTION(auth_ldap_url); 115 116 PATCH_OPTION(auth_ldap_basedn); 116 117 PATCH_OPTION(auth_ldap_binddn); … … 124 125 #ifdef USE_LDAP 125 126 PATCH_OPTION(ldap); 126 PATCH_OPTION(ldap_filter_pre);127 PATCH_OPTION(ldap_filter_post);128 127 #endif 129 128 … … 154 153 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.debug"))) { 155 154 PATCH_OPTION(auth_debug); 156 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap. hostname"))) {157 PATCH_OPTION(auth_ldap_ hostname);155 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.url"))) { 156 PATCH_OPTION(auth_ldap_url); 158 157 #ifdef USE_LDAP 159 158 PATCH_OPTION(ldap); 160 PATCH_OPTION(ldap_filter_pre);161 PATCH_OPTION(ldap_filter_post);162 159 #endif 163 160 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.base-dn"))) { 164 161 PATCH_OPTION(auth_ldap_basedn); 162 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.bind-dn"))) { 163 PATCH_OPTION(auth_ldap_binddn); 164 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.bind-pw"))) { 165 PATCH_OPTION(auth_ldap_bindpw); 165 166 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.filter"))) { 166 167 PATCH_OPTION(auth_ldap_filter); … … 319 320 { "auth.backend.plain.userfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */ 320 321 { "auth.require", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 3 */ 321 { "auth.backend.ldap. hostname", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 4 */322 { "auth.backend.ldap.url" , NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 4 */ 322 323 { "auth.backend.ldap.base-dn", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 5 */ 323 324 { "auth.backend.ldap.filter", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 6 */ … … 350 351 s->auth_backend_conf = buffer_init(); 351 352 352 s->auth_ldap_ hostname= buffer_init();353 s->auth_ldap_url = buffer_init(); 353 354 s->auth_ldap_basedn = buffer_init(); 354 355 s->auth_ldap_binddn = buffer_init(); … … 364 365 365 366 #ifdef USE_LDAP 366 s->ldap_filter_pre = buffer_init(); 367 s->ldap_filter_post = buffer_init(); 368 s->ldap = NULL; 367 s->ldap = malloc (sizeof(ldap_plugin_config)); 368 s->ldap->ldap_filter_pre = buffer_init(); 369 s->ldap->ldap_filter_post = buffer_init(); 370 s->ldap->ldap = NULL; 369 371 #endif 370 372 … … 373 375 cv[2].destination = s->auth_plain_userfile; 374 376 cv[3].destination = s->auth_require; 375 cv[4].destination = s->auth_ldap_ hostname;377 cv[4].destination = s->auth_ldap_url; 376 378 cv[5].destination = s->auth_ldap_basedn; 377 379 cv[6].destination = s->auth_ldap_filter; … … 520 522 } 521 523 } 522 523 switch(s->auth_backend) { 524 case AUTH_BACKEND_LDAP: { 525 handler_t ret = auth_ldap_init(srv, s); 526 if (ret == HANDLER_ERROR) 527 return (ret); 528 break; 529 } 530 default: 531 break; 532 } 533 } 534 535 return HANDLER_GO_ON; 524 } 525 526 return HANDLER_GO_ON; 536 527 } 537 528 … … 539 530 #ifdef USE_LDAP 540 531 int ret; 541 #if 0 542 if (s->auth_ldap_basedn->used == 0) { 543 log_error_write(srv, __FILE__, __LINE__, "s", "ldap: auth.backend.ldap.base-dn has to be set"); 544 545 return HANDLER_ERROR; 546 } 547 #endif 532 struct berval credentials; 533 char *binddn_ptr = NULL; 548 534 549 535 if (s->auth_ldap_filter->used) { … … 558 544 } 559 545 560 buffer_copy_string_len(s->ldap _filter_pre, s->auth_ldap_filter->ptr, dollar - s->auth_ldap_filter->ptr);561 buffer_copy_string(s->ldap _filter_post, dollar+1);562 } 563 564 if (s->auth_ldap_ hostname->used) {565 if ( NULL == (s->ldap = ldap_init(s->auth_ldap_hostname->ptr, LDAP_PORT))) {566 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap ...", strerror(errno));546 buffer_copy_string_len(s->ldap->ldap_filter_pre, s->auth_ldap_filter->ptr, dollar - s->auth_ldap_filter->ptr); 547 buffer_copy_string(s->ldap->ldap_filter_post, dollar+1); 548 } 549 550 if (s->auth_ldap_url->used) { 551 if ((ret = ldap_initialize(&s->ldap->ldap, s->auth_ldap_url->ptr))) { 552 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); 567 553 568 554 return HANDLER_ERROR; 569 555 } 570 556 571 ret = LDAP_VERSION3; 572 if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(s->ldap, LDAP_OPT_PROTOCOL_VERSION, &ret))) { 557 const int ldap_version = LDAP_VERSION3; 558 ret = ldap_set_option(s->ldap->ldap, LDAP_OPT_PROTOCOL_VERSION, &ldap_version); 559 if (ret != LDAP_OPT_SUCCESS) { 573 560 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); 574 561 562 ldap_memfree(s->ldap->ldap); 563 s->ldap->ldap = NULL; 564 575 565 return HANDLER_ERROR; 576 566 } 577 567 578 if (s->auth_ldap_starttls ) {568 if (s->auth_ldap_starttls == 1) { 579 569 /* if no CA file is given, it is ok, as we will use encryption 580 570 * if the server requires a CAfile it will tell us */ … … 585 575 "Loading CA certificate failed:", ldap_err2string(ret)); 586 576 577 ldap_memfree(s->ldap->ldap); 578 s->ldap->ldap = NULL; 579 587 580 return HANDLER_ERROR; 588 581 } … … 595 588 "Loading TLS certificate failed:", ldap_err2string(ret)); 596 589 590 ldap_memfree(s->ldap->ldap); 591 s->ldap->ldap = NULL; 592 597 593 return HANDLER_ERROR; 598 594 } … … 605 601 "Loading TLS key certificate failed:", ldap_err2string(ret)); 606 602 603 ldap_memfree(s->ldap->ldap); 604 s->ldap->ldap = NULL; 605 607 606 return HANDLER_ERROR; 608 607 } 609 608 } 610 609 611 if (LDAP_OPT_SUCCESS != (ret = ldap_start_tls_s(s->ldap , NULL, NULL))) {610 if (LDAP_OPT_SUCCESS != (ret = ldap_start_tls_s(s->ldap->ldap, NULL, NULL))) { 612 611 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap startTLS failed:", ldap_err2string(ret)); 612 613 ldap_memfree(s->ldap->ldap); 614 s->ldap->ldap = NULL; 613 615 614 616 return HANDLER_ERROR; … … 619 621 /* 1. */ 620 622 if (s->auth_ldap_binddn->used) { 621 if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, s->auth_ldap_binddn->ptr, s->auth_ldap_bindpw->ptr))) { 622 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); 623 624 return HANDLER_ERROR; 625 } 623 credentials.bv_val = s->auth_ldap_bindpw->ptr; 624 credentials.bv_len = s->auth_ldap_bindpw->used; 625 binddn_ptr = s->auth_ldap_binddn->ptr; 626 626 } else { 627 if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, NULL, NULL))) { 628 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); 629 630 return HANDLER_ERROR; 631 } 627 credentials.bv_val = NULL; 628 credentials.bv_len = 0; 629 binddn_ptr = NULL; 630 } 631 ret = ldap_sasl_bind_s(s->ldap->ldap, s->auth_ldap_binddn->ptr, LDAP_SASL_SIMPLE, &credentials, NULL, NULL, NULL); 632 if(ret != LDAP_SUCCESS) { 633 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); 634 635 ldap_memfree(s->ldap->ldap); 636 s->ldap->ldap = NULL; 637 return HANDLER_ERROR; 632 638 } 633 639 } … … 638 644 #endif 639 645 return HANDLER_GO_ON; 646 } 647 648 void auth_ldap_cleanup(ldap_plugin_config *p) { 649 if (p->ldap != NULL) 650 ldap_unbind_ext_s(p->ldap, NULL, NULL); 651 p->ldap = NULL; 640 652 } 641 653

