cups-browsed/0001-Removed-support-for-legacy-CUPS-browsing-and-for-LDA.patch

2391 lines
73 KiB
Diff

From 1d1072a0de573b7850958df614e9ec5b73ea0e0d Mon Sep 17 00:00:00 2001
From: Till Kamppeter <till.kamppeter@gmail.com>
Date: Tue, 1 Oct 2024 00:59:58 +0200
Subject: [PATCH] Removed support for legacy CUPS browsing and for LDAP
Legacy CUPS browsing is not needed any more. this functionality got
removed from CUPS with version 1.6, more than a decade ago. In
cups-browsed it was implemented as a legacy support layer for servers
or clients running long-term-support enterprise distributions still
using CUPS 1.5.x or older. Now the support life of all these
distributions should have expired and so this legacy support by
cups-browsed is not needed any more.
In addition, the legacy CUPS browsing implementation in cups-browsed
was listening for UDP packaets on port 631 and by default it accepted
packets from any source, making it easy for attackers to set up forged
printers which could make use of vulnerabilities of CUPS or just find
out about the identity and properties of clients. This is
CVE-2024-47176:
https://ubuntu.com/security/CVE-2024-47176
https://github.com/OpenPrinting/cups-browsed/security/advisories/GHSA-rj88-6mr5-rcw8
https://openprinting.github.io/OpenPrinting-News-Flash-cups-browsed-Remote-Code-Execution-vulnerability/
The removal of the legacy CUPS browsing support removes also this
vulnerability.
The LDAP implementation in cups-browsed does not follow the LDAP
printer schema RFC 7612 and is therefore of very limited use.
---
INSTALL | 3 +-
README.md | 53 +-
configure.ac | 46 +-
daemon/cups-browsed.8 | 38 +-
daemon/cups-browsed.c | 1675 ++---------------------------------
daemon/cups-browsed.conf.5 | 43 +-
daemon/cups-browsed.conf.in | 27 +-
test/run-tests.sh | 4 +-
8 files changed, 138 insertions(+), 1751 deletions(-)
diff --git a/INSTALL b/INSTALL
index 7c5d5941..e48305d2 100644
--- a/INSTALL
+++ b/INSTALL
@@ -111,5 +111,4 @@ PACKAGING THE SOFTWARE FOR OPERATING SYSTEM DISTRIBUTIONS
`--enable-auto-setup-driverless-only` then.
Otherwise cups-browsed is only needed for more advanced setups,
- like printer clusters or support for legacy CUPS (< 1.6.x) on
- remote servers or clients.
+ like printer clusters.
diff --git a/README.md b/README.md
index fbdcd186..ee4ee88d 100644
--- a/README.md
+++ b/README.md
@@ -26,15 +26,6 @@ cups-browsed has the following functionality:
several print dialogs use old CUPS APIs and therefore require
permanent local queues to see such printers.
-- Auto-discover shared printers on remote CUPS servers running CUPS
- 1.5.x or older via legacy CUPS browsing. This is intended for
- settings with print servers running long-term-support enterprise
- distributions.
-
-- Broadcast shared local printers using legacy CUPS browsing (of CUPS
- 1.5.x) for settings with printing clients running long-term-support
- enterprise distributions.
-
- Creating printer clusters where jobs are printed to one single queue
and get automatically passed on to a suitable member printer.
@@ -63,8 +54,8 @@ cups-browsed has the following functionality:
- Highly configurable: Which printers are considered? For which type
of printers queues are created? Cluster types and member printers?
- which names auto-created queues should get? DNS-SD and/or legacy
- browsing? ...
+ which names auto-created queues should get? DNS-SD and/or
+ BrowsePoll? ...
- Multi-threading allows several tasks to be done in parallel and
assures responsiveness of the daemon when there is a large amount of
@@ -154,43 +145,33 @@ Most of this is still valid for the current cups-browsed.
### HELPER DAEMON FOR BROWSING REMOTE CUPS PRINTERS AND IPP NETWORK PRINTERS
From version 1.6.0 on in CUPS the CUPS broadcasting/browsing
-facility was dropped, in favour of Bonjour-based broadcasting of
-shared printers. This is done as Bonjour broadcasting of shared
+facility was dropped, in favour of DNS-SD-based broadcasting of
+shared printers. This is done as DNS-SD broadcasting of shared
printers is a standard, established by the PWG (Printing Working
Group, http://www.pwg.org/), and most other network services
(shared file systems, shared media files/streams, remote desktop
-services, ...) are also broadcasted via Bonjour.
+services, ...) are also broadcasted via DNS-SD.
Problem is that CUPS only broadcasts its shared printers but does
not browse broadcasts of other CUPS servers to make the shared
remote printers available locally without any configuration
efforts. This is a regression compared to the old CUPS
broadcasting/browsing. The intention of CUPS upstream is that the
-application's print dialogs browse the Bonjour broadcasts as an
+application's print dialogs browse the DNS-SD broadcasts as an
AirPrint-capable iPhone does, but it will take its time until all
toolkit developers add the needed functionality, and programs
using old toolkits or no toolkits at all, or the command line stay
uncovered.
-The solution is cups-browsed, a helper daemon running in parallel
-to the CUPS daemon which listens to Bonjour broadcasts of shared
-CUPS printers on remote machines in the local network via Avahi,
-and can also listen for (and send) CUPS Browsing broadcasts. For
-each reported remote printer it creates a local raw queue pointing
-to the remote printer so that the printer appears in local print
-dialogs and is also available for printing via the command
-line. As with the former CUPS broadcasting/browsing with this
-queue the driver on the server is used and the local print dialogs
-give access to all options of the server-side printer driver.
-
-Note that CUPS broadcasting/browsing is available for legacy
-support, to let the local CUPS daemon work seamlessly together
-with remote CUPS daemons of version 1.5.x and older which only
-support CUPS broadcasting/browsing. In networks with only CUPS
-1.6.x servers (or Ubuntu or Fedora/Red Hat servers with CUPS
-1.5.x) please use the native Bonjour broadcasting of your servers
-and cups-browsed, configured for Bonjour browsing only on the
-clients.
+The solution is cups-browsed, a helper daemon running in parallel to
+the CUPS daemon which listens to DNS-SD broadcasts of shared CUPS
+printers on remote machines in the local network via Avahi. For each
+reported remote printer it creates a local raw queue pointing to the
+remote printer so that the printer appears in local print dialogs and
+is also available for printing via the command line. As with the
+former CUPS broadcasting/browsing with this queue the driver on the
+server is used and the local print dialogs give access to all options
+of the server-side printer driver.
Also high availability with redundant print servers and load
balancing is supported. If there is more than one server providing
@@ -301,7 +282,7 @@ up. cups-browsed is also robust against any shutdown and restart
of avahi-daemon.
Here is some info on how cups-browsed works internally (first concept of a
-daemon which does only Bonjour browsing):
+daemon which does only DNS-SD browsing):
- Daemon start
o Wait for CUPS daemon if it is not running
@@ -357,7 +338,7 @@ appears, create new queue as <original name>@<server name without
of the others by one with simple name (mark old queue disappeared
with timeout now-1 sec and create new queue with simple name).
-Fill description of the created CUPS queue with the Bonjour
+Fill description of the created CUPS queue with the DNS-SD
service name (= original description) and location with the server
name without .local.
diff --git a/configure.ac b/configure.ac
index 84de9129..2ff5a43b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -300,50 +300,6 @@ fi
AC_SUBST(AVAHI_LIBS)
AC_SUBST(AVAHI_CFLAGS)
-dnl
-dnl LDAP configuration stuff for CUPS.
-dnl
-dnl Copyright 2007-2011 by Apple Inc.
-dnl Copyright 2003-2006 by Easy Software Products, all rights reserved.
-dnl
-dnl These coded instructions, statements, and computer programs are the
-dnl property of Apple Inc. and are protected by Federal copyright
-dnl law. Distribution and use rights are outlined in the file "COPYING"
-dnl which should have been included with this file.
-dnl
-
-AC_ARG_ENABLE([ldap], [AS_HELP_STRING([--disable-ldap], [disable LDAP support.])],
- [enable_ldap="$enableval"],
- [enable_ldap=yes]
-)
-AC_ARG_WITH([ldap-libs], [AS_HELP_STRING([--with-ldap-libs], [set directory for LDAP library.])],
- LDFLAGS="-L$withval $LDFLAGS"
- DSOFLAGS="-L$withval $DSOFLAGS",)
-AC_ARG_WITH([ldap-includes], [AS_HELP_STRING([--with-ldap-includes], [set directory for LDAP includes.])],
- CFLAGS="-I$withval $CFLAGS"
- CPPFLAGS="-I$withval $CPPFLAGS",)
-
-if test x$enable_ldap != xno; then
-
- AC_CHECK_HEADER([ldap.h], [
- AC_SEARCH_LIBS([ldap_initialize], [ldap], [
- AC_DEFINE([HAVE_LDAP], [], [Define if LDAP support should be enabled])
- AC_DEFINE([HAVE_OPENLDAP], [], [If LDAP support is that of OpenLDAP])
- AC_CHECK_LIB([ldap], [ldap_start_tls],
- AC_DEFINE([HAVE_LDAP_SSL], [], [If LDAP has SSL/TLS support enabled]))],[
-
- AC_CHECK_LIB([ldap], [ldap_init], [
- AC_DEFINE([HAVE_LDAP], [], [Define if LDAP support should be enabled])
- AC_DEFINE([HAVE_MOZILLA_LDAP], [], [If LDAP support is that of Mozilla])
- AC_CHECK_HEADERS([ldap_ssl.h], [], [], [#include <ldap.h>])
- AC_CHECK_LIB([ldap], [ldapssl_init],
- AC_DEFINE([HAVE_LDAP_SSL], [], [If LDAP has SSL/TLS support enabled]))])]
- )
- AC_CHECK_LIB([ldap], [ldap_set_rebind_proc], AC_DEFINE([HAVE_LDAP_REBIND_PROC], [], [If libldap implements ldap_set_rebind_proc]))
- ])
-
-fi
-
PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.30.2])
AC_SUBST(GLIB_CFLAGS)
AC_SUBST(GLIB_LIBS)
@@ -487,7 +443,7 @@ Environment settings:
Build configuration:
cups-config: ${with_cups_config}
init directory: ${INITDDIR}
- cups dom socket: ${CUPS_DEFAULT_DOMAINSOCKET}
+ cups domain socket: ${CUPS_DEFAULT_DOMAINSOCKET}
avahi: ${enable_avahi}
browsing: ${with_browseremoteprotocols}
local queue naming for remote CUPS queues: ${REMOTE_CUPS_LOCAL_QUEUE_NAMING}
diff --git a/daemon/cups-browsed.8 b/daemon/cups-browsed.8
index 73c2f686..6eb713bf 100644
--- a/daemon/cups-browsed.8
+++ b/daemon/cups-browsed.8
@@ -16,20 +16,14 @@
.fam T
.fi
.SH DESCRIPTION
-\fBcups-browsed\fP has four independently switchable functions:
+\fBcups-browsed\fP has two independently switchable functions:
.IP 1. 4
-Browse Bonjour broadcasts of remote printers and create/remove local
-raw queues pointing to these printers.
+Browse DNS-SD broadcasts of remote printers and create/remove local
+CUPS queues pointing to these printers.
.IP 2. 4
-Browse CUPS broadcasts of remote printers and create/remove local raw
-queues pointing to these printers.
-.IP 3. 4
-Browse an LDAP server for printers and create/remove local raw
-queues pointing to these printers.
-.IP 4. 4
-Broadcast local queues with the CUPS protocol.
+Find shared printers on given CUPS servers and create local CUPS queues
+pointing to them.
.PP
-Note that 2. and 4. are only to allow communication with legacy CUPS servers (1.5.x or older) on the remote machine(s). The standard method to broadcast for shared/network printers to broadcast their presence is Bonjour. The CUPS broadcasting/browsing protocol is deprecated.
cups-browsed can be run permanently (from system boot to shutdown) or on-demand (for example to save resources on mobile devices). For running it on-demand an auto-shutdown feature can be activated to let cups-browsed terminate when it does not have queues any more to take care of.
@@ -76,28 +70,8 @@ Display usage and version info and do not start the daemon.
\fISIGUSR2\f1: Switches cups-browsed into auto shutdown mode.
.SH NOTES
-Please take references to cups 1.6.x to include newer versions.
-Similarly, cups 1.5.x is intended to encompass older versions too.
-.PP
-In environments with only cups 1.6.x servers and clients (plus
-\fBcups-browsed\fP on either server or client or both) the function described in 1.
-enables the automatic discovery of remote queues and their display in
-printing dialogues of applications and with command line tools.
-.PP
-The facility provided by 3. allows printers that are registered in an LDAP
-server to be added as local queues. CUPS servers 1.5.x are able to automatically
-register printers in LDAP. The facility provided by \fBcups-browsed\fP allows
-a filter string to further limit the printers that are browsed from LDAP.
-.PP
-The facility provided by 4. means that servers running cups 1.6.x plus
-\fBcups-browsed\fP can broadcast their local queues so that clients with cups
-1.5.x get these queues automatically available. The outcome of 2. is
-that clients running cups 1.6.x plus \fBcups-browsed\fP can use the CUPS
-broadcasts from servers with cups 1.5.x. As with browsing of Bonjour
-broadcasts, the created local raw queues are available to applications
-and command line tools.
-.PP
This manual page was written for the Debian Project, but it may be used by others.
+
.SH SEE ALSO
\fBcups-browsed.conf\fP(5)
diff --git a/daemon/cups-browsed.c b/daemon/cups-browsed.c
index 828ca94c..31122ec5 100644
--- a/daemon/cups-browsed.c
+++ b/daemon/cups-browsed.c
@@ -47,72 +47,6 @@
#include <gio/gio.h>
-
-#ifdef HAVE_LDAP
-# ifdef __sun
-# include <lber.h>
-# endif // __sun
-# include <ldap.h>
-# ifdef HAVE_LDAP_SSL_H
-# include <ldap_ssl.h>
-# endif // HAVE_LDAP_SSL_H
-#endif // HAVE_LDAP
-
-
-#ifdef HAVE_LDAP
-LDAP *BrowseLDAPHandle = NULL;
- // Handle to LDAP server
-char *BrowseLDAPBindDN = NULL,
- // LDAP login DN
- *BrowseLDAPDN = NULL,
- // LDAP search DN
- *BrowseLDAPPassword = NULL,
- // LDAP login password
- *BrowseLDAPServer = NULL,
- // LDAP server to use
- *BrowseLDAPFilter = NULL;
- // LDAP query filter
-int BrowseLDAPUpdate = TRUE,
- // enables LDAP updates
- BrowseLDAPInitialised = FALSE;
- // the init stuff has been done
-# ifdef HAVE_LDAP_SSL
-char *BrowseLDAPCACertFile = NULL;
- // LDAP CA CERT file to use
-# endif // HAVE_LDAP_SSL
-#endif // HAVE_LDAP
-
-
-#ifdef HAVE_LDAP
-#define LDAP_BROWSE_FILTER "(objectclass=cupsPrinter)"
-static LDAP *ldap_new_connection(void);
-static LDAP *ldap_reconnect(void);
-static void ldap_disconnect(LDAP *ld);
-static int ldap_search_rec(LDAP *ld, char *base, int scope,
- char *filter, char *attrs[],
- int attrsonly, LDAPMessage **res);
-static int ldap_getval_firststring(LDAP *ld, LDAPMessage *entry,
- char *attr, char *retval,
- unsigned long maxsize);
-static void ldap_freeres(LDAPMessage *entry);
-# ifdef HAVE_LDAP_REBIND_PROC
-# if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-static int ldap_rebind_proc(LDAP *RebindLDAPHandle,
- LDAP_CONST char *refsp,
- ber_tag_t request,
- ber_int_t msgid,
- void *params);
-# else
-static int ldap_rebind_proc(LDAP *RebindLDAPHandle,
- char **dnp,
- char **passwdp,
- int *authmethodp,
- int freeit,
- void *arg);
-# endif // defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-# endif // HAVE_LDAP_REBIND_PROC
-#endif // HAVE_LDAP
-
#include <cups/cups.h>
#include <cups/raster.h>
#include <cupsfilters/ipp.h>
@@ -291,18 +225,6 @@ typedef struct local_printer_s {
gboolean cups_browsed_controlled;
} local_printer_t;
-// Browse data to send for local printer
-typedef struct browse_data_s
-{
- int type;
- int state;
- char *uri;
- char *location;
- char *info;
- char *make_model;
- char *browse_options;
-} browse_data_t;
-
// Data structure for manual definition of load-balancing clusters
typedef struct cluster_s
{
@@ -439,8 +361,6 @@ static browsepoll_t *local_printers_context = NULL;
static http_t *local_conn = NULL;
static gboolean inhibit_local_printers_update = FALSE;
-static GList *browse_data = NULL;
-
static CupsNotifier *cups_notifier = NULL;
static GMainLoop *gmainloop = NULL;
@@ -450,23 +370,10 @@ static AvahiClient *client = NULL;
static AvahiServiceBrowser *sb1 = NULL, *sb2 = NULL;
static int avahi_present = 0;
#endif // HAVE_AVAHI
-#ifdef HAVE_LDAP
-static const char * const ldap_attrs[] =// CUPS LDAP attributes
- {
- "printerDescription",
- "printerLocation",
- "printerMakeAndModel",
- "printerType",
- "printerURI",
- NULL
- };
-#endif // HAVE_LDAP
static guint queues_timer_id = 0;
static int browsesocket = -1;
#define BROWSE_DNSSD (1<<0)
-#define BROWSE_CUPS (1<<1)
-#define BROWSE_LDAP (1<<2)
static unsigned int BrowseLocalProtocols = 0;
static unsigned int BrowseRemoteProtocols = BROWSE_DNSSD;
static unsigned int BrowseInterval = 60;
@@ -4113,1087 +4020,106 @@ get_local_printers (void)
g_hash_table_insert (local_printers,
g_ascii_strdown (dest->name, -1),
printer);
- }
-
- cupsFreeDests (num_dests, dests);
-
- pthread_rwlock_unlock(&lock);
-}
-
-
-static browse_data_t *
-new_browse_data (int type, int state, const gchar *uri,
- const gchar *location, const gchar *info,
- const gchar *make_model, const gchar *browse_options)
-{
- browse_data_t *data = g_malloc (sizeof (browse_data_t));
- data->type = type;
- data->state = state;
- data->uri = g_strdup (uri);
- data->location = g_strdup (location);
- data->info = g_strdup (info);
- data->make_model = g_strdup (make_model);
- data->browse_options = g_strdup (browse_options);
- return (data);
-}
-
-
-static void
-browse_data_free (gpointer data)
-{
- browse_data_t *bdata = data;
- debug_printf("browse_data_free() in THREAD %ld\n", pthread_self());
- g_free (bdata->uri);
- g_free (bdata->location);
- g_free (bdata->info);
- g_free (bdata->make_model);
- g_free (bdata->browse_options);
- g_free (bdata);
-}
-
-
-static void
-prepare_browse_data (void)
-{
- static const char * const rattrs[] = { "printer-type",
- "printer-state",
- "printer-uri-supported",
- "printer-info",
- "printer-location",
- "printer-make-and-model",
- "auth-info-required",
- "printer-uuid",
- "job-template" };
- ipp_t *request, *response = NULL;
- ipp_attribute_t *attr;
- http_t *conn = NULL;
- GString *browse_options = NULL;
-
- conn = http_connect_local ();
-
- if (conn == NULL)
- {
- debug_printf("Browse send failed to connect to localhost\n");
- goto fail;
- }
-
- request = ippNewRequest(CUPS_GET_PRINTERS);
- ippAddStrings (request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
- "requested-attributes", sizeof (rattrs) / sizeof (rattrs[0]),
- NULL, rattrs);
- ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "requesting-user-name", NULL, cupsUser ());
-
- debug_printf("preparing browse data\n");
- response = cupsDoRequest (conn, request, "/");
- if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE)
- {
- debug_printf("browse send failed for localhost: %s\n",
- cupsLastErrorString ());
- goto fail;
- }
-
- g_list_free_full (browse_data, browse_data_free);
- browse_data = NULL;
- for (attr = ippFirstAttribute(response); attr;
- attr = ippNextAttribute(response))
- {
- int type = -1, state = -1;
- const char *uri = NULL;
- gchar *location = NULL;
- gchar *info = NULL;
- gchar *make_model = NULL;
- browse_options = g_string_new ("");
-
- // Skip any non-printer attributes
- while (attr && ippGetGroupTag(attr) != IPP_TAG_PRINTER)
- attr = ippNextAttribute(response);
-
- if (!attr)
- break;
-
- while (attr && ippGetGroupTag(attr) == IPP_TAG_PRINTER)
- {
- const char *attrname = ippGetName(attr);
- int value_tag = ippGetValueTag(attr);
-
- if (!strcasecmp(attrname, "printer-type") &&
- value_tag == IPP_TAG_ENUM)
- {
- type = ippGetInteger(attr, 0);
- if (type & CUPS_PRINTER_NOT_SHARED)
- {
- // Skip CUPS queues not marked as shared
- state = -1;
- type = -1;
- break;
- }
- }
- else if (!strcasecmp(attrname, "printer-state") &&
- value_tag == IPP_TAG_ENUM)
- state = ippGetInteger(attr, 0);
- else if (!strcasecmp(attrname, "printer-uri-supported") &&
- value_tag == IPP_TAG_URI)
- uri = ippGetString(attr, 0, NULL);
- else if (!strcasecmp(attrname, "printer-location") &&
- value_tag == IPP_TAG_TEXT)
- {
- // Remove quotes
- gchar **tokens = g_strsplit (ippGetString(attr, 0, NULL), "\"", -1);
- location = g_strjoinv ("", tokens);
- g_strfreev (tokens);
- }
- else if (!strcasecmp(attrname, "printer-info") &&
- value_tag == IPP_TAG_TEXT)
- {
- // Remove quotes
- gchar **tokens = g_strsplit (ippGetString(attr, 0, NULL), "\"", -1);
- info = g_strjoinv ("", tokens);
- g_strfreev (tokens);
- }
- else if (!strcasecmp(attrname, "printer-make-and-model") &&
- value_tag == IPP_TAG_TEXT)
- {
- // Remove quotes
- gchar **tokens = g_strsplit (ippGetString(attr, 0, NULL), "\"", -1);
- make_model = g_strjoinv ("", tokens);
- g_strfreev (tokens);
- }
- else if (!strcasecmp(attrname, "auth-info-required") &&
- value_tag == IPP_TAG_KEYWORD)
- {
- if (strcasecmp (ippGetString(attr, 0, NULL), "none"))
- g_string_append_printf (browse_options, "auth-info-required=%s ",
- ippGetString(attr, 0, NULL));
- }
- else if (!strcasecmp(attrname, "printer-uuid") &&
- value_tag == IPP_TAG_URI)
- g_string_append_printf (browse_options, "uuid=%s ",
- ippGetString(attr, 0, NULL));
- else if (!strcasecmp(attrname, "job-sheets-default") &&
- value_tag == IPP_TAG_NAME &&
- ippGetCount(attr) == 2)
- g_string_append_printf (browse_options, "job-sheets=%s,%s ",
- ippGetString(attr, 0, NULL),
- ippGetString(attr, 1, NULL));
- else if (strstr(attrname, "-default"))
- {
- gchar *name = g_strdup (attrname);
- gchar *value = NULL;
- *strstr (name, "-default") = '\0';
-
- switch (value_tag)
- {
- gchar **tokens;
-
- case IPP_TAG_KEYWORD:
- case IPP_TAG_STRING:
- case IPP_TAG_NAME:
- // Escape value
- tokens = g_strsplit_set (ippGetString(attr, 0, NULL),
- " \"\'\\", -1);
- value = g_strjoinv ("\\", tokens);
- g_strfreev (tokens);
- break;
-
- default:
- // other values aren't needed?
- debug_printf("skipping %s (%d)\n", name, value_tag);
- break;
- }
-
- if (value)
- {
- g_string_append_printf (browse_options, "%s=%s ", name, value);
- g_free (value);
- }
-
- g_free (name);
- }
-
- attr = ippNextAttribute(response);
- }
-
- if (type != -1 && state != -1 && uri && location && info && make_model)
- {
- gchar *browse_options_str = g_string_free (browse_options, FALSE);
- browse_data_t *data;
- browse_options = NULL;
- g_strchomp (browse_options_str);
- data = new_browse_data (type, state, uri, location,
- info, make_model, browse_options_str);
- browse_data = g_list_insert (browse_data, data, 0);
- g_free (browse_options_str);
- }
-
- if (make_model)
- g_free (make_model);
-
- if (info)
- g_free (info);
-
- if (location)
- g_free (location);
-
- if (browse_options)
- {
- g_string_free (browse_options, TRUE);
- browse_options = NULL;
- }
-
- if (!attr)
- break;
- }
-
- fail:
- if (browse_options)
- g_string_free(browse_options, TRUE);
- if (response)
- ippDelete(response);
-}
-
-
-static void
-update_local_printers (void)
-{
- gboolean get_printers = FALSE;
- http_t *conn;
-
- if (inhibit_local_printers_update)
- return;
-
- conn = http_connect_local ();
- if (conn &&
- (!local_printers_context || local_printers_context->can_subscribe))
- {
- if (!local_printers_context ||
- local_printers_context->subscription_id == -1)
- {
- // No subscription yet. First, create the subscription.
- local_printers_create_subscription (conn);
- get_printers = TRUE;
- }
- else
- // We already have a subscription, so use it.
-
- // Note: for the moment, browse_poll_get_notifications() just
- // tells us whether we should re-fetch the printer list, so it
- // is safe to use here.
- get_printers = browse_poll_get_notifications (local_printers_context,
- conn);
- }
- else
- get_printers = TRUE;
-
- if (get_printers)
- {
- get_local_printers ();
-
- if (BrowseLocalProtocols & BROWSE_CUPS)
- prepare_browse_data ();
- }
-}
-
-
-static int
-check_jobs ()
-{
- int num_jobs = 0;
- cups_job_t *jobs = NULL;
- remote_printer_t *p;
- http_t *conn = NULL;
-
- conn = http_connect_local ();
- if (conn == NULL)
- {
- debug_printf("Cannot connect to local CUPS to check whether there are still jobs.\n");
- return (0);
- }
-
- if (cupsArrayCount(remote_printers) > 0)
- for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
- p;
- p = (remote_printer_t *)cupsArrayNext(remote_printers))
- if (!p->slave_of)
- {
- num_jobs = cupsGetJobs2(conn, &jobs, p->queue_name, 0,
- CUPS_WHICHJOBS_ACTIVE);
- if (num_jobs > 0)
- {
- debug_printf("Queue %s still has jobs!\n", p->queue_name);
- cupsFreeJobs(num_jobs, jobs);
- return (1);
- }
- }
-
- debug_printf("All our remote printers are without jobs.\n");
- return (0);
-}
-
-
-static gboolean
-autoshutdown_execute (gpointer data)
-{
- debug_printf("autoshutdown_execute() in THREAD %ld\n", pthread_self());
- // Are we still in auto shutdown mode and are we still without queues or
- // jobs
- if (autoshutdown &&
- (cupsArrayCount(remote_printers) == 0 ||
- (autoshutdown_on == NO_JOBS && check_jobs() == 0)))
- {
- debug_printf("Automatic shutdown as there are no print queues maintained by us or no jobs on them for %d sec.\n",
- autoshutdown_timeout);
- g_main_loop_quit(gmainloop);
- g_main_context_wakeup(NULL);
- }
-
- // Stop this timeout handler, we needed it only once
- return (FALSE);
-}
-
-
-#ifdef HAVE_LDAP_REBIND_PROC
-# if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-//
-// 'ldap_rebind_proc()' - Callback function for LDAP rebind
-//
-
-static int // O - Result code
-ldap_rebind_proc(LDAP *RebindLDAPHandle, // I - LDAP handle
- LDAP_CONST char *refsp, // I - ???
- ber_tag_t request, // I - ???
- ber_int_t msgid, // I - ???
- void *params) // I - ???
-{
- int rc; // Result code
-# if LDAP_API_VERSION > 3000
- struct berval bval; // Bind value
-# endif // LDAP_API_VERSION > 3000
- (void)request;
- (void)msgid;
- (void)params;
-
- //
- // Bind to new LDAP server...
- //
-
- debug_printf("ldap_rebind_proc: Rebind to %s\n", refsp);
-
-# if LDAP_API_VERSION > 3000
- bval.bv_val = BrowseLDAPPassword;
- bval.bv_len = (BrowseLDAPPassword == NULL) ? 0 : strlen(BrowseLDAPPassword);
-
- rc = ldap_sasl_bind_s(RebindLDAPHandle, BrowseLDAPBindDN, LDAP_SASL_SIMPLE,
- &bval, NULL, NULL, NULL);
-# else
- rc = ldap_bind_s(RebindLDAPHandle, BrowseLDAPBindDN, BrowseLDAPPassword,
- LDAP_AUTH_SIMPLE);
-# endif // LDAP_API_VERSION > 3000
-
- return (rc);
-}
-
-
-# else // defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-//
-// 'ldap_rebind_proc()' - Callback function for LDAP rebind
-//
-
-static int // O - Result code
-ldap_rebind_proc(LDAP *RebindLDAPHandle, // I - LDAP handle
- char **dnp, // I - ???
- char **passwdp, // I - ???
- int *authmethodp, // I - ???
- int freeit, // I - ???
- void *arg) // I - ???
-{
- switch (freeit)
- {
- case 1:
- //
- // Free current values...
- //
-
- debug_printf("ldap_rebind_proc: Free values...\n");
-
- if (dnp && *dnp)
- free(*dnp);
-
- if (passwdp && *passwdp)
- free(*passwdp);
- break;
-
- case 0:
- //
- // Return credentials for LDAP referal...
- //
-
- debug_printf("ldap_rebind_proc: Return necessary values...\n");
-
- *dnp = strdup(BrowseLDAPBindDN);
- *passwdp = strdup(BrowseLDAPPassword);
- *authmethodp = LDAP_AUTH_SIMPLE;
- break;
-
- default:
- //
- // Should never happen...
- //
-
- debug_printf("LDAP rebind has been called with wrong freeit value!\n");
- break;
- }
-
- return (LDAP_SUCCESS);
-}
-# endif // defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-#endif // HAVE_LDAP_REBIND_PROC
-
-
-#ifdef HAVE_LDAP
-//
-// 'ldap_new_connection()' - Start new LDAP connection
-//
-
-static LDAP * // O - LDAP handle
-ldap_new_connection(void)
-{
- int rc; // LDAP API status
- int version = 3; // LDAP version
- struct berval bv = {0, ""}; // SASL bind value
- LDAP *TempBrowseLDAPHandle=NULL;
- // Temporary LDAP Handle
-# if defined(HAVE_LDAP_SSL) && defined (HAVE_MOZILLA_LDAP)
- int ldap_ssl = 0; // LDAP SSL indicator
- int ssl_err = 0; // LDAP SSL error value
-# endif // defined(HAVE_LDAP_SSL) && defined (HAVE_MOZILLA_LDAP)
-
-
-# ifdef HAVE_OPENLDAP
-# ifdef HAVE_LDAP_SSL
- //
- // Set the certificate file to use for encrypted LDAP sessions...
- //
-
- if (BrowseLDAPCACertFile)
- {
- debug_printf("ldap_new_connection: Setting CA certificate file \"%s\"\n",
- BrowseLDAPCACertFile);
-
- if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
- (void *)BrowseLDAPCACertFile)) != LDAP_SUCCESS)
- debug_printf("Unable to set CA certificate file for LDAP "
- "connections: %d - %s\n", rc, ldap_err2string(rc));
- }
-# endif // HAVE_LDAP_SSL
-
- //
- // Initialize OPENLDAP connection...
- // LDAP stuff currently only supports ldapi EXTERNAL SASL binds...
- //
-
- if (!BrowseLDAPServer || !strcasecmp(BrowseLDAPServer, "localhost"))
- rc = ldap_initialize(&TempBrowseLDAPHandle, "ldapi:///");
- else
- rc = ldap_initialize(&TempBrowseLDAPHandle, BrowseLDAPServer);
-
-# else // HAVE_OPENLDAP
-
- int ldap_port = 0; // LDAP port
- char ldap_protocol[11], // LDAP protocol
- ldap_host[255]; // LDAP host
-
- //
- // Split LDAP URI into its components...
- //
-
- if (!BrowseLDAPServer)
- {
- debug_printf("BrowseLDAPServer not configured!\n");
- debug_printf("Disabling LDAP browsing!\n");
- //BrowseLocalProtocols &= ~BROWSE_LDAP;
- BrowseRemoteProtocols &= ~BROWSE_LDAP;
- return (NULL);
- }
-
- sscanf(BrowseLDAPServer, "%10[^:]://%254[^:/]:%d", ldap_protocol, ldap_host,
- &ldap_port);
-
- if (!strcmp(ldap_protocol, "ldap"))
- ldap_ssl = 0;
- else if (!strcmp(ldap_protocol, "ldaps"))
- ldap_ssl = 1;
- else
- {
- debug_printf("Unrecognized LDAP protocol (%s)!\n",
- ldap_protocol);
- debug_printf("Disabling LDAP browsing!\n");
- //BrowseLocalProtocols &= ~BROWSE_LDAP;
- BrowseRemoteProtocols &= ~BROWSE_LDAP;
- return (NULL);
- }
-
- if (ldap_port == 0)
- {
- if (ldap_ssl)
- ldap_port = LDAPS_PORT;
- else
- ldap_port = LDAP_PORT;
- }
-
- debug_printf("ldap_new_connection: PROT:%s HOST:%s PORT:%d\n",
- ldap_protocol, ldap_host, ldap_port);
-
- //
- // Initialize LDAP connection...
- //
-
- if (!ldap_ssl)
- {
- if ((TempBrowseLDAPHandle = ldap_init(ldap_host, ldap_port)) == NULL)
- rc = LDAP_OPERATIONS_ERROR;
- else
- rc = LDAP_SUCCESS;
-
-# ifdef HAVE_LDAP_SSL
- }
- else
- {
- //
- // Initialize SSL LDAP connection...
- //
-
- if (BrowseLDAPCACertFile)
- {
- rc = ldapssl_client_init(BrowseLDAPCACertFile, (void *)NULL);
- if (rc != LDAP_SUCCESS)
- {
- debug_printf("Failed to initialize LDAP SSL client!\n");
- rc = LDAP_OPERATIONS_ERROR;
- }
- else
- {
- if ((TempBrowseLDAPHandle = ldapssl_init(ldap_host, ldap_port,
- 1)) == NULL)
- rc = LDAP_OPERATIONS_ERROR;
- else
- rc = LDAP_SUCCESS;
- }
- }
- else
- {
- debug_printf("LDAP SSL certificate file/database not configured!\n");
- rc = LDAP_OPERATIONS_ERROR;
- }
-
-# else // HAVE_LDAP_SSL
-
- //
- // Return error, because client libraries doesn't support SSL
- //
-
- debug_printf("LDAP client libraries do not support SSL\n");
- rc = LDAP_OPERATIONS_ERROR;
-
-# endif // HAVE_LDAP_SSL
- }
-# endif // HAVE_OPENLDAP
-
- //
- // Check return code from LDAP initialize...
- //
-
- if (rc != LDAP_SUCCESS)
- {
- debug_printf("Unable to initialize LDAP!\n");
-
- if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR)
- debug_printf("Temporarily disabling LDAP browsing...\n");
- else
- {
- debug_printf("Disabling LDAP browsing!\n");
-
- //BrowseLocalProtocols &= ~BROWSE_LDAP;
- BrowseRemoteProtocols &= ~BROWSE_LDAP;
- }
-
- ldap_disconnect(TempBrowseLDAPHandle);
-
- return (NULL);
- }
-
- //
- // Upgrade LDAP version...
- //
-
- if (ldap_set_option(TempBrowseLDAPHandle, LDAP_OPT_PROTOCOL_VERSION,
- (const void *)&version) != LDAP_SUCCESS)
- {
- debug_printf("Unable to set LDAP protocol version %d!\n",
- version);
- debug_printf("Disabling LDAP browsing!\n");
-
- //BrowseLocalProtocols &= ~BROWSE_LDAP;
- BrowseRemoteProtocols &= ~BROWSE_LDAP;
- ldap_disconnect(TempBrowseLDAPHandle);
-
- return (NULL);
- }
-
- //
- // Register LDAP rebind procedure...
- //
-
-# ifdef HAVE_LDAP_REBIND_PROC
-# if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-
- rc = ldap_set_rebind_proc(TempBrowseLDAPHandle, &ldap_rebind_proc,
- (void *)NULL);
- if (rc != LDAP_SUCCESS)
- debug_printf("Setting LDAP rebind function failed with status %d: %s\n",
- rc, ldap_err2string(rc));
-
-# else
-
- ldap_set_rebind_proc(TempBrowseLDAPHandle, &ldap_rebind_proc, (void *)NULL);
-
-# endif // defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-# endif // HAVE_LDAP_REBIND_PROC
-
- //
- // Start LDAP bind...
- //
-
-# if LDAP_API_VERSION > 3000
- struct berval bval;
- bval.bv_val = BrowseLDAPPassword;
- bval.bv_len = (BrowseLDAPPassword == NULL) ? 0 : strlen(BrowseLDAPPassword);
-
- if (!BrowseLDAPServer || !strcasecmp(BrowseLDAPServer, "localhost"))
- rc = ldap_sasl_bind_s(TempBrowseLDAPHandle, NULL, "EXTERNAL", &bv, NULL,
- NULL, NULL);
- else
- rc = ldap_sasl_bind_s(TempBrowseLDAPHandle, BrowseLDAPBindDN,
- LDAP_SASL_SIMPLE, &bval, NULL, NULL, NULL);
-
-# else
- rc = ldap_bind_s(TempBrowseLDAPHandle, BrowseLDAPBindDN,
- BrowseLDAPPassword, LDAP_AUTH_SIMPLE);
-# endif // LDAP_API_VERSION > 3000
-
- if (rc != LDAP_SUCCESS)
- {
- debug_printf("LDAP bind failed with error %d: %s\n",
- rc, ldap_err2string(rc));
-
-# if defined(HAVE_LDAP_SSL) && defined (HAVE_MOZILLA_LDAP)
- if (ldap_ssl && (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR))
- {
- ssl_err = PORT_GetError();
- if (ssl_err != 0)
- debug_printf("LDAP SSL error %d: %s\n", ssl_err,
- ldapssl_err2string(ssl_err));
- }
-# endif // defined(HAVE_LDAP_SSL) && defined (HAVE_MOZILLA_LDAP)
-
- ldap_disconnect(TempBrowseLDAPHandle);
-
- return (NULL);
- }
-
- debug_printf("LDAP connection established\n");
-
- return (TempBrowseLDAPHandle);
-}
-
-
-//
-// 'ldap_reconnect()' - Reconnect to LDAP Server
-//
-
-static LDAP * // O - New LDAP handle
-ldap_reconnect(void)
-{
- LDAP *TempBrowseLDAPHandle = NULL; // Temp Handle to LDAP server
-
- //
- // Get a new LDAP Handle and replace the global Handle
- // if the new connection was successful.
- //
-
- debug_printf("Try LDAP reconnect...\n");
-
- TempBrowseLDAPHandle = ldap_new_connection();
-
- if (TempBrowseLDAPHandle != NULL)
- {
- if (BrowseLDAPHandle != NULL)
- ldap_disconnect(BrowseLDAPHandle);
-
- BrowseLDAPHandle = TempBrowseLDAPHandle;
- }
-
- return (BrowseLDAPHandle);
-}
-
-
-//
-// 'ldap_disconnect()' - Disconnect from LDAP Server
-//
-
-static void
-ldap_disconnect(LDAP *ld) // I - LDAP handle
-{
- int rc; // Return code
-
- //
- // Close LDAP handle...
- //
-
-# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
- rc = ldap_unbind_ext_s(ld, NULL, NULL);
-# else
- rc = ldap_unbind_s(ld);
-# endif // defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
-
- if (rc != LDAP_SUCCESS)
- debug_printf("Unbind from LDAP server failed with status %d: %s\n",
- rc, ldap_err2string(rc));
-}
-
-
-//
-// 'cupsdUpdateLDAPBrowse()' - Scan for new printers via LDAP...
-//
-
-static void
-cupsdUpdateLDAPBrowse(void)
-{
- char uri[HTTP_MAX_URI], // Printer URI
- host[HTTP_MAX_URI], // Hostname
- resource[HTTP_MAX_URI], // Resource path
- local_resource[HTTP_MAX_URI], // Resource path
- service_name[4096],
- location[1024], // Printer location
- info[1024], // Printer information
- make_model[1024], // Printer make and model
- type_num[30], // Printer type number
- scheme[32], // URI's scheme
- username[64]; // URI's username
- int port; // URI's port number
- char *c;
- int hl;
- int rc; // LDAP status
- int limit; // Size limit
- LDAPMessage *res, // LDAP search results
- *e; // Current entry from search
-
- debug_printf("UpdateLDAPBrowse\n");
-
- //
- // Reconnect if LDAP Handle is invalid...
- //
-
- if (! BrowseLDAPHandle)
- {
- ldap_reconnect();
- return;
- }
-
- //
- // Search for cups printers in LDAP directory...
- //
-
- rc = ldap_search_rec(BrowseLDAPHandle, BrowseLDAPDN, LDAP_SCOPE_SUBTREE,
- BrowseLDAPFilter, (char **)ldap_attrs, 0, &res);
-
- //
- // If ldap search was successfull then exit function
- // and temporary disable LDAP updates...
- //
-
- if (rc != LDAP_SUCCESS)
- {
- if (BrowseLDAPUpdate && ((rc == LDAP_SERVER_DOWN) ||
- (rc == LDAP_CONNECT_ERROR)))
- {
- BrowseLDAPUpdate = FALSE;
- debug_printf("LDAP update temporary disabled\n");
- }
- return;
- }
-
- //
- // If LDAP updates were disabled, we will reenable them...
- //
-
- if (!BrowseLDAPUpdate)
- {
- BrowseLDAPUpdate = TRUE;
- debug_printf("LDAP update enabled\n");
- }
-
- //
- // Count LDAP entries and return if no entry exist...
- //
-
- limit = ldap_count_entries(BrowseLDAPHandle, res);
- debug_printf("LDAP search returned %d entries\n", limit);
- if (limit < 1)
- {
- ldap_freeres(res);
- return;
- }
-
- //
- // Loop through the available printers...
- //
-
- for (e = ldap_first_entry(BrowseLDAPHandle, res);
- e;
- e = ldap_next_entry(BrowseLDAPHandle, e))
- {
- //
- // Get the required values from this entry...
- //
-
- if (ldap_getval_firststring(BrowseLDAPHandle, e,
- "printerDescription", info, sizeof(info)) == -1)
- continue;
-
- if (ldap_getval_firststring(BrowseLDAPHandle, e,
- "printerLocation", location,
- sizeof(location)) == -1)
- continue;
-
- if (ldap_getval_firststring(BrowseLDAPHandle, e,
- "printerMakeAndModel", make_model,
- sizeof(make_model)) == -1)
- continue;
-
- if (ldap_getval_firststring(BrowseLDAPHandle, e,
- "printerType", type_num,
- sizeof(type_num)) == -1)
- continue;
-
- if (ldap_getval_firststring(BrowseLDAPHandle, e,
- "printerURI", uri, sizeof(uri)) == -1)
- continue;
-
- //
- // Process the entry...
- //
-
- memset(scheme, 0, sizeof(scheme));
- memset(username, 0, sizeof(username));
- memset(host, 0, sizeof(host));
- memset(resource, 0, sizeof(resource));
- memset(local_resource, 0, sizeof(local_resource));
-
- httpSeparateURI (HTTP_URI_CODING_ALL, uri,
- scheme, sizeof(scheme) - 1,
- username, sizeof(username) - 1,
- host, sizeof(host) - 1,
- &port,
- resource, sizeof(resource)- 1);
-
- if (strncasecmp (resource, "/printers/", 10) &&
- strncasecmp (resource, "/classes/", 9))
- {
- debug_printf("don't understand URI: %s\n", uri);
- return;
- }
-
- strncpy (local_resource, resource + 1, sizeof (local_resource) - 1);
- local_resource[sizeof (local_resource) - 1] = '\0';
- c = strchr (local_resource, '?');
- if (c)
- *c = '\0';
-
- // Build the DNS-SD service name which CUPS would give to this printer
- // when DNS-SD-broadcasting it
- snprintf(service_name, sizeof (service_name), "%s @ %s",
- (strlen(info) > 0 ? info : strchr(local_resource, '/') + 1), host);
- // Cut off trailing ".local" of host name
- hl = strlen(service_name);
- if (hl > 6 && !strcasecmp(service_name + hl - 6, ".local"))
- service_name[hl - 6] = '\0';
- if (hl > 7 && !strcasecmp(service_name + hl - 7, ".local."))
- service_name[hl - 7] = '\0';
- // DNS-SD service name has max. 63 characters
- service_name[63] = '\0';
-
- debug_printf("LDAP: Remote host: %s; Port: %d; Remote queue name: %s; Service Name: %s\n",
- host, port, strchr(local_resource, '/') + 1, service_name);
-
- pthread_rwlock_wrlock(&lock);
- examine_discovered_printer_record(host, NULL, port, local_resource,
- service_name, location, info, "", "",
- "", 0, NULL);
- pthread_rwlock_unlock(&lock);
-
- }
-
- ldap_freeres(res);
-}
-
-
-//
-// 'ldap_search_rec()' - LDAP Search with reconnect
-//
-
-static int // O - Return code
-ldap_search_rec(LDAP *ld, // I - LDAP handler
- char *base, // I - Base dn
- int scope, // I - LDAP search scope
- char *filter, // I - Filter string
- char *attrs[], // I - Requested attributes
- int attrsonly, // I - Return only attributes?
- LDAPMessage **res) // I - LDAP handler
-{
- int rc; // Return code
- LDAP *ldr; // LDAP handler after reconnect
-
-
-# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
- rc = ldap_search_ext_s(ld, base, scope, filter, attrs, attrsonly, NULL, NULL,
- NULL, LDAP_NO_LIMIT, res);
-# else
- rc = ldap_search_s(ld, base, scope, filter, attrs, attrsonly, res);
-# endif // defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
-
- //
- // If we have a connection problem try again...
- //
-
- if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR)
- {
- debug_printf("LDAP search failed with status %d: %s\n",
- rc, ldap_err2string(rc));
- debug_printf("We try the LDAP search once again after reconnecting to "
- "the server\n");
- ldap_freeres(*res);
- ldr = ldap_reconnect();
-
-# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
- rc = ldap_search_ext_s(ldr, base, scope, filter, attrs, attrsonly, NULL,
- NULL, NULL, LDAP_NO_LIMIT, res);
-# else
- rc = ldap_search_s(ldr, base, scope, filter, attrs, attrsonly, res);
-# endif // defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
- }
-
- if (rc == LDAP_NO_SUCH_OBJECT)
- debug_printf("ldap_search_rec: LDAP entry/object not found\n");
- else if (rc != LDAP_SUCCESS)
- debug_printf("ldap_search_rec: LDAP search failed with status %d: %s\n",
- rc, ldap_err2string(rc));
-
- if (rc != LDAP_SUCCESS)
- ldap_freeres(*res);
-
- return (rc);
-}
-
-
-//
-// 'ldap_freeres()' - Free LDAPMessage
-//
+ }
-static void
-ldap_freeres(LDAPMessage *entry) // I - LDAP handler
-{
- int rc; // Return value
+ cupsFreeDests (num_dests, dests);
- rc = ldap_msgfree(entry);
- if (rc == -1)
- debug_printf("Can't free LDAPMessage!\n");
- else if (rc == 0)
- debug_printf("Freeing LDAPMessage was unnecessary\n");
+ pthread_rwlock_unlock(&lock);
}
-//
-// 'ldap_getval_char()' - Get first LDAP value and convert to string
-//
-
-static int // O - Return code
-ldap_getval_firststring(LDAP *ld, // I - LDAP handler
- LDAPMessage *entry, // I - LDAP message or search
- // result
- char *attr, // I - the wanted attribute
- char *retval, // O - String to return
- unsigned long maxsize) // I - Max string size
+static void
+update_local_printers (void)
{
- char *dn; // LDAP DN
- int rc = 0; // Return code
-# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
- struct berval **bval; // LDAP value array
- unsigned long size; // String size
-
+ gboolean get_printers = FALSE;
+ http_t *conn;
- //
- // Get value from LDAPMessage...
- //
+ if (inhibit_local_printers_update)
+ return;
- if ((bval = ldap_get_values_len(ld, entry, attr)) == NULL)
- {
- rc = -1;
- dn = ldap_get_dn(ld, entry);
- debug_printf("Failed to get LDAP value %s for %s!\n",
- attr, dn);
- ldap_memfree(dn);
- }
- else
+ conn = http_connect_local ();
+ if (conn &&
+ (!local_printers_context || local_printers_context->can_subscribe))
{
- //
- // Check size and copy value into our string...
- //
-
- size = maxsize;
- if (size < (bval[0]->bv_len + 1))
+ if (!local_printers_context ||
+ local_printers_context->subscription_id == -1)
{
- rc = -1;
- dn = ldap_get_dn(ld, entry);
- debug_printf("Attribute %s is too big! (dn: %s)\n",
- attr, dn);
- ldap_memfree(dn);
+ // No subscription yet. First, create the subscription.
+ local_printers_create_subscription (conn);
+ get_printers = TRUE;
}
else
- size = bval[0]->bv_len + 1;
+ // We already have a subscription, so use it.
- strncpy(retval, bval[0]->bv_val, size);
- if (size > 0)
- retval[size - 1] = '\0';
- ldap_value_free_len(bval);
+ // Note: for the moment, browse_poll_get_notifications() just
+ // tells us whether we should re-fetch the printer list, so it
+ // is safe to use here.
+ get_printers = browse_poll_get_notifications (local_printers_context,
+ conn);
}
-# else
- char **value; // LDAP value
+ else
+ get_printers = TRUE;
- //
- // Get value from LDAPMessage...
- //
+ if (get_printers)
+ get_local_printers ();
+}
+
+
+static int
+check_jobs ()
+{
+ int num_jobs = 0;
+ cups_job_t *jobs = NULL;
+ remote_printer_t *p;
+ http_t *conn = NULL;
- if ((value = (char **)ldap_get_values(ld, entry, attr)) == NULL)
+ conn = http_connect_local ();
+ if (conn == NULL)
{
- rc = -1;
- dn = ldap_get_dn(ld, entry);
- debug_printf("Failed to get LDAP value %s for %s!\n",
- attr, dn);
- ldap_memfree(dn);
+ debug_printf("Cannot connect to local CUPS to check whether there are still jobs.\n");
+ return (0);
}
- else
+
+ if (cupsArrayCount(remote_printers) > 0)
+ for (p = (remote_printer_t *)cupsArrayFirst(remote_printers);
+ p;
+ p = (remote_printer_t *)cupsArrayNext(remote_printers))
+ if (!p->slave_of)
+ {
+ num_jobs = cupsGetJobs2(conn, &jobs, p->queue_name, 0,
+ CUPS_WHICHJOBS_ACTIVE);
+ if (num_jobs > 0)
+ {
+ debug_printf("Queue %s still has jobs!\n", p->queue_name);
+ cupsFreeJobs(num_jobs, jobs);
+ return (1);
+ }
+ }
+
+ debug_printf("All our remote printers are without jobs.\n");
+ return (0);
+}
+
+
+static gboolean
+autoshutdown_execute (gpointer data)
+{
+ debug_printf("autoshutdown_execute() in THREAD %ld\n", pthread_self());
+ // Are we still in auto shutdown mode and are we still without queues or
+ // jobs
+ if (autoshutdown &&
+ (cupsArrayCount(remote_printers) == 0 ||
+ (autoshutdown_on == NO_JOBS && check_jobs() == 0)))
{
- strncpy(retval, *value, maxsize);
- if (maxsize > 0)
- retval[maxsize - 1] = '\0';
- ldap_value_free(value);
+ debug_printf("Automatic shutdown as there are no print queues maintained by us or no jobs on them for %d sec.\n",
+ autoshutdown_timeout);
+ g_main_loop_quit(gmainloop);
+ g_main_context_wakeup(NULL);
}
-# endif // defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
- return (rc);
+ // Stop this timeout handler, we needed it only once
+ return (FALSE);
}
-#endif // HAVE_LDAP
static int
@@ -6214,7 +5140,7 @@ get_local_queue_name(const char *service_name,
/* We can get resource without / or without string after / - use
* the original string (possible trailing / will be removed) */
if ((str = strrchr(resource, '/')) == NULL || strlen(str) <= 1)
- str = resource;
+ str = (char *)resource;
queue_name = remove_bad_chars(str, 0);
}
@@ -9610,8 +8536,7 @@ update_cups_queues(gpointer unused)
// DNS-SD has reported a new remote printer, create a CUPS queue
// for it, or upgrade an existing queue, or update a queue to
// use a backup host when it has disappeared on the currently
- // used host (...or, we've just received a CUPS Browsing packet
- // for this queue)
+ // used host (...or, we've just discovered this queue via BrowsePoll)
case STATUS_TO_BE_CREATED:
if (p->called)
break;
@@ -10134,7 +9059,7 @@ update_netifs (gpointer data)
if (strlen(list) + strlen(iface->address) + 2 <= sizeof(list))
{
snprintf(l, sizeof(list) - strlen(list) - 1,
- "%s*", iface->address);
+ "%.65533s*", iface->address);
l = list + strlen(list);
}
}
@@ -10318,7 +9243,7 @@ examine_discovered_printer_record(const char *host,
is_cups_queue = 1;
#endif // HAVE_AVAHI
// If we do not have a TXT record the printer was not discovered via
- // DNS-SD but via CUPS legacy or LDAP, so it is a remote CUPS queue
+ // DNS-SD and so it is a (BrowsePoll-discovered) remote CUPS queue
// and not an IPP network printer.
if (txt == NULL)
is_cups_queue = 1;
@@ -10441,8 +9366,8 @@ examine_discovered_printer_record(const char *host,
}
else
#endif // HAVE_AVAHI
- // Printer is discovered via legacy CUPS or LDAP, so we have to give
- // a IP-based/host-name-based URI to it ( or for DNS-SD-discovered
+ // Printer is discovered via BrowsePoll, so we have to give a
+ // IP-based/host-name-based URI to it (or for DNS-SD-discovered
// printers if DNSSDBasedDeviceURIs config option is not set)
httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri) - 1,
(strcasestr(type, "_ipps") ? "ipps" : "ipp"), NULL,
@@ -10465,8 +9390,8 @@ examine_discovered_printer_record(const char *host,
}
- // Update network interface info if we were discovered by LDAP
- // or legacy CUPS, needed for the is_local_hostname() function calls.
+ // Update network interface info if we were discovered by
+ // BrowsePoll, needed for the is_local_hostname() function calls.
// During DNS-SD discovery the update is already done by the Avahi
// event handler function.
if (FrequentNetifUpdate && (type == NULL || type[0] == '\0'))
@@ -10527,9 +9452,9 @@ examine_discovered_printer_record(const char *host,
// We have already created a local queue, check whether the
// discovered service allows us to upgrade the queue to IPPS
// or whether the URI part after ipp(s):// has changed, or
- // whether the discovered queue is discovered via DNS-SD
- // having more info in contrary to the existing being
- // discovered by legacy CUPS or LDAP
+ // whether the discovered queue is discovered via DNS-SD,
+ // having more info in contrary to the existing one being
+ // discovered by BrowsePoll
int downgrade = 0, upgrade = 0;
@@ -10568,14 +9493,14 @@ examine_discovered_printer_record(const char *host,
debug_printf("Printer %s: New discovered service from host %s, port %d, URI %s is from a non-loopback interface, we have already one from the loopback interface, skipping\n",
p->queue_name, remote_host, port, uri);
}
- // DNS-SD -> CUPS Legacy/LDAP
+ // DNS-SD -> BrowsePoll
else if (p->domain != NULL && p->domain[0] != '\0' &&
(domain == NULL || domain[0] == '\0') &&
p->type != NULL && p->type[0] != '\0' &&
(type == NULL || type[0] == '\0'))
{
downgrade = 1;
- debug_printf("Printer %s: New discovered service from host %s, port %d, URI %s is only discovered via legacy CUPS or LDAP, we have already a DNS-SD-discovered one, skipping\n",
+ debug_printf("Printer %s: New discovered service from host %s, port %d, URI %s is only discovered via BrowsePoll, we have already a DNS-SD-discovered one, skipping\n",
p->queue_name, remote_host, port, uri);
}
@@ -10597,11 +9522,11 @@ examine_discovered_printer_record(const char *host,
debug_printf("Upgrading printer %s (Host: %s, Port: %d) to use loopback interface \"lo\". New URI: %s\n",
p->queue_name, remote_host, port, uri);
}
- // CUPS Legacy/LDAP -> DNS-SD
+ // BrowsePoll -> DNS-SD
else if ((p->domain == NULL || p->domain[0] == '\0') &&
domain != NULL && domain[0] != '\0' &&
- (p->type == NULL || p->type[0] == '\0') &&
- type != NULL && type[0] != '\0')
+ (p->type == NULL || p->type[0] == '\0') &&
+ type != NULL && type[0] != '\0')
{
upgrade = 1;
debug_printf("Discovered printer %s (Host: %s, Port: %d, URI: %s) by DNS-SD now.\n",
@@ -11683,7 +10608,7 @@ avahi_init()
//
-// A CUPS printer has been discovered via CUPS Browsing
+// A CUPS printer has been discovered via BrowsePoll
// or with BrowsePoll
//
@@ -11757,7 +10682,7 @@ found_cups_printer(const char *remote_host,
// DNS-SD service name has max. 63 characters
service_name[63] = '\0';
- debug_printf("CUPS browsing: Remote host: %s; Port: %d; Remote queue name: %s; Service Name: %s\n",
+ debug_printf("BrowsePoll: Remote host: %s; Port: %d; Remote queue name: %s; Service Name: %s\n",
host, port, strchr(local_resource, '/') + 1, service_name);
pthread_rwlock_wrlock(&lock);
@@ -11790,203 +10715,6 @@ found_cups_printer(const char *remote_host,
}
-static gboolean
-process_browse_data (GIOChannel *source,
- GIOCondition condition,
- gpointer data)
-{
- char packet[2048];
- http_addr_t srcaddr;
- socklen_t srclen;
- ssize_t got;
- unsigned int type;
- unsigned int state;
- char remote_host[256];
- char uri[1024];
- char location[1024];
- char info[1024];
- char *c = NULL, *end = NULL;
-
- debug_printf("process_browse_data() in THREAD %ld\n", pthread_self());
-
- memset(packet, 0, sizeof(packet));
- memset(remote_host, 0, sizeof(remote_host));
- memset(uri, 0, sizeof(uri));
- memset(info, 0, sizeof(info));
-
- srclen = sizeof (srcaddr);
- got = recvfrom (browsesocket, packet, sizeof (packet) - 1, 0,
- &srcaddr.addr, &srclen);
- if (got == -1)
- {
- debug_printf ("cupsd-browsed: error receiving browse packet: %s\n",
- strerror (errno));
- // Remove this I/O source
- return (FALSE);
- }
-
- packet[got] = '\0';
- httpAddrString (&srcaddr, remote_host, sizeof (remote_host) - 1);
-
- // Check this packet is allowed
- if (!allowed ((struct sockaddr *) &srcaddr))
- {
- debug_printf("browse packet from %s disallowed\n",
- remote_host);
- return (TRUE);
- }
-
- debug_printf("browse packet received from %s\n",
- remote_host);
-
- if (sscanf (packet, "%x%x%1023s", &type, &state, uri) < 3)
- {
- debug_printf("incorrect browse packet format\n");
- return (TRUE);
- }
-
- info[0] = '\0';
-
- // do not read OOB
- end = packet + sizeof(packet);
- c = strchr (packet, '\"');
- if (c >= end)
- return (TRUE);
-
- if (c)
- {
- // Extract location field
- {
- int i;
- c++;
- for (i = 0;
- i < sizeof (location) - 1 && *c != '\"' && c < end;
- i++, c++)
- location[i] = *c;
- location[i] = '\0';
- debug_printf("process_browse_data: location: |%s|\n", location); // !!
- }
- for (; c < end && *c != '\"'; c++);
-
- if (c >= end)
- return (TRUE);
-
- if (*c == '\"')
- for (c++; c < end && isspace(*c); c++);
-
- if (c >= end)
- return (TRUE);
-
- // Is there an info field?
- if (*c == '\"')
- {
- int i;
- c++;
- for (i = 0;
- i < sizeof (info) - 1 && *c != '\"' && c < end;
- i++, c++)
- info[i] = *c;
- info[i] = '\0';
- debug_printf("process_browse_data: info: |%s|\n", info); // !!
- }
- }
- if (c >= end)
- return (TRUE);
-
- if (!(type & CUPS_PRINTER_DELETE))
- found_cups_printer (remote_host, uri, location, info);
-
- if (in_shutdown == 0)
- recheck_timer ();
-
- // Don't remove this I/O source
- return (TRUE);
-}
-
-
-static void
-broadcast_browse_packets (gpointer data,
- gpointer user_data)
-{
- browse_data_t *bdata = data;
- netif_t *browse;
- char packet[2048];
- char uri[HTTP_MAX_URI];
- char scheme[32];
- char username[64];
- char host[HTTP_MAX_HOST];
- int port;
- char resource[HTTP_MAX_URI];
-
- debug_printf("broadcast_browse_packets() in THREAD %ld\n", pthread_self());
-
- for (browse = (netif_t *)cupsArrayFirst (netifs);
- browse != NULL;
- browse = (netif_t *)cupsArrayNext (netifs))
- {
- // Replace 'localhost' with our IP address on this interface
- httpSeparateURI(HTTP_URI_CODING_ALL, bdata->uri,
- scheme, sizeof(scheme),
- username, sizeof(username),
- host, sizeof(host),
- &port,
- resource, sizeof(resource));
- httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof (uri),
- scheme, username, browse->address, port, resource);
-
- if (snprintf (packet, sizeof (packet),
- "%x " // type
- "%x " // state
- "%s " // uri
- "\"%s\" " // location
- "\"%s\" " // info
- "\"%s\" " // make-and-model
- "lease-duration=%d" // BrowseTimeout
- "%s%s" // other browse options
- "\n",
- bdata->type,
- bdata->state,
- uri,
- bdata->location,
- bdata->info,
- bdata->make_model,
- BrowseTimeout,
- bdata->browse_options ? " " : "",
- bdata->browse_options ? bdata->browse_options : "")
- >= sizeof (packet))
- {
- debug_printf ("oversize packet not sent\n");
- continue;
- }
-
- debug_printf("packet to send:\n%s", packet);
-
- int err = sendto (browsesocket, packet,
- strlen (packet), 0,
- &browse->broadcast.addr,
- httpAddrLength (&browse->broadcast));
- if (err == -1)
- debug_printf("cupsd-browsed: sendto returned %d: %s\n",
- err, strerror (errno));
- }
-}
-
-
-static gboolean
-send_browse_data (gpointer data)
-{
- debug_printf("send_browse_data() in THREAD %ld\n", pthread_self());
- update_netifs (NULL);
- res_init ();
- update_local_printers ();
- g_list_foreach (browse_data, broadcast_browse_packets, NULL);
- g_timeout_add_seconds (BrowseInterval, send_browse_data, NULL);
-
- // Stop this timeout handler, we called a new one
- return (FALSE);
-}
-
-
static browsepoll_printer_t *
new_browsepoll_printer (const char *uri_supported,
const char *location,
@@ -12410,81 +11138,6 @@ browse_poll (gpointer data)
}
-#ifdef HAVE_LDAP
-static gboolean
-browse_ldap_poll (gpointer data)
-{
- char *tmpFilter; // Query filter
- int filterLen;
-
- debug_printf("browse_ldap_poll() in THREAD %ld\n", pthread_self());
-
- // do real stuff here
- if (!BrowseLDAPDN)
- {
- debug_printf("Need to set BrowseLDAPDN to use LDAP browsing!\n");
- BrowseLocalProtocols &= ~BROWSE_LDAP;
- BrowseRemoteProtocols &= ~BROWSE_LDAP;
-
- return (FALSE);
- }
- else
- {
- if (!BrowseLDAPInitialised)
- {
- BrowseLDAPInitialised = TRUE;
- //
- // Query filter string
- //
-
- if (BrowseLDAPFilter)
- filterLen = snprintf(NULL, 0, "(&%s%s)", LDAP_BROWSE_FILTER,
- BrowseLDAPFilter);
- else
- filterLen = strlen(LDAP_BROWSE_FILTER);
-
- tmpFilter = (char *)malloc(filterLen + 1);
- if (!tmpFilter)
- {
- debug_printf("Could not allocate memory for LDAP browse query filter!\n");
- BrowseLocalProtocols &= ~BROWSE_LDAP;
- BrowseRemoteProtocols &= ~BROWSE_LDAP;
- return (FALSE);
- }
-
- if (BrowseLDAPFilter)
- {
- snprintf(tmpFilter, filterLen + 1, "(&%s%s)", LDAP_BROWSE_FILTER,
- BrowseLDAPFilter);
- free(BrowseLDAPFilter);
- BrowseLDAPFilter = NULL;
- }
- else
- strcpy(tmpFilter, LDAP_BROWSE_FILTER);
-
- BrowseLDAPFilter = tmpFilter;
-
- //
- // Open LDAP handle...
- //
-
- BrowseLDAPHandle = ldap_new_connection();
- }
-
- cupsdUpdateLDAPBrowse();
- if (in_shutdown == 0)
- recheck_timer();
- }
-
- // Call a new timeout handler so that we run again
- g_timeout_add_seconds (BrowseInterval, browse_ldap_poll, data);
-
- // Stop this timeout handler, we called a new one
- return (FALSE);
-}
-#endif // HAVE_LDAP
-
-
static void
sigterm_handler(int sig)
{
@@ -12728,10 +11381,6 @@ read_configuration (const char *filename)
{
if (!strcasecmp(p, "dnssd"))
protocols |= BROWSE_DNSSD;
- else if (!strcasecmp(p, "cups"))
- protocols |= BROWSE_CUPS;
- else if (!strcasecmp(p, "ldap"))
- protocols |= BROWSE_LDAP;
else if (strcasecmp(p, "none"))
debug_printf("Unknown protocol '%s'\n", p);
@@ -13402,40 +12051,6 @@ read_configuration (const char *filename)
debug_printf("Invalid value for pause between calls of update_cups_queues(): %d\n",
t);
}
-#ifdef HAVE_LDAP
- else if (!strcasecmp(line, "BrowseLDAPBindDN") && value)
- {
- if (value[0] != '\0')
- BrowseLDAPBindDN = strdup(value);
- }
-# ifdef HAVE_LDAP_SSL
- else if (!strcasecmp(line, "BrowseLDAPCACertFile") && value)
- {
- if (value[0] != '\0')
- BrowseLDAPCACertFile = strdup(value);
- }
-# endif // HAVE_LDAP_SSL
- else if (!strcasecmp(line, "BrowseLDAPDN") && value)
- {
- if (value[0] != '\0')
- BrowseLDAPDN = strdup(value);
- }
- else if (!strcasecmp(line, "BrowseLDAPPassword") && value)
- {
- if (value[0] != '\0')
- BrowseLDAPPassword = strdup(value);
- }
- else if (!strcasecmp(line, "BrowseLDAPServer") && value)
- {
- if (value[0] != '\0')
- BrowseLDAPServer = strdup(value);
- }
- else if (!strcasecmp(line, "BrowseLDAPFilter") && value)
- {
- if (value[0] != '\0')
- BrowseLDAPFilter = strdup(value);
- }
-#endif // HAVE_LDAP
}
if (browse_line_found == 0)
@@ -13526,10 +12141,7 @@ find_previous_queue (gpointer key,
// in a certain time frame, we will remove the queue
p->status = STATUS_UNCONFIRMED;
- if (BrowseRemoteProtocols & BROWSE_CUPS)
- p->timeout = time(NULL) + BrowseInterval * 3 / 2;
- else
- p->timeout = time(NULL) + TIMEOUT_CONFIRM;
+ p->timeout = time(NULL) + TIMEOUT_CONFIRM;
p->slave_of = NULL;
debug_printf("Found CUPS queue %s (URI: %s) from previous session.\n",
@@ -13864,12 +12476,6 @@ main(int argc, char*argv[])
BrowseLocalProtocols &= ~BROWSE_DNSSD;
}
- if (BrowseLocalProtocols & BROWSE_LDAP)
- {
- debug_printf("Local support for LDAP not implemented\n");
- BrowseLocalProtocols &= ~BROWSE_LDAP;
- }
-
#ifndef HAVE_AVAHI
if (BrowseRemoteProtocols & BROWSE_DNSSD)
{
@@ -13878,14 +12484,6 @@ main(int argc, char*argv[])
}
#endif // HAVE_AVAHI
-#ifndef HAVE_LDAP
- if (BrowseRemoteProtocols & BROWSE_LDAP)
- {
- debug_printf("Remote support for LDAP not supported\n");
- BrowseRemoteProtocols &= ~BROWSE_LDAP;
- }
-#endif // HAVE_LDAP
-
// Wait for CUPS daemon to start
while ((http = http_connect_local ()) == NULL)
sleep(1);
@@ -13974,50 +12572,6 @@ main(int argc, char*argv[])
}
}
- if (BrowseLocalProtocols & BROWSE_CUPS ||
- BrowseRemoteProtocols & BROWSE_CUPS)
- {
- // Set up our CUPS Browsing socket
- browsesocket = socket (AF_INET, SOCK_DGRAM, 0);
- if (browsesocket == -1)
- {
- debug_printf("failed to create CUPS Browsing socket: %s\n",
- strerror (errno));
- }
- else
- {
- struct sockaddr_in addr;
- memset (&addr, 0, sizeof (addr));
- addr.sin_addr.s_addr = htonl (INADDR_ANY);
- addr.sin_family = AF_INET;
- addr.sin_port = htons (BrowsePort);
- if (bind (browsesocket, (struct sockaddr *)&addr, sizeof (addr)))
- {
- debug_printf("failed to bind CUPS Browsing socket: %s\n",
- strerror (errno));
- close (browsesocket);
- browsesocket = -1;
- }
- else
- {
- int on = 1;
- if (setsockopt (browsesocket, SOL_SOCKET, SO_BROADCAST,
- &on, sizeof (on)))
- {
- debug_printf("failed to allow broadcast: %s\n",
- strerror (errno));
- BrowseLocalProtocols &= ~BROWSE_CUPS;
- }
- }
- }
-
- if (browsesocket == -1)
- {
- BrowseLocalProtocols &= ~BROWSE_CUPS;
- BrowseRemoteProtocols &= ~BROWSE_CUPS;
- }
- }
-
if (BrowseLocalProtocols == 0 &&
BrowseRemoteProtocols == 0 &&
!BrowsePoll)
@@ -14051,29 +12605,6 @@ main(int argc, char*argv[])
gmainloop = g_main_loop_new (NULL, FALSE);
recheck_timer ();
- if (BrowseRemoteProtocols & BROWSE_CUPS)
- {
- GIOChannel *browse_channel = g_io_channel_unix_new (browsesocket);
- g_io_channel_set_close_on_unref (browse_channel, FALSE);
- g_io_add_watch (browse_channel, G_IO_IN, process_browse_data, NULL);
- }
-
- if (BrowseLocalProtocols & BROWSE_CUPS)
- {
- debug_printf ("will send browse data every %ds\n",
- BrowseInterval);
- g_idle_add (send_browse_data, NULL);
- }
-
-#ifdef HAVE_LDAP
- if (BrowseRemoteProtocols & BROWSE_LDAP)
- {
- debug_printf ("will browse poll LDAP every %ds\n",
- BrowseInterval);
- g_idle_add (browse_ldap_poll, NULL);
- }
-#endif // HAVE_LDAP
-
if (BrowsePoll)
{
size_t index;
@@ -14194,24 +12725,12 @@ fail:
avahi_shutdown();
#endif // HAVE_AVAHI
-#ifdef HAVE_LDAP
- if (((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_LDAP) &&
- BrowseLDAPHandle)
- {
- ldap_disconnect(BrowseLDAPHandle);
- BrowseLDAPHandle = NULL;
- }
-#endif // HAVE_LDAP
-
if (browsesocket != -1)
close (browsesocket);
g_hash_table_destroy (local_printers);
g_hash_table_destroy (cups_supported_remote_printers);
- if (BrowseLocalProtocols & BROWSE_CUPS)
- g_list_free_full (browse_data, browse_data_free);
-
// Close log file if we have one
if (debug_logfile == 1)
stop_debug_logging();
diff --git a/daemon/cups-browsed.conf.5 b/daemon/cups-browsed.conf.5
index 83c69d9f..4af67884 100644
--- a/daemon/cups-browsed.conf.5
+++ b/daemon/cups-browsed.conf.5
@@ -47,7 +47,7 @@ journal or syslog. Only if you run cups-browsed from the command line
.fam T
.fi
-Only browse remote printers (via DNS-SD or CUPS browsing) from
+Only browse remote printers (via DNS-SD) from
selected servers using the "BrowseAllow", "BrowseDeny", and
"BrowseOrder" directives
.PP
@@ -330,8 +330,6 @@ Printers from all servers except "prinserver2.local" are accepted:
The BrowsePoll directive polls a server for available printers once
every 60 seconds. Multiple BrowsePoll directives can be specified
to poll multiple servers. The default port to connect to is 631.
-BrowsePoll works independently of whether CUPS browsing is activated
-in BrowseRemoteProtocols.
.PP
.nf
.fam C
@@ -345,12 +343,11 @@ in BrowseRemoteProtocols.
The BrowseLocalProtocols directive specifies the protocols to use
when advertising local shared printers on the network. The default
is "none". Control of advertising of local shared printers using
-dnssd is done in /etc/cups/cupsd.conf.
+dnssd is done by CUPS and configured in /etc/cups/cupsd.conf.
.PP
.nf
.fam C
BrowseLocalProtocols none
- BrowseLocalProtocols CUPS
.fam T
@@ -358,50 +355,26 @@ dnssd is done in /etc/cups/cupsd.conf.
The BrowseRemoteProtocols directive specifies the protocols to use
when finding remote shared printers on the network. Multiple
protocols can be specified by separating them with spaces.
-The default is "dnssd cups".
+The default is "dnssd".
.PP
.nf
.fam C
BrowseRemoteProtocols none
- BrowseRemoteProtocols CUPS dnssd
- BrowseRemoteProtocols CUPS
BrowseRemoteProtocols dnssd
- BrowseRemoteProtocols ldap
+
.fam T
.fi
The BrowseProtocols directive specifies the protocols to use when
finding remote shared printers on the network and advertising local
-shared printers. "dnssd" and "ldap" are ignored for BrowseLocalProtocols.
-Multiple protocols can be specified by separating them with spaces. The
-default is "none" for BrowseLocalProtocols and "dnssd cups" for
-BrowseRemoteProtocols.
+shared printers.
+Multiple protocols can be specified by separating them with spaces.
.PP
.nf
.fam C
BrowseProtocols none
- BrowseProtocols CUPS dnssd
- BrowseProtocols CUPS
BrowseProtocols dnssd
- BrowseProtocols ldap
-.fam T
-.fi
-The configuration for the LDAP browsing mode define where the LDAP search
-should be performed. If built with an LDAP library that supports TLS, the
-path to the server's certificate, or to a certificates store, can be
-specified.
-The optional filter allows the LDAP search to be more specific, and is used
-in addition to the hardcoded filter (objectclass=cupsPrinter).
-.PP
-.nf
-.fam C
- BrowseLDAPBindDN cn=cups-browsed,dc=domain,dc=tld
- BrowseLDAPCACertFile /path/to/server/certificate.pem
- BrowseLDAPDN ou=printers,dc=domain,dc=tld
- BrowseLDAPFilter (printerLocation=/Office 1/*)
- BrowseLDAPPassword s3cret
- BrowseLDAPServer ldaps://ldap.domain.tld
.fam T
.fi
@@ -459,8 +432,6 @@ The BrowseTimeout directive determines the amount of time that
browsing-related operations are allowed to take in seconds.
Notably, adding or removing one printer queue is considered as one
operation. The timeout applies to each one of those operations.
-Especially queues discovered by CUPS broadcasts will be removed after
-this timeout if no further broadcast from the server happens.
.PP
.nf
.fam C
@@ -582,7 +553,7 @@ Set DNSSDBasedDeviceURIs to "No" if cups-browsed should use the
conventional host-name/IP-based URIs.
.PP
Note that this option has only influence on URIs for printers
-discovered via DNS-SD, not via legacy CUPS broewsing or LDAP.
+discovered via DNS-SD, not via BrowsePoll.
Those printers get always assigned the conventional URIs.
.PP
.nf
diff --git a/daemon/cups-browsed.conf.in b/daemon/cups-browsed.conf.in
index 6c9612c1..af026966 100644
--- a/daemon/cups-browsed.conf.in
+++ b/daemon/cups-browsed.conf.in
@@ -36,27 +36,27 @@
# Which protocols will we use to discover printers on the network?
-# Can use DNSSD and/or CUPS and/or LDAP, or 'none' for neither.
+# Can use DNSSD or 'none'.
BrowseRemoteProtocols @BROWSEREMOTEPROTOCOLS@
# Which protocols will we use to broadcast shared local printers to the network?
-# Can use DNSSD and/or CUPS, or 'none' for neither.
-# Only CUPS is actually supported, as DNSSD is done by CUPS itself (we ignore
-# DNSSD in this directive).
+# Can use DNSSD or 'none'.
+# Broadcasting is currently not supported, as DNSSD is done by CUPS itself
+# (we ignore DNSSD in this directive).
# BrowseLocalProtocols none
# Settings of this directive apply to both BrowseRemoteProtocols and
# BrowseLocalProtocols.
-# Can use DNSSD and/or CUPS and/or LDAP, or 'none' for neither.
+# Can use DNSSD or 'none'.
# BrowseProtocols none
-# Only browse remote printers (via DNS-SD or CUPS browsing) from
+# Only browse remote printers (via DNS-SD) from
# selected servers using the "BrowseAllow", "BrowseDeny", and
# "BrowseOrder" directives
@@ -120,8 +120,6 @@ BrowseRemoteProtocols @BROWSEREMOTEPROTOCOLS@
# Browsing-related operations such as adding or removing printer queues
# and broadcasting are each allowed to take up to a given amount of time.
# It can be configured, in seconds, with the BrowseTimeout directive.
-# Especially queues discovered by CUPS broadcasts will be removed after
-# this timeout if no further broadcast from the server happens.
# BrowseTimeout 300
@@ -286,17 +284,6 @@ BrowseRemoteProtocols @BROWSEREMOTEPROTOCOLS@
# BrowsePoll cups.example.com:631/version=1.1
-# LDAP browsing configuration
-# The default value for all options is an empty string. Example configuration:
-
-# BrowseLDAPBindDN cn=cups-browsed,dc=domain,dc=tld
-# BrowseLDAPCACertFile /path/to/server/certificate.pem
-# BrowseLDAPDN ou=printers,dc=domain,dc=tld
-# BrowseLDAPFilter (printerLocation=/Office 1/*)
-# BrowseLDAPPassword s3cret
-# BrowseLDAPServer ldaps://ldap.domain.tld
-
-
# Use DomainSocket to access the local CUPS daemon via another than the
# default domain socket. "None" or "Off" lets cups-browsed not use CUPS'
# domain socket.
@@ -405,7 +392,7 @@ BrowseRemoteProtocols @BROWSEREMOTEPROTOCOLS@
# conventional host-name/IP-based URIs.
# Note that this option has only influence on URIs for printers
-# discovered via DNS-SD, not via legacy CUPS broewsing or LDAP.
+# discovered via DNS-SD, not via BrowsePoll.
# Those printers get always assigned the conventional URIs.
# DNSSDBasedDeviceURIs Yes
diff --git a/test/run-tests.sh b/test/run-tests.sh
index f3dfaf3d..23a5dd29 100755
--- a/test/run-tests.sh
+++ b/test/run-tests.sh
@@ -938,7 +938,7 @@ while test $tries -lt $timeout; do
done
if test $tries -ge $timeout; then
- echo "FAIL: CUPS browsed did not remove CUPS queue ${queue_prefix}_ippeve_1 for first test printer!"
+ echo "FAIL: cups-browsed did not remove CUPS queue ${queue_prefix}_ippeve_1 for first test printer!"
clean_up 1
exit 1
fi
@@ -1021,7 +1021,7 @@ $runcups lpstat -v
echo ""
if test $tries -ge $timeout; then
- echo "FAIL: CUPS browsed did not remove CUPS queue ${queue_prefix}_ippeve_2 for second test printer!"
+ echo "FAIL: cups-browsed did not remove CUPS queue ${queue_prefix}_ippeve_2 for second test printer!"
clean_up 1
exit 1
fi
--
2.47.0