2055 lines
66 KiB
Diff
2055 lines
66 KiB
Diff
From 6fd2bdfbdce76149af531ce9fca9062304238451 Mon Sep 17 00:00:00 2001
|
|
From: Till Kamppeter <till.kamppeter@gmail.com>
|
|
Date: Sun, 6 Oct 2024 08:42:37 +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/
|
|
|
|
Shortly after it was also found a another vulnerability of the legacy
|
|
CUPS browsing support. It was possible to send a well-formed CUPS
|
|
broadcast packet to UDP port 631 of cups-browsed, but with a port 80
|
|
URL of a web site which redirects on the port and then cups-browsed
|
|
falls into an infinite loop sending HTTP requests which can only be
|
|
stopped by "kill -9":
|
|
|
|
https://github.com/OpenPrinting/cups-filters/security/advisories/GHSA-rq86-c7g6-r2h8
|
|
|
|
The removal of the legacy CUPS browsing support removes these 2
|
|
vulnerabilities.
|
|
|
|
The LDAP implementation in cups-browsed does not follow the LDAP
|
|
printer schema RFC 7612 and is therefore of very limited use.
|
|
---
|
|
README | 39 +-
|
|
configure.ac | 44 --
|
|
utils/cups-browsed.8 | 38 +-
|
|
utils/cups-browsed.c | 1407 +-----------------------------------
|
|
utils/cups-browsed.conf.5 | 43 +-
|
|
utils/cups-browsed.conf.in | 27 +-
|
|
6 files changed, 54 insertions(+), 1544 deletions(-)
|
|
|
|
diff --git a/README b/README
|
|
index cc86b95bf..9ee901c5f 100644
|
|
--- a/README
|
|
+++ b/README
|
|
@@ -237,43 +237,34 @@ POSTSCRIPT PRINTING DEBUG MODE
|
|
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.
|
|
+ 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
|
|
@@ -388,7 +379,7 @@ HELPER DAEMON FOR BROWSING REMOTE CUPS PRINTERS AND IPP NETWORK PRINTERS
|
|
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
|
|
@@ -444,7 +435,7 @@ HELPER DAEMON FOR BROWSING REMOTE CUPS PRINTERS AND IPP NETWORK PRINTERS
|
|
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 7a54fdf12..32180d0da 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -364,50 +364,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)
|
|
diff --git a/utils/cups-browsed.8 b/utils/cups-browsed.8
|
|
index 73c2f686b..6eb713bf2 100644
|
|
--- a/utils/cups-browsed.8
|
|
+++ b/utils/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/utils/cups-browsed.c b/utils/cups-browsed.c
|
|
index 3873a5b6f..9136e7a88 100644
|
|
--- a/utils/cups-browsed.c
|
|
+++ b/utils/cups-browsed.c
|
|
@@ -53,72 +53,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/ppd.h>
|
|
#include <cups/raster.h>
|
|
@@ -279,17 +213,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 {
|
|
char *local_queue_name;
|
|
@@ -397,8 +320,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;
|
|
@@ -408,23 +329,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;
|
|
@@ -3924,209 +3832,6 @@ get_local_printers (void)
|
|
cupsFreeDests (num_dests, dests);
|
|
}
|
|
|
|
-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;
|
|
-
|
|
- 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;
|
|
- GString *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);
|
|
-
|
|
- if (!attr)
|
|
- break;
|
|
- }
|
|
-
|
|
- fail:
|
|
- if (response)
|
|
- ippDelete(response);
|
|
-}
|
|
|
|
static void
|
|
update_local_printers (void)
|
|
@@ -4156,12 +3861,8 @@ update_local_printers (void)
|
|
} else
|
|
get_printers = TRUE;
|
|
|
|
- if (get_printers) {
|
|
+ if (get_printers)
|
|
get_local_printers ();
|
|
-
|
|
- if (BrowseLocalProtocols & BROWSE_CUPS)
|
|
- prepare_browse_data ();
|
|
- }
|
|
}
|
|
|
|
int
|
|
@@ -4214,6 +3915,7 @@ autoshutdown_execute (gpointer data)
|
|
return FALSE;
|
|
}
|
|
|
|
+
|
|
int
|
|
color_space_score(const char *color_space)
|
|
{
|
|
@@ -4254,711 +3956,6 @@ color_space_score(const char *color_space)
|
|
}
|
|
|
|
|
|
-#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...
|
|
- */
|
|
-
|
|
-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);
|
|
-
|
|
- examine_discovered_printer_record(host, NULL, port, local_resource,
|
|
- service_name, location, info, "", "",
|
|
- "", 0, NULL);
|
|
-
|
|
- }
|
|
-
|
|
- 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 */
|
|
-
|
|
- 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");
|
|
-}
|
|
-
|
|
-
|
|
-/*
|
|
- * '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 */
|
|
-{
|
|
- 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 */
|
|
-
|
|
-
|
|
- /*
|
|
- * Get value from LDAPMessage...
|
|
- */
|
|
-
|
|
- 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 {
|
|
- /*
|
|
- * Check size and copy value into our string...
|
|
- */
|
|
-
|
|
- size = maxsize;
|
|
- if (size < (bval[0]->bv_len + 1)) {
|
|
- rc = -1;
|
|
- dn = ldap_get_dn(ld, entry);
|
|
- debug_printf("Attribute %s is too big! (dn: %s)\n",
|
|
- attr, dn);
|
|
- ldap_memfree(dn);
|
|
- } else
|
|
- size = bval[0]->bv_len + 1;
|
|
-
|
|
- strncpy(retval, bval[0]->bv_val, size);
|
|
- if (size > 0)
|
|
- retval[size - 1] = '\0';
|
|
- ldap_value_free_len(bval);
|
|
- }
|
|
-# else
|
|
- char **value; /* LDAP value */
|
|
-
|
|
- /*
|
|
- * Get value from LDAPMessage...
|
|
- */
|
|
-
|
|
- if ((value = (char **)ldap_get_values(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 {
|
|
- strncpy(retval, *value, maxsize);
|
|
- if (maxsize > 0)
|
|
- retval[maxsize - 1] = '\0';
|
|
- ldap_value_free(value);
|
|
- }
|
|
-# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */
|
|
-
|
|
- return (rc);
|
|
-}
|
|
-
|
|
-#endif /* HAVE_LDAP */
|
|
-
|
|
-
|
|
static int
|
|
create_subscription ()
|
|
{
|
|
@@ -7940,7 +6937,7 @@ gboolean 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) */
|
|
+ /* (...or, we've just discovered this queue via BrowsePoll) */
|
|
case STATUS_TO_BE_CREATED:
|
|
|
|
/* Do not create a queue for slaves */
|
|
@@ -9424,7 +8421,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);
|
|
}
|
|
}
|
|
@@ -9587,7 +8584,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;
|
|
@@ -9691,8 +8688,8 @@ examine_discovered_printer_record(const char *host,
|
|
(is_cups_queue ? "cups" : ""));
|
|
} 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
|
|
+ an 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,
|
|
@@ -9712,8 +8709,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 (type == NULL || type[0] == '\0')
|
|
@@ -9770,9 +8767,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;
|
|
|
|
@@ -9805,13 +8802,13 @@ examine_discovered_printer_record(const char *host,
|
|
downgrade = 1;
|
|
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);
|
|
}
|
|
|
|
@@ -9828,7 +8825,7 @@ examine_discovered_printer_record(const char *host,
|
|
upgrade = 1;
|
|
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') &&
|
|
@@ -9841,7 +8838,7 @@ examine_discovered_printer_record(const char *host,
|
|
|
|
/* Switch local queue over to this newly discovered service */
|
|
if (upgrade == 1) {
|
|
- /* Remove tiemout of legacy CUPS broadcasting */
|
|
+ /* Remove timeout of legacy CUPS broadcasting */
|
|
if (domain != NULL && domain[0] != '\0' &&
|
|
type != NULL && type[0] != '\0' &&
|
|
p->is_legacy) {
|
|
@@ -10681,8 +9678,7 @@ void avahi_init() {
|
|
#endif /* HAVE_AVAHI */
|
|
|
|
/*
|
|
- * A CUPS printer has been discovered via CUPS Browsing
|
|
- * or with BrowsePoll
|
|
+ * A CUPS printer has been discovered via BrowsePoll
|
|
*/
|
|
void
|
|
found_cups_printer (const char *remote_host, const char *uri,
|
|
@@ -10750,7 +9746,7 @@ found_cups_printer (const char *remote_host, const char *uri,
|
|
/* 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);
|
|
|
|
printer = examine_discovered_printer_record(host, NULL, port, local_resource,
|
|
@@ -10777,195 +9773,6 @@ found_cups_printer (const char *remote_host, const char *uri,
|
|
|
|
}
|
|
|
|
-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));
|
|
- }
|
|
-}
|
|
-
|
|
-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,
|
|
@@ -11352,72 +10159,6 @@ browse_poll (gpointer data)
|
|
return FALSE;
|
|
}
|
|
|
|
-#ifdef HAVE_LDAP
|
|
-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) {
|
|
(void)sig; /* remove compiler warnings... */
|
|
@@ -11622,10 +10363,6 @@ read_configuration (const char *filename)
|
|
while (p) {
|
|
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);
|
|
|
|
@@ -12141,31 +10878,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) {
|
|
@@ -12243,10 +10955,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",
|
|
@@ -12518,11 +11227,6 @@ int 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) {
|
|
debug_printf("Remote support for DNSSD not supported\n");
|
|
@@ -12530,13 +11234,6 @@ int 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);
|
|
@@ -12622,41 +11319,6 @@ int 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) {
|
|
@@ -12689,26 +11351,6 @@ int 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;
|
|
for (index = 0;
|
|
@@ -12822,23 +11464,12 @@ int main(int argc, char*argv[]) {
|
|
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/utils/cups-browsed.conf.5 b/utils/cups-browsed.conf.5
|
|
index 7e6ee3bff..3fc1e05c6 100644
|
|
--- a/utils/cups-browsed.conf.5
|
|
+++ b/utils/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/utils/cups-browsed.conf.in b/utils/cups-browsed.conf.in
|
|
index ee2f5bf34..1b7d2160d 100644
|
|
--- a/utils/cups-browsed.conf.in
|
|
+++ b/utils/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
|