[packages/cups] - up to 2.2.1; FC patches refresh

arekm arekm at pld-linux.org
Tue Nov 8 11:56:58 CET 2016


commit b3b509330e6840e7a1a1b6c08b72cbab040eb5d5
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date:   Tue Nov 8 11:56:47 2016 +0100

    - up to 2.2.1; FC patches refresh

 cups-avahi-address.patch       |   16 +-
 cups-avahi-no-threaded.patch   |  107 ++-
 cups-banners.patch             |   12 +
 cups-dnssd-deviceid.patch      |   38 +
 cups-driverd-timeout.patch     |   21 +
 cups-dymo-deviceid.patch       |   11 +
 cups-eggcups.patch             |  130 +++
 cups-enum-all.patch            |   17 +
 cups-filter-debug.patch        |   32 +
 cups-freebind.patch            |   15 +
 cups-hp-deviceid-oid.patch     |   21 +
 cups-ipp-multifile.patch       |   15 +
 cups-logrotate.patch           |   63 ++
 cups-lspp.patch                | 1997 ++++++++++++++++++++++++++++++++++++++++
 cups-man_pages_linking.patch   |    2 +-
 cups-pid.patch                 |   37 +
 cups-res_init.patch            |   26 +
 cups-ricoh-deviceid-oid.patch  |   21 +
 cups-systemd-socket.patch      |   24 +-
 cups-web-devices-timeout.patch |   19 +
 cups.spec                      |   44 +-
 21 files changed, 2587 insertions(+), 81 deletions(-)
---
diff --git a/cups.spec b/cups.spec
index 3dfd1b9..b8244b9 100644
--- a/cups.spec
+++ b/cups.spec
@@ -10,13 +10,13 @@
 Summary(pl.UTF-8):	Ogólny system druku dla Uniksa
 Summary(pt_BR.UTF-8):	Sistema Unix de Impressão
 Name:		cups
-Version:	2.1.4
-Release:	2
+Version:	2.2.1
+Release:	1
 Epoch:		1
 License:	LGPL v2 (libraries), GPL v2 (the rest)
 Group:		Applications/Printing
-Source0:	https://github.com/apple/cups/archive/release-%{version}.tar.gz
-# Source0-md5:	5a9b778799f3d43f8be9c3b7ac69d012
+Source0:	https://github.com/apple/cups/releases/download/v%{version}/%{name}-%{version}-source.tar.gz
+# Source0-md5:	a94da2a1e9dbdccb4f3836a38a431931
 Source1:	%{name}.init
 Source2:	%{name}.pamd
 Source3:	%{name}.logrotate
@@ -43,6 +43,22 @@ Patch18:	%{name}-final-content-type.patch
 # avahi patches from fedora
 Patch100:	%{name}-avahi-address.patch
 Patch101:	%{name}-avahi-no-threaded.patch
+Patch102:	cups-banners.patch
+Patch103:	cups-pid.patch
+Patch104:	cups-eggcups.patch
+Patch105:	cups-driverd-timeout.patch
+Patch106:	cups-logrotate.patch
+Patch107:	cups-res_init.patch
+Patch108:	cups-filter-debug.patch
+Patch109:	cups-hp-deviceid-oid.patch
+Patch110:	cups-dnssd-deviceid.patch
+Patch111:	cups-ricoh-deviceid-oid.patch
+Patch112:	cups-enum-all.patch
+Patch113:	cups-dymo-deviceid.patch
+Patch114:	cups-freebind.patch
+Patch115:	cups-ipp-multifile.patch
+Patch116:	cups-web-devices-timeout.patch
+Patch117:	cups-lspp.patch
 URL:		http://www.cups.org/
 BuildRequires:	acl-devel
 BuildRequires:	autoconf >= 2.60
@@ -232,7 +248,7 @@ LPD compatibility support for CUPS print server.
 Wsparcie dla LPD w serwerze wydruków CUPS.
 
 %prep
-%setup -q -n %{name}-release-%{version}
+%setup -q
 %patch0 -p1
 %patch2 -p1
 %patch3 -p1
@@ -257,6 +273,23 @@ Wsparcie dla LPD w serwerze wydruków CUPS.
 %patch101 -p1
 %endif
 
+%patch102 -p1
+%patch103 -p1
+%patch104 -p1
+%patch105 -p1
+%patch106 -p1
+%patch107 -p1
+%patch108 -p1
+%patch109 -p1
+%patch110 -p1
+%patch111 -p1
+%patch112 -p1
+%patch113 -p1
+%patch114 -p1
+%patch115 -p1
+%patch116 -p1
+%patch117 -p1
+
 %build
 %{__aclocal} -I config-scripts
 %{__autoconf}
@@ -415,7 +448,6 @@ fi
 %attr(600,root,lp) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/%{name}/snmp.conf
 %attr(640,root,root) %config(noreplace) %verify(not md5 mtime size) /etc/security/blacklist.cups
 %dir %attr(700,root,lp) %{_sysconfdir}/%{name}/ssl
-%dir %{_sysconfdir}/%{name}/interfaces
 %dir %attr(755,root,lp) %{_sysconfdir}/%{name}/ppd
 %attr(640,root,root) %config(noreplace) %verify(not md5 mtime size) /etc/logrotate.d/%{name}
 %attr(755,root,root) %{_bindir}/cupstestppd
