1/* 2 Unix SMB/CIFS implementation. 3 4 Some Helpful wrappers on LDAP 5 6 Copyright (C) Andrew Tridgell 2001 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21*/ 22 23#include "includes.h" 24 25#ifdef HAVE_LDAP 26/* 27 a wrapper around ldap_search_s that retries depending on the error code 28 this is supposed to catch dropped connections and auto-reconnect 29*/ 30ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope, 31 const char *expr, 32 const char **attrs, void **res) 33{ 34 ADS_STATUS status; 35 int count = 3; 36 char *bp; 37 38 *res = NULL; 39 40 if (!ads->ld && 41 time(NULL) - ads->last_attempt < ADS_RECONNECT_TIME) { 42 return ADS_ERROR(LDAP_SERVER_DOWN); 43 } 44 45 bp = strdup(bind_path); 46 47 if (!bp) { 48 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); 49 } 50 51 while (count--) { 52 *res = NULL; 53 status = ads_do_search_all(ads, bp, scope, expr, attrs, res); 54 if (ADS_ERR_OK(status)) { 55 DEBUG(5,("Search for %s gave %d replies\n", 56 expr, ads_count_replies(ads, *res))); 57 SAFE_FREE(bp); 58 return status; 59 } 60 61 if (*res) 62 ads_msgfree(ads, *res); 63 *res = NULL; 64 65 DEBUG(3,("Reopening ads connection to realm '%s' after error %s\n", 66 ads->config.realm, ads_errstr(status))); 67 68 if (ads->ld) { 69 ldap_unbind(ads->ld); 70 } 71 72 ads->ld = NULL; 73 status = ads_connect(ads); 74 75 if (!ADS_ERR_OK(status)) { 76 DEBUG(1,("ads_search_retry: failed to reconnect (%s)\n", 77 ads_errstr(status))); 78 ads_destroy(&ads); 79 SAFE_FREE(bp); 80 return status; 81 } 82 } 83 SAFE_FREE(bp); 84 85 if (!ADS_ERR_OK(status)) 86 DEBUG(1,("ads reopen failed after error %s\n", 87 ads_errstr(status))); 88 89 return status; 90} 91 92 93ADS_STATUS ads_search_retry(ADS_STRUCT *ads, void **res, 94 const char *expr, 95 const char **attrs) 96{ 97 return ads_do_search_retry(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE, 98 expr, attrs, res); 99} 100 101ADS_STATUS ads_search_retry_dn(ADS_STRUCT *ads, void **res, 102 const char *dn, 103 const char **attrs) 104{ 105 return ads_do_search_retry(ads, dn, LDAP_SCOPE_BASE, 106 "(objectclass=*)", attrs, res); 107} 108#endif 109