Accepting request 286363 from home:scarabeus_iv:branches:Printing

Final submission, there seem to be no activity on factory so it works
or nobody cares :)

- Add back the posttrans cleanup script as it is needed
- Add patch cups-systemd-socket.patch to fix socket activation
  and to match socket approach Fedora has.
- Version bump to 2.0.2:
  * Security: cupsRasterReadPixels buffer overflow with invalid page header and
    compressed raster data (STR #4551)
  * Mapping of PPD keywords to IPP keywords did not work if the PPD keyword was
    already an IPP keyword (<rdar://problem/19121005>)
  * cupsGetPPD* sent bad requests (STR #4567)
  * For detailed list see CHANGES.txt file
- Enable PIE for build
- Remove legacy paralel-port support as it is not really needed
  as most do not want it
- Update descriptions to just state what changed and let user
  find it out.
- Add back comment about %fdupes
- Remove exit 0 on scriptlets as it is provided by the %service bla
  ones already
- Fix the comment about openSUSE version on tmpfilesdir declaration
- cups-2.0.1 update:
  * lengthy list of changes see the upstream CHANGES.txt that is
    distributed with the package
  * Disabling of sslv3 to mitigate poodle
- Use gnutls to provide SSLOPtions configuration directive
  * openssl is no longer supported upstream
  * Remove the with-openssl-exception from license
- Remove cups.sysconfig as it is not used with systemd based distros
- Purposely lose support for SLE11 as it doubles size of some of the
  sections and keep suppor for openSUSE+SLE12
  * even with the conditions we would have to go unencrypted only

OBS-URL: https://build.opensuse.org/request/show/286363
OBS-URL: https://build.opensuse.org/package/show/Printing/cups?expand=0&rev=294
This commit is contained in:
Tomáš Chvátal 2015-02-16 15:27:41 +00:00 committed by Git OBS Bridge
parent a419140b09
commit c7ccef2b9b
30 changed files with 874 additions and 2738 deletions

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:39b8fdf82b711bff408ddc05ee8777a2064b2d6656c8713bf46d302c737a4ade
size 3026

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cd01bc308c1c6132d47aa2f33c8011879cbdbea676a9cf95c1c7b229a4601be9
size 3019

BIN
Postscript-level1.ppd.gz (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Postscript-level2.ppd.gz (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Postscript.ppd.gz (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -1,519 +0,0 @@
--- config.h.in.orig
+++ config.h.in
@@ -496,6 +496,13 @@
/*
+ * Do we have systemd support?
+ */
+
+#undef HAVE_SYSTEMD
+
+
+/*
* Various scripting languages...
*/
--- /dev/null
+++ config-scripts/cups-systemd.m4
@@ -0,0 +1,36 @@
+dnl
+dnl "$Id$"
+dnl
+dnl systemd stuff for CUPS.
+
+dnl Find whether systemd is available
+
+SDLIBS=""
+AC_ARG_WITH([systemdsystemunitdir],
+ AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
+ [], [with_systemdsystemunitdir=$($PKGCONFIG --variable=systemdsystemunitdir systemd)])
+if test "x$with_systemdsystemunitdir" != xno; then
+ AC_MSG_CHECKING(for libsystemd-daemon)
+ if $PKGCONFIG --exists libsystemd-daemon; then
+ AC_MSG_RESULT(yes)
+ SDCFLAGS=`$PKGCONFIG --cflags libsystemd-daemon`
+ SDLIBS=`$PKGCONFIG --libs libsystemd-daemon`
+ AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
+ AC_DEFINE(HAVE_SYSTEMD)
+ else
+ AC_MSG_RESULT(no)
+ fi
+fi
+
+if test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ; then
+ SYSTEMD_UNITS="cups.service cups.socket cups.path"
+else
+ SYSTEMD_UNITS=""
+fi
+
+AC_SUBST(SYSTEMD_UNITS)
+AC_SUBST(SDLIBS)
+
+dnl
+dnl "$Id$"
+dnl
--- configure.in.orig
+++ configure.in
@@ -37,6 +37,7 @@ sinclude(config-scripts/cups-pam.m4)
sinclude(config-scripts/cups-largefile.m4)
sinclude(config-scripts/cups-dnssd.m4)
sinclude(config-scripts/cups-launchd.m4)
+sinclude(config-scripts/cups-systemd.m4)
sinclude(config-scripts/cups-defaults.m4)
sinclude(config-scripts/cups-pdf.m4)
sinclude(config-scripts/cups-scripting.m4)
@@ -71,6 +72,9 @@ AC_OUTPUT(Makedefs
conf/snmp.conf
cups-config
data/testprint
+ data/cups.service
+ data/cups.socket
+ data/cups.path
desktop/cups.desktop
doc/help/ref-cupsd-conf.html
doc/help/standard.html
--- cups/usersys.c.orig
+++ cups/usersys.c
@@ -750,7 +750,7 @@ cups_read_client_conf(
struct stat sockinfo; /* Domain socket information */
if (!stat(CUPS_DEFAULT_DOMAINSOCKET, &sockinfo) &&
- (sockinfo.st_mode & S_IRWXO) == S_IRWXO)
+ (sockinfo.st_mode & (S_IROTH | S_IWOTH)) == (S_IROTH | S_IWOTH))
cups_server = CUPS_DEFAULT_DOMAINSOCKET;
else
#endif /* CUPS_DEFAULT_DOMAINSOCKET */
--- /dev/null
+++ data/cups.path.in
@@ -0,0 +1,8 @@
+[Unit]
+Description=CUPS Printer Service Spool
+
+[Path]
+PathExistsGlob=@CUPS_REQUESTS@/d*
+
+[Install]
+WantedBy=multi-user.target
--- /dev/null
+++ data/cups.service.in
@@ -0,0 +1,9 @@
+[Unit]
+Description=CUPS Printing Service
+
+[Service]
+ExecStart=@sbindir@/cupsd -f
+
+[Install]
+Also=cups.socket cups.path
+WantedBy=printer.target
--- /dev/null
+++ data/cups.socket.in
@@ -0,0 +1,11 @@
+[Unit]
+Description=CUPS Printing Service Sockets
+
+[Socket]
+ListenStream=@CUPS_DEFAULT_DOMAINSOCKET@
+ListenStream=631
+ListenDatagram=0.0.0.0:631
+BindIPv6Only=ipv6-only
+
+[Install]
+WantedBy=sockets.target
--- data/Makefile.orig
+++ data/Makefile
@@ -112,6 +112,12 @@ install-data:
$(INSTALL_DATA) $$file $(DATADIR)/ppdc; \
done
$(INSTALL_DIR) -m 755 $(DATADIR)/profiles
+ if test "x$(SYSTEMD_UNITS)" != "x" ; then \
+ $(INSTALL_DIR) -m 755 $(SYSTEMDUNITDIR); \
+ for file in $(SYSTEMD_UNITS); do \
+ $(INSTALL_DATA) $$file $(SYSTEMDUNITDIR); \
+ done; \
+ fi
#
@@ -159,6 +165,9 @@ uninstall:
-$(RMDIR) $(DATADIR)/charsets
-$(RMDIR) $(DATADIR)/banners
-$(RMDIR) $(DATADIR)
+ for file in $(SYSTEMD_UNITS); do \
+ $(RM) $(SYSTEMDUNITDIR)/$$file; \
+ done
#
--- Makedefs.in.orig
+++ Makedefs.in
@@ -143,6 +143,7 @@ CXXFLAGS = @CPPFLAGS@ @CXXFLAGS@
CXXLIBS = @CXXLIBS@
DBUS_NOTIFIER = @DBUS_NOTIFIER@
DBUS_NOTIFIERLIBS = @DBUS_NOTIFIERLIBS@
+SYSTEMD_UNITS = @SYSTEMD_UNITS@
DNSSD_BACKEND = @DNSSD_BACKEND@
DSOFLAGS = -L../cups @DSOFLAGS@
DSOLIBS = @DSOLIBS@ $(COMMONLIBS)
@@ -151,6 +152,7 @@ FONTS = @FONTS@
IMGLIBS = @IMGLIBS@
IMGFILTERS = @IMGFILTERS@
LAUNCHDLIBS = @LAUNCHDLIBS@
+SDLIBS = @SDLIBS@
LDFLAGS = -L../cgi-bin -L../cups -L../filter -L../ppdc \
-L../scheduler @LDARCHFLAGS@ \
@LDFLAGS@ @RELROFLAGS@ @PIEFLAGS@ $(OPTIM)
@@ -267,6 +269,7 @@ PAMFILE = @PAMFILE@
DEFAULT_LAUNCHD_CONF = @DEFAULT_LAUNCHD_CONF@
DBUSDIR = @DBUSDIR@
+SYSTEMDUNITDIR = $(BUILDROOT)@systemdsystemunitdir@
#
--- scheduler/client.h.orig
+++ scheduler/client.h
@@ -75,6 +75,9 @@ typedef struct
int fd; /* File descriptor for this server */
http_addr_t address; /* Bind address of socket */
http_encryption_t encryption; /* To encrypt or not to encrypt... */
+#ifdef HAVE_SYSTEMD
+ int is_systemd; /* Is this a systemd socket? */
+#endif /* HAVE_SYSTEMD */
} cupsd_listener_t;
--- scheduler/dirsvc.c.orig
+++ scheduler/dirsvc.c
@@ -1457,7 +1457,7 @@ cupsdStartBrowsing(void)
}
}
- if (BrowseSocket >= 0)
+ if (BrowseSocket >= 0 && !BrowseSocketIsSystemd)
{
/*
* Bind the socket to browse port...
@@ -1501,13 +1501,17 @@ cupsdStartBrowsing(void)
cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to set broadcast mode - %s.",
strerror(errno));
+ if (!BrowseSocketIsSystemd)
+ {
#ifdef WIN32
- closesocket(BrowseSocket);
+ closesocket(BrowseSocket);
#else
- close(BrowseSocket);
+ close(BrowseSocket);
#endif /* WIN32 */
- BrowseSocket = -1;
+ BrowseSocket = -1;
+ }
+
BrowseLocalProtocols &= ~BROWSE_CUPS;
BrowseRemoteProtocols &= ~BROWSE_CUPS;
@@ -1820,15 +1824,22 @@ cupsdStopBrowsing(void)
if (((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_CUPS) &&
BrowseSocket >= 0)
{
- /*
- * Close the socket and remove it from the input selection set.
- */
+ if (!BrowseSocketIsSystemd)
+ {
+ /*
+ * Close the socket.
+ */
#ifdef WIN32
- closesocket(BrowseSocket);
+ closesocket(BrowseSocket);
#else
- close(BrowseSocket);
+ close(BrowseSocket);
#endif /* WIN32 */
+ }
+
+ /*
+ * Remove it from the input selection set.
+ */
cupsdRemoveSelect(BrowseSocket);
BrowseSocket = -1;
@@ -5146,11 +5157,14 @@ update_cups_browse(void)
strerror(errno));
cupsdLogMessage(CUPSD_LOG_ERROR, "CUPS browsing turned off.");
+ if (!BrowseSocketIsSystemd)
+ {
#ifdef WIN32
- closesocket(BrowseSocket);
+ closesocket(BrowseSocket);
#else
- close(BrowseSocket);
+ close(BrowseSocket);
#endif /* WIN32 */
+ }
cupsdRemoveSelect(BrowseSocket);
BrowseSocket = -1;
--- scheduler/dirsvc.h.orig
+++ scheduler/dirsvc.h
@@ -96,6 +96,8 @@ VAR int Browsing VALUE(TRUE),
/* Short names for remote printers? */
BrowseSocket VALUE(-1),
/* Socket for browsing */
+ BrowseSocketIsSystemd VALUE(0),
+ /* BrowseSocket is systemd-provided? */
BrowsePort VALUE(IPP_PORT),
/* Port number for broadcasts */
BrowseInterval VALUE(DEFAULT_INTERVAL),
--- scheduler/listen.c.orig
+++ scheduler/listen.c
@@ -401,7 +401,11 @@ cupsdStopListening(void)
lis;
lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
{
- if (lis->fd != -1)
+ if (lis->fd != -1
+#ifdef HAVE_SYSTEMD
+ && !lis->is_systemd
+#endif /* HAVE_SYSTEMD */
+ )
{
#ifdef WIN32
closesocket(lis->fd);
--- scheduler/main.c.orig
+++ scheduler/main.c
@@ -26,6 +26,8 @@
* launchd_checkin() - Check-in with launchd and collect the listening
* fds.
* launchd_checkout() - Update the launchd KeepAlive file as needed.
+ * systemd_checkin() - Check-in with systemd and collect the
+ * listening fds.
* parent_handler() - Catch USR1/CHLD signals...
* process_children() - Process all dead children...
* select_timeout() - Calculate the select timeout value.
@@ -62,6 +64,10 @@
# endif /* !LAUNCH_JOBKEY_SERVICEIPC */
#endif /* HAVE_LAUNCH_H */
+#ifdef HAVE_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif /* HAVE_SYSTEMD */
+
#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
# include <malloc.h>
#endif /* HAVE_MALLOC_H && HAVE_MALLINFO */
@@ -78,6 +84,9 @@
static void launchd_checkin(void);
static void launchd_checkout(void);
#endif /* HAVE_LAUNCHD */
+#ifdef HAVE_SYSTEMD
+static void systemd_checkin(void);
+#endif /* HAVE_SYSTEMD */
static void parent_handler(int sig);
static void process_children(void);
static void sigchld_handler(int sig);
@@ -519,6 +528,13 @@ main(int argc, /* I - Number of comm
}
#endif /* HAVE_LAUNCHD */
+#ifdef HAVE_SYSTEMD
+ /*
+ * If we were started by systemd get the listen sockets file descriptors...
+ */
+ systemd_checkin();
+#endif /* HAVE_SYSTEMD */
+
/*
* Startup the server...
*/
@@ -730,6 +746,15 @@ main(int argc, /* I - Number of comm
}
#endif /* HAVE_LAUNCHD */
+#ifdef HAVE_SYSTEMD
+ /*
+ * If we were started by systemd get the listen sockets file
+ * descriptors...
+ */
+
+ systemd_checkin();
+#endif /* HAVE_SYSTEMD */
+
/*
* Startup the server...
*/
@@ -1535,6 +1560,147 @@ launchd_checkout(void)
}
#endif /* HAVE_LAUNCHD */
+#ifdef HAVE_SYSTEMD
+static void
+systemd_checkin(void)
+{
+ int n, fd;
+
+ n = sd_listen_fds(0);
+ if (n < 0)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "systemd_checkin: Failed to acquire sockets from systemd - %s",
+ strerror(-n));
+ exit(EXIT_FAILURE);
+ return;
+ }
+
+ if (n == 0)
+ return;
+
+ for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
+ {
+ http_addr_t addr;
+ socklen_t addrlen = sizeof (addr);
+ int r;
+ cupsd_listener_t *lis;
+ char s[256];
+
+ r = sd_is_socket(fd, AF_UNSPEC, SOCK_STREAM, 1);
+ if (r < 0)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "systemd_checkin: Unable to verify socket type - %s",
+ strerror(-r));
+ continue;
+ }
+
+ if (!r)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Browsing=%d", Browsing);
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "BrowseLocalProtocols=%x", BrowseLocalProtocols);
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "BrowseRemoteProtocols=%x", BrowseRemoteProtocols);
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "BROWSE_CUPS=%x", BROWSE_CUPS);
+ if (Browsing &&
+ ((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_CUPS))
+ {
+ r = sd_is_socket(fd, AF_UNSPEC, SOCK_DGRAM, 0);
+ if (r < 0)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "systemd_checkin: Unable to verify socket type - %s",
+ strerror(-r));
+ continue;
+ }
+
+ if (r)
+ {
+ /*
+ * This is the browse socket.
+ */
+
+ char addrstr[256];
+ if (getsockname(fd, (struct sockaddr*) &addr, &addrlen))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "systemd_checkin: Unable to get local address - %s",
+ strerror(errno));
+ continue;
+ }
+
+ httpAddrString (&addr, addrstr, sizeof (addrstr));
+ BrowseSocket = fd;
+ BrowseSocketIsSystemd = 1;
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "systemd_checkin: Matched browse (port %d) with fd %d:%s...",
+ BrowsePort, fd, addrstr);
+ continue;
+ }
+
+ }
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "systemd_checkin: Socket not of the right type");
+ continue;
+ }
+
+ if (getsockname(fd, (struct sockaddr*) &addr, &addrlen))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "systemd_checkin: Unable to get local address - %s",
+ strerror(errno));
+ continue;
+ }
+
+ /*
+ * Try to match the systemd socket address to one of the listeners...
+ */
+
+ for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
+ lis;
+ lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
+ if (httpAddrEqual(&lis->address, &addr))
+ break;
+
+ if (lis)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "systemd_checkin: Matched existing listener %s with fd %d...",
+ httpAddrString(&(lis->address), s, sizeof(s)), fd);
+ }
+ else
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "systemd_checkin: Adding new listener %s with fd %d...",
+ httpAddrString(&addr, s, sizeof(s)), fd);
+
+ if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "systemd_checkin: Unable to allocate listener - "
+ "%s.", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ cupsArrayAdd(Listeners, lis);
+
+ memcpy(&lis->address, &addr, sizeof(lis->address));
+ }
+
+ lis->fd = fd;
+ lis->is_systemd = 1;
+
+# ifdef HAVE_SSL
+ if (_httpAddrPort(&(lis->address)) == 443)
+ lis->encryption = HTTP_ENCRYPT_ALWAYS;
+# endif /* HAVE_SSL */
+ }
+}
+#endif /* HAVE_SYSTEMD */
/*
* 'parent_handler()' - Catch USR1/CHLD signals...
--- scheduler/Makefile.orig
+++ scheduler/Makefile
@@ -379,7 +379,7 @@ cupsd: $(CUPSDOBJS) $(LIBCUPSMIME) ../cu
$(CC) $(LDFLAGS) -o cupsd $(CUPSDOBJS) -L. -lcupsmime \
$(LIBZ) $(SSLLIBS) $(LIBSLP) $(LIBLDAP) $(PAMLIBS) \
$(LIBPAPER) $(LIBMALLOC) $(SERVERLIBS) $(DNSSDLIBS) $(LIBS) \
- $(LIBGSSAPI) $(LIBWRAP)
+ $(LIBGSSAPI) $(LIBWRAP) $(SDLIBS)
cupsd-static: $(CUPSDOBJS) libcupsmime.a ../cups/$(LIBCUPSSTATIC)
echo Linking $@...
@@ -387,7 +387,7 @@ cupsd-static: $(CUPSDOBJS) libcupsmime.a
$(LIBZ) $(SSLLIBS) $(LIBSLP) $(LIBLDAP) $(PAMLIBS) \
../cups/$(LIBCUPSSTATIC) $(COMMONLIBS) $(LIBZ) $(LIBPAPER) \
$(LIBMALLOC) $(SERVERLIBS) $(DNSSDLIBS) $(LIBGSSAPI) \
- $(LIBWRAP)
+ $(LIBWRAP) $(SDLIBS)
#

View File

@ -1,15 +0,0 @@
--- data/cups.socket.in.orig 2014-01-08 15:31:12.000000000 +0100
+++ data/cups.socket.in 2014-01-08 15:33:07.000000000 +0100
@@ -3,8 +3,10 @@ Description=CUPS Printing Service Socket
[Socket]
ListenStream=@CUPS_DEFAULT_DOMAINSOCKET@
-ListenStream=631
-ListenDatagram=0.0.0.0:631
+ListenStream=127.0.0.1:631
+ListenStream=[::1]:631
+ListenDatagram=127.0.0.1:631
+ListenDatagram=[::1]:631
BindIPv6Only=ipv6-only
[Install]

View File

@ -1,16 +0,0 @@
--- data/cups.service.in.orig 2014-01-29 13:57:17.000000000 +0100
+++ data/cups.service.in 2014-01-29 14:14:54.000000000 +0100
@@ -1,10 +1,10 @@
[Unit]
Description=CUPS Printing Service
+After=network.target
[Service]
ExecStart=@sbindir@/cupsd -f
[Install]
-Alias=cupsd.service
-Also=cups.socket cups.path
-WantedBy=printer.target
+WantedBy=multi-user.target
+

View File

@ -1,10 +0,0 @@
--- cups-1.3.6/conf/cupsd.conf.in.orig 2008-02-28 20:08:52.000000000 +0100
+++ cups-1.3.6/conf/cupsd.conf.in 2008-02-28 20:13:47.000000000 +0100
@@ -29,6 +29,7 @@
# Restrict access to the server...
<Location />
Order allow,deny
+ Allow 127.0.0.2
</Location>
# Restrict access to the admin pages...

View File

@ -6,7 +6,7 @@ Index: desktop/cups.desktop.in
[Desktop Entry]
-Categories=System;Printing;HardwareSettings;X-Red-Hat-Base;
-Exec=@CUPS_HTMLVIEW@ http://localhost:631/
+Categories=Settings;Printing;HardwareSettings;
+Categories=System;Printing;Settings;HardwareSettings;
+Exec=desktop-launch http://localhost:631/
+NotShowIn=GNOME;
Icon=cups

View File

@ -1,408 +0,0 @@
--- doc/help/ref-cupsd-conf.html.in.orig 2012-01-30 22:40:21.000000000 +0100
+++ doc/help/ref-cupsd-conf.html.in 2014-02-05 14:13:23.000000000 +0100
@@ -917,6 +917,28 @@ ConfigFilePerm 0640
</BLOCKQUOTE>
+<H2 CLASS="title"><A NAME="ConfigurationChangeRestriction">ConfigurationChangeRestriction</A></H2>
+
+<H3>Examples</H3>
+
+<PRE CLASS="command">
+ConfigurationChangeRestriction all
+ConfigurationChangeRestriction root-only
+ConfigurationChangeRestriction none
+</PRE>
+
+<H3>Description</H3>
+
+<P>The <CODE>ConfigurationChangeRestriction</CODE> directive specifies
+the degree of restriction for changes to cupsd.conf. Keywords dealing
+with filenames, paths, and users are security-sensitive. Changes to
+them via HTTP are forbidden by default (<CODE>all</CODE>). The value
+<CODE>none</CODE> removes any restriction altogether (note that this
+is unsafe). The value <CODE>root-only</CODE> allows only users
+authorised as user "root" to adjust security-sensitive configuration
+settings, but note that users adjusting settings using polkit (via
+cups-pk-helper) are authenticated as user "root".</P>
+
<H2 CLASS="title"><A NAME="DataDir">DataDir</A></H2>
--- man/cupsctl.man.orig 2011-01-11 04:04:04.000000000 +0100
+++ man/cupsctl.man 2014-02-05 14:15:23.000000000 +0100
@@ -90,7 +90,8 @@ Disable printer sharing:
cupsctl --no-shared-printers
.fi
.LP
-Enable printing using the file: pseudo-device:
+Enable printing using the file: pseudo-device (note that this is
+forbidden by default):
.nf
cupsctl FileDevice=Yes
.fi
--- man/cupsd.conf.man.in.orig 2011-05-18 23:33:35.000000000 +0200
+++ man/cupsd.conf.man.in 2014-02-05 14:16:58.000000000 +0100
@@ -238,6 +238,21 @@ ConfigFilePerm mode
Specifies the permissions for all configuration files that the scheduler
writes.
.TP 5
+ConfigurationChangeRestriction all
+.TP 5
+ConfigurationChangeRestriction root-only
+.TP 5
+ConfigurationChangeRestriction none
+.br
+Specifies the degree of restriction for changes to cupsd.conf.
+Keywords dealing with filenames, paths, and users are
+security-sensitive. Changes to them via HTTP are forbidden by default
+("all"). The value "none" removes any restriction altogether (note
+that this is unsafe). The value "root-only" allows only users
+authorised as user "root" to adjust security-sensitive configuration
+settings, but note that users adjusting settings using polkit (via
+cups-pk-helper) are authenticated as user "root".
+.TP 5
DataDir path
.br
Specified the directory where data files can be found.
--- scheduler/client.c.orig 2012-03-07 07:05:39.000000000 +0100
+++ scheduler/client.c 2014-02-05 14:32:49.000000000 +0100
@@ -1685,13 +1685,10 @@ cupsdReadClient(cupsd_client_t *con) /*
* Validate the resource name...
*/
- if (strncmp(con->uri, "/admin/conf/", 12) ||
- strchr(con->uri + 12, '/') ||
- strlen(con->uri) == 12)
+ if (strcmp(con->uri, "/admin/conf/cupsd.conf"))
{
/*
- * PUT can only be done to configuration files under
- * /admin/conf...
+ * PUT can only be done to the cupsd.conf file...
*/
cupsdLogMessage(CUPSD_LOG_ERROR,
@@ -3827,6 +3824,8 @@ install_conf_file(cupsd_client_t *con) /
char buffer[16384]; /* Copy buffer */
ssize_t bytes; /* Number of bytes */
+ if (!cupsdCheckConfigurationAllowed (con))
+ return (HTTP_FORBIDDEN);
/*
* Open the request file...
--- scheduler/conf.h.orig 2011-04-22 19:47:03.000000000 +0200
+++ scheduler/conf.h 2014-02-05 14:44:49.000000000 +0100
@@ -92,6 +92,18 @@ typedef struct
/*
+ * Configuration change restriction (CVE-2012-5519)
+ */
+
+typedef enum
+{
+ CUPSD_CONFRESTRICT_NONE, /* No checking of PUT cupsd.conf */
+ CUPSD_CONFRESTRICT_ROOT, /* Only allow root to change all opts */
+ CUPSD_CONFRESTRICT_ALL, /* Restricted keywords not to be changed */
+} cupsd_confrestrict_t;
+
+
+/*
* Globals...
*/
@@ -165,6 +177,8 @@ VAR int ClassifyOverride VALUE(0),
/* Allow overrides? */
ConfigFilePerm VALUE(0640),
/* Permissions for config files */
+ ConfigurationChangeRestriction VALUE(CUPSD_CONFRESTRICT_ALL),
+ /* CVE-2012-5519 protection */
LogDebugHistory VALUE(200),
/* Amount of automatic debug history */
FatalErrors VALUE(CUPSD_FATAL_CONFIG),
@@ -291,6 +305,7 @@ __attribute__ ((__format__ (__printf__,
extern int cupsdLogPage(cupsd_job_t *job, const char *page);
extern int cupsdLogRequest(cupsd_client_t *con, http_status_t code);
extern int cupsdReadConfiguration(void);
+extern int cupsdCheckConfigurationAllowed(cupsd_client_t *con);
extern int cupsdWriteErrorLog(int level, const char *message);
--- scheduler/conf.c.orig 2011-11-16 16:28:11.000000000 +0100
+++ scheduler/conf.c 2014-02-05 15:03:28.000000000 +0100
@@ -3196,6 +3196,22 @@ read_configuration(cups_file_t *fp) /* I
cupsdLogMessage(CUPSD_LOG_INFO, "Polling %s:%d", pollp->hostname,
pollp->port);
}
+ else if (!strcasecmp(line, "ConfigurationChangeRestriction") && value)
+ {
+ if (!strcasecmp(value, "none"))
+ ConfigurationChangeRestriction = CUPSD_CONFRESTRICT_NONE;
+ else if (!strcasecmp(value, "root-only"))
+ ConfigurationChangeRestriction = CUPSD_CONFRESTRICT_ROOT;
+ else if (!strcasecmp(value, "all"))
+ ConfigurationChangeRestriction = CUPSD_CONFRESTRICT_ALL;
+ else
+ {
+ cupsdLogMessage(CUPSD_LOG_WARN,
+ "Unknown restriction type %s on line %d.",
+ value, linenum);
+ return (0);
+ }
+ }
else if (!_cups_strcasecmp(line, "DefaultAuthType") && value)
{
/*
@@ -3657,6 +3673,250 @@ read_configuration(cups_file_t *fp) /* I
}
+static cups_array_t *
+_cupsdGetBlacklistedConfLines(cups_file_t *fp)
+{
+ cups_array_t *conf;
+ int linenum;
+ char keyword[HTTP_MAX_BUFFER],
+ *temp,
+ *value;
+ const char **kw;
+ size_t len;
+ const char *blacklist[] = {
+ "ConfigurationChangeRestriction",
+ "AccessLog",
+ "BrowseLDAPCACertFile",
+ "CacheDir",
+ "ConfigFilePerm",
+ "DataDir",
+ "DocumentRoot",
+ "ErrorLog",
+ "FatalErrors",
+ "FileDevice",
+ "FontPath",
+ "Group",
+ "JobPrivateAccess",
+ "JobPrivateValues",
+ "LogFilePerm",
+ "PageLog",
+ "Printcap",
+ "PrintcapFormat",
+ "PrintcapGUI",
+ "RemoteRoot",
+ "RequestRoot",
+ "ServerBin",
+ "ServerCertificate",
+ "ServerKey",
+ "ServerRoot",
+ "StateDir",
+ "SubscriptionPrivateAccess",
+ "SubscriptionPrivateValues",
+ "SystemGroup",
+ "SystemGroupAuthKey",
+ "TempDir",
+ "User",
+ "WebInterface",
+ NULL
+ };
+
+ conf = cupsArrayNew (NULL, NULL);
+
+ /*
+ * Loop through each line in the file...
+ */
+
+ linenum = 0;
+
+ while (cupsFileGetConf(fp, keyword, sizeof(keyword), &value, &linenum))
+ {
+ for (kw = blacklist; *kw; kw++)
+ if (!strcasecmp (keyword, *kw))
+ break;
+
+ if (*kw == NULL)
+ continue;
+
+ /*
+ * Remember lines we might need to compare against, but only the
+ * last occurrence of each keyword, except for
+ * SystemGroup. SystemGroup is special because it is cumulative:
+ * each SystemGroup line adds groups to the list. For that reason,
+ * we remember multiple SystemGroup lines and don't care about the
+ * order...
+ */
+
+ len = strlen (keyword);
+ if (strcasecmp(keyword, "SystemGroup") != 0)
+ {
+ for (temp = (char *) cupsArrayFirst(conf);
+ temp;
+ temp = (char *) cupsArrayNext(conf))
+ {
+ if (!strncasecmp (temp, keyword, len) && temp[len] == ' ')
+ {
+ cupsArrayRemove(conf, temp);
+
+ /*
+ * There can only be one such line because we do this for each
+ * line containing a blacklisted keyword
+ */
+
+ break;
+ }
+ }
+ }
+
+ len += (value ? strlen (value) : 0) + 2;
+ temp = malloc (len);
+ if (!temp)
+ goto fail;
+
+ snprintf (temp, len, "%s %s", keyword, value ? value : "");
+ cupsArrayAdd(conf, temp);
+ }
+
+ return conf;
+
+fail:
+ for (temp = (char *) cupsArrayFirst(conf);
+ temp;
+ temp = (char *) cupsArrayNext(conf))
+ free(temp);
+ cupsArrayDelete(conf);
+ return NULL;
+}
+
+
+/*
+ * 'cupsdCheckConfigurationAllowed()' - Check whether the new configuration
+ * file can be installed
+ */
+
+int /* O - 1 if allowed, 0 otherwise */
+cupsdCheckConfigurationAllowed(cupsd_client_t *con)
+{
+ int status = 0;
+ cups_file_t *fp;
+ cups_array_t *oldconf,
+ *newconf = NULL;
+ char *oldline,
+ *newline;
+
+ if (ConfigurationChangeRestriction == CUPSD_CONFRESTRICT_NONE)
+ /*
+ * Option checking disabled...
+ */
+ return (1);
+
+ if (ConfigurationChangeRestriction == CUPSD_CONFRESTRICT_ROOT &&
+ !strcmp (con->username, "root"))
+ /*
+ * This is requested by root and our configuration tells us to
+ * accept it.
+ */
+ return (1);
+
+ /*
+ * First read the current cupsd.conf...
+ */
+
+ if ((fp = cupsFileOpen (ConfigurationFile, "r")) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_WARN, "Unable to open configuration file?!");
+ return (0);
+ }
+
+ oldconf = _cupsdGetBlacklistedConfLines(fp);
+ cupsFileClose(fp);
+ if (!oldconf)
+ return (0);
+
+ /*
+ * Now take a look at the proposed new cupsd.conf...
+ */
+
+ if ((fp = cupsFileOpen(con->filename, "r")) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_WARN, "Unable to examine new config file");
+ goto fail;
+ }
+
+ newconf = _cupsdGetBlacklistedConfLines(fp);
+ cupsFileClose(fp);
+ if (!newconf)
+ goto fail;
+
+ /*
+ * Now compare the blacklisted directives in each.
+ */
+
+ status = 1;
+ for (oldline = (char *) cupsArrayFirst(oldconf);
+ oldline;
+ oldline = (char *) cupsArrayNext(oldconf))
+ {
+ for (newline = (char *) cupsArrayFirst(newconf);
+ newline;
+ newline = (char *) cupsArrayNext(newconf))
+ if (!strcmp (oldline, newline))
+ break;
+
+ if (newline == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Attempt to remove or change '%s' denied", oldline);
+ status = 0;
+ break;
+ }
+
+ cupsArrayRemove(newconf, newline);
+ free(newline);
+ }
+
+ if (status)
+ {
+ /*
+ * All the original directives are still present. Have any been added?
+ */
+
+ newline = (char *) cupsArrayFirst(newconf);
+ if (newline != NULL)
+ {
+ char *p;
+
+ cupsArrayRemove(newconf, newline);
+
+ p = strchr (newline, ' ');
+ if (p)
+ *p = '\0';
+
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Attempt to add '%s' directive denied", newline);
+ free(newline);
+ status = 0;
+ }
+ }
+
+fail:
+ for (oldline = (char *) cupsArrayFirst(oldconf);
+ oldline;
+ oldline = (char *) cupsArrayNext(oldconf))
+ free(oldline);
+ cupsArrayDelete(oldconf);
+
+ if (newconf)
+ {
+ for (newline = (char *) cupsArrayFirst(newconf);
+ newline;
+ newline = (char *) cupsArrayNext(newconf))
+ free(newline);
+ cupsArrayDelete(newconf);
+ }
+
+ return (status);
+}
+
+
/*
* 'read_location()' - Read a <Location path> definition.
*/

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8023034e8b58eab1ad7279364e872270a77459f6fb59a84d03229cb1d2a6d0e5
size 9583002

View File

@ -1,288 +0,0 @@
diff -Nur cups-1.5.4.dist/cgi-bin/ipp-var.c cups-1.5.4/cgi-bin/ipp-var.c
--- cups-1.5.4.dist/cgi-bin/ipp-var.c 2011-05-20 05:49:49.000000000 +0200
+++ cups-1.5.4/cgi-bin/ipp-var.c 2014-03-09 13:21:20.065678625 +0100
@@ -1192,7 +1192,7 @@
t = (time_t)attr->values[i].integer;
date = localtime(&t);
- strftime(valptr, sizeof(value) - (valptr - value), "%c", date);
+ _cupsstrftime(valptr, sizeof(value) - (valptr - value), "%c", date);
}
else
snprintf(valptr, sizeof(value) - (valptr - value),
diff -Nur cups-1.5.4.dist/cups/language-private.h cups-1.5.4/cups/language-private.h
--- cups-1.5.4.dist/cups/language-private.h 2010-11-20 02:03:46.000000000 +0100
+++ cups-1.5.4/cups/language-private.h 2014-03-09 13:21:20.073680045 +0100
@@ -79,6 +79,7 @@
extern const char *_cupsMessageLookup(cups_array_t *a, const char *m);
extern void _cupsSetLocale(char *argv[]);
+extern size_t _cupsstrftime(char *s, size_t max, const char *format, const struct tm *tm);
# ifdef __cplusplus
}
diff -Nur cups-1.5.4.dist/cups/libcups2.def cups-1.5.4/cups/libcups2.def
--- cups-1.5.4.dist/cups/libcups2.def 2011-09-09 23:55:11.000000000 +0200
+++ cups-1.5.4/cups/libcups2.def 2014-03-09 13:21:20.077680723 +0100
@@ -9,6 +9,7 @@
_cupsLangPrintf
_cupsLangPuts
_cupsLangString
+_cupsstrftime
_cupsMD5Append
_cupsMD5Finish
_cupsMD5Init
diff -Nur cups-1.5.4.dist/cups/libcups_s.exp cups-1.5.4/cups/libcups_s.exp
--- cups-1.5.4.dist/cups/libcups_s.exp 2011-04-16 01:38:13.000000000 +0200
+++ cups-1.5.4/cups/libcups_s.exp 2014-03-09 13:21:20.085681923 +0100
@@ -7,6 +7,7 @@
_cupsLangPrintf
_cupsLangPuts
_cupsLangString
+_cupsstrftime
_cupsMD5Append
_cupsMD5Finish
_cupsMD5Init
diff -Nur cups-1.5.4.dist/cups/Makefile cups-1.5.4/cups/Makefile
--- cups-1.5.4.dist/cups/Makefile 2011-09-09 18:34:29.000000000 +0200
+++ cups-1.5.4/cups/Makefile 2014-03-09 13:21:20.089682442 +0100
@@ -63,6 +63,7 @@
snmp.o \
snprintf.o \
string.o \
+ strftime.o \
tempfile.o \
thread.o \
transcode.o \
diff -Nur cups-1.5.4.dist/cups/strftime.c cups-1.5.4/cups/strftime.c
--- cups-1.5.4.dist/cups/strftime.c 1970-01-01 01:00:00.000000000 +0100
+++ cups-1.5.4/cups/strftime.c 2014-03-09 13:21:20.093682921 +0100
@@ -0,0 +1,56 @@
+/*
+ * "$Id$"
+ *
+ * Localized strftime function for CUPS.
+ *
+ *
+ * Contents:
+ *
+ * _cupsstrftime() - format date and time
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cups-private.h"
+
+
+/*
+ * '_cupsstrftime()' - format date and time in current locale and convert to UTF8
+ */
+
+size_t
+_cupsstrftime(char *s, size_t max, const char *format, const struct tm *tm)
+{
+ size_t size=0;
+ char date[256]; /* Date buffer */
+ cups_utf8_t utf8[256]; /* Date in utf8 */
+ _cups_globals_t *cg; /* Global data */
+
+ cg = _cupsGlobals();
+
+ if (!cg->lang_default)
+ cg->lang_default = cupsLangDefault();
+
+ if ((size=strftime(date, max, format, tm))!=0)
+ {
+
+ if (cg->lang_default->encoding != CUPS_UTF8)
+ {
+ cupsCharsetToUTF8(utf8, date, (int)sizeof(utf8), cg->lang_default->encoding);
+ strncpy(s, utf8, 256);
+ }
+ else {
+ strncpy(s, date, 256);
+ }
+ }
+ return ((size_t)size);
+}
+
+
+
+
+/*
+ * End of "$Id$".
+ */
diff -Nur cups-1.5.4.dist/cups/testipp.c cups-1.5.4/cups/testipp.c
--- cups-1.5.4.dist/cups/testipp.c 2011-09-14 02:31:10.000000000 +0200
+++ cups-1.5.4/cups/testipp.c 2014-03-09 13:21:20.101683760 +0100
@@ -891,7 +891,7 @@
{
vtime = ippDateToTime(val->date);
vdate = localtime(&vtime);
- strftime(vstring, sizeof(vstring), "%c", vdate);
+ _cupsstrftime(vstring, sizeof(vstring), "%c", vdate);
printf(" (%s)", vstring);
}
}
diff -Nur cups-1.5.4.dist/filter/bannertops.c cups-1.5.4/filter/bannertops.c
--- cups-1.5.4.dist/filter/bannertops.c 2011-05-20 05:49:49.000000000 +0200
+++ cups-1.5.4/filter/bannertops.c 2014-03-09 13:21:20.105684120 +0100
@@ -843,7 +843,7 @@
curtime = (time_t)atoi(option);
curdate = localtime(&curtime);
- strftime(text, sizeof(text), "%c", curdate);
+ _cupsstrftime(text, sizeof(text), "%c", curdate);
}
else
strlcpy(text, "?", sizeof(text));
@@ -865,7 +865,7 @@
curtime = (time_t)atoi(option);
curdate = localtime(&curtime);
- strftime(text, sizeof(text), "%c", curdate);
+ _cupsstrftime(text, sizeof(text), "%c", curdate);
}
else
strlcpy(text, "?", sizeof(text));
@@ -1066,7 +1066,7 @@
curtime = time(NULL);
curtm = localtime(&curtime);
- strftime(curdate, sizeof(curdate), "%c", curtm);
+ _cupsstrftime(curdate, sizeof(curdate), "%c", curtm);
puts("%!PS-Adobe-3.0");
printf("%%%%BoundingBox: %.0f %.0f %.0f %.0f\n", PageLeft, PageBottom,
diff -Nur cups-1.5.4.dist/filter/imagetops.c cups-1.5.4/filter/imagetops.c
--- cups-1.5.4.dist/filter/imagetops.c 2011-08-17 23:01:53.000000000 +0200
+++ cups-1.5.4/filter/imagetops.c 2014-03-09 13:21:20.113684721 +0100
@@ -618,7 +618,7 @@
puts("%%DocumentData: Clean7Bit");
puts("%%DocumentNeededResources: font Helvetica-Bold");
puts("%%Creator: imagetops/" CUPS_SVERSION);
- strftime(curdate, sizeof(curdate), "%c", curtm);
+ _cupsstrftime(curdate, sizeof(curdate), "%c", curtm);
printf("%%%%CreationDate: %s\n", curdate);
WriteTextComment("Title", argv[3]);
WriteTextComment("For", argv[2]);
diff -Nur cups-1.5.4.dist/filter/texttops.c cups-1.5.4/filter/texttops.c
--- cups-1.5.4.dist/filter/texttops.c 2010-12-03 07:29:20.000000000 +0100
+++ cups-1.5.4/filter/texttops.c 2014-03-09 13:21:20.117684961 +0100
@@ -223,7 +223,7 @@
curtime = time(NULL);
curtm = localtime(&curtime);
- strftime(curdate, sizeof(curdate), "%c", curtm);
+ _cupsstrftime(curdate, sizeof(curdate), "%c", curtm);
puts("%!PS-Adobe-3.0");
printf("%%%%BoundingBox: 0 0 %.0f %.0f\n", PageWidth, PageLength);
diff -Nur cups-1.5.4.dist/scheduler/testsub.c cups-1.5.4/scheduler/testsub.c
--- cups-1.5.4.dist/scheduler/testsub.c 2010-03-24 01:45:34.000000000 +0100
+++ cups-1.5.4/scheduler/testsub.c 2014-03-09 13:21:20.125685362 +0100
@@ -442,7 +442,7 @@
{
vtime = ippDateToTime(val->date);
vdate = localtime(&vtime);
- strftime(vstring, sizeof(vstring), "%c", vdate);
+ _cupsstrftime(vstring, sizeof(vstring), "%c", vdate);
printf(" (%s)", vstring);
}
}
diff -Nur cups-1.5.4.dist/systemv/lpstat.c cups-1.5.4/systemv/lpstat.c
--- cups-1.5.4.dist/systemv/lpstat.c 2011-10-07 23:41:07.000000000 +0200
+++ cups-1.5.4/systemv/lpstat.c 2014-03-09 13:21:20.133685662 +0100
@@ -744,7 +744,7 @@
if (match_list(printers, printer))
{
pdate = localtime(&ptime);
- strftime(printer_state_time, sizeof(printer_state_time), "%c", pdate);
+ _cupsstrftime(printer_state_time, sizeof(printer_state_time), "%c", pdate);
if (accepting)
_cupsLangPrintf(stdout, _("%s accepting requests since %s"),
@@ -1436,7 +1436,7 @@
* Show the consolidated output format for the SGI tools...
*/
- if (!strftime(date, sizeof(date), "%b %d %H:%M", jobdate))
+ if (!_cupsstrftime(date, sizeof(date), "%b %d %H:%M", jobdate))
strcpy(date, "Unknown");
_cupsLangPrintf(stdout, "%s;%s;%d;%s;%s",
@@ -1445,7 +1445,7 @@
}
else
{
- if (!strftime(date, sizeof(date), "%c", jobdate))
+ if (!_cupsstrftime(date, sizeof(date), "%c", jobdate))
strcpy(date, "Unknown");
if (ranking)
@@ -1764,7 +1764,7 @@
*/
pdate = localtime(&ptime);
- strftime(printer_state_time, sizeof(printer_state_time), "%c", pdate);
+ _cupsstrftime(printer_state_time, sizeof(printer_state_time), "%c", pdate);
switch (pstate)
{
--- cups-1.5.4.dist/test/run-stp-tests.sh 2014-03-12 08:35:30.805162912 +0100
+++ cups-1.5.4/test/run-stp-tests.sh 2014-03-12 09:45:53.668548631 +0100
@@ -411,6 +411,19 @@
i=`expr $i + 1`
done
+cat >>/tmp/cups-$user/printers.conf <<EOF
+<Printer test5.4>
+Accepting Yes
+DeviceURI file:/dev/null
+Info Test raw printer $i
+JobSheets none none
+Location CUPS test suite
+State Idle
+StateTime 1394607600
+StateMessage Printer $1 is idle.
+</Printer>
+EOF
+
if test -f /tmp/cups-$user/printers.conf; then
cp /tmp/cups-$user/printers.conf /tmp/cups-$user/printers.conf.orig
else
--- cups-1.5.4.dist/test/5.4-lpstat.sh 2014-03-12 08:26:22.738824487 +0100
+++ cups-1.5.4/test/5.4-lpstat.sh 2014-03-12 09:44:43.838713821 +0100
@@ -38,6 +38,30 @@
fi
echo ""
+echo "LPSTAT Test"
+echo ""
+echo " lpstat -p"
+state="`../systemv/lpstat -p test5.4 | head -1 2>&1`"
+if test $? != 0 -o "x$state" != "xprinter test5.4 is idle. enabled since Wed Mar 12 08:00:00 2014"; then
+ echo " FAILED"
+ exit 1
+else
+ echo " PASSED"
+fi
+echo ""
+
+echo "LPSTAT Test2"
+echo ""
+echo " LC_ALL=de_DE@euro lpstat -p"
+state="`LC_ALL=de_DE@euro ../systemv/lpstat -p test5.4 | head -1 2>&1`"
+if test $? != 0 -o "x$state" != "xprinter test5.4 is idle. enabled since Mi 12 Mär 2014 08:00:00 CET"; then
+ echo " FAILED"
+ exit 1
+else
+ echo " PASSED"
+fi
+echo ""
+
#
# End of "$Id: 5.4-lpstat.sh 8498 2009-04-13 17:03:15Z mike $".
#

View File

@ -1,9 +1,12 @@
--- conf/cupsd.conf.in.orig 2014-01-29 14:31:32.000000000 +0100
+++ conf/cupsd.conf.in 2014-01-29 15:20:30.000000000 +0100
@@ -136,6 +136,39 @@ WebInterface @CUPS_WEBIF@
Index: conf/cupsd.conf.in
===================================================================
--- conf/cupsd.conf.in.orig
+++ conf/cupsd.conf.in
@@ -127,3 +127,36 @@ WebInterface @CUPS_WEBIF@
Order deny,allow
</Limit>
</Policy>
+
+# The policy below is added by SUSE during build of our cups package.
+# The policy 'allowallforanybody' is totally open and insecure and therefore
+# it can only be used within an internal network where only trused users exist
@ -14,7 +17,7 @@
+# print jobs from an internal network to any external destination, see
+# http://en.opensuse.org/SDB:CUPS_in_a_Nutshell
+# For documentation regarding 'Managing Operation Policies' see
+# http://www.cups.org/documentation.php/doc-1.5/policies.html
+# http://www.cups.org/documentation.php/doc-1.7/policies.html
+<Policy allowallforanybody>
+ # Allow anybody to access job's private values:
+ JobPrivateAccess all
@ -36,7 +39,3 @@
+</Policy>
+# Explicitly set the CUPS 'default' policy to be used by default:
+DefaultPolicy default
+
#
# End of "$Id: cupsd.conf.in 9407 2010-12-09 21:24:51Z mike $".
#

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:858720f76b66fd0441ae2a16f7cabd9554c8c64607e28ffacf16c36c53a3b18b
size 8766982

View File

@ -1,77 +1,28 @@
# Sample client configuration file for the Common UNIX Printing System
# (CUPS).
#
# Copyright 1997-2005 by Easy Software Products, all rights reserved.
# Klaus Singvogel <kssingvo@suse.de> modified it for SUSE distribution.
#
# These coded instructions, statements, and computer programs are the
# property of Easy Software Products and are protected by Federal
# copyright law. Distribution and use rights are outlined in the file
# "LICENSE.txt" which should have been included with this file. If this
# file is missing or damaged please contact Easy Software Products
# at:
#
# Attn: CUPS Licensing Information
# Easy Software Products
# 44141 Airport View Drive, Suite 204
# Hollywood, Maryland 20636 USA
#
# Voice: (301) 373-9600
# EMail: cups-info@cups.org
# WWW: http://www.cups.org
#
# CUPS client configuration file (optional).
########################################################################
# #
# This is the CUPS client configuration file. This file is used to #
# define client-specific parameters, such as the default server or #
# default encryption settings. #
# #
# Put this file on /etc/cups/client.conf (system use) or #
# ~/.cups/client.conf (personal use). #
# #
# more information in the manual page client.conf(5)
########################################################################
# You may use /etc/cups/client.conf (system wide)
# or ~/.cups/client.conf (per user).
# For more information see "man 5 client.conf".
#
# Encryption: directive specifies the default encryption settings for
# the client.
#
# Possible values:
#
# IfRequested
# Never
# Required
# Always
#
# The default value is "IfRequested".
# This parameter can also be set # using the CUPS_ENCRYPTION environment
# variable.
#
# The ServerName directive specifies the remote server
# that is to be used for all client operations. That is, it
# redirects all client requests directly to that remote server
# so that a local running cupsd is not used in this case.
# The default is to use the local server ("localhost") or domain socket.
# Only one ServerName directive may appear.
# If multiple names are present, only the last one is used.
# The default port number is 631 but can be overridden by adding
# a colon followed by the desired port number.
# The default IPP version is 2.0 but can be overridden by adding
# a slash followed by version=V where V is 1.0 or 1.1 or 2.0 or 2.1 or 2.2.
# IPP version 2.0 does do not work with CUPS 1.3 or older servers.
# If an CUPS 1.3 or older server is used, its older IPP version
# must be specified as .../version=1.1 or .../version=1.0.
#Encryption IfRequested
#Encryption Never
#Encryption Required
#Encryption Always
# Examples:
# ServerName sever.example.com
# ServerName 192.0.2.10
# ServerName sever.example.com:8631
# ServerName older.server.example.com/version=1.1
# ServerName older.server.example.com:8631/version=1.1
#
# ServerName: directive specifies sets the remote server that is to be
# used for all client operations. That is, it redirects all client
# requests to the remote server.
#
# By default CUPS will use the domain socket /var/run/cups/cups.sock or
# local server ("localhost"), if so configured. The value can be
# overwritten by the CUPS_SERVER environment variable.
#
# The default port number is 631 but can be overridden by adding a colon
# followed by the desired port number to the value.
#
# ONLY ONE SERVER NAME MAY BE SPECIFIED AT A TIME. To use more than one
# server you must use a local scheduler with browsing and possibly
# polling.
#
#ServerName /domain/socket
#ServerName foo.bar.com
#ServerName 11.22.33.444
#ServerName foo.bar.com:8631

View File

@ -1,13 +1,11 @@
--- cups-config.in.orig
+++ cups-config.in
@@ -35,8 +35,8 @@ INSTALLSTATIC=@INSTALLSTATIC@
--- cups-config.in.orig 2011-08-27 11:23:01.000000000 +0200
+++ cups-config.in 2012-11-27 15:47:27.000000000 +0100
@@ -35,7 +35,7 @@ INSTALLSTATIC=@INSTALLSTATIC@
# flags for C++ compiler:
CFLAGS=""
LDFLAGS="@EXPORT_LDFLAGS@"
-LIBS="@LIBGSSAPI@ @EXPORT_SSLLIBS@ @EXPORT_LIBZ@ @LIBS@"
-IMGLIBS="@EXPORT_LIBTIFF@ @EXPORT_LIBJPEG@ @EXPORT_LIBPNG@"
-LIBS="@LIBGSSAPI@ @EXPORT_SSLLIBS@ @LIBZ@ @LIBS@"
+LIBS=""
+IMGLIBS=""
# Check for local invocation...
selfdir=`dirname $0`

View File

@ -1,33 +0,0 @@
--- cups-1.5.4.orig/config.h.in
+++ cups-1.5.4/config.h.in
@@ -131,7 +131,7 @@
#define CUPS_SBINDIR "/usr/sbin"
#define CUPS_SERVERBIN "/usr/lib/cups"
#define CUPS_SERVERROOT "/etc/cups"
-#define CUPS_STATEDIR "/var/run/cups"
+#define CUPS_STATEDIR "/run/cups"
/*
--- cups-1.5.4.orig/configure
+++ cups-1.5.4/configure
@@ -6424,7 +6424,7 @@ case "$uname" in
;;
*)
# All others
- CUPS_STATEDIR="$localstatedir/run/cups"
+ CUPS_STATEDIR="/run/cups"
;;
esac
cat >>confdefs.h <<_ACEOF
--- cups-1.5.4.orig/config-scripts/cups-directories.m4
+++ cups-1.5.4/config-scripts/cups-directories.m4
@@ -429,7 +429,7 @@ case "$uname" in
;;
*)
# All others
- CUPS_STATEDIR="$localstatedir/run/cups"
+ CUPS_STATEDIR="/run/cups"
;;
esac
AC_DEFINE_UNQUOTED(CUPS_STATEDIR, "$CUPS_STATEDIR")

View File

@ -1,18 +0,0 @@
--- scheduler/cups-polld.c.orig 2012-03-02 19:26:30.000000000 +0100
+++ scheduler/cups-polld.c 2013-07-05 14:33:08.000000000 +0200
@@ -169,10 +169,15 @@ main(int argc, /* I - Number of comm
/*
* Sleep for any remaining time...
+ * but in case of unusual issues (if remain <= 0 or if restart_polling)
+ * sleep interval seconds to avoid any possible busy-loop
+ * see for example https://bugzilla.novell.com/show_bug.cgi?id=828228
*/
if (remain > 0 && !restart_polling)
sleep(remain);
+ else
+ sleep(interval);
}
return (1);

View File

@ -1,11 +0,0 @@
Index: cups-1.5.4/data/cups.service.in
===================================================================
--- cups-1.5.4.orig/data/cups.service.in
+++ cups-1.5.4/data/cups.service.in
@@ -5,5 +5,6 @@ Description=CUPS Printing Service
ExecStart=@sbindir@/cupsd -f
[Install]
+Alias=cupsd.service
Also=cups.socket cups.path
WantedBy=printer.target

60
cups-systemd-socket.patch Normal file
View File

@ -0,0 +1,60 @@
diff -up cups-2.0.2/cups/usersys.c.ustTJg cups-2.0.2/cups/usersys.c
--- cups-2.0.2/cups/usersys.c.ustTJg 2015-02-10 13:40:24.294545077 +0100
+++ cups-2.0.2/cups/usersys.c 2015-02-10 13:46:56.763989233 +0100
@@ -1017,7 +1017,7 @@ cups_finalize_client_conf(
struct stat sockinfo; /* Domain socket information */
if (!stat(CUPS_DEFAULT_DOMAINSOCKET, &sockinfo) &&
- (sockinfo.st_mode & S_IRWXO) == S_IRWXO)
+ (sockinfo.st_mode & (S_IROTH | S_IWOTH)) == (S_IROTH | S_IWOTH))
cups_set_server_name(cc, CUPS_DEFAULT_DOMAINSOCKET);
else
#endif /* CUPS_DEFAULT_DOMAINSOCKET */
diff -up cups-2.0.2/scheduler/main.c.ustTJg cups-2.0.2/scheduler/main.c
--- cups-2.0.2/scheduler/main.c.ustTJg 2015-02-10 13:40:24.121547526 +0100
+++ cups-2.0.2/scheduler/main.c 2015-02-10 13:40:24.295545063 +0100
@@ -658,8 +658,15 @@ main(int argc, /* I - Number of comm
#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
if (OnDemand)
+ {
cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL, "Scheduler started on demand.");
- else
+# ifdef HAVE_SYSTEMD
+ sd_notifyf(0, "READY=1\n"
+ "STATUS=Scheduler is running...\n"
+ "MAINPID=%lu",
+ (unsigned long) getpid());
+# endif /* HAVE_SYSTEMD */
+ } else
#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
if (fg)
cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL, "Scheduler started in foreground.");
diff -up cups-2.0.2/scheduler/org.cups.cupsd.path.in.ustTJg cups-2.0.2/scheduler/org.cups.cupsd.path.in
--- cups-2.0.2/scheduler/org.cups.cupsd.path.in.ustTJg 2014-03-21 15:50:24.000000000 +0100
+++ cups-2.0.2/scheduler/org.cups.cupsd.path.in 2015-02-10 13:40:24.295545063 +0100
@@ -2,7 +2,7 @@
Description=CUPS Scheduler
[Path]
-PathExists=@CUPS_CACHEDIR@/org.cups.cupsd
+PathExistsGlob=@CUPS_REQUESTS@/d*
[Install]
WantedBy=multi-user.target
diff -up cups-2.0.2/scheduler/org.cups.cupsd.service.in.ustTJg cups-2.0.2/scheduler/org.cups.cupsd.service.in
--- cups-2.0.2/scheduler/org.cups.cupsd.service.in.ustTJg 2014-10-21 13:55:01.000000000 +0200
+++ cups-2.0.2/scheduler/org.cups.cupsd.service.in 2015-02-10 13:40:24.296545049 +0100
@@ -1,10 +1,11 @@
[Unit]
Description=CUPS Scheduler
Documentation=man:cupsd(8)
+After=network.target
[Service]
ExecStart=@sbindir@/cupsd -l
-Type=simple
+Type=notify
[Install]
Also=org.cups.cupsd.socket org.cups.cupsd.path

File diff suppressed because it is too large Load Diff

169
cups.init
View File

@ -1,169 +0,0 @@
#! /bin/bash
#
# Copyright (C) 1995-2001 SuSE GmbH Nuernberg, Germany.
# Copyright (C) 2002 SuSE Linux AG, Nuernberg, Germany.
# Copyright (C) 2002--2008 Klaus Singvogel, SUSE / Novell Inc.
# Copyright (C) 2010 Johannes Meixner, SUSE LINUX Products GmbH
#
# Author: Kurt Garloff, 2000
# Klaus Singvogel, 2002--2008
# Johannes Meixner, 2010
#
# /etc/init.d/cups
# and its symbolic link
# /usr/sbin/rccups
#
# System startup script for the CUPS printer daemon
#
### BEGIN INIT INFO
# Provides: cupsd
# Required-Start: $local_fs $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Should-Start: dbus $named $portmap ptal slpd printbill
# Should-Stop: $portmap
# Default-Start: 2 3 5
# Default-Stop: 0 1 6
# Short-Description: CUPS printer daemon
# Description: Start CUPS to provide spooling and printing files
# functionality for local and remote printers. Also required if
# printers are broadcasted ("Browsing") by remote CUPS servers.
### END INIT INFO
# Return values acc. to LSB for all commands but status:
# 0 - success
# 1 - generic or unspecified error
# 2 - invalid or excess argument(s)
# 3 - unimplemented feature (e.g. "reload")
# 4 - insufficient privilege
# 5 - program is not installed
# 6 - program is not configured
# 7 - program is not running
#
# Note that starting an already running service, stopping
# or restarting a not-running service as well as the restart
# with force-reload (in case signalling is not supported) are
# considered a success.
# Source SuSE config, only if exists with size greater zero
test -s /etc/rc.config && . /etc/rc.config
# Shell functions sourced from /etc/rc.status:
# rc_check check and set local and overall rc status
# rc_status check and set local and overall rc status
# rc_status -v ditto but be verbose in local rc status
# rc_status -v -r ditto and clear the local rc status
# rc_failed set local and overall rc status to failed
# rc_failed <num> set local and overall rc status to <num><num>
# rc_reset clear local rc status (overall remains)
# rc_exit exit appropriate to overall rc status
if test -s /etc/rc.status
then . /etc/rc.status
else exit 1
fi
# Reset status of this service:
rc_reset
CUPSD_BIN=/usr/sbin/cupsd
test -x $CUPSD_BIN || exit 5
# Get CUPSD_OPTIONS
test -s /etc/sysconfig/cups && . /etc/sysconfig/cups
# Enforce default umask to avoid problems with wrong file permissions
# for example of /etc/printcap (see Novell/Suse Bugzilla bnc#31567).
umask 022
case "$1" in
start)
echo -n "Starting cupsd"
## Start daemon with startproc(8).
## If this fails the echo return value is set appropriate.
# NOTE: startproc return 0, even if service is
# already running to match LSB spec.
startproc $CUPSD_BIN $CUPSD_OPTIONS
# Remember status and be verbose:
rc_status -v
;;
stop)
echo -n "Shutting down cupsd"
## Stop daemon with killproc(8).
## If this fails the echo return value is set appropriate.
# NOTE: killproc with explicite signal specified
# like "killproc -TERM" sends only SIGTERM and exits
# to match LSB spec. (see Novell/Suse Bugzilla bnc#595796).
# Without explicite signal the default signal SIGTERM is sent
# and afterwards killproc waits by default only up to 5 seconds
# before killproc sends SIGKILL if cupsd has not yet terminated.
# Wait at most 10 seconds until the cupsd does actually no longer run
# so that the cupsd should have sufficient time for its clean up:
killproc -t 10 $CUPSD_BIN
# Remember status and be verbose:
rc_status -v
;;
try-restart)
## Stop the service and if this succeeds (i.e. the
## service was running before), start it again.
## Note: try-restart is not (yet) part of LSB (as of 0.7.5)
$0 status >/dev/null && $0 restart
# Remember status and be quiet:
rc_status
;;
restart)
## Stop the service and regardless of whether it was
## running or not, start it again.
$0 stop
# The above waits at most 10 seconds until the cupsd does actually no longer run
# otherwise "startproc $CUPSD_BIN" would not start a new cupsd
# (see Novell/Suse Bugzilla bnc#622058).
# Start a new cupsd:
$0 start
# Remember status and be quiet:
rc_status
;;
force-reload)
## Signal the daemon to reload its config.
## Most daemons do this on signal 1 (SIGHUP).
## If it does not support it, restart.
if ps -C cupsd -o user | grep -q '^root$'
then echo -n "Reload service cupsd"
killproc -HUP $CUPSD_BIN
rc_status -v
else $0 restart
fi
;;
reload)
## Like force-reload, but if daemon does not support
## signalling, do nothing.
# If it supports signalling:
if ps -C cupsd -o user | grep -q '^root$'
then echo -n "Reload service cupsd"
killproc -HUP $CUPSD_BIN
rc_status -v
else echo -n '"reload" not possible (cupsd does not run as user root) use "restart" instead'
rc_status -s
fi
;;
status)
echo -n "Checking for cupsd: "
## Check status with checkproc(8), if process is running
## checkproc will return with exit status 0.
# Status has a slightly different for the status command:
# 0 - service running
# 1 - service dead, but /var/run/ pid file exists
# 2 - service dead, but /var/lock/ lock file exists
# 3 - service not running
# NOTE: checkproc returns LSB compliant status values.
checkproc $CUPSD_BIN
rc_status -v
;;
probe)
## Optional: Probe for the necessity of a reload,
## give out the argument which is required for a reload.
rc_failed 3
;;
*)
echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload|probe}"
exit 1
;;
esac
rc_exit

