*** scheduler/dirsvc.c.orig Wed Sep 6 11:10:18 2006 --- scheduler/dirsvc.c Thu Sep 7 08:30:29 2006 *************** *** 28,33 **** --- 28,34 ---- * cupsdSendBrowseDelete() - Send a "browse delete" message for a * printer. * cupsdSendBrowseList() - Send new browsing information as necessary. + * cupsdLDAPRebindProc() - Callback function for LDAP rebind * cupsdStartBrowsing() - Start sending and receiving broadcast * information. * cupsdStartPolling() - Start polling servers as needed. *************** *** 36,41 **** --- 37,43 ---- * cupsdStopPolling() - Stop polling servers as needed. * cupsdUpdateCUPSBrowse() - Update the browse lists using the CUPS * protocol. + * cupsdReconnectLDAP() - Reconnect to LDAP Server * cupsdUpdateLDAPBrowse() - Scan for new printers via LDAP... * cupsdUpdatePolling() - Read status messages from the poll daemons. * cupsdUpdateSLPBrowse() - Get browsing information via SLP. *************** *** 833,839 **** --- 835,861 ---- } + #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) /* + * 'cupsdLDAPRebindProc()' - Callback function for LDAP rebind + */ + static int cupsdLDAPRebindProc (LDAP *RebindLDAPHandle, + LDAP_CONST char *refsp, + ber_tag_t request, + ber_int_t msgid, void *params) + { + int rc; + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdLDAPRebindProc: Rebind to %s", refsp); + rc = ldap_bind_s(RebindLDAPHandle, BrowseLDAPBindDN, + BrowseLDAPPassword, LDAP_AUTH_SIMPLE); + return rc; + } + #endif + + + /* * 'cupsdStartBrowsing()' - Start sending and receiving broadcast information. */ *************** *** 1015,1020 **** --- 1037,1052 ---- } else { + + #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) + rc = ldap_set_rebind_proc(BrowseLDAPHandle, &cupsdLDAPRebindProc, (void *)NULL); + if ( rc != LDAP_SUCCESS ) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Setting LDAP rebind function failed with status %d: %s", + rc, ldap_err2string(rc)); + #endif + + if (!BrowseLDAPServer || !strcasecmp(BrowseLDAPServer, "localhost")) rc = ldap_sasl_bind_s(BrowseLDAPHandle, NULL, "EXTERNAL", &bv, NULL, NULL, NULL); *************** *** 1194,1200 **** if (((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_LDAP) && BrowseLDAPHandle) { ! ldap_unbind(BrowseLDAPHandle); BrowseLDAPHandle = NULL; } #endif /* HAVE_OPENLDAP */ --- 1226,1232 ---- if (((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_LDAP) && BrowseLDAPHandle) { ! ldap_unbind_ext_s(BrowseLDAPHandle, NULL, NULL); BrowseLDAPHandle = NULL; } #endif /* HAVE_OPENLDAP */ *************** *** 1506,1511 **** --- 1538,1619 ---- #ifdef HAVE_OPENLDAP /* + * 'cupsdReconnectLDAP()' - Reconnect to LDAP Server + */ + + void + cupsdReconnectLDAP(void) + { + int rc; /* LDAP API status */ + int version = 3; /* LDAP version */ + struct berval bv = {0, ""}; /* SASL bind value */ + + LDAP *TempBrowseLDAPHandle; + /* Temp Handle to LDAP server */ + + cupsdLogMessage(CUPSD_LOG_INFO, + "Try to reconnect to LDAP server..."); + + TempBrowseLDAPHandle = NULL; + + if (!BrowseLDAPServer || !strcasecmp(BrowseLDAPServer, "localhost")) + rc = ldap_initialize(&TempBrowseLDAPHandle, "ldapi:///"); + else + rc = ldap_initialize(&TempBrowseLDAPHandle, BrowseLDAPServer); + + if (rc != LDAP_SUCCESS) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to initialize LDAP!"); + TempBrowseLDAPHandle = NULL; + } + else if (ldap_set_option(TempBrowseLDAPHandle, LDAP_OPT_PROTOCOL_VERSION, + (const void *)&version) != LDAP_SUCCESS) + { + ldap_unbind_ext(TempBrowseLDAPHandle, NULL, NULL); + TempBrowseLDAPHandle = NULL; + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to set LDAP protocol version!"); + } + else + { + #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) + rc = ldap_set_rebind_proc(TempBrowseLDAPHandle, &cupsdLDAPRebindProc, (void *)NULL); + if ( rc != LDAP_SUCCESS ) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Setting LDAP rebind function failed with status %d: %s", + rc, ldap_err2string(rc)); + #endif + + if (!BrowseLDAPServer || !strcasecmp(BrowseLDAPServer, "localhost")) + rc = ldap_sasl_bind_s(TempBrowseLDAPHandle, NULL, "EXTERNAL", &bv, NULL, + NULL, NULL); + else + rc = ldap_bind_s(TempBrowseLDAPHandle, BrowseLDAPBindDN, + BrowseLDAPPassword, LDAP_AUTH_SIMPLE); + + if (rc != LDAP_SUCCESS) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "LDAP bind returned error %d: %s", rc, + ldap_err2string(rc)); + + ldap_unbind_ext(TempBrowseLDAPHandle, NULL, NULL); + TempBrowseLDAPHandle = NULL; + } + } + if (TempBrowseLDAPHandle != NULL) + { + if (BrowseLDAPHandle != NULL) + { + ldap_unbind_ext_s(BrowseLDAPHandle, NULL, NULL); + } + BrowseLDAPHandle = TempBrowseLDAPHandle; + } + } + + + /* * 'cupsdUpdateLDAPBrowse()' - Scan for new printers via LDAP... */ *************** *** 1541,1546 **** --- 1649,1658 ---- cupsdLogMessage(CUPSD_LOG_ERROR, "LDAP search returned error %d: %s", rc, ldap_err2string(rc)); + + if ( LDAP_SERVER_DOWN == rc ) + cupsdReconnectLDAP(); + return; } *************** *** 1561,1567 **** * Get the required values from this entry... */ ! if ((value = ldap_get_values(BrowseLDAPHandle, e, "printerDescription")) == NULL) continue; --- 1673,1679 ---- * Get the required values from this entry... */ ! if ((value = (char **) ldap_get_values(BrowseLDAPHandle, e, "printerDescription")) == NULL) continue; *************** *** 1568,1574 **** strlcpy(info, *value, sizeof(info)); ldap_value_free(value); ! if ((value = ldap_get_values(BrowseLDAPHandle, e, "printerLocation")) == NULL) continue; --- 1680,1686 ---- strlcpy(info, *value, sizeof(info)); ldap_value_free(value); ! if ((value = (char **) ldap_get_values(BrowseLDAPHandle, e, "printerLocation")) == NULL) continue; *************** *** 1575,1581 **** strlcpy(location, *value, sizeof(location)); ldap_value_free(value); ! if ((value = ldap_get_values(BrowseLDAPHandle, e, "printerMakeAndModel")) == NULL) continue; --- 1687,1693 ---- strlcpy(location, *value, sizeof(location)); ldap_value_free(value); ! if ((value = (char **) ldap_get_values(BrowseLDAPHandle, e, "printerMakeAndModel")) == NULL) continue; *************** *** 1582,1588 **** strlcpy(make_model, *value, sizeof(make_model)); ldap_value_free(value); ! if ((value = ldap_get_values(BrowseLDAPHandle, e, "printerType")) == NULL) continue; --- 1694,1700 ---- strlcpy(make_model, *value, sizeof(make_model)); ldap_value_free(value); ! if ((value = (char **) ldap_get_values(BrowseLDAPHandle, e, "printerType")) == NULL) continue; *************** *** 1589,1595 **** type = atoi(*value); ldap_value_free(value); ! if ((value = ldap_get_values(BrowseLDAPHandle, e, "printerURI")) == NULL) continue; --- 1701,1707 ---- type = atoi(*value); ldap_value_free(value); ! if ((value = (char **) ldap_get_values(BrowseLDAPHandle, e, "printerURI")) == NULL) continue; *************** *** 2684,2690 **** int i; /* Looping var... */ LDAPMod mods[7]; /* The 7 attributes we will be adding */ LDAPMod *pmods[8]; /* Pointers to the 7 attributes + NULL */ ! LDAPMessage *res; /* Search result token */ char *cn_value[2], /* Change records */ *uri[2], *info[2], --- 2796,2803 ---- int i; /* Looping var... */ LDAPMod mods[7]; /* The 7 attributes we will be adding */ LDAPMod *pmods[8]; /* Pointers to the 7 attributes + NULL */ ! LDAPMessage *res, /* Search result token */ ! *e; /* Current entry from search */ char *cn_value[2], /* Change records */ *uri[2], *info[2], *************** *** 2702,2708 **** --- 2815,2829 ---- "cupsPrinter", NULL }; + char old_uri[HTTP_MAX_URI], /* Printer URI */ + old_location[1024], /* Printer location */ + old_info[1024], /* Printer information */ + old_make_model[1024], /* Printer make and model */ + **value; /* Holds the returned data from LDAP */ + int old_type; /* Printer type */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "send_ldap_browse: %s\n", p->name); /* *************** *** 2727,2736 **** snprintf(filter, sizeof(filter), "(&(objectclass=cupsPrinter)(printerURI=%s))", p->uri); ! ldap_search_s(BrowseLDAPHandle, BrowseLDAPDN, LDAP_SCOPE_SUBTREE, filter, (char **)ldap_attrs, 0, &res); cupsdLogMessage(CUPSD_LOG_DEBUG2, "send_ldap_browse: Searching \"%s\"", filter); mods[0].mod_type = "cn"; mods[0].mod_values = cn_value; --- 2848,2866 ---- snprintf(filter, sizeof(filter), "(&(objectclass=cupsPrinter)(printerURI=%s))", p->uri); ! rc = ldap_search_s(BrowseLDAPHandle, BrowseLDAPDN, LDAP_SCOPE_SUBTREE, filter, (char **)ldap_attrs, 0, &res); cupsdLogMessage(CUPSD_LOG_DEBUG2, "send_ldap_browse: Searching \"%s\"", filter); + if ( rc != LDAP_SUCCESS ) { + cupsdLogMessage(CUPSD_LOG_ERROR, + "send_ldap_browse: LDAP search failed with status %d: %s", + rc, ldap_err2string(rc)); + + if ( LDAP_SERVER_DOWN == rc ) + cupsdReconnectLDAP(); + return; + } mods[0].mod_type = "cn"; mods[0].mod_values = cn_value; *************** *** 2753,2776 **** if (ldap_count_entries(BrowseLDAPHandle, res) > 0) { /* ! * Printer has already been registered, modify the current ! * registration... */ ! cupsdLogMessage(CUPSD_LOG_DEBUG2, ! "send_ldap_browse: Replacing entry..."); ! for (i = 0; i < 7; i ++) { ! pmods[i] = mods + i; ! pmods[i]->mod_op = LDAP_MOD_REPLACE; } ! pmods[i] = NULL; ! if ((rc = ldap_modify_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS) ! cupsdLogMessage(CUPSD_LOG_ERROR, ! "LDAP modify for %s failed with status %d: %s", ! p->name, rc, ldap_err2string(rc)); } else { --- 2883,2999 ---- if (ldap_count_entries(BrowseLDAPHandle, res) > 0) { /* ! * Printer has already been registered, check if ! * modification is required... */ ! e = ldap_first_entry(BrowseLDAPHandle, res); ! /* ! * Get the required values from this entry... ! */ ! ! if ((value = (char **) ldap_get_values(BrowseLDAPHandle, e, ! "printerDescription")) == NULL) { ! cupsdLogMessage(CUPSD_LOG_DEBUG, ! "send_ldap_browse: ldap_get printerDescription failed!"); ! old_info[0] = '\0'; } ! else ! { ! strlcpy(old_info, *value, sizeof(old_info)); ! ldap_value_free(value); ! } ! if ((value = (char **) ldap_get_values(BrowseLDAPHandle, e, ! "printerLocation")) == NULL) ! { ! cupsdLogMessage(CUPSD_LOG_DEBUG, ! "send_ldap_browse: ldap_get printerLocation failed!"); ! old_location[0] = '\0'; ! } ! else ! { ! strlcpy(old_location, *value, sizeof(old_location)); ! ldap_value_free(value); ! } ! ! if ((value = (char **) ldap_get_values(BrowseLDAPHandle, e, ! "printerMakeAndModel")) == NULL) ! { ! cupsdLogMessage(CUPSD_LOG_DEBUG, ! "send_ldap_browse: ldap_get printerMakeAndModel failed!"); ! old_make_model[0] = '\0'; ! } ! else ! { ! strlcpy(old_make_model, *value, sizeof(old_make_model)); ! ldap_value_free(value); ! } ! ! if ((value = (char **) ldap_get_values(BrowseLDAPHandle, e, ! "printerType")) == NULL) ! { ! cupsdLogMessage(CUPSD_LOG_DEBUG, ! "send_ldap_browse: ldap_get printerType failed!"); ! old_type = 0; ! } ! else ! { ! old_type = atoi(*value); ! ldap_value_free(value); ! } ! ! if ((value = (char **) ldap_get_values(BrowseLDAPHandle, e, ! "printerURI")) == NULL) ! { ! cupsdLogMessage(CUPSD_LOG_DEBUG, ! "send_ldap_browse: ldap_get printerURI failed!"); ! old_uri[0] = '\0'; ! } ! else ! { ! strlcpy(old_uri, *value, sizeof(old_uri)); ! ldap_value_free(value); ! } ! ! if ( ( strcmp(info[0], old_info) == 0 ) ! && ( strcmp(uri[0], old_uri) == 0 ) ! && ( strcmp(location[0], old_location) == 0 ) ! && ( strcmp(make_model[0], old_make_model) == 0 ) ! && ( p->type == old_type )) ! { ! cupsdLogMessage(CUPSD_LOG_DEBUG2, ! "send_ldap_browse: No update required"); ! } ! else ! { ! ! /* ! * Printer has already been registered, modify the current ! * registration... ! */ ! ! cupsdLogMessage(CUPSD_LOG_DEBUG2, ! "send_ldap_browse: Replacing entry..."); ! ! for (i = 0; i < 7; i ++) ! { ! pmods[i] = mods + i; ! pmods[i]->mod_op = LDAP_MOD_REPLACE; ! } ! pmods[i] = NULL; ! ! if ((rc = ldap_modify_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS) ! { ! cupsdLogMessage(CUPSD_LOG_ERROR, ! "LDAP modify for %s failed with status %d: %s", ! p->name, rc, ldap_err2string(rc)); ! if ( LDAP_SERVER_DOWN == rc ) ! cupsdReconnectLDAP(); ! } ! } } else { *************** *** 2790,2798 **** --- 3013,3025 ---- pmods[i] = NULL; if ((rc = ldap_add_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS) + { cupsdLogMessage(CUPSD_LOG_ERROR, "LDAP add for %s failed with status %d: %s", p->name, rc, ldap_err2string(rc)); + if ( LDAP_SERVER_DOWN == rc ) + cupsdReconnectLDAP(); + } } } #endif /* HAVE_OPENLDAP */