diff --git a/cups-avahi-address.patch b/cups-avahi-address.patch
index b731d83..b8090ea 100644
--- a/cups-avahi-address.patch
+++ b/cups-avahi-address.patch
@@ -1,7 +1,7 @@
-diff -up cups-2.0rc1/cups/http-support.c.avahi-address cups-2.0rc1/cups/http-support.c
---- cups-2.0rc1/cups/http-support.c.avahi-address	2014-08-28 17:37:22.000000000 +0200
-+++ cups-2.0rc1/cups/http-support.c	2014-09-12 15:31:45.062950696 +0200
-@@ -2342,7 +2342,7 @@ http_resolve_cb(
+diff -up cups-2.2b2/cups/http-support.c.avahi-address cups-2.2b2/cups/http-support.c
+--- cups-2.2b2/cups/http-support.c.avahi-address	2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/cups/http-support.c	2016-06-27 15:31:34.201361844 +0200
+@@ -2340,7 +2340,7 @@ http_resolve_cb(
      const char             *type,	/* I - Registration type */
      const char             *domain,	/* I - Domain (unused) */
      const char             *hostTarget,	/* I - Hostname */
@@ -10,7 +10,7 @@ diff -up cups-2.0rc1/cups/http-support.c.avahi-address cups-2.0rc1/cups/http-sup
      uint16_t               port,	/* I - Port number */
      AvahiStringList        *txt,	/* I - TXT record */
      AvahiLookupResultFlags flags,	/* I - Lookup flags (unused) */
-@@ -2495,39 +2495,62 @@ http_resolve_cb(
+@@ -2493,39 +2493,62 @@ http_resolve_cb(
      * getting the IP address of the .local name and then do reverse-lookups...
      */
  
@@ -20,7 +20,7 @@ diff -up cups-2.0rc1/cups/http-support.c.avahi-address cups-2.0rc1/cups/http-sup
 +    size_t addrlen;
 +    int error;
  
-     DEBUG_printf(("8http_resolve_cb: Looking up \"%s\".", hostTarget));
+     DEBUG_printf(("5http_resolve_cb: Looking up \"%s\".", hostTarget));
  
 -    snprintf(fqdn, sizeof(fqdn), "%d", ntohs(port));
 -    if ((addrlist = httpAddrGetList(hostTarget, AF_UNSPEC, fqdn)) != NULL)
@@ -54,7 +54,7 @@ diff -up cups-2.0rc1/cups/http-support.c.avahi-address cups-2.0rc1/cups/http-sup
  
 -        if (!error)
 -	{
--	  DEBUG_printf(("8http_resolve_cb: Found \"%s\".", fqdn));
+-	  DEBUG_printf(("5http_resolve_cb: Found \"%s\".", fqdn));
 +	if ((hostptr = fqdn + strlen(fqdn) - 6) <= fqdn ||
 +	    _cups_strcasecmp(hostptr, ".local"))
  
@@ -73,7 +73,7 @@ diff -up cups-2.0rc1/cups/http-support.c.avahi-address cups-2.0rc1/cups/http-sup
 +
  #ifdef DEBUG
 -	else
--	  DEBUG_printf(("8http_resolve_cb: \"%s\" did not resolve: %d",
+-	  DEBUG_printf(("5http_resolve_cb: \"%s\" did not resolve: %d",
 -	                httpAddrString(&(addr->addr), fqdn, sizeof(fqdn)),
 -			error));
 +	DEBUG_printf(("8http_resolve_cb: \"%s\" did not resolve: %d",
diff --git a/cups-avahi-no-threaded.patch b/cups-avahi-no-threaded.patch
index 0a8ea62..f81c71f 100644
--- a/cups-avahi-no-threaded.patch
+++ b/cups-avahi-no-threaded.patch
@@ -1,6 +1,6 @@
-diff -up cups-2.0.2/scheduler/avahi.c.KUoOri cups-2.0.2/scheduler/avahi.c
---- cups-2.0.2/scheduler/avahi.c.KUoOri	2015-02-10 13:47:38.620396709 +0100
-+++ cups-2.0.2/scheduler/avahi.c	2015-02-10 13:47:38.620396709 +0100
+diff -up cups-2.2b2/scheduler/avahi.c.avahi-no-threaded cups-2.2b2/scheduler/avahi.c
+--- cups-2.2b2/scheduler/avahi.c.avahi-no-threaded	2016-06-27 17:55:19.568728958 +0200
++++ cups-2.2b2/scheduler/avahi.c	2016-06-27 17:55:19.568728958 +0200
 @@ -0,0 +1,441 @@
 +/*
 + * "$Id$"
@@ -443,9 +443,9 @@ diff -up cups-2.0.2/scheduler/avahi.c.KUoOri cups-2.0.2/scheduler/avahi.c
 +/*
 + * End of "$Id$".
 + */
-diff -up cups-2.0.2/scheduler/avahi.h.KUoOri cups-2.0.2/scheduler/avahi.h
---- cups-2.0.2/scheduler/avahi.h.KUoOri	2015-02-10 13:47:38.620396709 +0100
-+++ cups-2.0.2/scheduler/avahi.h	2015-02-10 13:47:38.620396709 +0100
+diff -up cups-2.2b2/scheduler/avahi.h.avahi-no-threaded cups-2.2b2/scheduler/avahi.h
+--- cups-2.2b2/scheduler/avahi.h.avahi-no-threaded	2016-06-27 17:55:19.568728958 +0200
++++ cups-2.2b2/scheduler/avahi.h	2016-06-27 17:55:19.568728958 +0200
 @@ -0,0 +1,69 @@
 +/*
 + * "$Id$"
@@ -516,10 +516,10 @@ diff -up cups-2.0.2/scheduler/avahi.h.KUoOri cups-2.0.2/scheduler/avahi.h
 +/*
 + * End of "$Id$".
 + */
-diff -up cups-2.0.2/scheduler/cupsd.h.KUoOri cups-2.0.2/scheduler/cupsd.h
---- cups-2.0.2/scheduler/cupsd.h.KUoOri	2014-03-21 17:42:53.000000000 +0100
-+++ cups-2.0.2/scheduler/cupsd.h	2015-02-10 13:47:38.624396652 +0100
-@@ -119,6 +119,7 @@ extern const char *cups_hstrerror(int);
+diff -up cups-2.2b2/scheduler/cupsd.h.avahi-no-threaded cups-2.2b2/scheduler/cupsd.h
+--- cups-2.2b2/scheduler/cupsd.h.avahi-no-threaded	2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/scheduler/cupsd.h	2016-06-27 17:57:45.476572827 +0200
+@@ -118,6 +118,7 @@ extern const char *cups_hstrerror(int);
  #include "colorman.h"
  #include "conf.h"
  #include "banners.h"
@@ -527,7 +527,7 @@ diff -up cups-2.0.2/scheduler/cupsd.h.KUoOri cups-2.0.2/scheduler/cupsd.h
  #include "dirsvc.h"
  #include "network.h"
  #include "subscriptions.h"
-@@ -139,6 +140,15 @@ extern const char *cups_hstrerror(int);
+@@ -138,6 +139,15 @@ extern const char *cups_hstrerror(int);
  
  typedef void (*cupsd_selfunc_t)(void *data);
  
@@ -543,21 +543,21 @@ diff -up cups-2.0.2/scheduler/cupsd.h.KUoOri cups-2.0.2/scheduler/cupsd.h
  
  /*
   * Globals...
-@@ -163,6 +173,10 @@ VAR int			OnDemand	VALUE(0);
+@@ -162,6 +172,9 @@ VAR int			OnDemand	VALUE(0);
  					/* Launched on demand */
- #endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
+ #endif /* HAVE_ONDEMAND */
  
 +#ifdef HAVE_AVAHI
 +VAR cups_array_t *Timeouts;		/* Timed callbacks for main loop */
 +#endif /* HAVE_AVAHI */
-+
  
  /*
   * Prototypes...
-@@ -226,6 +240,17 @@ extern void		cupsdStopSelect(void);
+@@ -224,3 +237,15 @@ extern void		cupsdStopSelect(void);
+ /* server.c */
  extern void		cupsdStartServer(void);
  extern void		cupsdStopServer(void);
- 
++
 +#ifdef HAVE_AVAHI
 +extern void     cupsdInitTimeouts(void);
 +extern cupsd_timeout_t *cupsdAddTimeout (const struct timeval *tv,
@@ -569,13 +569,11 @@ diff -up cups-2.0.2/scheduler/cupsd.h.KUoOri cups-2.0.2/scheduler/cupsd.h
 +				    const struct timeval *tv);
 +extern void     cupsdRemoveTimeout (cupsd_timeout_t *timeout);
 +#endif /* HAVE_AVAHI */
- 
- /*
-  * End of "$Id: cupsd.h 11717 2014-03-21 16:42:53Z msweet $".
-diff -up cups-2.0.2/scheduler/dirsvc.c.KUoOri cups-2.0.2/scheduler/dirsvc.c
---- cups-2.0.2/scheduler/dirsvc.c.KUoOri	2015-01-30 17:16:12.000000000 +0100
-+++ cups-2.0.2/scheduler/dirsvc.c	2015-02-10 13:50:47.131728120 +0100
-@@ -195,7 +195,7 @@ cupsdStartBrowsing(void)
+\ No newline at end of file
+diff -up cups-2.2b2/scheduler/dirsvc.c.avahi-no-threaded cups-2.2b2/scheduler/dirsvc.c
+--- cups-2.2b2/scheduler/dirsvc.c.avahi-no-threaded	2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/scheduler/dirsvc.c	2016-06-27 17:55:19.569728950 +0200
+@@ -193,7 +193,7 @@ cupsdStartBrowsing(void)
      cupsdUpdateDNSSDName();
  
  #  else /* HAVE_AVAHI */
@@ -584,7 +582,7 @@ diff -up cups-2.0.2/scheduler/dirsvc.c.KUoOri cups-2.0.2/scheduler/dirsvc.c
      {
        cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create DNS-SD thread.");
  
-@@ -206,7 +206,7 @@ cupsdStartBrowsing(void)
+@@ -204,7 +204,7 @@ cupsdStartBrowsing(void)
      {
        int error;			/* Error code, if any */
  
@@ -593,7 +591,7 @@ diff -up cups-2.0.2/scheduler/dirsvc.c.KUoOri cups-2.0.2/scheduler/dirsvc.c
  
        if (DNSSDClient == NULL)
        {
-@@ -217,11 +217,9 @@ cupsdStartBrowsing(void)
+@@ -215,11 +215,9 @@ cupsdStartBrowsing(void)
          if (FatalErrors & CUPSD_FATAL_BROWSE)
  	  cupsdEndProcess(getpid(), 0);
  
@@ -606,7 +604,7 @@ diff -up cups-2.0.2/scheduler/dirsvc.c.KUoOri cups-2.0.2/scheduler/dirsvc.c
      }
  #  endif /* HAVE_DNSSD */
    }
-@@ -608,7 +606,7 @@ dnssdClientCallback(
+@@ -606,7 +604,7 @@ dnssdClientCallback(
  	  * Renew Avahi client...
  	  */
  
@@ -615,7 +613,7 @@ diff -up cups-2.0.2/scheduler/dirsvc.c.KUoOri cups-2.0.2/scheduler/dirsvc.c
  
  	  if (!DNSSDClient)
  	  {
-@@ -672,13 +670,7 @@ dnssdDeregisterInstance(
+@@ -670,13 +668,7 @@ dnssdDeregisterInstance(
    DNSServiceRefDeallocate(*srv);
  
  #  else /* HAVE_AVAHI */
@@ -629,7 +627,7 @@ diff -up cups-2.0.2/scheduler/dirsvc.c.KUoOri cups-2.0.2/scheduler/dirsvc.c
  #  endif /* HAVE_DNSSD */
  
    *srv = NULL;
-@@ -999,16 +991,10 @@ dnssdRegisterInstance(
+@@ -997,16 +989,10 @@ dnssdRegisterInstance(
    (void)commit;
  
  #  else /* HAVE_AVAHI */
@@ -646,7 +644,7 @@ diff -up cups-2.0.2/scheduler/dirsvc.c.KUoOri cups-2.0.2/scheduler/dirsvc.c
      cupsdLogMessage(CUPSD_LOG_WARN, "DNS-SD registration of \"%s\" failed: %s",
                      name, dnssdErrorString(avahi_client_errno(DNSSDClient)));
      return (0);
-@@ -1123,9 +1109,6 @@ dnssdRegisterInstance(
+@@ -1121,9 +1107,6 @@ dnssdRegisterInstance(
        cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD commit of \"%s\" failed.",
                        name);
    }
@@ -656,7 +654,7 @@ diff -up cups-2.0.2/scheduler/dirsvc.c.KUoOri cups-2.0.2/scheduler/dirsvc.c
  #  endif /* HAVE_DNSSD */
  
    if (error)
-@@ -1296,9 +1279,6 @@ dnssdStop(void)
+@@ -1294,9 +1277,6 @@ dnssdStop(void)
    DNSSDMaster = NULL;
  
  #  else /* HAVE_AVAHI */
@@ -666,7 +664,7 @@ diff -up cups-2.0.2/scheduler/dirsvc.c.KUoOri cups-2.0.2/scheduler/dirsvc.c
    if (DNSSDClient)
    {
      avahi_client_free(DNSSDClient);
-@@ -1307,7 +1287,7 @@ dnssdStop(void)
+@@ -1305,7 +1285,7 @@ dnssdStop(void)
  
    if (DNSSDMaster)
    {
@@ -675,10 +673,10 @@ diff -up cups-2.0.2/scheduler/dirsvc.c.KUoOri cups-2.0.2/scheduler/dirsvc.c
      DNSSDMaster = NULL;
    }
  #  endif /* HAVE_DNSSD */
-diff -up cups-2.0.2/scheduler/dirsvc.h.KUoOri cups-2.0.2/scheduler/dirsvc.h
---- cups-2.0.2/scheduler/dirsvc.h.KUoOri	2013-05-29 13:51:34.000000000 +0200
-+++ cups-2.0.2/scheduler/dirsvc.h	2015-02-10 13:47:38.640396426 +0100
-@@ -51,7 +51,7 @@ VAR cups_array_t	*DNSSDPrinters	VALUE(NU
+diff -up cups-2.2b2/scheduler/dirsvc.h.avahi-no-threaded cups-2.2b2/scheduler/dirsvc.h
+--- cups-2.2b2/scheduler/dirsvc.h.avahi-no-threaded	2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/scheduler/dirsvc.h	2016-06-27 17:55:19.569728950 +0200
+@@ -49,7 +49,7 @@ VAR cups_array_t	*DNSSDPrinters	VALUE(NU
  VAR DNSServiceRef	DNSSDMaster	VALUE(NULL);
  					/* Master DNS-SD service reference */
  #  else /* HAVE_AVAHI */
@@ -687,21 +685,22 @@ diff -up cups-2.0.2/scheduler/dirsvc.h.KUoOri cups-2.0.2/scheduler/dirsvc.h
  					/* Master polling interface for Avahi */
  VAR AvahiClient		*DNSSDClient	VALUE(NULL);
  					/* Client information */
-diff -up cups-2.0.2/scheduler/main.c.KUoOri cups-2.0.2/scheduler/main.c
---- cups-2.0.2/scheduler/main.c.KUoOri	2015-02-10 13:40:24.295545063 +0100
-+++ cups-2.0.2/scheduler/main.c	2015-02-10 13:47:38.641396412 +0100
-@@ -129,6 +129,10 @@ main(int  argc,				/* I - Number of comm
+diff -up cups-2.2b2/scheduler/main.c.avahi-no-threaded cups-2.2b2/scheduler/main.c
+--- cups-2.2b2/scheduler/main.c.avahi-no-threaded	2016-06-27 17:55:19.555729061 +0200
++++ cups-2.2b2/scheduler/main.c	2016-06-27 17:58:44.350106330 +0200
+@@ -131,7 +131,10 @@ main(int  argc,				/* I - Number of comm
    int			service_idle_exit;
  					/* Idle exit on select timeout? */
- #endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
+ #endif /* HAVE_ONDEMAND */
+-
 +#ifdef HAVE_AVAHI
 +  cupsd_timeout_t	*tmo;		/* Next scheduled timed callback */
 +  long			tmo_delay;	/* Time before it must be called */
 +#endif /* HAVE_AVAHI */
  
- 
  #ifdef HAVE_GETEUID
-@@ -577,6 +581,14 @@ main(int  argc,				/* I - Number of comm
+  /*
+@@ -609,6 +612,14 @@ main(int  argc,				/* I - Number of comm
  
    httpInitialize();
  
@@ -716,7 +715,7 @@ diff -up cups-2.0.2/scheduler/main.c.KUoOri cups-2.0.2/scheduler/main.c
    cupsdStartServer();
  
   /*
-@@ -883,6 +895,16 @@ main(int  argc,				/* I - Number of comm
+@@ -930,6 +941,16 @@ main(int  argc,				/* I - Number of comm
      }
  #endif /* __APPLE__ */
  
@@ -733,9 +732,9 @@ diff -up cups-2.0.2/scheduler/main.c.KUoOri cups-2.0.2/scheduler/main.c
  #ifndef __APPLE__
     /*
      * Update the network interfaces once a minute...
-@@ -1574,6 +1596,10 @@ select_timeout(int fds)			/* I - Number
+@@ -1620,6 +1641,10 @@ select_timeout(int fds)			/* I - Number
+   cupsd_client_t	*con;		/* Client information */
    cupsd_job_t		*job;		/* Job information */
-   cupsd_subscription_t	*sub;		/* Subscription information */
    const char		*why;		/* Debugging aid */
 +#ifdef HAVE_AVAHI
 +  cupsd_timeout_t	*tmo;		/* Timed callback */
@@ -744,7 +743,7 @@ diff -up cups-2.0.2/scheduler/main.c.KUoOri cups-2.0.2/scheduler/main.c
  
  
    cupsdLogMessage(CUPSD_LOG_DEBUG2, "select_timeout: JobHistoryUpdate=%ld",
-@@ -1619,6 +1645,19 @@ select_timeout(int fds)			/* I - Number
+@@ -1665,6 +1690,19 @@ select_timeout(int fds)			/* I - Number
    }
  #endif /* __APPLE__ */
  
@@ -764,10 +763,10 @@ diff -up cups-2.0.2/scheduler/main.c.KUoOri cups-2.0.2/scheduler/main.c
   /*
    * Check whether we are accepting new connections...
    */
-diff -up cups-2.0.2/scheduler/Makefile.KUoOri cups-2.0.2/scheduler/Makefile
---- cups-2.0.2/scheduler/Makefile.KUoOri	2014-10-21 13:55:01.000000000 +0200
-+++ cups-2.0.2/scheduler/Makefile	2015-02-10 13:47:38.646396341 +0100
-@@ -17,6 +17,7 @@ include ../Makedefs
+diff -up cups-2.2b2/scheduler/Makefile.avahi-no-threaded cups-2.2b2/scheduler/Makefile
+--- cups-2.2b2/scheduler/Makefile.avahi-no-threaded	2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/scheduler/Makefile	2016-06-27 17:55:19.569728950 +0200
+@@ -15,6 +15,7 @@ include ../Makedefs
  
  CUPSDOBJS =	\
  		auth.o \
@@ -775,7 +774,7 @@ diff -up cups-2.0.2/scheduler/Makefile.KUoOri cups-2.0.2/scheduler/Makefile
  		banners.o \
  		cert.o \
  		classes.o \
-@@ -40,7 +41,8 @@ CUPSDOBJS =	\
+@@ -38,7 +39,8 @@ CUPSDOBJS =	\
  		server.o \
  		statbuf.o \
  		subscriptions.o \
@@ -785,9 +784,9 @@ diff -up cups-2.0.2/scheduler/Makefile.KUoOri cups-2.0.2/scheduler/Makefile
  LIBOBJS =	\
  		filter.o \
  		mime.o \
-diff -up cups-2.0.2/scheduler/timeout.c.KUoOri cups-2.0.2/scheduler/timeout.c
---- cups-2.0.2/scheduler/timeout.c.KUoOri	2015-02-10 13:47:38.646396341 +0100
-+++ cups-2.0.2/scheduler/timeout.c	2015-02-10 13:47:38.646396341 +0100
+diff -up cups-2.2b2/scheduler/timeout.c.avahi-no-threaded cups-2.2b2/scheduler/timeout.c
+--- cups-2.2b2/scheduler/timeout.c.avahi-no-threaded	2016-06-27 17:55:19.569728950 +0200
++++ cups-2.2b2/scheduler/timeout.c	2016-06-27 17:55:19.569728950 +0200
 @@ -0,0 +1,235 @@
 +/*
 + * "$Id$"
diff --git a/cups-banners.patch b/cups-banners.patch
new file mode 100644
index 0000000..aa19282
--- /dev/null
+++ b/cups-banners.patch
@@ -0,0 +1,12 @@
+diff -up cups-1.5b1/scheduler/banners.c.banners cups-1.5b1/scheduler/banners.c
+--- cups-1.5b1/scheduler/banners.c.banners	2011-05-20 05:49:49.000000000 +0200
++++ cups-1.5b1/scheduler/banners.c	2011-05-23 17:35:30.000000000 +0200
+@@ -110,6 +110,8 @@ cupsdLoadBanners(const char *d)		/* I - 
+     if ((ext = strrchr(dent->filename, '.')) != NULL)
+       if (!strcmp(ext, ".bck") ||
+           !strcmp(ext, ".bak") ||
++          !strcmp(ext, ".rpmnew") ||
++          !strcmp(ext, ".rpmsave") ||
+ 	  !strcmp(ext, ".sav"))
+ 	continue;
+ 
diff --git a/cups-dnssd-deviceid.patch b/cups-dnssd-deviceid.patch
new file mode 100644
index 0000000..7bd2463
--- /dev/null
+++ b/cups-dnssd-deviceid.patch
@@ -0,0 +1,38 @@
+diff -up cups-2.1.4/backend/dnssd.c.dnssd-deviceid cups-2.1.4/backend/dnssd.c
+--- cups-2.1.4/backend/dnssd.c.dnssd-deviceid	2016-06-15 14:36:19.922353606 +0200
++++ cups-2.1.4/backend/dnssd.c	2016-06-15 14:45:45.794966648 +0200
+@@ -1188,15 +1188,22 @@ query_callback(
+   if (device->device_id)
+     free(device->device_id);
+ 
++if (device_id[0])
++{
++  /* Mark this as the real device ID. */
++  ptr = device_id + strlen(device_id);
++  snprintf(ptr, sizeof(device_id) - (ptr - device_id), "FZY:0;");
++}
++
+   if (!device_id[0] && strcmp(model, "Unknown"))
+   {
+     if (make_and_model[0])
+-      snprintf(device_id, sizeof(device_id), "MFG:%s;MDL:%s;",
++      snprintf(device_id, sizeof(device_id), "MFG:%s;MDL:%s;FZY:1;",
+ 	       make_and_model, model);
+     else if (!_cups_strncasecmp(model, "designjet ", 10))
+-      snprintf(device_id, sizeof(device_id), "MFG:HP;MDL:%s;", model + 10);
++      snprintf(device_id, sizeof(device_id), "MFG:HP;MDL:%s;FZY:1;", model + 10);
+     else if (!_cups_strncasecmp(model, "stylus ", 7))
+-      snprintf(device_id, sizeof(device_id), "MFG:EPSON;MDL:%s;", model + 7);
++      snprintf(device_id, sizeof(device_id), "MFG:EPSON;MDL:%s;FZY:1;", model + 7);
+     else if ((ptr = strchr(model, ' ')) != NULL)
+     {
+      /*
+@@ -1206,7 +1213,7 @@ query_callback(
+       memcpy(make_and_model, model, (size_t)(ptr - model));
+       make_and_model[ptr - model] = '\0';
+ 
+-      snprintf(device_id, sizeof(device_id), "MFG:%s;MDL:%s;",
++      snprintf(device_id, sizeof(device_id), "MFG:%s;MDL:%s;FZY:1;",
+ 	       make_and_model, ptr + 1);
+     }
+   }
diff --git a/cups-driverd-timeout.patch b/cups-driverd-timeout.patch
new file mode 100644
index 0000000..b7240a3
--- /dev/null
+++ b/cups-driverd-timeout.patch
@@ -0,0 +1,21 @@
+diff -up cups-1.7b1/scheduler/ipp.c.driverd-timeout cups-1.7b1/scheduler/ipp.c
+--- cups-1.7b1/scheduler/ipp.c.driverd-timeout	2013-04-19 12:24:43.003841810 +0200
++++ cups-1.7b1/scheduler/ipp.c	2013-04-19 12:24:43.204839107 +0200
+@@ -4556,7 +4556,7 @@ copy_model(cupsd_client_t *con,		/* I -
+   close(temppipe[1]);
+ 
+  /*
+-  * Wait up to 30 seconds for the PPD file to be copied...
++  * Wait up to 70 seconds for the PPD file to be copied...
+   */
+ 
+   total = 0;
+@@ -4576,7 +4576,7 @@ copy_model(cupsd_client_t *con,		/* I -
+     FD_SET(temppipe[0], &input);
+     FD_SET(CGIPipes[0], &input);
+ 
+-    timeout.tv_sec  = 30;
++    timeout.tv_sec  = 70;
+     timeout.tv_usec = 0;
+ 
+     if ((i = select(maxfd, &input, NULL, NULL, &timeout)) < 0)
diff --git a/cups-dymo-deviceid.patch b/cups-dymo-deviceid.patch
new file mode 100644
index 0000000..cc2995d
--- /dev/null
+++ b/cups-dymo-deviceid.patch
@@ -0,0 +1,11 @@
+diff -up cups-1.6.2/ppdc/sample.drv.dymo-deviceid cups-1.6.2/ppdc/sample.drv
+--- cups-1.6.2/ppdc/sample.drv.dymo-deviceid	2013-06-18 16:57:02.110662953 +0100
++++ cups-1.6.2/ppdc/sample.drv	2013-06-18 16:58:56.513989117 +0100
+@@ -125,6 +125,7 @@ Version "1.5"
+ {
+   Manufacturer "Dymo"
+   ModelName "Label Printer"
++  Attribute "1284DeviceID" "" "MFG:DYMO;MDL:LabelWriter 400;"
+   Attribute NickName "" "Dymo Label Printer"
+   PCFileName "dymo.ppd"
+   DriverType label
diff --git a/cups-eggcups.patch b/cups-eggcups.patch
new file mode 100644
index 0000000..908f518
--- /dev/null
+++ b/cups-eggcups.patch
@@ -0,0 +1,130 @@
+diff -up cups-2.1b1/backend/ipp.c.eggcups cups-2.1b1/backend/ipp.c
+--- cups-2.1b1/backend/ipp.c.eggcups	2015-05-28 03:19:14.000000000 +0200
++++ cups-2.1b1/backend/ipp.c	2015-06-29 12:56:54.872807227 +0200
+@@ -149,6 +149,70 @@ static char		tmpfilename[1024] = "";
+ static char		mandatory_attrs[1024] = "";
+ 					/* cupsMandatory value */
+ 
++#if HAVE_DBUS
++#include <dbus/dbus.h>
++
++static DBusConnection *dbus_connection = NULL;
++
++static int
++init_dbus (void)
++{
++  DBusConnection *connection;
++  DBusError error;
++
++  if (dbus_connection &&
++      !dbus_connection_get_is_connected (dbus_connection)) {
++    dbus_connection_unref (dbus_connection);
++    dbus_connection = NULL;
++  }
++
++  dbus_error_init (&error);
++  connection = dbus_bus_get (getuid () ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM, &error);
++  if (connection == NULL) {
++    dbus_error_free (&error);
++    return -1;
++  }
++
++  dbus_connection = connection;
++  return 0;
++}
++
++int
++dbus_broadcast_queued_remote (const char *printer_uri,
++			      ipp_status_t status,
++			      unsigned int local_job_id,
++			      unsigned int remote_job_id,
++			      const char *username,
++			      const char *printer_name)
++{
++  DBusMessage *message;
++  DBusMessageIter iter;
++  const char *errstr;
++
++  if (!dbus_connection || !dbus_connection_get_is_connected (dbus_connection)) {
++    if (init_dbus () || !dbus_connection)
++      return -1;
++  }
++
++  errstr = ippErrorString (status);
++  message = dbus_message_new_signal ("/com/redhat/PrinterSpooler",
++				     "com.redhat.PrinterSpooler",
++				     "JobQueuedRemote");
++  dbus_message_iter_init_append (message, &iter);
++  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &printer_uri);
++  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &errstr);
++  dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &local_job_id);
++  dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &remote_job_id);
++  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &username);
++  dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &printer_name);
++
++  dbus_connection_send (dbus_connection, message, NULL);
++  dbus_connection_flush (dbus_connection);
++  dbus_message_unref (message);
++
++  return 0;
++}
++#endif /* HAVE_DBUS */
+ 
+ /*
+  * Local functions...
+@@ -1700,6 +1764,15 @@ main(int  argc,				/* I - Number of comm
+       fprintf(stderr, "DEBUG: Print job accepted - job ID %d.\n", job_id);
+     }
+ 
++#if HAVE_DBUS
++    dbus_broadcast_queued_remote (argv[0],
++				  ipp_status,
++				  atoi (argv[1]),
++				  job_id,
++				  argv[2],
++				  getenv ("PRINTER"));
++#endif /* HAVE_DBUS */
++
+     ippDelete(response);
+ 
+     if (job_canceled)
+diff -up cups-2.1b1/backend/Makefile.eggcups cups-2.1b1/backend/Makefile
+--- cups-2.1b1/backend/Makefile.eggcups	2014-05-09 00:42:44.000000000 +0200
++++ cups-2.1b1/backend/Makefile	2015-06-29 12:54:55.753026774 +0200
+@@ -264,7 +264,7 @@ dnssd:	dnssd.o ../cups/$(LIBCUPS) libbac
+ 
+ ipp:	ipp.o ../cups/$(LIBCUPS) libbackend.a
+ 	echo Linking $@...
+-	$(CC) $(LDFLAGS) -o ipp ipp.o libbackend.a $(LIBS)
++	$(CC) $(LDFLAGS) -o ipp ipp.o libbackend.a $(LIBS) $(SERVERLIBS)
+ 	$(RM) http
+ 	$(LN) ipp http
+ 
+diff -up cups-2.1b1/scheduler/subscriptions.c.eggcups cups-2.1b1/scheduler/subscriptions.c
+--- cups-2.1b1/scheduler/subscriptions.c.eggcups	2014-02-06 19:33:34.000000000 +0100
++++ cups-2.1b1/scheduler/subscriptions.c	2015-06-29 12:54:55.753026774 +0200
+@@ -1293,13 +1293,13 @@ cupsd_send_dbus(cupsd_eventmask_t event,
+     what = "PrinterAdded";
+   else if (event & CUPSD_EVENT_PRINTER_DELETED)
+     what = "PrinterRemoved";
+-  else if (event & CUPSD_EVENT_PRINTER_CHANGED)
+-    what = "QueueChanged";
+   else if (event & CUPSD_EVENT_JOB_CREATED)
+     what = "JobQueuedLocal";
+   else if ((event & CUPSD_EVENT_JOB_STATE) && job &&
+            job->state_value == IPP_JOB_PROCESSING)
+     what = "JobStartedLocal";
++  else if (event & (CUPSD_EVENT_PRINTER_CHANGED|CUPSD_EVENT_JOB_STATE_CHANGED|CUPSD_EVENT_PRINTER_STATE_CHANGED))
++    what = "QueueChanged";
+   else
+     return;
+ 
+@@ -1335,7 +1335,7 @@ cupsd_send_dbus(cupsd_eventmask_t event,
+   dbus_message_append_iter_init(message, &iter);
+   if (dest)
+     dbus_message_iter_append_string(&iter, dest->name);
+-  if (job)
++  if (job && strcmp (what, "QueueChanged") != 0)
+   {
+     dbus_message_iter_append_uint32(&iter, job->id);
+     dbus_message_iter_append_string(&iter, job->username);
diff --git a/cups-enum-all.patch b/cups-enum-all.patch
new file mode 100644
index 0000000..0ac3983
--- /dev/null
+++ b/cups-enum-all.patch
@@ -0,0 +1,17 @@
+diff -up cups-1.6.2/cups/dest.c.enum-all cups-1.6.2/cups/dest.c
+--- cups-1.6.2/cups/dest.c.enum-all	2013-06-04 10:58:36.169786250 +0100
++++ cups-1.6.2/cups/dest.c	2013-06-04 10:59:02.147900811 +0100
+@@ -2724,9 +2724,12 @@ cups_dnssd_browse_cb(
+ 	break;
+ 
+     case AVAHI_BROWSER_REMOVE:
+-    case AVAHI_BROWSER_ALL_FOR_NOW:
+     case AVAHI_BROWSER_CACHE_EXHAUSTED:
+         break;
++
++    case AVAHI_BROWSER_ALL_FOR_NOW:
++	avahi_simple_poll_quit(data->simple_poll);
++        break;
+   }
+ }
+ 
diff --git a/cups-filter-debug.patch b/cups-filter-debug.patch
new file mode 100644
index 0000000..96c82da
--- /dev/null
+++ b/cups-filter-debug.patch
@@ -0,0 +1,32 @@
+diff -up cups-1.6b1/scheduler/job.c.filter-debug cups-1.6b1/scheduler/job.c
+--- cups-1.6b1/scheduler/job.c.filter-debug	2012-05-25 16:06:01.000000000 +0200
++++ cups-1.6b1/scheduler/job.c	2012-05-25 16:07:46.309259511 +0200
+@@ -625,10 +625,28 @@ cupsdContinueJob(cupsd_job_t *job)	/* I
+ 
+     if (!filters)
+     {
++      mime_filter_t *current;
++
+       cupsdLogJob(job, CUPSD_LOG_ERROR,
+ 		  "Unable to convert file %d to printable format.",
+ 		  job->current_file);
+ 
++      cupsdLogJob(job, CUPSD_LOG_ERROR,
++		  "Required: %s/%s -> %s/%s",
++		  job->filetypes[job->current_file]->super,
++		  job->filetypes[job->current_file]->type,
++		  job->printer->filetype->super,
++		  job->printer->filetype->type);
++
++      for (current = (mime_filter_t *)cupsArrayFirst(MimeDatabase->srcs);
++	   current;
++	   current = (mime_filter_t *)cupsArrayNext(MimeDatabase->srcs))
++	  cupsdLogJob(job, CUPSD_LOG_ERROR,
++		      "Available: %s/%s -> %s/%s (%s)",
++		      current->src->super, current->src->type,
++		      current->dst->super, current->dst->type,
++		      current->filter);
++
+       abort_message = "Aborting job because it cannot be printed.";
+       abort_state   = IPP_JOB_ABORTED;
+ 
diff --git a/cups-freebind.patch b/cups-freebind.patch
new file mode 100644
index 0000000..6d9ba43
--- /dev/null
+++ b/cups-freebind.patch
@@ -0,0 +1,15 @@
+diff -up cups-2.0.2/cups/http-addr.c.freebind cups-2.0.2/cups/http-addr.c
+--- cups-2.0.2/cups/http-addr.c.freebind	2015-02-10 14:46:33.000000000 +0100
++++ cups-2.0.2/cups/http-addr.c	2015-02-10 14:50:35.074759141 +0100
+@@ -186,6 +186,10 @@ httpAddrListen(http_addr_t *addr,	/* I -
+   val = 1;
+   setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, CUPS_SOCAST &val, sizeof(val));
+ 
++#ifdef __linux
++  setsockopt(fd, IPPROTO_IP, IP_FREEBIND, CUPS_SOCAST &val, sizeof(val));
++#endif /* __linux */
++
+ #ifdef IPV6_V6ONLY
+   if (addr->addr.sa_family == AF_INET6)
+     setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, CUPS_SOCAST &val, sizeof(val));
+diff -up cups-2.0.2/scheduler/listen.c.freebind cups-2.0.2/scheduler/listen.c
diff --git a/cups-hp-deviceid-oid.patch b/cups-hp-deviceid-oid.patch
new file mode 100644
index 0000000..da5136a
--- /dev/null
+++ b/cups-hp-deviceid-oid.patch
@@ -0,0 +1,21 @@
+diff -up cups-1.5b1/backend/snmp.c.hp-deviceid-oid cups-1.5b1/backend/snmp.c
+--- cups-1.5b1/backend/snmp.c.hp-deviceid-oid	2011-05-20 05:49:49.000000000 +0200
++++ cups-1.5b1/backend/snmp.c	2011-05-24 17:24:48.000000000 +0200
+@@ -187,6 +187,7 @@ static const int	UriOID[] = { CUPS_OID_p
+ static const int	LexmarkProductOID[] = { 1,3,6,1,4,1,641,2,1,2,1,2,1,-1 };
+ static const int	LexmarkProductOID2[] = { 1,3,6,1,4,1,674,10898,100,2,1,2,1,2,1,-1 };
+ static const int	LexmarkDeviceIdOID[] = { 1,3,6,1,4,1,641,2,1,2,1,3,1,-1 };
++static const int	HPDeviceIdOID[] = { 1,3,6,1,4,1,11,2,3,9,1,1,7,0,-1 };
+ static const int	XeroxProductOID[] = { 1,3,6,1,4,1,128,2,1,3,1,2,0,-1 };
+ static cups_array_t	*DeviceURIs = NULL;
+ static int		HostNameLookups = 0;
+@@ -1006,6 +1007,9 @@ read_snmp_response(int fd)		/* I - SNMP 
+ 	_cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1,
+ 	               packet.community, CUPS_ASN1_GET_REQUEST,
+ 		       DEVICE_PRODUCT, XeroxProductOID);
++	_cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1,
++		       packet.community, CUPS_ASN1_GET_REQUEST,
++		       DEVICE_ID, HPDeviceIdOID);
+         break;
+ 
+     case DEVICE_DESCRIPTION :
diff --git a/cups-ipp-multifile.patch b/cups-ipp-multifile.patch
new file mode 100644
index 0000000..beac7fa
--- /dev/null
+++ b/cups-ipp-multifile.patch
@@ -0,0 +1,15 @@
+diff -up cups-1.7.0/backend/ipp.c.ipp-multifile cups-1.7.0/backend/ipp.c
+--- cups-1.7.0/backend/ipp.c.ipp-multifile	2013-10-24 15:52:00.745814354 +0100
++++ cups-1.7.0/backend/ipp.c	2013-10-24 15:53:46.463266724 +0100
+@@ -1758,7 +1758,10 @@ main(int  argc,				/* I - Number of comm
+ 	ippAddBoolean(request, IPP_TAG_OPERATION, "last-document",
+         	      (i + 1) >= num_files);
+ 
+-	if (document_format)
++	if (num_files > 1)
++	  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE,
++		       "document-format", NULL, "application/octet-stream");
++	else if (document_format)
+ 	  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE,
+ 		       "document-format", NULL, document_format);
+ 
diff --git a/cups-logrotate.patch b/cups-logrotate.patch
new file mode 100644
index 0000000..6b8eb8c
--- /dev/null
+++ b/cups-logrotate.patch
@@ -0,0 +1,63 @@
+diff -up cups-2.1b1/scheduler/log.c.logrotate cups-2.1b1/scheduler/log.c
+--- cups-2.1b1/scheduler/log.c.logrotate	2015-06-04 20:00:31.000000000 +0200
++++ cups-2.1b1/scheduler/log.c	2015-06-29 13:25:09.623350218 +0200
+@@ -26,6 +26,9 @@
+ #  include <systemd/sd-journal.h>
+ #endif /* HAVE_ASL_H */
+ #include <syslog.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <unistd.h>
+ 
+ 
+ /*
+@@ -135,12 +138,10 @@ cupsdCheckLogFile(cups_file_t **lf,	/* I
+   }
+ 
+  /*
+-  * Format the filename as needed...
++  * Format the filename...
+   */
+ 
+-  if (!*lf ||
+-      (strncmp(logname, "/dev/", 5) && cupsFileTell(*lf) > MaxLogSize &&
+-       MaxLogSize > 0))
++  if (strncmp(logname, "/dev/", 5))
+   {
+    /*
+     * Handle format strings...
+@@ -254,6 +255,34 @@ cupsdCheckLogFile(cups_file_t **lf,	/* I
+      /*
+       * Change ownership and permissions of non-device logs...
+       */
++
++      fchown(cupsFileNumber(*lf), RunUser, Group);
++      fchmod(cupsFileNumber(*lf), LogFilePerm);
++    }
++  }
++
++ /*
++  * Has someone else (i.e. logrotate) already rotated the log for us?
++  */
++  else if (strncmp(filename, "/dev/", 5))
++  {
++    struct stat st;
++    if (stat(filename, &st) || st.st_size == 0)
++    {
++      /* File is either missing or has zero size. */
++
++      cupsFileClose(*lf);
++      if ((*lf = cupsFileOpen(filename, "a")) == NULL)
++      {
++	syslog(LOG_ERR, "Unable to open log file \"%s\" - %s", filename,
++             strerror(errno));
++
++	return (0);
++      }
++
++     /*
++      * Change ownership and permissions of non-device logs...
++      */
+ 
+       fchown(cupsFileNumber(*lf), RunUser, Group);
+       fchmod(cupsFileNumber(*lf), LogFilePerm);
diff --git a/cups-lspp.patch b/cups-lspp.patch
new file mode 100644
index 0000000..93a3a49
--- /dev/null
+++ b/cups-lspp.patch
@@ -0,0 +1,1997 @@
+diff -up cups-2.2b2/config.h.in.lspp cups-2.2b2/config.h.in
+--- cups-2.2b2/config.h.in.lspp	2016-06-27 17:39:48.075973879 +0200
++++ cups-2.2b2/config.h.in	2016-06-27 17:47:31.376356684 +0200
+@@ -737,4 +737,11 @@ static __inline int _cups_abs(int i) { r
+ #  endif /* __GNUC__ || __STDC_VERSION__ */
+ #endif /* !HAVE_ABS && !abs */
+ 
++/*
++ * Are we trying to meet LSPP requirements?
++ */
++
++#undef WITH_LSPP
++
++
+ #endif /* !_CUPS_CONFIG_H_ */
+diff -up cups-2.2b2/config-scripts/cups-lspp.m4.lspp cups-2.2b2/config-scripts/cups-lspp.m4
+--- cups-2.2b2/config-scripts/cups-lspp.m4.lspp	2016-06-27 17:39:48.076973871 +0200
++++ cups-2.2b2/config-scripts/cups-lspp.m4	2016-06-27 17:39:48.076973871 +0200
+@@ -0,0 +1,36 @@
++dnl
++dnl   LSPP code for the Common UNIX Printing System (CUPS).
++dnl
++dnl   Copyright 2005-2006 by Hewlett-Packard Development Company, L.P.
++dnl
++dnl   This program is free software; you can redistribute it and/or modify
++dnl   it under the terms of the GNU General Public License as published by
++dnl   the Free Software Foundation; version 2.
++dnl
++dnl   This program is distributed in the hope that it will be useful, but
++dnl   WITHOUT ANY WARRANTY; without even the implied warranty of
++dnl   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++dnl   General Public License for more details.
++dnl
++dnl   You should have received a copy of the GNU General Public License
++dnl   along with this program; if not, write to the Free Software Foundation,
++dnl   Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301 USA
++dnl
++
++dnl Are we trying to meet LSPP requirements
++AC_ARG_ENABLE(lspp, [  --enable-lspp           turn on auditing and label support, default=no])
++
++if test x"$enable_lspp" != xno; then
++    case "$uname" in
++        Linux)
++            AC_CHECK_LIB(audit,audit_log_user_message, [LIBAUDIT="-laudit" AC_SUBST(LIBAUDIT)])
++            AC_CHECK_HEADER(libaudit.h)
++            AC_CHECK_LIB(selinux,getpeercon, [LIBSELINUX="-lselinux" AC_SUBST(LIBSELINUX)])
++            AC_CHECK_HEADER(selinux/selinux.h)
++            AC_DEFINE(WITH_LSPP)
++            ;;
++        *)
++            # All others
++            ;;
++    esac
++fi
+diff -up cups-2.2b2/configure.ac.lspp cups-2.2b2/configure.ac
+--- cups-2.2b2/configure.ac.lspp	2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/configure.ac	2016-06-27 17:39:48.076973871 +0200
+@@ -38,6 +38,8 @@ sinclude(config-scripts/cups-startup.m4)
+ sinclude(config-scripts/cups-defaults.m4)
+ sinclude(config-scripts/cups-scripting.m4)
+ 
++sinclude(config-scripts/cups-lspp.m4)
++
+ INSTALL_LANGUAGES=""
+ UNINSTALL_LANGUAGES=""
+ LANGFILES=""
+diff -up cups-2.2b2/filter/common.c.lspp cups-2.2b2/filter/common.c
+--- cups-2.2b2/filter/common.c.lspp	2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/filter/common.c	2016-06-27 17:39:48.076973871 +0200
+@@ -17,6 +17,12 @@
+  * Include necessary headers...
+  */
+ 
++#include "config.h"
++#ifdef WITH_LSPP
++#define _GNU_SOURCE
++#include <string.h>
++#endif /* WITH_LSPP */
++
+ #include "common.h"
+ #include <locale.h>
+ 
+@@ -299,6 +305,18 @@ WriteLabelProlog(const char *label,	/* I
+ {
+   const char	*classification;	/* CLASSIFICATION environment variable */
+   const char	*ptr;			/* Temporary string pointer */
++#ifdef WITH_LSPP
++  int           i,                      /* counter */
++                n,                      /* counter */
++                lines,                  /* number of lines needed */
++                line_len,               /* index into tmp_label */
++                label_len,              /* length of the label in characters */
++                label_index,            /* index into the label */
++                longest,                /* length of the longest line */
++                longest_line,           /* index to the longest line */
++                max_width;              /* maximum width in characters */
++  char          **wrapped_label;        /* label with line breaks */
++#endif /* WITH_LSPP */
+ 
+ 
+  /*
+@@ -321,6 +339,124 @@ WriteLabelProlog(const char *label,	/* I
+     return;
+   }
+ 
++#ifdef WITH_LSPP
++  if (strncmp(classification, "LSPP:", 5) == 0 && label == NULL)
++  {
++   /*
++    * Based on the 12pt fixed width font below determine the max_width
++    */
++    max_width = width / 8;
++    longest_line = 0;
++    longest = 0;
++    classification += 5; // Skip the "LSPP:"
++    label_len = strlen(classification);
++
++    if (label_len > max_width)
++    {
++      lines = 1 + (int)(label_len / max_width);
++      line_len = (int)(label_len / lines);
++      wrapped_label = malloc(sizeof(*wrapped_label) * lines);
++      label_index = i = n = 0;
++      while (classification[label_index])
++      {
++        if ((label_index + line_len) > label_len)
++          break;
++        switch (classification[label_index + line_len + i])
++        {
++          case ':':
++          case ',':
++          case '-':
++            i++;
++            wrapped_label[n++] = strndup(&classification[label_index], (line_len + i));
++            label_index += line_len + i;
++            i = 0;
++            break;
++          default:
++            i++;
++            break;
++        }
++        if ((i + line_len) == max_width)
++        {
++          wrapped_label[n++] = strndup(&(classification[label_index]), (line_len + i));
++          label_index = label_index + line_len + i;
++          i = 0;
++        }
++      }
++      wrapped_label[n] = strndup(&classification[label_index], label_len - label_index);
++    }
++    else
++    {
++      lines = 1;
++      wrapped_label = malloc(sizeof(*wrapped_label));
++      wrapped_label[0] = (char*)classification;
++    }
++
++    for (n = 0; n < lines; n++ )
++    {
++      printf("userdict/ESPp%c(", ('a' + n));
++      for (ptr = wrapped_label[n], i = 0; *ptr; ptr ++, i++)
++        if (*ptr < 32 || *ptr > 126)
++          printf("\\%03o", *ptr);
++        else
++        {
++          if (*ptr == '(' || *ptr == ')' || *ptr == '\\')
++            putchar('\\');
++
++          printf("%c", *ptr);
++        }
++      if (i > longest)
++      {
++        longest = i;
++        longest_line = n;
++      }
++      printf(")put\n");
++    }
++
++   /*
++    * For LSPP use a fixed width font so that line wrapping can be calculated
++    */
++
++    puts("userdict/ESPlf /Nimbus-Mono findfont 12 scalefont put");
++
++   /*
++    * Finally, the procedure to write the labels on the page...
++    */
++
++    printf("userdict/ESPwl{\n"
++           "  ESPlf setfont\n");
++    printf("  ESPp%c stringwidth pop dup 12 add exch -0.5 mul %.0f add\n ",
++           'a' + longest_line, width * 0.5f);
++    for (n = 1; n < lines; n++)
++      printf(" dup");
++    printf("\n  1 setgray\n");
++    printf("  dup 6 sub %.0f %d index %.0f ESPrf\n",
++           (bottom - 2.0), (2 + lines), 6.0 + (16.0 * lines));
++    printf("  dup 6 sub %.0f %d index %.0f ESPrf\n",
++           (top - 6.0 - (16.0 * lines)), (2 + lines), 4.0 + (16.0 * lines));
++    printf("  0 setgray\n");
++    printf("  dup 6 sub %.0f %d index %.0f ESPrs\n",
++           (bottom - 2.0), (2 + lines), 6.0 + (16.0 * lines));
++    printf("  dup 6 sub %.0f %d index %.0f ESPrs\n",
++           (top - 6.0 - (16.0 * lines)), (2 + lines), 4.0 + (16.0 * lines));
++    for (n = 0; n < lines; n ++)
++    {
++      printf("  dup %.0f moveto ESPp%c show\n",
++             bottom + 6.0 + ((lines - (n+1)) * 16.0), 'a' + n);
++      printf("  %.0f moveto ESPp%c show\n", top + 2.0 - ((n + 1) * 16.0), 'a' + n);
++    }
++    printf("  pop\n"
++           "}bind put\n");
++
++   /*
++    * Do some clean up at the end of the LSPP special case
++    */
++    free(wrapped_label);
++
++  }
++  else
++  {
++#endif /* !WITH_LSPP */
++  
+  /*
+   * Set the classification + page label string...
+   */
+@@ -401,7 +537,10 @@ WriteLabelProlog(const char *label,	/* I
+   printf("  %.0f moveto ESPpl show\n", top - 14.0);
+   puts("pop");
+   puts("}bind put");
++  }
++#ifdef WITH_LSPP
+ }
++#endif /* WITH_LSPP */
+ 
+ 
+ /*
+diff -up cups-2.2b2/filter/pstops.c.lspp cups-2.2b2/filter/pstops.c
+--- cups-2.2b2/filter/pstops.c.lspp	2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/filter/pstops.c	2016-06-27 17:39:48.077973863 +0200
+@@ -3176,6 +3176,18 @@ write_label_prolog(pstops_doc_t *doc,	/*
+ {
+   const char	*classification;	/* CLASSIFICATION environment variable */
+   const char	*ptr;			/* Temporary string pointer */
++#ifdef WITH_LSPP
++  int           i,                      /* counter */
++                n,                      /* counter */
++                lines,                  /* number of lines needed */
++                line_len,               /* index into tmp_label */
++                label_len,              /* length of the label in characters */
++                label_index,            /* index into the label */
++                longest,                /* length of the longest line */
++                longest_line,           /* index to the longest line */
++                max_width;              /* maximum width in characters */
++  char          **wrapped_label;        /* label with line breaks */
++#endif /* WITH_LSPP */
+ 
+ 
+  /*
+@@ -3198,6 +3210,124 @@ write_label_prolog(pstops_doc_t *doc,	/*
+     return;
+   }
+ 
++#ifdef WITH_LSPP
++  if (strncmp(classification, "LSPP:", 5) == 0 && label == NULL)
++  {
++   /*
++    * Based on the 12pt fixed width font below determine the max_width
++    */
++    max_width = width / 8;
++    longest_line = 0;
++    longest = 0;
++    classification += 5; // Skip the "LSPP:"
++    label_len = strlen(classification);
++
++    if (label_len > max_width)
++    {
++      lines = 1 + (int)(label_len / max_width);
++      line_len = (int)(label_len / lines);
++      wrapped_label = malloc(sizeof(*wrapped_label) * lines);
++      label_index = i = n = 0;
++      while (classification[label_index])
++      {
++        if ((label_index + line_len) > label_len)
++          break;
++        switch (classification[label_index + line_len + i])
++        {
++          case ':':
++          case ',':
++          case '-':
++            i++;
++            wrapped_label[n++] = strndup(&classification[label_index], (line_len + i));
++            label_index += line_len + i;
++            i = 0;
++            break;
++          default:
++            i++;
++            break;
++        }
++        if ((i + line_len) == max_width)
++        {
++          wrapped_label[n++] = strndup(&(classification[label_index]), (line_len + i));
++          label_index = label_index + line_len + i;
++          i = 0;
++        }
++      }
++      wrapped_label[n] = strndup(&classification[label_index], label_len - label_index);
++    }
++    else
++    {
++      lines = 1;
++      wrapped_label = malloc(sizeof(*wrapped_label));
++      wrapped_label[0] = (char*)classification;
++    }
++
++    for (n = 0; n < lines; n++ )
++    {
++      printf("userdict/ESPp%c(", ('a' + n));
++      for (ptr = wrapped_label[n], i = 0; *ptr; ptr ++, i++)
++        if (*ptr < 32 || *ptr > 126)
++          printf("\\%03o", *ptr);
++        else
++        {
++          if (*ptr == '(' || *ptr == ')' || *ptr == '\\')
++            putchar('\\');
++
++          printf("%c", *ptr);
++        }
++      if (i > longest)
++      {
++        longest = i;
++        longest_line = n;
++      }
++      printf(")put\n");
++    }
++
++   /*
++    * For LSPP use a fixed width font so that line wrapping can be calculated
++    */
++
++    puts("userdict/ESPlf /Nimbus-Mono findfont 12 scalefont put");
++
++   /*
++    * Finally, the procedure to write the labels on the page...
++    */
++
++    printf("userdict/ESPwl{\n"
++           "  ESPlf setfont\n");
++    printf("  ESPp%c stringwidth pop dup 12 add exch -0.5 mul %.0f add\n ",
++           'a' + longest_line, width * 0.5f);
++    for (n = 1; n < lines; n++)
++      printf(" dup");
++    printf("\n  1 setgray\n");
++    printf("  dup 6 sub %.0f %d index %.0f ESPrf\n",
++           (bottom - 2.0), (2 + lines), 6.0 + (16.0 * lines));
++    printf("  dup 6 sub %.0f %d index %.0f ESPrf\n",
++           (top - 6.0 - (16.0 * lines)), (2 + lines), 4.0 + (16.0 * lines));
++    printf("  0 setgray\n");
++    printf("  dup 6 sub %.0f %d index %.0f ESPrs\n",
++           (bottom - 2.0), (2 + lines), 6.0 + (16.0 * lines));
++    printf("  dup 6 sub %.0f %d index %.0f ESPrs\n",
++           (top - 6.0 - (16.0 * lines)), (2 + lines), 4.0 + (16.0 * lines));
++    for (n = 0; n < lines; n ++)
++    {
++      printf("  dup %.0f moveto ESPp%c show\n",
++             bottom + 6.0 + ((lines - (n+1)) * 16.0), 'a' + n);
++      printf("  %.0f moveto ESPp%c show\n", top + 2.0 - ((n + 1) * 16.0), 'a' + n);
++    }
++    printf("  pop\n"
++           "}bind put\n");
++
++   /*
++    * Do some clean up at the end of the LSPP special case
++    */
++    free(wrapped_label);
++
++  }
++  else
++  {
++#endif /* !WITH_LSPP */
++
+  /*
+   * Set the classification + page label string...
+   */
+@@ -3276,7 +3406,10 @@ write_label_prolog(pstops_doc_t *doc,	/*
+   doc_printf(doc, "  %.0f moveto ESPpl show\n", top - 14.0);
+   doc_puts(doc, "pop\n");
+   doc_puts(doc, "}bind put\n");
++  }
++#ifdef WITH_LSPP
+ }
++#endif /* WITH_LSPP */
+ 
+ 
+ /*
+diff -up cups-2.2b2/Makedefs.in.lspp cups-2.2b2/Makedefs.in
+--- cups-2.2b2/Makedefs.in.lspp	2016-06-27 17:39:48.045974117 +0200
++++ cups-2.2b2/Makedefs.in	2016-06-27 17:39:48.077973863 +0200
+@@ -143,7 +143,7 @@ LDFLAGS		=	-L../cgi-bin -L../cups -L../f
+ 			@LDFLAGS@ @RELROFLAGS@ @PIEFLAGS@ $(OPTIM)
+ LINKCUPS	=	@LINKCUPS@ $(LIBGSSAPI) $(DNSSDLIBS) $(LIBZ)
+ LINKCUPSIMAGE	=	@LINKCUPSIMAGE@
+-LIBS		=	$(LINKCUPS) $(COMMONLIBS)
++LIBS		=	$(LINKCUPS) $(COMMONLIBS) @LIBAUDIT@ @LIBSELINUX@
+ ONDEMANDFLAGS	=	@ONDEMANDFLAGS@
+ ONDEMANDLIBS	=	@ONDEMANDLIBS@
+ OPTIM		=	@OPTIM@
+diff -up cups-2.2b2/scheduler/client.c.lspp cups-2.2b2/scheduler/client.c
+--- cups-2.2b2/scheduler/client.c.lspp	2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/scheduler/client.c	2016-06-27 17:39:48.077973863 +0200
+@@ -22,12 +22,20 @@
+ #define _HTTP_NO_PRIVATE
+ #include "cupsd.h"
+ 
++#ifndef _GNU_SOURCE
++#define _GNU_SOURCE
++#endif /* !defined(_GNU_SOURCE) */
+ #ifdef __APPLE__
+ #  include <libproc.h>
+ #endif /* __APPLE__ */
+ #ifdef HAVE_TCPD_H
+ #  include <tcpd.h>
+ #endif /* HAVE_TCPD_H */
++#ifdef WITH_LSPP
++#  include <selinux/selinux.h>
++#  include <selinux/context.h>
++#  include <fcntl.h>
++#endif /* WITH_LSPP */
+ 
+ 
+ /*
+@@ -266,6 +274,59 @@ cupsdAcceptClient(cupsd_listener_t *lis)
+   }
+ #endif /* HAVE_TCPD_H */
+ 
++#ifdef WITH_LSPP
++  if (is_lspp_config())
++  {
++    struct ucred cr;
++    unsigned int cl=sizeof(cr);
++
++    if (getsockopt(httpGetFd(con->http), SOL_SOCKET, SO_PEERCRED, &cr, &cl) == 0)
++    {
++     /*
++      * client_pid_to_auid() can be racey
++      * In this case the pid is based on a socket connected to the client
++      */
++      if ((con->auid = client_pid_to_auid(cr.pid)) == -1)
++      {
++        httpClose(con->http);
++        cupsdLogClient(con, CUPSD_LOG_ERROR,
++		       "Unable to determine client auid for client pid=%d",
++		       cr.pid);
++        free(con);
++        return;
++      }
++      cupsdLogClient(con, CUPSD_LOG_INFO,
++		     "peer's pid=%d, uid=%d, gid=%d, auid=%d",
++		     cr.pid, cr.uid, cr.gid, con->auid);
++    }
++    else
++    {
++      httpClose(con->http);
++      cupsdLogClient(con, CUPSD_LOG_ERROR, "getsockopt() failed");
++      free(con);
++      return; 
++    }
++
++   /*
++    * get the context of the peer connection
++    */
++    if (getpeercon(httpGetFd(con->http), &con->scon))
++    {
++      httpClose(con->http);
++      cupsdLogClient(con, CUPSD_LOG_ERROR, "getpeercon() failed");
++      free(con);
++      return; 
++    }
++
++    cupsdLogClient(con, CUPSD_LOG_INFO, "client context=%s", con->scon);
++  }
++  else
++  {
++    cupsdLogClient(con, CUPSD_LOG_DEBUG, "skipping getpeercon()");
++    cupsdSetString(&con->scon, UNKNOWN_SL);
++  }
++#endif /* WITH_LSPP */
++
+ #ifdef AF_LOCAL
+   if (httpAddrFamily(httpGetAddress(con->http)) == AF_LOCAL)
+   {
+@@ -560,6 +621,13 @@ cupsdReadClient(cupsd_client_t *con)	/*
+   mime_type_t		*type;		/* MIME type of file */
+   cupsd_printer_t	*p;		/* Printer */
+   static unsigned	request_id = 0;	/* Request ID for temp files */
++#ifdef WITH_LSPP
++  security_context_t	spoolcon;	/* context of the job file */
++  context_t		clicon;		/* contex_t container for con->scon */
++  context_t		tmpcon;		/* temp context to swap the level */
++  char			*clirange;	/* SELinux sensitivity range */
++  char			*cliclearance;	/* SELinux low end clearance */
++#endif /* WITH_LSPP */
+ 
+ 
+   status = HTTP_STATUS_CONTINUE;
+@@ -1924,6 +1992,73 @@ cupsdReadClient(cupsd_client_t *con)	/*
+             fcntl(con->file, F_SETFD, fcntl(con->file, F_GETFD) | FD_CLOEXEC);
+ 	  }
+ 
++#ifdef WITH_LSPP
++	  if (strncmp(con->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) != 0)
++	  {
++	    if (getfilecon(con->filename, &spoolcon) == -1)
++	    {
++	      cupsdSendError(con, HTTP_STATUS_SERVER_ERROR, CUPSD_AUTH_NONE);
++	      cupsdCloseClient(con);
++	      return;
++	    }
++	    clicon = context_new(con->scon);
++	    tmpcon = context_new(spoolcon);
++	    freecon(spoolcon);
++	    if (!clicon || !tmpcon)
++	    {
++	      cupsdSendError(con, HTTP_STATUS_SERVER_ERROR, CUPSD_AUTH_NONE);
++	      if (clicon)
++		context_free(clicon);
++	      if (tmpcon)
++		context_free(tmpcon);
++	      cupsdCloseClient(con);
++	      return;
++	    }
++	    clirange = (char *) context_range_get(clicon);
++	    if (clirange)
++	    {
++	      clirange = strdup(clirange);
++	      if ((cliclearance = strtok(clirange, "-")) != NULL)
++	      {
++		if (context_range_set(tmpcon, cliclearance) == -1)
++		{
++		  cupsdSendError(con, HTTP_STATUS_SERVER_ERROR, CUPSD_AUTH_NONE);
++		  free(clirange);
++		  context_free(tmpcon);
++		  context_free(clicon);
++		  cupsdCloseClient(con);
++		  return;
++		}
++	      }
++	      else
++	      {
++		if (context_range_set(tmpcon, (context_range_get(clicon))) == -1)
++		{
++		  cupsdSendError(con, HTTP_STATUS_SERVER_ERROR, CUPSD_AUTH_NONE);
++		  free(clirange);
++		  context_free(tmpcon);
++		  context_free(clicon);
++		  cupsdCloseClient(con);
++		  return;
++		}
++	      }
++	      free(clirange);
++	    }
++	    if (setfilecon(con->filename, context_str(tmpcon)) == -1)
++	    {
++	      cupsdSendError(con, HTTP_STATUS_SERVER_ERROR, CUPSD_AUTH_NONE);
++	      context_free(tmpcon);
++	      context_free(clicon);
++	      cupsdCloseClient(con);
++	      return;
++	    }
++	    cupsdLogClient(con, CUPSD_LOG_DEBUG2, "%s set to %s", 
++			   con->filename, context_str(tmpcon));
++	    context_free(tmpcon);
++	    context_free(clicon);
++	  }
++#endif /* WITH_LSPP */
++
+ 	  if (httpGetState(con->http) != HTTP_STATE_POST_SEND)
+ 	  {
+ 	    if (!httpWait(con->http, 0))
+@@ -3456,6 +3591,49 @@ is_path_absolute(const char *path)	/* I
+   return (1);
+ }
+ 
++#ifdef WITH_LSPP
++/*
++ * 'client_pid_to_auid()' - Using the client's pid, read /proc and determine the loginuid.
++ */
++
++uid_t client_pid_to_auid(pid_t clipid)
++{
++  uid_t uid;
++  int len, in;
++  char buf[16] = {0};
++  char fname[32] = {0};
++
++
++ /*
++  * Hopefully this pid is still the one we are interested in.
++  */
++  snprintf(fname, 32, "/proc/%d/loginuid", clipid);
++  in = open(fname, O_NOFOLLOW|O_RDONLY);
++
++  if (in < 0)
++    return (uid_t) -1;
++
++  errno = 0;
++
++  do {
++    len = read(in, buf, sizeof(buf));
++  } while (len < 0 && errno == EINTR);
++
++  close(in);
++
++  if (len < 0 || len >= sizeof(buf))
++    return (uid_t) -1;
++
++  errno = 0;
++  buf[len] = 0;
++  uid = strtol(buf, 0, 10);
++
++  if (errno != 0)
++    return (uid_t) -1;
++  else
++    return uid;
++}
++#endif /* WITH_LSPP */
+ 
+ /*
+  * 'pipe_command()' - Pipe the output of a command to the remote client.
+diff -up cups-2.2b2/scheduler/client.h.lspp cups-2.2b2/scheduler/client.h
+--- cups-2.2b2/scheduler/client.h.lspp	2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/scheduler/client.h	2016-06-27 17:39:48.077973863 +0200
+@@ -16,6 +16,13 @@
+ #endif /* HAVE_AUTHORIZATION_H */
+ 
+ 
++/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */
++/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
++
++#ifdef WITH_LSPP
++#include <selinux/selinux.h>
++#endif /* WITH_LSPP */
++
+ /*
+  * HTTP client structure...
+  */
+@@ -65,6 +72,10 @@ struct cupsd_client_s
+ #ifdef HAVE_AUTHORIZATION_H
+   AuthorizationRef	authref;	/* Authorization ref */
+ #endif /* HAVE_AUTHORIZATION_H */
++#ifdef WITH_LSPP
++  security_context_t	scon;		/* Security context of connection */
++  uid_t			auid;		/* Audit loginuid of the client */
++#endif /* WITH_LSPP */
+ };
+ 
+ #define HTTP(con) ((con)->http)
+@@ -138,6 +149,9 @@ extern void	cupsdStartListening(void);
+ extern void	cupsdStopListening(void);
+ extern void	cupsdUpdateCGI(void);
+ extern void	cupsdWriteClient(cupsd_client_t *con);
++#ifdef WITH_LSPP
++extern uid_t	client_pid_to_auid(pid_t clipid);
++#endif /* WITH_LSPP */
+ 
+ #ifdef HAVE_SSL
+ extern int	cupsdEndTLS(cupsd_client_t *con);
+diff -up cups-2.2b2/scheduler/conf.c.lspp cups-2.2b2/scheduler/conf.c
+--- cups-2.2b2/scheduler/conf.c.lspp	2016-06-27 17:39:48.072973903 +0200
++++ cups-2.2b2/scheduler/conf.c	2016-06-27 17:39:48.078973855 +0200
+@@ -40,6 +40,9 @@
+ #  define INADDR_NONE	0xffffffff
+ #endif /* !INADDR_NONE */
+ 
++#ifdef WITH_LSPP
++#  include <libaudit.h>
++#endif /* WITH_LSPP */
+ 
+ /*
+  * Configuration variable structure...
+@@ -131,6 +134,10 @@ static const cupsd_var_t	cupsd_vars[] =
+   { "ServerName",		&ServerName,		CUPSD_VARTYPE_STRING },
+   { "StrictConformance",	&StrictConformance,	CUPSD_VARTYPE_BOOLEAN },
+   { "Timeout",			&Timeout,		CUPSD_VARTYPE_TIME },
++#ifdef WITH_LSPP
++  { "AuditLog",			&AuditLog,		CUPSD_VARTYPE_INTEGER },
++  { "PerPageLabels",		&PerPageLabels,		CUPSD_VARTYPE_BOOLEAN },
++#endif /* WITH_LSPP */
+   { "WebInterface",		&WebInterface,		CUPSD_VARTYPE_BOOLEAN }
+ };
+ static const cupsd_var_t	cupsfiles_vars[] =
+@@ -577,6 +584,9 @@ cupsdReadConfiguration(void)
+   const char	*tmpdir;		/* TMPDIR environment variable */
+   struct stat	tmpinfo;		/* Temporary directory info */
+   cupsd_policy_t *p;			/* Policy */
++#ifdef WITH_LSPP
++  char		*audit_message;		/* Audit message string */
++#endif /* WITH_LSPP */
+ 
+ 
+  /*
+@@ -931,6 +941,25 @@ cupsdReadConfiguration(void)
+ 
+   RunUser = getuid();
+ 
++#ifdef WITH_LSPP
++  if (AuditLog != -1)
++  {
++   /*
++    * ClassifyOverride is set during read_configuration, if its ON, report it now
++    */
++    if (ClassifyOverride)
++      audit_log_user_message(AuditLog, AUDIT_USYS_CONFIG,
++                "[Config] ClassifyOverride=enabled Users can override print banners",
++                ServerName, NULL, NULL, 1);
++   /*
++    * PerPageLabel is set during read_configuration, if its OFF, report it now
++    */
++    if (!PerPageLabels)
++      audit_log_user_message(AuditLog, AUDIT_USYS_CONFIG,
++                "[Config] PerPageLabels=disabled", ServerName, NULL, NULL, 1);
++  }
++#endif /* WITH_LSPP */
++
+   cupsdLogMessage(CUPSD_LOG_INFO, "Remote access is %s.",
+                   RemotePort ? "enabled" : "disabled");
+ 
+@@ -1350,7 +1379,19 @@ cupsdReadConfiguration(void)
+     cupsdClearString(&Classification);
+ 
+   if (Classification)
++  {
+     cupsdLogMessage(CUPSD_LOG_INFO, "Security set to \"%s\"", Classification);
++#ifdef WITH_LSPP
++    if (AuditLog != -1)
++    {
++      audit_message = NULL;
++      cupsdSetStringf(&audit_message, "[Config] Classification=%s", Classification);
++      audit_log_user_message(AuditLog, AUDIT_LABEL_LEVEL_CHANGE, audit_message,
++                             ServerName, NULL, NULL, 1);
++      cupsdClearString(&audit_message);
++    }
++#endif /* WITH_LSPP */
++  }
+ 
+  /*
+   * Check the MaxClients setting, and then allocate memory for it...
+@@ -3827,6 +3868,18 @@ read_location(cups_file_t *fp,		/* I - C
+   return ((FatalErrors & CUPSD_FATAL_CONFIG) ? 0 : linenum);
+ }
+ 
++#ifdef WITH_LSPP
++int is_lspp_config()
++{
++  if (Classification != NULL)
++    return ((_cups_strcasecmp(Classification, MLS_CONFIG) == 0) 
++            || (_cups_strcasecmp(Classification, TE_CONFIG) == 0)
++            || (_cups_strcasecmp(Classification, SELINUX_CONFIG) == 0));
++  else
++    return 0;
++}
++#endif /* WITH_LSPP */
++
+ 
+ /*
+  * 'read_policy()' - Read a <Policy name> definition.
+diff -up cups-2.2b2/scheduler/conf.h.lspp cups-2.2b2/scheduler/conf.h
+--- cups-2.2b2/scheduler/conf.h.lspp	2016-06-27 17:39:48.078973855 +0200
++++ cups-2.2b2/scheduler/conf.h	2016-06-27 17:44:46.370632333 +0200
+@@ -248,6 +248,13 @@ VAR char		*ServerKeychain		VALUE(NULL);
+ 					/* Keychain holding cert + key */
+ #endif /* HAVE_SSL */
+ 
++#ifdef WITH_LSPP
++VAR int			AuditLog		VALUE(-1),
++					/* File descriptor for audit */
++			PerPageLabels		VALUE(TRUE);
++					/* Put the label on each page */
++#endif /* WITH_LSPP */
++
+ #ifdef HAVE_ONDEMAND
+ VAR int			IdleExitTimeout		VALUE(60);
+ 					/* Time after which an idle cupsd will exit */
+@@ -266,6 +273,9 @@ VAR int			HaveServerCreds		VALUE(0);
+ VAR gss_cred_id_t	ServerCreds;	/* Server's GSS credentials */
+ #endif /* HAVE_GSSAPI */
+ 
++#ifdef WITH_LSPP
++extern int		is_lspp_config(void);
++#endif /* WITH_LSPP */
+ 
+ /*
+  * Prototypes...
+diff -up cups-2.2b2/scheduler/cupsd.h.lspp cups-2.2b2/scheduler/cupsd.h
+--- cups-2.2b2/scheduler/cupsd.h.lspp	2016-06-27 17:39:48.064973966 +0200
++++ cups-2.2b2/scheduler/cupsd.h	2016-06-27 17:39:48.078973855 +0200
+@@ -11,6 +11,8 @@
+  * file is missing or damaged, see the license at "http://www.cups.org/".
+  */
+ 
++/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */
++/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
+ 
+ /*
+  * Include necessary headers.
+@@ -36,13 +38,20 @@
+ #  include <unistd.h>
+ #endif /* WIN32 */
+ 
++#include "config.h"
++#ifdef WITH_LSPP
++#  define MLS_CONFIG "mls"
++#  define TE_CONFIG "te"
++#  define SELINUX_CONFIG "SELinux"
++#  define UNKNOWN_SL "UNKNOWN SL"
++#endif /* WITH_LSPP */
++
+ #include "mime.h"
+ 
+ #if defined(HAVE_CDSASSL)
+ #  include <CoreFoundation/CoreFoundation.h>
+ #endif /* HAVE_CDSASSL */
+ 
+-
+ /*
+  * Some OS's don't have hstrerror(), most notably Solaris...
+  */
+diff -up cups-2.2b2/scheduler/ipp.c.lspp cups-2.2b2/scheduler/ipp.c
+--- cups-2.2b2/scheduler/ipp.c.lspp	2016-06-27 17:39:48.028974252 +0200
++++ cups-2.2b2/scheduler/ipp.c	2016-06-27 17:39:48.080973839 +0200
+@@ -14,6 +14,9 @@
+  * file is missing or damaged, see the license at "http://www.cups.org/".
+  */
+ 
++/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */
++/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
++
+ /*
+  * Include necessary headers...
+  */
+@@ -37,6 +40,14 @@ extern int mbr_check_membership_by_id(uu
+ #  endif /* HAVE_MEMBERSHIPPRIV_H */
+ #endif /* __APPLE__ */
+ 
++#ifdef WITH_LSPP
++#include <libaudit.h>
++#include <selinux/selinux.h>
++#include <selinux/context.h>
++#include <selinux/avc.h>
++#include <selinux/flask.h>
++#include <selinux/av_permissions.h>
++#endif /* WITH_LSPP */
+ 
+ /*
+  * Local functions...
+@@ -61,6 +72,9 @@ static void	cancel_all_jobs(cupsd_client
+ static void	cancel_job(cupsd_client_t *con, ipp_attribute_t *uri);
+ static void	cancel_subscription(cupsd_client_t *con, int id);
+ static int	check_rss_recipient(const char *recipient);
++#ifdef WITH_LSPP
++static int	check_context(cupsd_client_t *con, cupsd_job_t *job);
++#endif /* WITH_LSPP */
+ static int	check_quotas(cupsd_client_t *con, cupsd_printer_t *p);
+ static void	close_job(cupsd_client_t *con, ipp_attribute_t *uri);
+ static void	copy_attrs(ipp_t *to, ipp_t *from, cups_array_t *ra,
+@@ -1248,6 +1262,21 @@ add_job(cupsd_client_t  *con,		/* I - Cl
+     "time-at-creation",
+     "time-at-processing"
+   };
++#ifdef WITH_LSPP
++  char		*audit_message;		/* Audit message string */
++  char		*printerfile;		/* device file pointed to by the printer */
++  char		*userheader = NULL;	/* User supplied job-sheets[0] */
++  char		*userfooter = NULL;	/* User supplied job-sheets[1] */
++  int		override = 0;		/* Was a banner overrode on a job */
++  security_id_t	clisid;			/* SELinux SID for the client */
++  security_id_t	psid;			/* SELinux SID for the printer */
++  context_t	printercon;		/* Printer's context string */
++  struct stat	printerstat;		/* Printer's stat buffer */
++  security_context_t	devcon;		/* Printer's SELinux context */
++  struct avc_entry_ref	avcref;		/* Pointer to the access vector cache */
++  security_class_t	tclass;		/* Object class for the SELinux check */
++  access_vector_t	avr;		/* Access method being requested */
++#endif /* WITH_LSPP */
+ 
+ 
+   cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job(%p[%d], %p(%s), %p(%s/%s))",
+@@ -1559,6 +1588,106 @@ add_job(cupsd_client_t  *con,		/* I - Cl
+     return (NULL);
+   }
+ 
++#ifdef WITH_LSPP
++  if (is_lspp_config())
++  {
++    if (!con->scon || strncmp(con->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) == 0)
++    {
++      cupsdLogMessage(CUPSD_LOG_ERROR, "add_job: missing classification for connection \'%s\'!", printer->name);
++      send_ipp_status(con, IPP_INTERNAL_ERROR, _("Missing required security attributes."));
++      return (NULL);
++    }
++
++   /*
++    * Perform an access check so that if the user gets feedback at enqueue time
++    */
++
++    printerfile = strstr(printer->device_uri, "/dev/");
++    if (printerfile == NULL && (strncmp(printer->device_uri, "file:/", 6) == 0))
++      printerfile = printer->device_uri + strlen("file:");
++
++    if (printerfile != NULL)
++    {
++      cupsdLogMessage(CUPSD_LOG_DEBUG, "add_job: Attempting an access check on printer device %s",
++                      printerfile);
++
++      if (lstat(printerfile, &printerstat) < 0)
++      {
++	if (errno != ENOENT)
++	{
++	  send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Unable to stat the printer"));
++	  return (NULL);
++	}
++	/*
++	 * The printer does not exist, so for now assume it's a FileDevice
++	 */
++	tclass = SECCLASS_FILE;
++	avr = FILE__WRITE;
++      }
++      else if (S_ISCHR(printerstat.st_mode))
++      {
++	tclass = SECCLASS_CHR_FILE;
++	avr = CHR_FILE__WRITE;
++      }
++      else if (S_ISREG(printerstat.st_mode))
++      {
++	tclass = SECCLASS_FILE;
++	avr = FILE__WRITE;
++      }
++      else
++      {
++	send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Printer is not a character device or regular file"));
++	return (NULL);
++      }
++      static int avc_initialized = 0;
++      if (!avc_initialized++)
++          avc_init("cupsd_enqueue_", NULL, NULL, NULL, NULL);
++      avc_entry_ref_init(&avcref);
++      if (avc_context_to_sid(con->scon, &clisid) != 0)
++      {
++        send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Unable to get the SELinux sid of the client"));
++        return (NULL);
++      }
++      if (getfilecon(printerfile, &devcon) == -1)
++      {
++        send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Unable to get the SELinux context of the printer"));
++        return (NULL);
++      }
++      printercon = context_new(devcon);
++      cupsdLogMessage(CUPSD_LOG_DEBUG, "add_job: printer context %s client context %s",
++                      context_str(printercon), con->scon);
++      context_free(printercon);
++
++      if (avc_context_to_sid(devcon, &psid) != 0)
++      {
++        send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Unable to get the SELinux sid of the printer"));
++        freecon(devcon);
++        return (NULL);
++      }
++      freecon(devcon);
++      if (avc_has_perm(clisid, psid, tclass, avr, &avcref, NULL) != 0)
++      {
++       /*
++        * The access check failed, so cancel the job and send an audit message
++        */
++        if (AuditLog != -1)
++        {
++          audit_message = NULL;
++          cupsdSetStringf(&audit_message, "job=? auid=%u acct=%s obj=%s refused"
++                          " unable to access printer=%s", con->auid,
++                          con->username, con->scon, printer->name);
++          audit_log_user_message(AuditLog, AUDIT_USER_LABELED_EXPORT, audit_message,
++                                 ServerName, NULL, NULL, 0);
++          cupsdClearString(&audit_message);
++        }
++
++        send_ipp_status(con, IPP_NOT_AUTHORIZED, _("SELinux prohibits access to the printer"));
++        return (NULL);
++      }
++    }
++  }
++#endif /* WITH_LSPP */
++
+   if ((job = cupsdAddJob(priority, printer->name)) == NULL)
+   {
+     send_ipp_status(con, IPP_INTERNAL_ERROR,
+@@ -1567,6 +1696,32 @@ add_job(cupsd_client_t  *con,		/* I - Cl
+     return (NULL);
+   }
+ 
++#ifdef WITH_LSPP
++  if (is_lspp_config())
++  {
++   /*
++    * duplicate the security context and auid of the connection into the job structure
++    */
++    job->scon = strdup(con->scon);
++    job->auid = con->auid;
++
++   /* 
++    * add the security context to the request so that on a restart the security
++    * attributes will be able to be restored
++    */
++    ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "security-context", 
++		 NULL, job->scon);
++  }
++  else
++  {
++   /*
++    * Fill in the security context of the job as unlabeled
++    */
++    cupsdLogMessage(CUPSD_LOG_DEBUG, "add_job: setting context of job to %s", UNKNOWN_SL);
++    cupsdSetString(&job->scon, UNKNOWN_SL);
++  }
++#endif /* WITH_LSPP */
++
+   job->dtype   = printer->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_REMOTE);
+   job->attrs   = con->request;
+   job->dirty   = 1;
+@@ -1756,6 +1911,29 @@ add_job(cupsd_client_t  *con,		/* I - Cl
+       ippSetString(job->attrs, &attr, 0, printer->job_sheets[0]);
+       ippSetString(job->attrs, &attr, 1, printer->job_sheets[1]);
+     }
++#ifdef WITH_LSPP
++    else
++    {
++     /*
++      * The option was present, so capture the user supplied strings
++      */
++      userheader = strdup(attr->values[0].string.text);
++
++      if (attr->num_values > 1)
++        userfooter = strdup(attr->values[1].string.text);
++
++      if (Classification != NULL && (strcmp(userheader, Classification) == 0)
++          && userfooter &&(strcmp(userfooter, Classification) == 0))
++      {
++       /*
++        * Since both values are Classification, the user is not trying to Override
++        */
++        free(userheader);
++        if (userfooter) free(userfooter);
++        userheader = userfooter = NULL;
++      }
++    }
++#endif /* WITH_LSPP */
+ 
+     job->job_sheets = attr;
+ 
+@@ -1786,6 +1964,9 @@ add_job(cupsd_client_t  *con,		/* I - Cl
+ 	                		     "job-sheets=\"%s,none\", "
+ 					     "job-originating-user-name=\"%s\"",
+ 	              Classification, job->username);
++#ifdef WITH_LSPP
++	  override = 1;
++#endif /* WITH_LSPP */
+ 	}
+ 	else if (attr->num_values == 2 &&
+ 	         strcmp(attr->values[0].string.text,
+@@ -1804,6 +1985,9 @@ add_job(cupsd_client_t  *con,		/* I - Cl
+ 					     "job-originating-user-name=\"%s\"",
+ 		      attr->values[0].string.text,
+ 		      attr->values[1].string.text, job->username);
++#ifdef WITH_LSPP
++	  override = 1;
++#endif /* WITH_LSPP */
+ 	}
+ 	else if (strcmp(attr->values[0].string.text, Classification) &&
+ 	         strcmp(attr->values[0].string.text, "none") &&
+@@ -1824,6 +2008,9 @@ add_job(cupsd_client_t  *con,		/* I - Cl
+ 			"job-originating-user-name=\"%s\"",
+ 			attr->values[0].string.text,
+ 			attr->values[1].string.text, job->username);
++#ifdef WITH_LSPP
++	  override = 1;
++#endif /* WITH_LSPP */
+         }
+       }
+       else if (strcmp(attr->values[0].string.text, Classification) &&
+@@ -1864,8 +2051,52 @@ add_job(cupsd_client_t  *con,		/* I - Cl
+ 		      "job-sheets=\"%s\", "
+ 		      "job-originating-user-name=\"%s\"",
+ 		      Classification, job->username);
++#ifdef WITH_LSPP
++	override = 1;
++#endif /* WITH_LSPP */
+       }
++#ifdef WITH_LSPP
++      if (is_lspp_config() && AuditLog != -1)
++      {
++        audit_message = NULL;
++
++        if (userheader || userfooter)
++        {
++          if (!override)
++          {
++           /*
++            * The user overrode the banner, so audit it
++            */
++            cupsdSetStringf(&audit_message, "job=%d user supplied job-sheets=%s,%s"
++                            " using banners=%s,%s", job->id, userheader,
++                            userfooter, attr->values[0].string.text,
++                            (attr->num_values > 1) ? attr->values[1].string.text : "(null)");
++            audit_log_user_message(AuditLog, AUDIT_LABEL_OVERRIDE, audit_message,
++                                   ServerName, NULL, NULL, 1);
++	  }
++          else
++          {
++           /*
++            * The user tried to override the banner, audit the failure
++            */
++            cupsdSetStringf(&audit_message, "job=%d user supplied job-sheets=%s,%s"
++                            " ignored banners=%s,%s", job->id, userheader,
++                            userfooter, attr->values[0].string.text,
++                            (attr->num_values > 1) ? attr->values[1].string.text : "(null)");
++            audit_log_user_message(AuditLog, AUDIT_LABEL_OVERRIDE, audit_message,
++                                   ServerName, NULL, NULL, 0);
++	  }
++          cupsdClearString(&audit_message);
++	}
++      }
++
++      if (userheader)
++        free(userheader);
++      if (userfooter)
++        free(userfooter);
++#endif /* WITH_LSPP */
+     }
++    
+ 
+    /*
+     * See if we need to add the starting sheet...
+@@ -3619,6 +3850,128 @@ check_rss_recipient(
+ }
+ 
+ 
++#ifdef WITH_LSPP
++/*
++ * 'check_context()' - Check SELinux security context of a user and job
++ */
++
++static int				/* O - 1 if OK, 0 if not, -1 on error */
++check_context(cupsd_client_t *con,	/* I - Client connection */
++             cupsd_job_t    *job)	/* I - Job */
++{
++  int			enforcing;	/* is SELinux in enforcing mode */
++  char			filename[1024]; /* Filename of the spool file */
++  security_id_t		clisid;		/* SELinux SID of the client */
++  security_id_t		jobsid;		/* SELinux SID of the job */
++  security_id_t		filesid;	/* SELinux SID of the spool file */
++  struct avc_entry_ref	avcref;		/* AVC entry cache pointer */
++  security_class_t	tclass;		/* SELinux security class */
++  access_vector_t	avr;		/* SELinux access being queried */
++  security_context_t	spoolfilecon;	/* SELinux context of the spool file */
++
++
++ /*
++  * Validate the input to be sure there are contexts to work with...
++  */
++
++  if (con->scon == NULL || job->scon == NULL
++      || strncmp(con->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) == 0
++      || strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) == 0)
++    return -1;
++
++  if ((enforcing = security_getenforce()) == -1)
++  {
++    cupsdLogJob(job, CUPSD_LOG_ERROR,
++		"Error while determining SELinux enforcement");
++    return -1;
++  }
++  cupsdLogJob(job, CUPSD_LOG_DEBUG,
++	      "check_context: client context %s job context %s",
++	      con->scon, job->scon);
++
++
++ /*
++  * Initialize the avc engine...
++  */
++
++  static int avc_initialized = 0;
++  if (! avc_initialized++)
++  {
++    if (avc_init("cupsd", NULL, NULL, NULL, NULL) < 0)
++    {
++      cupsdLogJob(job, CUPSD_LOG_ERROR, "check_context: unable avc_init");
++      return -1;
++    } 
++  } 
++  if (avc_context_to_sid(con->scon, &clisid) != 0)
++  {
++    cupsdLogJob(job, CUPSD_LOG_ERROR,
++		"check_context: unable to convert %s to SELinux sid",
++		con->scon);
++    return -1;
++  }
++  if (avc_context_to_sid(job->scon, &jobsid) != 0)
++  {
++    cupsdLogJob(job, CUPSD_LOG_ERROR,
++		"check_context: unable to convert %s to SELinux sid",
++		job->scon);
++    return -1;
++  }
++  avc_entry_ref_init(&avcref);
++  tclass = SECCLASS_FILE;
++  avr = FILE__READ;
++
++ /*
++  * Perform the check with the client as the subject, first with the job as the object
++  *   if that fails then with the spool file as the object...
++  */
++
++  if (avc_has_perm_noaudit(clisid, jobsid, tclass, avr, &avcref, NULL) != 0)
++  {
++    cupsdLogJob(job, CUPSD_LOG_INFO,
++		"check_context: SELinux denied access "
++		"based on the client context");
++
++    snprintf(filename, sizeof(filename), "%s/c%05d", RequestRoot, job->id);
++    if (getfilecon(filename, &spoolfilecon) == -1)
++    {
++      cupsdLogJob(job, CUPSD_LOG_ERROR,
++		  "check_context: Unable to get spoolfile context");
++      return -1;
++    }
++    if (avc_context_to_sid(spoolfilecon, &filesid) != 0)
++    {
++      cupsdLogJob(job, CUPSD_LOG_ERROR,
++		  "check_context: Unable to determine the "
++		  "SELinux sid for the spool file");
++      freecon(spoolfilecon);
++      return -1;
++    }
++    freecon(spoolfilecon);
++    if (avc_has_perm_noaudit(clisid, filesid, tclass, avr, &avcref, NULL) != 0)
++    {
++      cupsdLogJob(job, CUPSD_LOG_INFO,
++		  "check_context: SELinux denied access to the spool file");
++      return 0;
++    }
++    cupsdLogJob(job, CUPSD_LOG_INFO,
++		"check_context: SELinux allowed access to the spool file");
++    return 1;
++  }
++  else
++    if (enforcing == 0)
++      cupsdLogJob(job, CUPSD_LOG_INFO,
++		  "check_context: allowing operation due to permissive mode");
++    else
++      cupsdLogJob(job, CUPSD_LOG_INFO,
++		  "check_context: SELinux allowed access based on the "
++		  "client context");
++
++  return 1;
++}
++#endif /* WITH_LSPP */
++
++
+ /*
+  * 'check_quotas()' - Check quotas for a printer and user.
+  */
+@@ -4075,6 +4428,15 @@ copy_banner(cupsd_client_t *con,	/* I -
+   char		attrname[255],		/* Name of attribute */
+ 		*s;			/* Pointer into name */
+   ipp_attribute_t *attr;		/* Attribute */
++#ifdef WITH_LSPP
++  const char	*mls_label;		/* SL of print job */
++  char		*jobrange;		/* SELinux sensitivity range */
++  char		*jobclearance;		/* SELinux low end clearance */
++  context_t	jobcon;			/* SELinux context of the job */
++  context_t	tmpcon;			/* Temp context to set the level */
++  security_context_t	spoolcon;	/* Context of the file in the spool */
++#endif /* WITH_LSPP */
++
+ 
+ 
+   cupsdLogMessage(CUPSD_LOG_DEBUG2,
+@@ -4110,6 +4472,85 @@ copy_banner(cupsd_client_t *con,	/* I -
+ 
+   fchmod(cupsFileNumber(out), 0640);
+   fchown(cupsFileNumber(out), RunUser, Group);
++#ifdef WITH_LSPP
++  if (job->scon != NULL &&
++      strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) != 0)
++  {
++    if (getfilecon(filename, &spoolcon) == -1)
++    {
++      cupsdLogJob(job, CUPSD_LOG_ERROR,
++		  "Unable to get the context of the banner file %s - %s",
++		  filename, strerror(errno));
++      job->num_files --;
++      return (0);
++    }
++    tmpcon = context_new(spoolcon);
++    jobcon = context_new(job->scon);
++    freecon(spoolcon);
++    if (!tmpcon || !jobcon)
++    {
++      if (tmpcon)
++        context_free(tmpcon);
++      if (jobcon)
++        context_free(jobcon);
++      cupsdLogJob(job, CUPSD_LOG_ERROR,
++		  "copy_banner: Unable to get the SELinux contexts");
++      job->num_files --;
++      return (0);
++    }
++    jobrange = (char *) context_range_get(jobcon);
++    if (jobrange)
++    {
++      jobrange = strdup(jobrange);
++      if ((jobclearance = strtok(jobrange, "-")) != NULL)
++      {
++	if (context_range_set(tmpcon, jobclearance) == -1)
++	{
++	  cupsdLogJob(job, CUPSD_LOG_ERROR,
++		      "copy_banner: Unable to set the "
++		      "level of the context for file %s - %s",
++		      filename, strerror(errno));
++	  free(jobrange);
++	  context_free(jobcon);
++	  context_free(tmpcon);
++	  job->num_files --;
++	  return (0);
++	}
++      }
++      else
++      {
++	if (context_range_set(tmpcon, (context_range_get(jobcon))) == -1)
++	{
++	  cupsdLogJob(job, CUPSD_LOG_ERROR,
++		      "copy_banner: Unable to set the "
++		      "level of the context for file %s - %s",
++		      filename, strerror(errno));
++	  free(jobrange);
++	  context_free(jobcon);
++	  context_free(tmpcon);
++	  job->num_files --;
++	  return (0);
++	}
++      }
++      free(jobrange);
++    }
++    if (setfilecon(filename, context_str(tmpcon)) == -1)
++    {
++      cupsdLogJob(job, CUPSD_LOG_ERROR,
++		  "copy_banner: Unable to set the "
++		  "context of the banner file %s - %s",
++		  filename, strerror(errno));
++      context_free(jobcon);
++      context_free(tmpcon);
++      job->num_files --;
++      return (0);
++    }
++    cupsdLogJob(job, CUPSD_LOG_DEBUG2, "copy_banner: %s set to %s",
++		filename, context_str(tmpcon));
++    context_free(jobcon);
++    context_free(tmpcon);
++  }
++#endif /* WITH_LSPP */
+ 
+  /*
+   * Try the localized banner file under the subdirectory...
+@@ -4204,6 +4645,24 @@ copy_banner(cupsd_client_t *con,	/* I -
+       else
+         s = attrname;
+ 
++#ifdef WITH_LSPP
++      if (strcmp(s, "mls-label") == 0)
++      {
++        if (job->scon != NULL && strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) != 0)
++        {
++          jobcon = context_new(job->scon);
++          if (_cups_strcasecmp(name, MLS_CONFIG) == 0)
++            mls_label = context_range_get(jobcon);
++          else if (_cups_strcasecmp(name, TE_CONFIG) == 0)
++            mls_label = context_type_get(jobcon);
++          else // default to using the whole context string
++            mls_label = context_str(jobcon);
++          cupsFilePuts(out, mls_label);
++          context_free(jobcon);
++        }
++        continue;
++      }
++#endif /* WITH_LSPP */
+       if (!strcmp(s, "printer-name"))
+       {
+         cupsFilePuts(out, job->dest);
+@@ -6389,6 +6848,22 @@ get_job_attrs(cupsd_client_t  *con,	/* I
+ 
+   exclude = cupsdGetPrivateAttrs(policy, con, printer, job->username);
+ 
++
++#ifdef WITH_LSPP
++ /*
++  * Check SELinux...
++  */
++  if (is_lspp_config() && check_context(con, job) != 1)
++  {
++   /*
++    * Unfortunately we have to lie to the user...
++    */
++    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid);
++    return;
++  }
++#endif /* WITH_LSPP */
++
++
+  /*
+   * Copy attributes...
+   */
+@@ -6786,6 +7261,11 @@ get_jobs(cupsd_client_t  *con,		/* I - C
+       if (username[0] && _cups_strcasecmp(username, job->username))
+ 	continue;
+ 
++#ifdef WITH_LSPP
++      if (is_lspp_config() && check_context(con, job) != 1)
++	continue;
++#endif /* WITH_LSPP */
++
+       if (count > 0)
+ 	ippAddSeparator(con->response);
+ 
+@@ -11415,6 +11895,11 @@ validate_user(cupsd_job_t    *job,	/* I
+ 
+   strlcpy(username, get_username(con), userlen);
+ 
++#ifdef WITH_LSPP
++  if (is_lspp_config() && check_context(con, job) != 1)
++    return 0;
++#endif /* WITH_LSPP */
++
+  /*
+   * Check the username against the owner...
+   */
+diff -up cups-2.2b2/scheduler/job.c.lspp cups-2.2b2/scheduler/job.c
+--- cups-2.2b2/scheduler/job.c.lspp	2016-06-27 17:39:48.041974149 +0200
++++ cups-2.2b2/scheduler/job.c	2016-06-27 17:39:48.081973831 +0200
+@@ -11,6 +11,9 @@
+  * file is missing or damaged, see the license at "http://www.cups.org/".
+  */
+ 
++/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */
++/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
++
+ /*
+  * Include necessary headers...
+  */
+@@ -26,6 +29,14 @@
+ #  endif /* HAVE_IOKIT_PWR_MGT_IOPMLIBPRIVATE_H */
+ #endif /* __APPLE__ */
+ 
++#ifdef WITH_LSPP
++#include <libaudit.h>
++#include <selinux/selinux.h>
++#include <selinux/context.h>
++#include <selinux/avc.h>
++#include <selinux/flask.h>
++#include <selinux/av_permissions.h>
++#endif /* WITH_LSPP */
+ 
+ /*
+  * Design Notes for Job Management
+@@ -546,6 +557,14 @@ cupsdContinueJob(cupsd_job_t *job)	/* I
+ 					/* PRINTER_STATE_REASONS env var */
+ 			rip_max_cache[255];
+ 					/* RIP_MAX_CACHE env variable */
++#ifdef WITH_LSPP
++  char			*audit_message = NULL;	/* Audit message string */
++  context_t		jobcon;		/* SELinux context of the job */
++  char			*label_template = NULL;	/* SL to put in classification
++						   env var */
++  const char		*mls_label = NULL;	/* SL to put in classification
++						   env var */
++#endif /* WITH_LSPP */
+ 
+ 
+   cupsdLogMessage(CUPSD_LOG_DEBUG2,
+@@ -1082,6 +1101,67 @@ cupsdContinueJob(cupsd_job_t *job)	/* I
+   if (final_content_type[0])
+     envp[envc ++] = final_content_type;
+ 
++#ifdef WITH_LSPP
++  if (is_lspp_config())
++  {
++    if (!job->scon || strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) == 0)
++    {
++      if (AuditLog != -1)
++      {
++        audit_message = NULL;
++        cupsdSetStringf(&audit_message, "job=%d auid=%u acct=%s printer=%s title=%s",
++                        job->id, job->auid, job->username, job->printer->name, title);
++        audit_log_user_message(AuditLog, AUDIT_USER_UNLABELED_EXPORT, audit_message,
++                               ServerName, NULL, NULL, 1);
++        cupsdClearString(&audit_message);
++      }
++    }
++    else 
++    {
++      jobcon = context_new(job->scon);
++
++      if ((attr = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_NAME)) == NULL)
++        label_template = strdup(Classification);
++      else if (attr->num_values > 1 &&
++               strcmp(attr->values[1].string.text, "none") != 0)
++        label_template = strdup(attr->values[1].string.text);
++      else
++        label_template = strdup(attr->values[0].string.text);
++
++      if (_cups_strcasecmp(label_template, MLS_CONFIG) == 0)
++        mls_label = context_range_get(jobcon);
++      else if (_cups_strcasecmp(label_template, TE_CONFIG) == 0)
++        mls_label = context_type_get(jobcon);
++      else if (_cups_strcasecmp(label_template, SELINUX_CONFIG) == 0)
++        mls_label = context_str(jobcon);
++      else
++        mls_label = label_template;
++
++      if (mls_label && (PerPageLabels || banner_page))
++      {
++        snprintf(classification, sizeof(classification), "CLASSIFICATION=LSPP:%s", mls_label);
++        envp[envc ++] = classification;
++      }
++
++      if ((AuditLog != -1) && !banner_page)
++      {
++        audit_message = NULL;
++        cupsdSetStringf(&audit_message, "job=%d auid=%u acct=%s printer=%s title=%s"
++                        " obj=%s label=%s", job->id, job->auid, job->username,
++                        job->printer->name, title, job->scon, mls_label?mls_label:"none");
++        audit_log_user_message(AuditLog, AUDIT_USER_LABELED_EXPORT, audit_message,
++                               ServerName, NULL, NULL, 1);
++        cupsdClearString(&audit_message);
++      }
++      context_free(jobcon);
++      free(label_template);
++    }
++  }
++  else
++   /*
++    * Fall through to the non-LSPP behavior
++    */
++#endif /* WITH_LSPP */
+   if (Classification && !banner_page)
+   {
+     if ((attr = ippFindAttribute(job->attrs, "job-sheets",
+@@ -1905,6 +1985,22 @@ cupsdLoadJob(cupsd_job_t *job)		/* I - J
+       ippSetString(job->attrs, &job->reasons, 0, "none");
+   }
+ 
++#ifdef WITH_LSPP
++  if ((attr = ippFindAttribute(job->attrs, "security-context", IPP_TAG_NAME)) != NULL)
++    cupsdSetString(&job->scon, attr->values[0].string.text);
++  else if (is_lspp_config())
++  {
++   /*
++    * There was no security context so delete the job
++    */
++    cupsdLogJob(job, CUPSD_LOG_ERROR,
++		"Missing or bad security-context attribute "
++		"in control file \"%s\"!",
++		jobfile);
++    goto error;
++  }
++#endif /* WITH_LSPP */
++
+   job->impressions = ippFindAttribute(job->attrs, "job-impressions-completed", IPP_TAG_INTEGER);
+   job->sheets      = ippFindAttribute(job->attrs, "job-media-sheets-completed", IPP_TAG_INTEGER);
+   job->job_sheets  = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_NAME);
+@@ -2318,6 +2414,14 @@ cupsdSaveJob(cupsd_job_t *job)		/* I - J
+ {
+   char		filename[1024];		/* Job control filename */
+   cups_file_t	*fp;			/* Job file */
++#ifdef WITH_LSPP
++  security_context_t	spoolcon;	/* context of the job control file */
++  context_t		jobcon;		/* contex_t container for job->scon */
++  context_t		tmpcon;		/* Temp context to swap the level */
++  char			*jobclearance;	/* SELinux low end clearance */
++  const char		*jobrange;	/* SELinux sensitivity range */
++  char			*jobrange_copy;	/* SELinux sensitivity range */
++#endif /* WITH_LSPP */
+ 
+ 
+   cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSaveJob(job=%p(%d)): job->attrs=%p",
+@@ -2340,6 +2444,78 @@ cupsdSaveJob(cupsd_job_t *job)		/* I - J
+ 
+   fchown(cupsFileNumber(fp), RunUser, Group);
+ 
++#ifdef WITH_LSPP
++  if (job->scon && strncmp(job->scon, UNKNOWN_SL, strlen(UNKNOWN_SL)) != 0)
++  {
++    if (getfilecon(filename, &spoolcon) == -1)
++    {
++      cupsdLogJob(job, CUPSD_LOG_ERROR,
++		  "Unable to get context of job control file \"%s\" - %s.",
++		  filename, strerror(errno));
++      return;
++    }
++    jobcon = context_new(job->scon);
++    tmpcon = context_new(spoolcon);
++    freecon(spoolcon);
++    if (!jobcon || !tmpcon)
++    {
++      if (jobcon)
++        context_free(jobcon);
++      if (tmpcon)
++        context_free(tmpcon);
++      cupsdLogJob(job, CUPSD_LOG_ERROR, "Unable to get SELinux contexts");
++      return;
++    }
++    jobrange = context_range_get(jobcon);
++    if (jobrange)
++    {
++      jobrange_copy = strdup(jobrange);
++      if ((jobclearance = strtok(jobrange_copy, "-")) != NULL)
++      {
++	if (context_range_set(tmpcon, jobclearance) == -1)
++	{
++	  cupsdLogJob(job, CUPSD_LOG_ERROR,
++		      "Unable to set the range for "
++		      "job control file \"%s\" - %s.",
++		      filename, strerror(errno));
++	  free(jobrange_copy);
++	  context_free(tmpcon);
++	  context_free(jobcon);
++	  return;
++	}
++      }
++      else
++      {
++	if (context_range_set(tmpcon, (context_range_get(jobcon))) == -1)
++	{
++	  cupsdLogJob(job, CUPSD_LOG_ERROR,
++		      "Unable to set the range for "
++		      "job control file \"%s\" - %s.",
++		      filename, strerror(errno));
++	  free(jobrange_copy);
++	  context_free(tmpcon);
++	  context_free(jobcon);
++	  return;
++	}
++      }
++      free(jobrange_copy);
++    }
++    if (setfilecon(filename, context_str(tmpcon)) == -1)
++    {
++      cupsdLogJob(job, CUPSD_LOG_ERROR,
++		  "Unable to set context of job control file \"%s\" - %s.",
++		  filename, strerror(errno));
++      context_free(tmpcon);
++      context_free(jobcon);
++      return;
++    }
++    cupsdLogJob(job, CUPSD_LOG_DEBUG2, "New spool file context=%s",
++		 context_str(tmpcon));
++    context_free(tmpcon);
++    context_free(jobcon);
++  }
++#endif /* WITH_LSPP */
++
+   job->attrs->state = IPP_IDLE;
+ 
+   if (ippWriteIO(fp, (ipp_iocb_t)cupsFileWrite, 1, NULL,
+@@ -3919,6 +4095,19 @@ get_options(cupsd_job_t *job,		/* I - Jo
+ 	  banner_page)
+         continue;
+ 
++#ifdef WITH_LSPP
++     /*
++      * In LSPP mode refuse to honor the page-label
++      */
++      if (is_lspp_config() &&
++          !strcmp(attr->name, "page-label"))
++      {
++        cupsdLogJob(job, CUPSD_LOG_DEBUG,
++		    "Ignoring page-label option due to LSPP mode");
++        continue;
++      }
++#endif /* WITH_LSPP */
++
+      /*
+       * Otherwise add them to the list...
+       */
+@@ -4680,6 +4869,18 @@ start_job(cupsd_job_t     *job,		/* I -
+           cupsd_printer_t *printer)	/* I - Printer to print job */
+ {
+   const char	*filename;		/* Support filename */
++#ifdef WITH_LSPP
++  char			*audit_message = NULL;	/* Audit message string */
++  char			*printerfile = NULL;	/* Device file pointed to by the printer */
++  security_id_t		clisid;		/* SELinux SID for the client */
++  security_id_t		psid;		/* SELinux SID for the printer */
++  context_t		printercon;	/* Printer's context string */
++  struct stat		printerstat;	/* Printer's stat buffer */
++  security_context_t	devcon;		/* Printer's SELinux context */
++  struct avc_entry_ref	avcref;		/* Pointer to the access vector cache */
++  security_class_t	tclass;		/* Object class for the SELinux check */
++  access_vector_t	avr;		/* Access method being requested */
++#endif /* WITH_LSPP */
+   ipp_attribute_t *cancel_after = ippFindAttribute(job->attrs,
+ 						   "job-cancel-after",
+ 						   IPP_TAG_INTEGER);
+@@ -4856,6 +5057,113 @@ start_job(cupsd_job_t     *job,		/* I -
+   fcntl(job->side_pipes[1], F_SETFD,
+ 	fcntl(job->side_pipes[1], F_GETFD) | FD_CLOEXEC);
+ 
++#ifdef WITH_LSPP
++  if (is_lspp_config())
++  {
++   /*
++    * Perform an access check before printing, but only if the printer starts with /dev/
++    */
++    printerfile = strstr(printer->device_uri, "/dev/");
++    if (printerfile == NULL && (strncmp(printer->device_uri, "file:/", 6) == 0))
++      printerfile = printer->device_uri + strlen("file:");
++
++    if (printerfile != NULL)
++    {
++      cupsdLogJob(job, CUPSD_LOG_DEBUG,
++		  "Attempting to check access on printer device %s",
++		  printerfile);
++      if (lstat(printerfile, &printerstat) < 0)
++      {
++	if (errno != ENOENT)
++	{
++	  cupsdLogJob(job, CUPSD_LOG_ERROR,
++		      "Unable to stat the printer");
++	  cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
++	  return ;
++	}
++	/*
++	 * The printer does not exist, so for now assume it's a FileDevice
++	 */
++	tclass = SECCLASS_FILE;
++	avr = FILE__WRITE;
++      }
++      else if (S_ISCHR(printerstat.st_mode))
++      {
++	tclass = SECCLASS_CHR_FILE;
++	avr = CHR_FILE__WRITE;
++      }
++      else if (S_ISREG(printerstat.st_mode))
++      {
++	tclass = SECCLASS_FILE;
++	avr = FILE__WRITE;
++      }
++      else
++      {
++	cupsdLogJob(job, CUPSD_LOG_ERROR,
++		    "StartJob: Printer is not a character device or "
++		    "regular file");
++	cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
++	return ;
++      }
++      static int avc_initialized = 0;
++      if (!avc_initialized++)
++          avc_init("cupsd_dequeue_", NULL, NULL, NULL, NULL);
++      avc_entry_ref_init(&avcref);
++      if (avc_context_to_sid(job->scon, &clisid) != 0)
++      {
++        cupsdLogJob(job, CUPSD_LOG_ERROR,
++		    "Unable to determine the SELinux sid for the job");
++        cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
++        return ;
++      }
++      if (getfilecon(printerfile, &devcon) == -1)
++      {
++        cupsdLogJob(job, CUPSD_LOG_ERROR,
++		    "Unable to get the SELinux context of %s",
++		    printerfile);
++        cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
++        return ;
++      }
++      printercon = context_new(devcon);
++      cupsdLogJob(job, CUPSD_LOG_DEBUG,
++		  "Printer context %s client context %s",
++		  context_str(printercon), job->scon);
++      context_free(printercon);
++
++      if (avc_context_to_sid(devcon, &psid) != 0)
++      {
++        cupsdLogJob(job, CUPSD_LOG_ERROR,
++		    "Unable to determine the SELinux sid for the printer");
++        freecon(devcon);
++        cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
++        return ;
++      }
++      freecon(devcon);
++
++      if (avc_has_perm(clisid, psid, tclass, avr, &avcref, NULL) != 0)
++      {
++       /*
++        * The access check failed, so cancel the job and send an audit message
++        */
++        if (AuditLog != -1)
++        {
++          audit_message = NULL;
++          cupsdSetStringf(&audit_message, "job=%d auid=%u acct=%s obj=%s canceled"
++                                          " unable to access printer=%s", job->id,
++                          job->auid, (job->username)?job->username:"?", job->scon, printer->name);
++          audit_log_user_message(AuditLog, AUDIT_USER_LABELED_EXPORT, audit_message,
++                                 ServerName, NULL, NULL, 0);
++          cupsdClearString(&audit_message);
++        }
++
++        cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, NULL);
++
++        return ;
++      }
++    }
++  }
++#endif /* WITH_LSPP */
++
+  /*
+   * Now start the first file in the job...
+   */
+diff -up cups-2.2b2/scheduler/job.h.lspp cups-2.2b2/scheduler/job.h
+--- cups-2.2b2/scheduler/job.h.lspp	2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/scheduler/job.h	2016-06-27 17:39:48.081973831 +0200
+@@ -11,6 +11,13 @@
+  * file is missing or damaged, see the license at "http://www.cups.org/".
+  */
+ 
++/* Copyright (C) 2005 Trusted Computer Solutions, Inc. */
++/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
++
++#ifdef WITH_LSPP
++#include <selinux/selinux.h>
++#endif /* WITH_LSPP */
++
+ /*
+  * Constants...
+  */
+@@ -88,6 +95,10 @@ struct cupsd_job_s			/**** Job request *
+   int			progress;	/* Printing progress */
+   int			num_keywords;	/* Number of PPD keywords */
+   cups_option_t		*keywords;	/* PPD keywords */
++#ifdef WITH_LSPP
++  security_context_t	scon;		/* Security context of job */
++  uid_t			auid;		/* Audit loginuid for this job */
++#endif /* WITH_LSPP */
+ };
+ 
+ typedef struct cupsd_joblog_s		/**** Job log message ****/
+diff -up cups-2.2b2/scheduler/main.c.lspp cups-2.2b2/scheduler/main.c
+--- cups-2.2b2/scheduler/main.c.lspp	2016-06-27 17:39:48.064973966 +0200
++++ cups-2.2b2/scheduler/main.c	2016-06-27 17:39:48.081973831 +0200
+@@ -56,6 +56,9 @@
+ #  include <sys/param.h>
+ #endif /* HAVE_SYS_PARAM_H */
+ 
++#ifdef WITH_LSPP
++#  include <libaudit.h>
++#endif /* WITH_LSPP */
+ 
+ /*
+  * Local functions...
+@@ -122,6 +125,9 @@ main(int  argc,				/* I - Number of comm
+ #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+   struct sigaction	action;		/* Actions for POSIX signals */
+ #endif /* HAVE_SIGACTION && !HAVE_SIGSET */
++#if WITH_LSPP
++  auditfail_t           failmode;       /* Action for audit_open failure */
++#endif /* WITH_LSPP */
+ #ifdef __APPLE__
+   int			use_sysman = 1;	/* Use system management functions? */
+ #else
+@@ -505,6 +511,25 @@ main(int  argc,				/* I - Number of comm
+     exit(errno);
+   }
+ 
++#ifdef WITH_LSPP
++  if ((AuditLog = audit_open()) < 0 )
++  {
++    if (get_auditfail_action(&failmode) == 0)
++    {
++      if (failmode == FAIL_LOG)
++      {
++        cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to connect to audit subsystem.");
++        AuditLog = -1;
++      }
++      else if (failmode == FAIL_TERMINATE)
++      {
++        fprintf(stderr, "cupsd: unable to start auditing, terminating");
++        return -1;
++      }
++    }
++  }
++#endif /* WITH_LSPP */
++
+  /*
+   * Set the timezone info...
+   */
+@@ -1205,6 +1230,11 @@ main(int  argc,				/* I - Number of comm
+ 
+   cupsdStopSelect();
+ 
++#ifdef WITH_LSPP
++  if (AuditLog != -1)
++    audit_close(AuditLog);
++#endif /* WITH_LSPP */
++
+   return (!stop_scheduler);
+ }
+ 
+diff -up cups-2.2b2/scheduler/printers.c.lspp cups-2.2b2/scheduler/printers.c
+--- cups-2.2b2/scheduler/printers.c.lspp	2016-06-27 17:39:48.013974372 +0200
++++ cups-2.2b2/scheduler/printers.c	2016-06-27 17:39:48.082973823 +0200
+@@ -11,6 +11,8 @@
+  * file is missing or damaged, see the license at "http://www.cups.org/".
+  */
+ 
++/* (c) Copyright 2005-2006 Hewlett-Packard Development Company, L.P. */
++
+ /*
+  * Include necessary headers...
+  */
+@@ -35,6 +37,10 @@
+ #  include <asl.h>
+ #endif /* __APPLE__ */
+ 
++#ifdef WITH_LSPP
++#  include <libaudit.h>
++#  include <selinux/context.h>
++#endif /* WITH_LSPP */
+ 
+ /*
+  * Local functions...
+@@ -2191,6 +2197,13 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)
+   ipp_attribute_t *attr;		/* Attribute data */
+   char		*name,			/* Current user/group name */
+ 		*filter;		/* Current filter */
++#ifdef WITH_LSPP
++  char		*audit_message;		/* Audit message string */
++  char		*printerfile;		/* Path to a local printer dev */
++  char		*rangestr;		/* Printer's range if its available */
++  security_context_t	devcon;		/* Printer SELinux context */
++  context_t	printercon;		/* context_t for the printer */
++#endif /* WITH_LSPP */
+ 
+ 
+   DEBUG_printf(("cupsdSetPrinterAttrs: entering name = %s, type = %x\n", p->name,
+@@ -2318,6 +2331,45 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)
+       attr->values[1].string.text = _cupsStrAlloc(Classification ?
+ 	                                   Classification : p->job_sheets[1]);
+     }
++#ifdef WITH_LSPP
++    if (AuditLog != -1)
++    {
++      audit_message = NULL;
++      rangestr = NULL;
++      printercon = 0;
++      printerfile = strstr(p->device_uri, "/dev/");
++      if (printerfile == NULL && (strncmp(p->device_uri, "file:/", 6) == 0))
++        printerfile = p->device_uri + strlen("file:");
++
++      if (printerfile != NULL)
++      {
++        if (getfilecon(printerfile, &devcon) == -1)
++        {
++          if(is_selinux_enabled())
++            cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdSetPrinterAttrs: Unable to get printer context");
++        }
++        else
++        {
++          printercon = context_new(devcon);
++          freecon(devcon);
++        }
++      }
++
++      if (printercon && context_range_get(printercon))
++        rangestr = strdup(context_range_get(printercon));
++      else
++        rangestr = strdup("unknown");
++
++      cupsdSetStringf(&audit_message, "printer=%s uri=%s banners=%s,%s range=%s",
++                      p->name, p->sanitized_device_uri, p->job_sheets[0], p->job_sheets[1], rangestr);
++      audit_log_user_message(AuditLog, AUDIT_LABEL_LEVEL_CHANGE, audit_message,
++                             ServerName, NULL, NULL, 1);
++      if (printercon)
++        context_free(printercon);
++      free(rangestr);
++      cupsdClearString(&audit_message);
++    }
++#endif /* WITH_LSPP */
+   }
+ 
+   p->raw    = 0;
diff --git a/cups-man_pages_linking.patch b/cups-man_pages_linking.patch
index 983c629..57d4973 100644
--- a/cups-man_pages_linking.patch
+++ b/cups-man_pages_linking.patch
@@ -22,7 +22,7 @@
 @@ -69,10 +69,10 @@
  		;;
  	Linux* | GNU* | Darwin*)
- 		# Linux, GNU Hurd, and OS X
+ 		# Linux, GNU Hurd, and macOS
 -		MAN1EXT=1.gz
 -		MAN5EXT=5.gz
 -		MAN7EXT=7.gz
diff --git a/cups-pid.patch b/cups-pid.patch
new file mode 100644
index 0000000..23ffd47
--- /dev/null
+++ b/cups-pid.patch
@@ -0,0 +1,37 @@
+diff -up cups-1.5b1/scheduler/main.c.pid cups-1.5b1/scheduler/main.c
+--- cups-1.5b1/scheduler/main.c.pid	2011-05-18 22:44:16.000000000 +0200
++++ cups-1.5b1/scheduler/main.c	2011-05-23 18:01:20.000000000 +0200
+@@ -311,6 +311,8 @@ main(int  argc,				/* I - Number of comm
+     * Setup signal handlers for the parent...
+     */
+ 
++    pid_t pid;
++
+ #ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
+     sigset(SIGUSR1, parent_handler);
+     sigset(SIGCHLD, parent_handler);
+@@ -334,7 +336,7 @@ main(int  argc,				/* I - Number of comm
+     signal(SIGHUP, SIG_IGN);
+ #endif /* HAVE_SIGSET */
+ 
+-    if (fork() > 0)
++    if ((pid = fork()) > 0)
+     {
+      /*
+       * OK, wait for the child to startup and send us SIGUSR1 or to crash
+@@ -346,7 +348,15 @@ main(int  argc,				/* I - Number of comm
+         sleep(1);
+ 
+       if (parent_signal == SIGUSR1)
++      {
++        FILE *f = fopen ("/var/run/cupsd.pid", "w");
++        if (f)
++        {
++          fprintf (f, "%d\n", pid);
++          fclose (f);
++        }
+         return (0);
++      }
+ 
+       if (wait(&i) < 0)
+       {
diff --git a/cups-res_init.patch b/cups-res_init.patch
new file mode 100644
index 0000000..3866521
--- /dev/null
+++ b/cups-res_init.patch
@@ -0,0 +1,26 @@
+diff -up cups-1.7b1/cups/http-addr.c.res_init cups-1.7b1/cups/http-addr.c
+--- cups-1.7b1/cups/http-addr.c.res_init	2013-03-20 19:14:10.000000000 +0100
++++ cups-1.7b1/cups/http-addr.c	2013-04-19 12:01:36.927512159 +0200
+@@ -319,7 +319,8 @@ httpAddrLookup(
+ 
+     if (error)
+     {
+-      if (error == EAI_FAIL)
++      if (error == EAI_FAIL || error == EAI_AGAIN || error == EAI_NODATA ||
++          error == EAI_NONAME)
+         cg->need_res_init = 1;
+ 
+       return (httpAddrString(addr, name, namelen));
+diff -up cups-1.7b1/cups/http-addrlist.c.res_init cups-1.7b1/cups/http-addrlist.c
+--- cups-1.7b1/cups/http-addrlist.c.res_init	2013-04-19 12:01:36.930512119 +0200
++++ cups-1.7b1/cups/http-addrlist.c	2013-04-19 12:03:13.769229554 +0200
+@@ -581,7 +581,8 @@ httpAddrGetList(const char *hostname,	/*
+     }
+     else
+     {
+-      if (error == EAI_FAIL)
++      if (error == EAI_FAIL || error == EAI_AGAIN || error == EAI_NODATA ||
++          error == EAI_NONAME)
+         cg->need_res_init = 1;
+ 
+       _cupsSetError(IPP_STATUS_ERROR_INTERNAL, gai_strerror(error), 0);
diff --git a/cups-ricoh-deviceid-oid.patch b/cups-ricoh-deviceid-oid.patch
new file mode 100644
index 0000000..c148f95
--- /dev/null
+++ b/cups-ricoh-deviceid-oid.patch
@@ -0,0 +1,21 @@
+diff -up cups-1.5b1/backend/snmp.c.ricoh-deviceid-oid cups-1.5b1/backend/snmp.c
+--- cups-1.5b1/backend/snmp.c.ricoh-deviceid-oid	2011-05-24 17:29:48.000000000 +0200
++++ cups-1.5b1/backend/snmp.c	2011-05-24 17:29:48.000000000 +0200
+@@ -188,6 +188,7 @@ static const int	LexmarkProductOID[] = {
+ static const int	LexmarkProductOID2[] = { 1,3,6,1,4,1,674,10898,100,2,1,2,1,2,1,-1 };
+ static const int	LexmarkDeviceIdOID[] = { 1,3,6,1,4,1,641,2,1,2,1,3,1,-1 };
+ static const int	HPDeviceIdOID[] = { 1,3,6,1,4,1,11,2,3,9,1,1,7,0,-1 };
++static const int	RicohDeviceIdOID[] = { 1,3,6,1,4,1,367,3,2,1,1,1,11,0,-1 };
+ static const int	XeroxProductOID[] = { 1,3,6,1,4,1,128,2,1,3,1,2,0,-1 };
+ static cups_array_t	*DeviceURIs = NULL;
+ static int		HostNameLookups = 0;
+@@ -1005,6 +1006,9 @@ read_snmp_response(int fd)		/* I - SNMP 
+ 	               packet.community, CUPS_ASN1_GET_REQUEST,
+ 		       DEVICE_ID, LexmarkDeviceIdOID);
+ 	_cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1,
++		       packet.community, CUPS_ASN1_GET_REQUEST,
++		       DEVICE_ID, RicohDeviceIdOID);
++	_cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1,
+ 	               packet.community, CUPS_ASN1_GET_REQUEST,
+ 		       DEVICE_PRODUCT, XeroxProductOID);
+ 	_cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1,
diff --git a/cups-systemd-socket.patch b/cups-systemd-socket.patch
index 03c21b8..c6c3506 100644
--- a/cups-systemd-socket.patch
+++ b/cups-systemd-socket.patch
@@ -1,9 +1,9 @@
-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
+diff -up cups-2.2b2/scheduler/main.c.systemd-socket cups-2.2b2/scheduler/main.c
+--- cups-2.2b2/scheduler/main.c.systemd-socket	2016-06-27 15:12:24.930881404 +0200
++++ cups-2.2b2/scheduler/main.c	2016-06-27 15:19:38.118234985 +0200
+@@ -690,8 +690,15 @@ main(int  argc,				/* I - Number of comm
  
- #if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
+ #if defined(HAVE_ONDEMAND)
    if (OnDemand)
 +  {
      cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL, "Scheduler started on demand.");
@@ -15,12 +15,12 @@ diff -up cups-2.0.2/scheduler/main.c.ustTJg cups-2.0.2/scheduler/main.c
 +               (unsigned long) getpid());
 +# endif /* HAVE_SYSTEMD */
 +  } else
- #endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
+ #endif /* HAVE_ONDEMAND */
    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
+diff -up cups-2.2b2/scheduler/org.cups.cupsd.path.in.systemd-socket cups-2.2b2/scheduler/org.cups.cupsd.path.in
+--- cups-2.2b2/scheduler/org.cups.cupsd.path.in.systemd-socket	2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/scheduler/org.cups.cupsd.path.in	2016-06-27 15:12:24.930881404 +0200
 @@ -2,7 +2,7 @@
  Description=CUPS Scheduler
  
@@ -30,9 +30,9 @@ diff -up cups-2.0.2/scheduler/org.cups.cupsd.path.in.ustTJg cups-2.0.2/scheduler
  
  [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
+diff -up cups-2.2b2/scheduler/org.cups.cupsd.service.in.systemd-socket cups-2.2b2/scheduler/org.cups.cupsd.service.in
+--- cups-2.2b2/scheduler/org.cups.cupsd.service.in.systemd-socket	2016-06-24 17:43:35.000000000 +0200
++++ cups-2.2b2/scheduler/org.cups.cupsd.service.in	2016-06-27 15:12:24.930881404 +0200
 @@ -1,10 +1,11 @@
  [Unit]
  Description=CUPS Scheduler
diff --git a/cups-web-devices-timeout.patch b/cups-web-devices-timeout.patch
new file mode 100644
index 0000000..fa3a320
--- /dev/null
+++ b/cups-web-devices-timeout.patch
@@ -0,0 +1,19 @@
+diff -up cups-1.7rc1/cgi-bin/admin.c.web-devices-timeout cups-1.7rc1/cgi-bin/admin.c
+--- cups-1.7rc1/cgi-bin/admin.c.web-devices-timeout	2013-05-29 12:51:34.000000000 +0100
++++ cups-1.7rc1/cgi-bin/admin.c	2013-08-16 16:01:17.308264287 +0100
+@@ -1019,13 +1019,13 @@ do_am_printer(http_t *http,		/* I - HTTP
+     }
+ 
+    /*
+-    * Scan for devices for up to 30 seconds...
++    * Scan for devices for up to 10 seconds...
+     */
+ 
+     fputs("DEBUG: Getting list of devices...\n", stderr);
+ 
+     current_device = 0;
+-    if (cupsGetDevices(http, 5, CUPS_INCLUDE_ALL, CUPS_EXCLUDE_NONE,
++    if (cupsGetDevices(http, 10, CUPS_INCLUDE_ALL, CUPS_EXCLUDE_NONE,
+                        (cups_device_cb_t)choose_device_cb,
+ 		       (void *)title) == IPP_OK)
+     {
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/cups.git/commitdiff/b3b509330e6840e7a1a1b6c08b72cbab040eb5d5



More information about the pld-cvs-commit mailing list