825
cups.spec

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +0,0 @@
## Path: System/Printing/CUPS
## Description: Cups options
## Type: string
## Default: cups
## ServiceReload: cups
## ServiceRestart: cups
#
IDENT="cups"
## Type: string
## Default: "CUPS printer daemon"
DESCRIPTIVE="CUPS printer daemon"
## Type: string
## Default: ""
#
# change CUPSD_OPTIONS for arguments of start of cupsd
# e.g. CUPSD_OPTIONS="-c /etc/cups/cupsd.conf"
CUPSD_OPTIONS=""

View File

@ -1,11 +0,0 @@
service printer
{
disable = yes
flags = NAMEINARGS
socket_type = stream
protocol = tcp
wait = no
user = lp
server = /usr/lib/cups/daemon/cups-lpd
server_args = cups-lpd -o document-format=application/octet-stream
}

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d3be50ca7f9dc699b9dfd3cbe1d655b4934547ba2e3ce0c5cc1560844829237e
size 1913

View File

@ -1,72 +0,0 @@
Index: backend/ipp.c
===================================================================
--- backend/ipp.c (revision 10611)
+++ backend/ipp.c (working copy)
@@ -1279,6 +1279,16 @@
}
/*
+ * If the printer only claims to support IPP/1.0, or if the user specifically
+ * included version=1.0 in the URI, then do not try to use Create-Job or
+ * Send-Document. This is another dreaded compatibility hack, but unfortunately
+ * there are enough broken printers out there that we need this for now...
+ */
+
+ if (version == 10)
+ create_job = send_document = 0;
+
+ /*
* Start monitoring the printer in the background...
*/
@@ -1494,10 +1504,9 @@
goto cleanup;
}
}
- else if (ipp_status == IPP_ERROR_JOB_CANCELED)
+ else if (ipp_status == IPP_ERROR_JOB_CANCELED ||
+ ipp_status == IPP_NOT_AUTHORIZED)
goto cleanup;
- else if (ipp_status == IPP_NOT_AUTHORIZED)
- continue;
else
{
/*
@@ -1678,14 +1687,35 @@
ipp_status == IPP_NOT_POSSIBLE ||
ipp_status == IPP_PRINTER_BUSY)
continue;
- else if (ipp_status == IPP_REQUEST_VALUE)
+ else if (ipp_status == IPP_REQUEST_VALUE ||
+ ipp_status == IPP_ERROR_JOB_CANCELED ||
+ ipp_status == IPP_NOT_AUTHORIZED)
{
/*
- * Print file is too large, abort this job...
+ * Print file is too large, job was canceled, or we need new
+ * authentication data...
*/
goto cleanup;
}
+ else if (ipp_status == IPP_NOT_FOUND)
+ {
+ /*
+ * Printer does not actually implement support for Create-Job/
+ * Send-Document, so log the conformance issue and stop the printer.
+ */
+
+ fputs("DEBUG: This printer claims to support Create-Job and "
+ "Send-Document, but those operations failed.\n", stderr);
+ fputs("DEBUG: Add '?version=1.0' to the device URI to use legacy "
+ "compatibility mode.\n", stderr);
+ update_reasons(NULL, "+cups-ipp-conformance-failure-report,"
+ "cups-ipp-missing-send-document");
+
+ ipp_status = IPP_INTERNAL_ERROR; /* Force queue to stop */
+
+ goto cleanup;
+ }
else
copies_remaining --;

