Ticket #1535: lighttpd-1.5.0_pre1992-ldap.patch
| File lighttpd-1.5.0_pre1992-ldap.patch, 15.8 kB (added by dev-zero, 9 months ago) |
|---|
-
src/http_auth.c
54 54 */ 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 = '='; 59 60 … … 697 698 } 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 */ 708 710 … … 737 739 if (p->conf.auth_ldap_allow_empty_pw != 1 && pw[0] == '\0') 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);752 buffer_append_string_buffer(p->ldap_filter, p->conf.ldap->ldap_filter_post); 744 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); 745 755 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) 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);771 "ldap:", ldap_err2string(ret), ", filter:", p->ldap_filter); 755 772 756 773 return -1; 757 }758 774 } 759 775 760 if (NULL == (first = ldap_first_entry(p->conf.ldap, lm))) { 761 log_error_write(srv, __FILE__, __LINE__, "s", "ldap ..."); 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 } 762 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)); 785 763 786 ldap_msgfree(lm); 764 787 765 788 return -1; 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); 772 797 … … 775 800 776 801 ldap_msgfree(lm); 777 802 803 /* 3. */ 804 ret = ldap_initialize(&ldap, p->conf.auth_ldap_url->ptr); 805 if (ret) { 806 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); 778 807 779 /* 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)); 808 ldap_memfree(dn); 809 782 810 return -1; 783 811 } 784 812 785 ret = LDAP_VERSION3; 786 if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ret))) { 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) { 787 816 log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); 788 817 789 ldap_unbind_s(ldap); 818 ldap_memfree(ldap); 819 ldap_memfree(dn); 790 820 791 821 return -1; 792 822 } 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; 801 833 } 802 834 } 803 835 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); 804 844 805 if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(ldap, dn, pw))) { 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; 811 854 } 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 */ 817 861 -
src/http_auth.h
17 17 AUTH_BACKEND_HTDIGEST 18 18 } auth_backend_t; 19 19 20 #ifdef USE_LDAP 20 21 typedef struct { 22 LDAP *ldap; 23 24 buffer *ldap_filter_pre; 25 buffer *ldap_filter_post; 26 } ldap_plugin_config; 27 #endif 28 29 typedef struct { 21 30 /* auth */ 22 31 array *auth_require; 23 32 … … 29 38 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; 35 44 buffer *auth_ldap_bindpw; … … 46 55 auth_backend_t auth_backend; 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; 55 61 -
src/mod_auth.c
16 16 #include "sys-files.h" 17 17 18 18 handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s); 19 void auth_ldap_cleanup(ldap_plugin_config* p); 19 20 20 21 21 /** 22 22 * the basic and digest auth framework 23 23 * … … 74 74 buffer_free(s->auth_htpasswd_userfile); 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); 80 80 buffer_free(s->auth_ldap_bindpw); … … 84 84 buffer_free(s->auth_ldap_key); 85 85 86 86 #ifdef USE_LDAP 87 buffer_free(s->ldap _filter_pre);88 buffer_free(s->ldap _filter_post);87 buffer_free(s->ldap->ldap_filter_pre); 88 buffer_free(s->ldap->ldap_filter_post); 89 89 90 if (s->ldap) ldap_unbind_s(s->ldap); 90 auth_ldap_cleanup(s->ldap); 91 free(s->ldap); 91 92 #endif 92 93 93 94 free(s); … … 111 112 PATCH_OPTION(auth_htpasswd_userfile); 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); 117 118 PATCH_OPTION(auth_ldap_bindpw); … … 123 124 PATCH_OPTION(auth_ldap_allow_empty_pw); 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 130 129 /* skip the first, the global context */ … … 153 152 PATCH_OPTION(auth_require); 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); 167 168 } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("auth.backend.ldap.ca-file"))) { … … 318 319 { "auth.backend.plain.groupfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ 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 */ 324 325 { "auth.backend.ldap.ca-file", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 7 */ … … 349 350 s->auth_htpasswd_userfile = buffer_init(); 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(); 355 356 s->auth_ldap_bindpw = buffer_init(); … … 363 364 s->auth_require = array_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 371 373 cv[0].destination = s->auth_backend_conf; 372 374 cv[1].destination = s->auth_plain_groupfile; 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; 378 380 cv[7].destination = s->auth_ldap_cafile; … … 519 521 array_insert_unique(s->auth_require, (data_unset *)a); 520 522 } 521 523 } 524 } 522 525 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; 526 return HANDLER_GO_ON; 536 527 } 537 528 538 529 handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s) { 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"); 532 struct berval credentials; 533 char *binddn_ptr = NULL; 544 534 545 return HANDLER_ERROR;546 }547 #endif548 549 535 if (s->auth_ldap_filter->used) { 550 536 char *dollar; 551 537 … … 557 543 return HANDLER_ERROR; 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);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); 562 548 } 563 549 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));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 */ 581 571 if (!buffer_is_empty(s->auth_ldap_cafile)) { … … 584 574 log_error_write(srv, __FILE__, __LINE__, "ss", 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 } 589 582 } … … 594 587 log_error_write(srv, __FILE__, __LINE__, "ss", 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 } 599 595 } … … 604 600 log_error_write(srv, __FILE__, __LINE__, "ss", 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)); 613 612 613 ldap_memfree(s->ldap->ldap); 614 s->ldap->ldap = NULL; 615 614 616 return HANDLER_ERROR; 615 617 } 616 618 } … … 618 620 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)); 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)); 629 634 630 return HANDLER_ERROR; 631 } 635 ldap_memfree(s->ldap->ldap); 636 s->ldap->ldap = NULL; 637 return HANDLER_ERROR; 632 638 } 633 639 } 634 640 #else … … 639 645 return HANDLER_GO_ON; 640 646 } 641 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; 652 } 653 642 654 LI_EXPORT int mod_auth_plugin_init(plugin *p) { 643 655 p->version = LIGHTTPD_VERSION_ID; 644 656 p->name = buffer_init_string("auth");