View File

@ -1,36 +0,0 @@
Index: scheduler/cups-lpd.c
===================================================================
--- scheduler/cups-lpd.c (revision 11557)
+++ scheduler/cups-lpd.c (revision 11558)
@@ -781,7 +770,8 @@
int fd; /* Temporary file */
FILE *fp; /* File pointer */
char filename[1024]; /* Temporary filename */
- int bytes; /* Bytes received */
+ ssize_t bytes; /* Bytes received */
+ size_t total; /* Total bytes */
char line[256], /* Line from file/stdin */
command, /* Command from line */
*count, /* Number of bytes */
@@ -965,15 +955,15 @@
* Copy the data or control file from the client...
*/
- for (i = atoi(count); i > 0; i -= bytes)
+ for (total = (size_t)strtoll(count, NULL, 10); total > 0; total -= (size_t)bytes)
{
- if (i > sizeof(line))
- bytes = sizeof(line);
+ if (total > sizeof(line))
+ bytes = (ssize_t)sizeof(line);
else
- bytes = i;
+ bytes = (ssize_t)total;
- if ((bytes = fread(line, 1, bytes, stdin)) > 0)
- bytes = write(fd, line, bytes);
+ if ((bytes = (ssize_t)fread(line, 1, (size_t)bytes, stdin)) > 0)
+ bytes = write(fd, line, (size_t)bytes);
if (bytes < 1)
{

View File

@ -1,164 +0,0 @@
--- scheduler/client.c.orig 2014-09-02 11:26:57.000000000 +0200
+++ scheduler/client.c 2014-09-02 12:35:05.000000000 +0200
@@ -3672,51 +3672,72 @@ get_file(cupsd_client_t *con, /* I - C
if ((ptr = strchr(filename, '?')) != NULL)
*ptr = '\0';
/*
* Grab the status for this language; if there isn't a language-specific file
* then fallback to the default one...
*/
- if ((status = stat(filename, filestats)) != 0 && language[0] &&
+ if ((status = lstat(filename, filestats)) != 0 && language[0] &&
strncmp(con->uri, "/icons/", 7) &&
strncmp(con->uri, "/ppd/", 5) &&
strncmp(con->uri, "/rss/", 5) &&
strncmp(con->uri, "/admin/conf/", 12) &&
strncmp(con->uri, "/admin/log/", 11))
{
/*
* Drop the country code...
*/
language[3] = '\0';
snprintf(filename, len, "%s%s%s", DocumentRoot, language, con->uri);
if ((ptr = strchr(filename, '?')) != NULL)
*ptr = '\0';
- if ((status = stat(filename, filestats)) != 0)
+ if ((status = lstat(filename, filestats)) != 0)
{
/*
* Drop the language prefix and try the root directory...
*/
language[0] = '\0';
snprintf(filename, len, "%s%s", DocumentRoot, con->uri);
if ((ptr = strchr(filename, '?')) != NULL)
*ptr = '\0';
- status = stat(filename, filestats);
+ status = lstat(filename, filestats);
}
}
/*
- * If we're found a directory, get the index.html file instead...
+ * If we've found a symlink, 404 the sucker to avoid disclosing information.
+ */
+
+ if (!status && S_ISLNK(filestats->st_mode))
+ {
+ cupsdLogMessage(CUPSD_LOG_INFO, "[Client %d] Symlinks such as \"%s\" are not allowed.", con->http.fd, filename);
+ return (NULL);
+ }
+
+ /*
+ * Similarly, if the file/directory does not have world read permissions, do
+ * not allow access...
+ */
+
+ if (!status && !(filestats->st_mode & S_IROTH))
+ {
+ cupsdLogMessage(CUPSD_LOG_INFO, "[Client %d] Files/directories such as \"%s\" must be world-readable.", con->http.fd, filename);
+ return (NULL);
+ }
+
+ /*
+ * If we've found a directory, get the index.html file instead...
*/
if (!status && S_ISDIR(filestats->st_mode))
{
/*
* Make sure the URI ends with a slash...
*/
@@ -3749,58 +3770,79 @@ get_file(cupsd_client_t *con, /* I - C
if ((ptr = strchr(filename, '?')) != NULL)
*ptr = '\0';
ptr = filename + strlen(filename);
plen = len - (ptr - filename);
strlcpy(ptr, "index.html", plen);
- status = stat(filename, filestats);
+ status = lstat(filename, filestats);
#ifdef HAVE_JAVA
if (status)
{
strlcpy(ptr, "index.class", plen);
- status = stat(filename, filestats);
+ status = lstat(filename, filestats);
}
#endif /* HAVE_JAVA */
#ifdef HAVE_PERL
if (status)
{
strlcpy(ptr, "index.pl", plen);
- status = stat(filename, filestats);
+ status = lstat(filename, filestats);
}
#endif /* HAVE_PERL */
#ifdef HAVE_PHP
if (status)
{
strlcpy(ptr, "index.php", plen);
- status = stat(filename, filestats);
+ status = lstat(filename, filestats);
}
#endif /* HAVE_PHP */
#ifdef HAVE_PYTHON
if (status)
{
strlcpy(ptr, "index.pyc", plen);
- status = stat(filename, filestats);
+ status = lstat(filename, filestats);
}
if (status)
{
strlcpy(ptr, "index.py", plen);
status = stat(filename, filestats);
}
#endif /* HAVE_PYTHON */
}
while (status && language[0]);
+
+ /*
+ * If we've found a symlink, 404 the sucker to avoid disclosing information.
+ */
+
+ if (!status && S_ISLNK(filestats->st_mode))
+ {
+ cupsdLogMessage(CUPSD_LOG_INFO, "[Client %d] Symlinks such as \"%s\" are not allowed.", con->http.fd, filename);
+ return (NULL);
+ }
+
+ /*
+ * Similarly, if the file/directory does not have world read permissions, do
+ * not allow access...
+ */
+
+ if (!status && !(filestats->st_mode & S_IROTH))
+ {
+ cupsdLogMessage(CUPSD_LOG_INFO, "[Client %d] Files/directories such as \"%s\" must be world-readable.", con->http.fd, filename);
+ return (NULL);
+ }
}
cupsdLogMessage(CUPSD_LOG_DEBUG2,
"get_file(con=%p(%d), filestats=%p, filename=%p, len=%d) = "
"%s", con, con->http.fd, filestats, filename, len,
status ? "(null)" : filename);
if (status)