commit
a4e76e2143
@ -0,0 +1,2 @@
|
|||||||
|
b5e3389fb9450bfed377c95c0230c029c053acc4 SOURCES/cups-2.2.6-source.tar.gz
|
||||||
|
79ee155bed4c18088be472a6e364f37ad6e410a6 SOURCES/cupsprinter.png
|
@ -0,0 +1,2 @@
|
|||||||
|
SOURCES/cups-2.2.6-source.tar.gz
|
||||||
|
SOURCES/cupsprinter.png
|
@ -0,0 +1,497 @@
|
|||||||
|
diff -up cups-2.2.6/cups/http-private.h.remove-weak-ciphers cups-2.2.6/cups/http-private.h
|
||||||
|
--- cups-2.2.6/cups/http-private.h.remove-weak-ciphers 2017-11-01 15:57:53.000000000 +0100
|
||||||
|
+++ cups-2.2.6/cups/http-private.h 2018-08-07 11:53:54.985633959 +0200
|
||||||
|
@@ -180,13 +180,17 @@ extern "C" {
|
||||||
|
|
||||||
|
# define _HTTP_TLS_NONE 0 /* No TLS options */
|
||||||
|
# define _HTTP_TLS_ALLOW_RC4 1 /* Allow RC4 cipher suites */
|
||||||
|
-# define _HTTP_TLS_ALLOW_SSL3 2 /* Allow SSL 3.0 */
|
||||||
|
-# define _HTTP_TLS_ALLOW_DH 4 /* Allow DH/DHE key negotiation */
|
||||||
|
-# define _HTTP_TLS_DENY_TLS10 16 /* Deny TLS 1.0 */
|
||||||
|
-# define _HTTP_TLS_DENY_CBC 32 /* Deny CBC cipher suites */
|
||||||
|
-# define _HTTP_TLS_ONLY_TLS10 64 /* Only use TLS 1.0 */
|
||||||
|
+# define _HTTP_TLS_ALLOW_DH 2 /* Allow DH/DHE key negotiation */
|
||||||
|
+# define _HTTP_TLS_DENY_CBC 4 /* Deny CBC cipher suites */
|
||||||
|
# define _HTTP_TLS_SET_DEFAULT 128 /* Setting the default TLS options */
|
||||||
|
|
||||||
|
+# define _HTTP_TLS_SSL3 0 /* Min/max version is SSL/3.0 */
|
||||||
|
+# define _HTTP_TLS_1_0 1 /* Min/max version is TLS/1.0 */
|
||||||
|
+# define _HTTP_TLS_1_1 2 /* Min/max version is TLS/1.1 */
|
||||||
|
+# define _HTTP_TLS_1_2 3 /* Min/max version is TLS/1.2 */
|
||||||
|
+# define _HTTP_TLS_1_3 4 /* Min/max version is TLS/1.3 */
|
||||||
|
+# define _HTTP_TLS_MAX 5 /* Highest known TLS version */
|
||||||
|
+
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Types and functions for SSL support...
|
||||||
|
@@ -442,7 +446,7 @@ extern void _httpTLSInitialize(void);
|
||||||
|
extern size_t _httpTLSPending(http_t *http);
|
||||||
|
extern int _httpTLSRead(http_t *http, char *buf, int len);
|
||||||
|
extern int _httpTLSSetCredentials(http_t *http);
|
||||||
|
-extern void _httpTLSSetOptions(int options);
|
||||||
|
+extern void _httpTLSSetOptions(int options, int min_version, int max_version);
|
||||||
|
extern int _httpTLSStart(http_t *http);
|
||||||
|
extern void _httpTLSStop(http_t *http);
|
||||||
|
extern int _httpTLSWrite(http_t *http, const char *buf, int len);
|
||||||
|
diff -up cups-2.2.6/cups/tlscheck.c.remove-weak-ciphers cups-2.2.6/cups/tlscheck.c
|
||||||
|
--- cups-2.2.6/cups/tlscheck.c.remove-weak-ciphers 2017-11-01 15:57:53.000000000 +0100
|
||||||
|
+++ cups-2.2.6/cups/tlscheck.c 2018-08-07 11:53:54.987633942 +0200
|
||||||
|
@@ -54,6 +54,8 @@ main(int argc, /* I - Number of comm
|
||||||
|
int af = AF_UNSPEC, /* Address family */
|
||||||
|
tls_options = _HTTP_TLS_NONE,
|
||||||
|
/* TLS options */
|
||||||
|
+ tls_min_version = _HTTP_TLS_1_0,
|
||||||
|
+ tls_max_version = _HTTP_TLS_MAX,
|
||||||
|
verbose = 0; /* Verbosity */
|
||||||
|
ipp_t *request, /* IPP Get-Printer-Attributes request */
|
||||||
|
*response; /* IPP Get-Printer-Attributes response */
|
||||||
|
@@ -88,11 +90,12 @@ main(int argc, /* I - Number of comm
|
||||||
|
}
|
||||||
|
else if (!strcmp(argv[i], "--no-tls10"))
|
||||||
|
{
|
||||||
|
- tls_options |= _HTTP_TLS_DENY_TLS10;
|
||||||
|
+ tls_min_version = _HTTP_TLS_1_1;
|
||||||
|
}
|
||||||
|
else if (!strcmp(argv[i], "--tls10"))
|
||||||
|
{
|
||||||
|
- tls_options |= _HTTP_TLS_ONLY_TLS10;
|
||||||
|
+ tls_min_version = _HTTP_TLS_1_0;
|
||||||
|
+ tls_max_version = _HTTP_TLS_1_0;
|
||||||
|
}
|
||||||
|
else if (!strcmp(argv[i], "--rc4"))
|
||||||
|
{
|
||||||
|
@@ -148,7 +151,7 @@ main(int argc, /* I - Number of comm
|
||||||
|
if (!port)
|
||||||
|
port = 631;
|
||||||
|
|
||||||
|
- _httpTLSSetOptions(tls_options);
|
||||||
|
+ _httpTLSSetOptions(tls_options, tls_min_version, tls_max_version);
|
||||||
|
|
||||||
|
http = httpConnect2(server, port, NULL, af, HTTP_ENCRYPTION_ALWAYS, 1, 30000, NULL);
|
||||||
|
if (!http)
|
||||||
|
diff -up cups-2.2.6/cups/tls-darwin.c.remove-weak-ciphers cups-2.2.6/cups/tls-darwin.c
|
||||||
|
--- cups-2.2.6/cups/tls-darwin.c.remove-weak-ciphers 2017-11-01 15:57:53.000000000 +0100
|
||||||
|
+++ cups-2.2.6/cups/tls-darwin.c 2018-08-07 11:53:54.986633951 +0200
|
||||||
|
@@ -53,7 +53,9 @@ static char *tls_keypath = NULL;
|
||||||
|
/* Server cert keychain path */
|
||||||
|
static _cups_mutex_t tls_mutex = _CUPS_MUTEX_INITIALIZER;
|
||||||
|
/* Mutex for keychain/certs */
|
||||||
|
-static int tls_options = -1;/* Options for TLS connections */
|
||||||
|
+static int tls_options = -1,/* Options for TLS connections */
|
||||||
|
+ tls_min_version = _HTTP_TLS_1_0,
|
||||||
|
+ tls_max_version = _HTTP_TLS_MAX;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -1139,10 +1141,16 @@ _httpTLSRead(http_t *http, /* I - HTTP
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
-_httpTLSSetOptions(int options) /* I - Options */
|
||||||
|
+_httpTLSSetOptions(int options, /* I - Options */
|
||||||
|
+ int min_version, /* I - Minimum TLS version */
|
||||||
|
+ int max_version) /* I - Maximum TLS version */
|
||||||
|
{
|
||||||
|
if (!(options & _HTTP_TLS_SET_DEFAULT) || tls_options < 0)
|
||||||
|
- tls_options = options;
|
||||||
|
+ {
|
||||||
|
+ tls_options = options;
|
||||||
|
+ tls_min_version = min_version;
|
||||||
|
+ tls_max_version = max_version;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1174,7 +1182,7 @@ _httpTLSStart(http_t *http) /* I - HTTP
|
||||||
|
{
|
||||||
|
DEBUG_puts("4_httpTLSStart: Setting defaults.");
|
||||||
|
_cupsSetDefaults();
|
||||||
|
- DEBUG_printf(("4_httpTLSStart: tls_options=%x", tls_options));
|
||||||
|
+ DEBUG_printf(("4_httpTLSStart: tls_options=%x, tls_min_version=%d, tls_max_version=%d", tls_options, tls_min_version, tls_max_version));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_SECKEYCHAINOPEN
|
||||||
|
@@ -1217,22 +1225,23 @@ _httpTLSStart(http_t *http) /* I - HTTP
|
||||||
|
|
||||||
|
if (!error)
|
||||||
|
{
|
||||||
|
- SSLProtocol minProtocol;
|
||||||
|
-
|
||||||
|
- if (tls_options & _HTTP_TLS_DENY_TLS10)
|
||||||
|
- minProtocol = kTLSProtocol11;
|
||||||
|
- else if (tls_options & _HTTP_TLS_ALLOW_SSL3)
|
||||||
|
- minProtocol = kSSLProtocol3;
|
||||||
|
- else
|
||||||
|
- minProtocol = kTLSProtocol1;
|
||||||
|
+ static const SSLProtocol protocols[] = /* Min/max protocol versions */
|
||||||
|
+ {
|
||||||
|
+ kSSLProtocol3,
|
||||||
|
+ kTLSProtocol1,
|
||||||
|
+ kTLSProtocol11,
|
||||||
|
+ kTLSProtocol12,
|
||||||
|
+ kTLSProtocol13,
|
||||||
|
+ kTLSProtocolMaxSupported
|
||||||
|
+ };
|
||||||
|
|
||||||
|
- error = SSLSetProtocolVersionMin(http->tls, minProtocol);
|
||||||
|
- DEBUG_printf(("4_httpTLSStart: SSLSetProtocolVersionMin(%d), error=%d", minProtocol, (int)error));
|
||||||
|
+ error = SSLSetProtocolVersionMin(http->tls, protocols[tls_min_version]);
|
||||||
|
+ DEBUG_printf(("4_httpTLSStart: SSLSetProtocolVersionMin(%d), error=%d", protocols[tls_min_version], (int)error));
|
||||||
|
|
||||||
|
- if (!error && (tls_options & _HTTP_TLS_ONLY_TLS10))
|
||||||
|
+ if (!error)
|
||||||
|
{
|
||||||
|
- error = SSLSetProtocolVersionMax(http->tls, kTLSProtocol1);
|
||||||
|
- DEBUG_printf(("4_httpTLSStart: SSLSetProtocolVersionMax(kTLSProtocol1), error=%d", (int)error));
|
||||||
|
+ error = SSLSetProtocolVersionMax(http->tls, protocols[tls_max_version]);
|
||||||
|
+ DEBUG_printf(("4_httpTLSStart: SSLSetProtocolVersionMax(%d), error=%d", protocols[tls_max_version], (int)error));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff -up cups-2.2.6/cups/tls-gnutls.c.remove-weak-ciphers cups-2.2.6/cups/tls-gnutls.c
|
||||||
|
--- cups-2.2.6/cups/tls-gnutls.c.remove-weak-ciphers 2017-11-01 15:57:53.000000000 +0100
|
||||||
|
+++ cups-2.2.6/cups/tls-gnutls.c 2018-08-07 11:58:45.164114342 +0200
|
||||||
|
@@ -35,7 +35,9 @@ static char *tls_keypath = NULL;
|
||||||
|
/* Server cert keychain path */
|
||||||
|
static _cups_mutex_t tls_mutex = _CUPS_MUTEX_INITIALIZER;
|
||||||
|
/* Mutex for keychain/certs */
|
||||||
|
-static int tls_options = -1;/* Options for TLS connections */
|
||||||
|
+static int tls_options = -1,/* Options for TLS connections */
|
||||||
|
+ tls_min_version = _HTTP_TLS_1_0,
|
||||||
|
+ tls_max_version = _HTTP_TLS_MAX;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -1224,10 +1226,16 @@ _httpTLSSetCredentials(http_t *http) /*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
-_httpTLSSetOptions(int options) /* I - Options */
|
||||||
|
+_httpTLSSetOptions(int options, /* I - Options */
|
||||||
|
+ int min_version, /* I - Minimum TLS version */
|
||||||
|
+ int max_version) /* I - Maximum TLS version */
|
||||||
|
{
|
||||||
|
if (!(options & _HTTP_TLS_SET_DEFAULT) || tls_options < 0)
|
||||||
|
- tls_options = options;
|
||||||
|
+ {
|
||||||
|
+ tls_options = options;
|
||||||
|
+ tls_min_version = min_version;
|
||||||
|
+ tls_max_version = max_version;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1245,6 +1253,16 @@ _httpTLSStart(http_t *http) /* I - Conn
|
||||||
|
/* TLS credentials */
|
||||||
|
char priority_string[2048];
|
||||||
|
/* Priority string */
|
||||||
|
+ int version; /* Current version */
|
||||||
|
+ static const char * const versions[] =/* SSL/TLS versions */
|
||||||
|
+ {
|
||||||
|
+ "VERS-SSL3.0",
|
||||||
|
+ "VERS-TLS1.0",
|
||||||
|
+ "VERS-TLS1.1",
|
||||||
|
+ "VERS-TLS1.2",
|
||||||
|
+ "VERS-TLS1.3",
|
||||||
|
+ "VERS-TLS-ALL"
|
||||||
|
+ };
|
||||||
|
|
||||||
|
|
||||||
|
DEBUG_printf(("3_httpTLSStart(http=%p)", http));
|
||||||
|
@@ -1506,14 +1524,40 @@ _httpTLSStart(http_t *http) /* I - Conn
|
||||||
|
|
||||||
|
strlcpy(priority_string, "NORMAL", sizeof(priority_string));
|
||||||
|
|
||||||
|
- if (tls_options & _HTTP_TLS_DENY_TLS10)
|
||||||
|
- strlcat(priority_string, ":+VERS-TLS-ALL:-VERS-TLS1.0:-VERS-SSL3.0", sizeof(priority_string));
|
||||||
|
- else if (tls_options & _HTTP_TLS_ALLOW_SSL3)
|
||||||
|
+ if (tls_max_version < _HTTP_TLS_MAX)
|
||||||
|
+ {
|
||||||
|
+ /*
|
||||||
|
+ * Require specific TLS versions...
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ strlcat(priority_string, ":-VERS-TLS-ALL", sizeof(priority_string));
|
||||||
|
+ for (version = tls_min_version; version <= tls_max_version; version ++)
|
||||||
|
+ {
|
||||||
|
+ strlcat(priority_string, ":+", sizeof(priority_string));
|
||||||
|
+ strlcat(priority_string, versions[version], sizeof(priority_string));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else if (tls_min_version == _HTTP_TLS_SSL3)
|
||||||
|
+ {
|
||||||
|
+ /*
|
||||||
|
+ * Allow all versions of TLS and SSL/3.0...
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
strlcat(priority_string, ":+VERS-TLS-ALL:+VERS-SSL3.0", sizeof(priority_string));
|
||||||
|
- else if (tls_options & _HTTP_TLS_ONLY_TLS10)
|
||||||
|
- strlcat(priority_string, ":-VERS-TLS-ALL:-VERS-SSL3.0:+VERS-TLS1.0", sizeof(priority_string));
|
||||||
|
+ }
|
||||||
|
else
|
||||||
|
- strlcat(priority_string, ":+VERS-TLS-ALL:-VERS-SSL3.0", sizeof(priority_string));
|
||||||
|
+ {
|
||||||
|
+ /*
|
||||||
|
+ * Require a minimum version...
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ strlcat(priority_string, ":+VERS-TLS-ALL", sizeof(priority_string));
|
||||||
|
+ for (version = 0; version < tls_min_version; version ++)
|
||||||
|
+ {
|
||||||
|
+ strlcat(priority_string, ":-", sizeof(priority_string));
|
||||||
|
+ strlcat(priority_string, versions[version], sizeof(priority_string));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (tls_options & _HTTP_TLS_ALLOW_RC4)
|
||||||
|
strlcat(priority_string, ":+ARCFOUR-128", sizeof(priority_string));
|
||||||
|
diff -up cups-2.2.6/cups/tls-sspi.c.remove-weak-ciphers cups-2.2.6/cups/tls-sspi.c
|
||||||
|
--- cups-2.2.6/cups/tls-sspi.c.remove-weak-ciphers 2017-11-01 15:57:53.000000000 +0100
|
||||||
|
+++ cups-2.2.6/cups/tls-sspi.c 2018-08-07 11:53:54.986633951 +0200
|
||||||
|
@@ -52,7 +52,9 @@
|
||||||
|
* Local globals...
|
||||||
|
*/
|
||||||
|
|
||||||
|
-static int tls_options = -1;/* Options for TLS connections */
|
||||||
|
+static int tls_options = -1,/* Options for TLS connections */
|
||||||
|
+ tls_min_version = _HTTP_TLS_1_0,
|
||||||
|
+ tls_max_version = _HTTP_TLS_MAX;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -914,7 +916,11 @@ void
|
||||||
|
_httpTLSSetOptions(int options) /* I - Options */
|
||||||
|
{
|
||||||
|
if (!(options & _HTTP_TLS_SET_DEFAULT) || tls_options < 0)
|
||||||
|
- tls_options = options;
|
||||||
|
+ {
|
||||||
|
+ tls_options = options;
|
||||||
|
+ tls_min_version = min_version;
|
||||||
|
+ tls_max_version = max_version;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1782,14 +1788,14 @@ http_sspi_find_credentials(
|
||||||
|
#else
|
||||||
|
if (http->mode == _HTTP_MODE_SERVER)
|
||||||
|
{
|
||||||
|
- if (tls_options & _HTTP_TLS_ALLOW_SSL3)
|
||||||
|
+ if (tls_min_version == _HTTP_TLS_SSL3)
|
||||||
|
SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_SERVER | SP_PROT_SSL3_SERVER;
|
||||||
|
else
|
||||||
|
SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_SERVER;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
- if (tls_options & _HTTP_TLS_ALLOW_SSL3)
|
||||||
|
+ if (tls_min_version == _HTTP_TLS_SSL3)
|
||||||
|
SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT | SP_PROT_SSL3_CLIENT;
|
||||||
|
else
|
||||||
|
SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT;
|
||||||
|
diff -up cups-2.2.6/cups/usersys.c.remove-weak-ciphers cups-2.2.6/cups/usersys.c
|
||||||
|
--- cups-2.2.6/cups/usersys.c.remove-weak-ciphers 2018-08-07 11:53:54.945634283 +0200
|
||||||
|
+++ cups-2.2.6/cups/usersys.c 2018-08-07 11:53:54.987633942 +0200
|
||||||
|
@@ -54,7 +54,9 @@
|
||||||
|
typedef struct _cups_client_conf_s /**** client.conf config data ****/
|
||||||
|
{
|
||||||
|
#ifdef HAVE_SSL
|
||||||
|
- int ssl_options; /* SSLOptions values */
|
||||||
|
+ int ssl_options, /* SSLOptions values */
|
||||||
|
+ ssl_min_version,/* Minimum SSL/TLS version */
|
||||||
|
+ ssl_max_version;/* Maximum SSL/TLS version */
|
||||||
|
#endif /* HAVE_SSL */
|
||||||
|
int trust_first, /* Trust on first use? */
|
||||||
|
any_root, /* Allow any (e.g., self-signed) root */
|
||||||
|
@@ -957,7 +959,7 @@ _cupsSetDefaults(void)
|
||||||
|
cg->validate_certs = cc.validate_certs;
|
||||||
|
|
||||||
|
#ifdef HAVE_SSL
|
||||||
|
- _httpTLSSetOptions(cc.ssl_options | _HTTP_TLS_SET_DEFAULT);
|
||||||
|
+ _httpTLSSetOptions(cc.ssl_options | _HTTP_TLS_SET_DEFAULT, cc.ssl_min_version, cc.ssl_max_version);
|
||||||
|
#endif /* HAVE_SSL */
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1336,7 +1338,9 @@ cups_set_ssl_options(
|
||||||
|
* SSLOptions [AllowRC4] [AllowSSL3] [AllowDH] [DenyTLS1.0] [None]
|
||||||
|
*/
|
||||||
|
|
||||||
|
- int options = _HTTP_TLS_NONE; /* SSL/TLS options */
|
||||||
|
+ int options = _HTTP_TLS_NONE, /* SSL/TLS options */
|
||||||
|
+ min_version = _HTTP_TLS_1_0, /* Minimum SSL/TLS version */
|
||||||
|
+ max_version = _HTTP_TLS_MAX; /* Maximum SSL/TLS version */
|
||||||
|
char temp[256], /* Copy of value */
|
||||||
|
*start, /* Start of option */
|
||||||
|
*end; /* End of option */
|
||||||
|
@@ -1364,20 +1368,38 @@ cups_set_ssl_options(
|
||||||
|
if (!_cups_strcasecmp(start, "AllowRC4"))
|
||||||
|
options |= _HTTP_TLS_ALLOW_RC4;
|
||||||
|
else if (!_cups_strcasecmp(start, "AllowSSL3"))
|
||||||
|
- options |= _HTTP_TLS_ALLOW_SSL3;
|
||||||
|
+ min_version = _HTTP_TLS_SSL3;
|
||||||
|
else if (!_cups_strcasecmp(start, "AllowDH"))
|
||||||
|
options |= _HTTP_TLS_ALLOW_DH;
|
||||||
|
else if (!_cups_strcasecmp(start, "DenyCBC"))
|
||||||
|
options |= _HTTP_TLS_DENY_CBC;
|
||||||
|
else if (!_cups_strcasecmp(start, "DenyTLS1.0"))
|
||||||
|
- options |= _HTTP_TLS_DENY_TLS10;
|
||||||
|
+ min_version = _HTTP_TLS_1_1;
|
||||||
|
+ else if (!_cups_strcasecmp(start, "MaxTLS1.0"))
|
||||||
|
+ max_version = _HTTP_TLS_1_0;
|
||||||
|
+ else if (!_cups_strcasecmp(start, "MaxTLS1.1"))
|
||||||
|
+ max_version = _HTTP_TLS_1_1;
|
||||||
|
+ else if (!_cups_strcasecmp(start, "MaxTLS1.2"))
|
||||||
|
+ max_version = _HTTP_TLS_1_2;
|
||||||
|
+ else if (!_cups_strcasecmp(start, "MaxTLS1.3"))
|
||||||
|
+ max_version = _HTTP_TLS_1_3;
|
||||||
|
+ else if (!_cups_strcasecmp(start, "MinTLS1.0"))
|
||||||
|
+ min_version = _HTTP_TLS_1_0;
|
||||||
|
+ else if (!_cups_strcasecmp(start, "MinTLS1.1"))
|
||||||
|
+ min_version = _HTTP_TLS_1_1;
|
||||||
|
+ else if (!_cups_strcasecmp(start, "MinTLS1.2"))
|
||||||
|
+ min_version = _HTTP_TLS_1_2;
|
||||||
|
+ else if (!_cups_strcasecmp(start, "MinTLS1.3"))
|
||||||
|
+ min_version = _HTTP_TLS_1_3;
|
||||||
|
else if (!_cups_strcasecmp(start, "None"))
|
||||||
|
options = _HTTP_TLS_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
- cc->ssl_options = options;
|
||||||
|
+ cc->ssl_options = options;
|
||||||
|
+ cc->ssl_max_version = max_version;
|
||||||
|
+ cc->ssl_min_version = min_version;
|
||||||
|
|
||||||
|
- DEBUG_printf(("4cups_set_ssl_options(cc=%p, value=\"%s\") options=%x", (void *)cc, value, options));
|
||||||
|
+ DEBUG_printf(("4cups_set_ssl_options(cc=%p, value=\"%s\") options=%x, min_version=%d, max_version=%d", (void *)cc, value, options, min_version, max_version));
|
||||||
|
}
|
||||||
|
#endif /* HAVE_SSL */
|
||||||
|
|
||||||
|
diff -up cups-2.2.6/man/client.conf.man.in.remove-weak-ciphers cups-2.2.6/man/client.conf.man.in
|
||||||
|
--- cups-2.2.6/man/client.conf.man.in.remove-weak-ciphers 2017-11-01 15:57:53.000000000 +0100
|
||||||
|
+++ cups-2.2.6/man/client.conf.man.in 2018-08-07 11:53:54.987633942 +0200
|
||||||
|
@@ -10,7 +10,7 @@
|
||||||
|
.\" which should have been included with this file. If this file is
|
||||||
|
.\" file is missing or damaged, see the license at "http://www.cups.org/".
|
||||||
|
.\"
|
||||||
|
-.TH client.conf 5 "CUPS" "19 October 2017" "Apple Inc."
|
||||||
|
+.TH client.conf 5 "CUPS" "3 November 2017" "Apple Inc."
|
||||||
|
.SH NAME
|
||||||
|
client.conf \- client configuration file for cups
|
||||||
|
.SH DESCRIPTION
|
||||||
|
@@ -56,7 +56,7 @@ Specifies the address and optionally the
|
||||||
|
\fBServerName \fIhostname-or-ip-address\fR[\fI:port\fR]\fB/version=1.1\fR
|
||||||
|
Specifies the address and optionally the port to use when connecting to a server running CUPS 1.3.12 and earlier.
|
||||||
|
.TP 5
|
||||||
|
-\fBSSLOptions \fR[\fIAllowDH\fR] [\fIAllowRC4\fR] [\fIAllowSSL3\fR] [\fIDenyCBC\fR] [\fIDenyTLS1.0\fR]
|
||||||
|
+\fBSSLOptions \fR[\fIAllowDH\fR] [\fIAllowRC4\fR] [\fIAllowSSL3\fR] [\fIDenyCBC\fR] [\fIDenyTLS1.0\fR] [\fIMaxTLS1.0\fR] [\fIMaxTLS1.1\fR] [\fIMaxTLS1.2\fR] [\fIMaxTLS1.3\fR] [\fIMinTLS1.0\fR] [\fIMinTLS1.1\fR] [\fIMinTLS1.2\fR] [\fIMinTLS1.3\fR]
|
||||||
|
.TP 5
|
||||||
|
\fBSSLOptions None\fR
|
||||||
|
Sets encryption options (only in /etc/cups/client.conf).
|
||||||
|
@@ -68,6 +68,9 @@ The \fIAllowRC4\fR option enables the 12
|
||||||
|
The \fIAllowSSL3\fR option enables SSL v3.0, which is required for some older clients that do not support TLS v1.0.
|
||||||
|
The \fIDenyCBC\fR option disables all CBC cipher suites.
|
||||||
|
The \fIDenyTLS1.0\fR option disables TLS v1.0 support - this sets the minimum protocol version to TLS v1.1.
|
||||||
|
+The \fMinTLS\fR options set the minimum TLS version to support.
|
||||||
|
+The \fMaxTLS\fR options set the maximum TLS version to support.
|
||||||
|
+Not all operating systems support TLS 1.3 at this time.
|
||||||
|
.TP 5
|
||||||
|
\fBTrustOnFirstUse Yes\fR
|
||||||
|
.TP 5
|
||||||
|
diff -up cups-2.2.6/man/cupsd.conf.man.in.remove-weak-ciphers cups-2.2.6/man/cupsd.conf.man.in
|
||||||
|
--- cups-2.2.6/man/cupsd.conf.man.in.remove-weak-ciphers 2018-08-07 11:53:54.981633991 +0200
|
||||||
|
+++ cups-2.2.6/man/cupsd.conf.man.in 2018-08-07 11:53:54.987633942 +0200
|
||||||
|
@@ -432,10 +432,11 @@ The default is "Minimal".
|
||||||
|
Listens on the specified address and port for encrypted connections.
|
||||||
|
.\"#SSLOptions
|
||||||
|
.TP 5
|
||||||
|
-\fBSSLOptions \fR[\fIAllowDH\fR] [\fIAllowRC4\fR] [\fIAllowSSL3\fR] [\fIDenyCBC\fR] [\fIDenyTLS1.0\fR]
|
||||||
|
+.TP 5
|
||||||
|
+\fBSSLOptions \fR[\fIAllowDH\fR] [\fIAllowRC4\fR] [\fIAllowSSL3\fR] [\fIDenyCBC\fR] [\fIDenyTLS1.0\fR] [\fIMaxTLS1.0\fR] [\fIMaxTLS1.1\fR] [\fIMaxTLS1.2\fR] [\fIMaxTLS1.3\fR] [\fIMinTLS1.0\fR] [\fIMinTLS1.1\fR] [\fIMinTLS1.2\fR] [\fIMinTLS1.3\fR]
|
||||||
|
.TP 5
|
||||||
|
\fBSSLOptions None\fR
|
||||||
|
-Sets encryption options.
|
||||||
|
+Sets encryption options (only in /etc/cups/client.conf).
|
||||||
|
By default, CUPS only supports encryption using TLS v1.0 or higher using known secure cipher suites.
|
||||||
|
Security is reduced when \fIAllow\fR options are used.
|
||||||
|
Security is enhanced when \fIDeny\fR options are used.
|
||||||
|
@@ -444,6 +445,9 @@ The \fIAllowRC4\fR option enables the 12
|
||||||
|
The \fIAllowSSL3\fR option enables SSL v3.0, which is required for some older clients that do not support TLS v1.0.
|
||||||
|
The \fIDenyCBC\fR option disables all CBC cipher suites.
|
||||||
|
The \fIDenyTLS1.0\fR option disables TLS v1.0 support - this sets the minimum protocol version to TLS v1.1.
|
||||||
|
+The \fMinTLS\fR options set the minimum TLS version to support.
|
||||||
|
+The \fMaxTLS\fR options set the maximum TLS version to support.
|
||||||
|
+Not all operating systems support TLS 1.3 at this time.
|
||||||
|
.\"#SSLPort
|
||||||
|
.TP 5
|
||||||
|
\fBSSLPort \fIport\fR
|
||||||
|
diff -up cups-2.2.6/scheduler/conf.c.remove-weak-ciphers cups-2.2.6/scheduler/conf.c
|
||||||
|
--- cups-2.2.6/scheduler/conf.c.remove-weak-ciphers 2018-08-07 11:53:54.981633991 +0200
|
||||||
|
+++ cups-2.2.6/scheduler/conf.c 2018-08-07 11:53:54.988633934 +0200
|
||||||
|
@@ -630,7 +630,7 @@ cupsdReadConfiguration(void)
|
||||||
|
cupsdSetString(&ServerKeychain, "/Library/Keychains/System.keychain");
|
||||||
|
# endif /* HAVE_GNUTLS */
|
||||||
|
|
||||||
|
- _httpTLSSetOptions(0);
|
||||||
|
+ _httpTLSSetOptions(_HTTP_TLS_NONE, _HTTP_TLS_1_0, _HTTP_TLS_MAX);
|
||||||
|
#endif /* HAVE_SSL */
|
||||||
|
|
||||||
|
language = cupsLangDefault();
|
||||||
|
@@ -3024,7 +3024,9 @@ read_cupsd_conf(cups_file_t *fp) /* I -
|
||||||
|
* SSLOptions [AllowRC4] [AllowSSL3] [AllowDH] [DenyCBC] [DenyTLS1.0] [None]
|
||||||
|
*/
|
||||||
|
|
||||||
|
- int options = 0; /* SSL/TLS options */
|
||||||
|
+ int options = _HTTP_TLS_NONE,/* SSL/TLS options */
|
||||||
|
+ min_version = _HTTP_TLS_1_0,
|
||||||
|
+ max_version = _HTTP_TLS_MAX;
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
@@ -3048,24 +3050,40 @@ read_cupsd_conf(cups_file_t *fp) /* I -
|
||||||
|
* Compare...
|
||||||
|
*/
|
||||||
|
|
||||||
|
- if (!_cups_strcasecmp(start, "AllowRC4"))
|
||||||
|
+ if (!_cups_strcasecmp(start, "AllowRC4"))
|
||||||
|
options |= _HTTP_TLS_ALLOW_RC4;
|
||||||
|
- else if (!_cups_strcasecmp(start, "AllowSSL3"))
|
||||||
|
- options |= _HTTP_TLS_ALLOW_SSL3;
|
||||||
|
+ else if (!_cups_strcasecmp(start, "AllowSSL3"))
|
||||||
|
+ min_version = _HTTP_TLS_SSL3;
|
||||||
|
else if (!_cups_strcasecmp(start, "AllowDH"))
|
||||||
|
options |= _HTTP_TLS_ALLOW_DH;
|
||||||
|
else if (!_cups_strcasecmp(start, "DenyCBC"))
|
||||||
|
options |= _HTTP_TLS_DENY_CBC;
|
||||||
|
else if (!_cups_strcasecmp(start, "DenyTLS1.0"))
|
||||||
|
- options |= _HTTP_TLS_DENY_TLS10;
|
||||||
|
- else if (!_cups_strcasecmp(start, "None"))
|
||||||
|
- options = 0;
|
||||||
|
+ min_version = _HTTP_TLS_1_1;
|
||||||
|
+ else if (!_cups_strcasecmp(start, "MaxTLS1.0"))
|
||||||
|
+ max_version = _HTTP_TLS_1_0;
|
||||||
|
+ else if (!_cups_strcasecmp(start, "MaxTLS1.1"))
|
||||||
|
+ max_version = _HTTP_TLS_1_1;
|
||||||
|
+ else if (!_cups_strcasecmp(start, "MaxTLS1.2"))
|
||||||
|
+ max_version = _HTTP_TLS_1_2;
|
||||||
|
+ else if (!_cups_strcasecmp(start, "MaxTLS1.3"))
|
||||||
|
+ max_version = _HTTP_TLS_1_3;
|
||||||
|
+ else if (!_cups_strcasecmp(start, "MinTLS1.0"))
|
||||||
|
+ min_version = _HTTP_TLS_1_0;
|
||||||
|
+ else if (!_cups_strcasecmp(start, "MinTLS1.1"))
|
||||||
|
+ min_version = _HTTP_TLS_1_1;
|
||||||
|
+ else if (!_cups_strcasecmp(start, "MinTLS1.2"))
|
||||||
|
+ min_version = _HTTP_TLS_1_2;
|
||||||
|
+ else if (!_cups_strcasecmp(start, "MinTLS1.3"))
|
||||||
|
+ min_version = _HTTP_TLS_1_3;
|
||||||
|
+ else if (!_cups_strcasecmp(start, "None"))
|
||||||
|
+ options = _HTTP_TLS_NONE;
|
||||||
|
else if (_cups_strcasecmp(start, "NoEmptyFragments"))
|
||||||
|
cupsdLogMessage(CUPSD_LOG_WARN, "Unknown SSL option %s at line %d.", start, linenum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- _httpTLSSetOptions(options);
|
||||||
|
+ _httpTLSSetOptions(options, min_version, max_version);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_SSL */
|
||||||
|
else if ((!_cups_strcasecmp(line, "Port") || !_cups_strcasecmp(line, "Listen")
|
@ -0,0 +1,33 @@
|
|||||||
|
diff -up cups-2.2.6/conf/cupsd.conf.in.idleexittimeout cups-2.2.6/conf/cupsd.conf.in
|
||||||
|
--- cups-2.2.6/conf/cupsd.conf.in.idleexittimeout 2017-11-01 15:57:53.000000000 +0100
|
||||||
|
+++ cups-2.2.6/conf/cupsd.conf.in 2021-11-29 11:45:37.416058954 +0100
|
||||||
|
@@ -22,6 +22,9 @@ DefaultAuthType Basic
|
||||||
|
# Web interface setting...
|
||||||
|
WebInterface @CUPS_WEBIF@
|
||||||
|
|
||||||
|
+# Timeout after cupsd exits if idle (applied only if cupsd runs on-demand - with -l)
|
||||||
|
+IdleExitTimeout @EXIT_TIMEOUT@
|
||||||
|
+
|
||||||
|
# Restrict access to the server...
|
||||||
|
<Location />
|
||||||
|
Order allow,deny
|
||||||
|
diff -up cups-2.2.6/config-scripts/cups-defaults.m4.idleexittimeout cups-2.2.6/config-scripts/cups-defaults.m4
|
||||||
|
--- cups-2.2.6/config-scripts/cups-defaults.m4.idleexittimeout 2021-11-29 11:45:37.416058954 +0100
|
||||||
|
+++ cups-2.2.6/config-scripts/cups-defaults.m4 2021-11-29 11:46:31.680612421 +0100
|
||||||
|
@@ -425,3 +425,16 @@ esac
|
||||||
|
|
||||||
|
AC_SUBST(CUPS_WEBIF)
|
||||||
|
AC_DEFINE_UNQUOTED(CUPS_DEFAULT_WEBIF, $CUPS_DEFAULT_WEBIF)
|
||||||
|
+
|
||||||
|
+dnl Set default value of IdleExitTimeout
|
||||||
|
+AC_ARG_WITH([idle_exit_timeout], AS_HELP_STRING([--with-idle-exit-timeout], [set the default value for IdleExitTimeout, default=60]), [
|
||||||
|
+ AS_IF([test "x$withval" = "xno"], [
|
||||||
|
+ EXIT_TIMEOUT=0
|
||||||
|
+ ], [
|
||||||
|
+ EXIT_TIMEOUT=$withval
|
||||||
|
+ ])
|
||||||
|
+], [
|
||||||
|
+ EXIT_TIMEOUT=60
|
||||||
|
+])
|
||||||
|
+
|
||||||
|
+AC_SUBST([EXIT_TIMEOUT])
|
@ -0,0 +1,33 @@
|
|||||||
|
diff -up cups-2.3.3op2/config-scripts/cups-defaults.m4.conf-timeoutstartsec cups-2.3.3op2/config-scripts/cups-defaults.m4
|
||||||
|
--- cups-2.3.3op2/config-scripts/cups-defaults.m4.conf-timeoutstartsec 2021-11-29 13:50:14.568976028 +0100
|
||||||
|
+++ cups-2.3.3op2/config-scripts/cups-defaults.m4 2021-11-29 13:51:02.785567762 +0100
|
||||||
|
@@ -482,3 +482,18 @@ AC_ARG_WITH([idle_exit_timeout], AS_HELP
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_SUBST([EXIT_TIMEOUT])
|
||||||
|
+
|
||||||
|
+dnl set TimeoutStartSec for cups.service
|
||||||
|
+dnl - if used as --without-*, it sets TimeoutStartSec to infinity
|
||||||
|
+AC_ARG_WITH([systemd-timeoutstartsec],
|
||||||
|
+ AS_HELP_STRING([--with-systemd-timeoutstartsec],
|
||||||
|
+ [set TimeoutStartSec value in cups.service, default=default value in systemd]), [
|
||||||
|
+ AS_IF([ test "x$withval" = "xno" ], [
|
||||||
|
+ TIMEOUTSTARTSEC="TimeoutStartSec=infinity"
|
||||||
|
+ ], [
|
||||||
|
+ TIMEOUTSTARTSEC="TimeoutStartSec=$withval"
|
||||||
|
+ ])
|
||||||
|
+], [
|
||||||
|
+ TIMEOUTSTARTSEC=""
|
||||||
|
+])
|
||||||
|
+AC_SUBST([TIMEOUTSTARTSEC])
|
||||||
|
diff -up cups-2.3.3op2/scheduler/org.cups.cupsd.service.in.conf-timeoutstartsec cups-2.3.3op2/scheduler/org.cups.cupsd.service.in
|
||||||
|
--- cups-2.3.3op2/scheduler/org.cups.cupsd.service.in.conf-timeoutstartsec 2021-11-29 13:50:14.551976172 +0100
|
||||||
|
+++ cups-2.3.3op2/scheduler/org.cups.cupsd.service.in 2021-11-29 13:50:14.568976028 +0100
|
||||||
|
@@ -8,6 +8,7 @@ Requires=cups.socket
|
||||||
|
ExecStart=@sbindir@/cupsd -l
|
||||||
|
Type=notify
|
||||||
|
Restart=on-failure
|
||||||
|
+@TIMEOUTSTARTSEC@
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
Also=cups.socket cups.path
|
@ -0,0 +1,22 @@
|
|||||||
|
diff --git a/cgi-bin/var.c b/cgi-bin/var.c
|
||||||
|
index 316b67f05..12f3c8344 100644
|
||||||
|
--- a/cgi-bin/var.c
|
||||||
|
+++ b/cgi-bin/var.c
|
||||||
|
@@ -1186,6 +1186,7 @@ cgi_set_sid(void)
|
||||||
|
const char *remote_addr, /* REMOTE_ADDR */
|
||||||
|
*server_name, /* SERVER_NAME */
|
||||||
|
*server_port; /* SERVER_PORT */
|
||||||
|
+ struct timeval curtime; /* Current time */
|
||||||
|
|
||||||
|
|
||||||
|
if ((remote_addr = getenv("REMOTE_ADDR")) == NULL)
|
||||||
|
@@ -1195,7 +1196,8 @@ cgi_set_sid(void)
|
||||||
|
if ((server_port = getenv("SERVER_PORT")) == NULL)
|
||||||
|
server_port = "SERVER_PORT";
|
||||||
|
|
||||||
|
- CUPS_SRAND(time(NULL));
|
||||||
|
+ gettimeofday(&curtime, NULL);
|
||||||
|
+ CUPS_SRAND(curtime.tv_sec + curtime.tv_usec);
|
||||||
|
snprintf(buffer, sizeof(buffer), "%s:%s:%s:%02X%02X%02X%02X%02X%02X%02X%02X",
|
||||||
|
remote_addr, server_name, server_port,
|
||||||
|
(unsigned)CUPS_RAND() & 255, (unsigned)CUPS_RAND() & 255,
|
@ -0,0 +1,24 @@
|
|||||||
|
diff -up cups-2.2.6/cups/usersys.c.defaulttls cups-2.2.6/cups/usersys.c
|
||||||
|
--- cups-2.2.6/cups/usersys.c.defaulttls 2018-09-03 12:10:36.111230611 +0200
|
||||||
|
+++ cups-2.2.6/cups/usersys.c 2018-09-03 12:12:41.307074414 +0200
|
||||||
|
@@ -1166,11 +1166,15 @@ cups_init_client_conf(
|
||||||
|
|
||||||
|
memset(cc, 0, sizeof(_cups_client_conf_t));
|
||||||
|
|
||||||
|
- cc->encryption = (http_encryption_t)-1;
|
||||||
|
- cc->trust_first = -1;
|
||||||
|
- cc->any_root = -1;
|
||||||
|
- cc->expired_certs = -1;
|
||||||
|
- cc->validate_certs = -1;
|
||||||
|
+#ifdef HAVE_SSL
|
||||||
|
+ cc->ssl_min_version = _HTTP_TLS_1_0;
|
||||||
|
+ cc->ssl_max_version = _HTTP_TLS_MAX;
|
||||||
|
+#endif /* HAVE_SSL */
|
||||||
|
+ cc->encryption = (http_encryption_t)-1;
|
||||||
|
+ cc->trust_first = -1;
|
||||||
|
+ cc->any_root = -1;
|
||||||
|
+ cc->expired_certs = -1;
|
||||||
|
+ cc->validate_certs = -1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load settings from the org.cups.PrintingPrefs plist (which trump
|
@ -0,0 +1,21 @@
|
|||||||
|
diff -up cups-2.3.3op2/backend/lpd.c.lpd-delay cups-2.3.3op2/backend/lpd.c
|
||||||
|
--- cups-2.3.3op2/backend/lpd.c.lpd-delay 2021-02-01 22:10:25.000000000 +0100
|
||||||
|
+++ cups-2.3.3op2/backend/lpd.c 2023-06-28 17:28:52.465476261 +0200
|
||||||
|
@@ -63,7 +63,7 @@ static int abort_job = 0; /* Non-zero i
|
||||||
|
|
||||||
|
#define RESERVE_NONE 0 /* Don't reserve a priviledged port */
|
||||||
|
#define RESERVE_RFC1179 1 /* Reserve port 721-731 */
|
||||||
|
-#define RESERVE_ANY 2 /* Reserve port 1-1023 */
|
||||||
|
+#define RESERVE_ANY 2 /* Reserve port 512-1023 */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -778,7 +778,7 @@ lpd_queue(const char *hostname, /*
|
||||||
|
|
||||||
|
if (lport < 721 && reserve == RESERVE_RFC1179)
|
||||||
|
lport = 731;
|
||||||
|
- else if (lport < 1)
|
||||||
|
+ else if (lport < 512)
|
||||||
|
lport = 1023;
|
||||||
|
|
||||||
|
#ifdef HAVE_GETEUID
|
@ -0,0 +1,43 @@
|
|||||||
|
From 3e4dd41459dabc5d18edbe06eb5b81291885204b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael R Sweet <michael.r.sweet@gmail.com>
|
||||||
|
Date: Wed, 5 Dec 2018 12:18:19 -0500
|
||||||
|
Subject: [PATCH] Fix handling of MaxJobTime 0 (Issue #5438)
|
||||||
|
|
||||||
|
---
|
||||||
|
CHANGES.md | 5 +++--
|
||||||
|
scheduler/job.c | 4 +++-
|
||||||
|
scheduler/printers.c | 2 +-
|
||||||
|
3 files changed, 7 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/scheduler/job.c b/scheduler/job.c
|
||||||
|
index 3cbe56aa8..638f256db 100644
|
||||||
|
--- a/scheduler/job.c
|
||||||
|
+++ b/scheduler/job.c
|
||||||
|
@@ -5148,8 +5148,10 @@ update_job(cupsd_job_t *job) /* I - Job to check */
|
||||||
|
|
||||||
|
if (cancel_after)
|
||||||
|
job->cancel_time = time(NULL) + ippGetInteger(cancel_after, 0);
|
||||||
|
- else
|
||||||
|
+ else if (MaxJobTime > 0)
|
||||||
|
job->cancel_time = time(NULL) + MaxJobTime;
|
||||||
|
+ else
|
||||||
|
+ job->cancel_time = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/scheduler/printers.c b/scheduler/printers.c
|
||||||
|
index bb99907ad..68239d85d 100644
|
||||||
|
--- a/scheduler/printers.c
|
||||||
|
+++ b/scheduler/printers.c
|
||||||
|
@@ -3370,7 +3370,7 @@ add_printer_defaults(cupsd_printer_t *p)/* I - Printer */
|
||||||
|
"document-format-default", NULL, "application/octet-stream");
|
||||||
|
|
||||||
|
if (!cupsGetOption("job-cancel-after", p->num_options, p->options))
|
||||||
|
- ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
|
||||||
|
+ ippAddInteger(p->attrs, IPP_TAG_PRINTER, MaxJobTime > 0 ? IPP_TAG_INTEGER : IPP_TAG_NOVALUE,
|
||||||
|
"job-cancel-after-default", MaxJobTime);
|
||||||
|
|
||||||
|
if (!cupsGetOption("job-hold-until", p->num_options, p->options))
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -0,0 +1,481 @@
|
|||||||
|
From d47f6aec436e0e9df6554436e391471097686ecc Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael R Sweet <michael.r.sweet@gmail.com>
|
||||||
|
Date: Tue, 8 May 2018 15:24:21 -0700
|
||||||
|
Subject: [PATCH] Fix local privilege escalation to root and sandbox bypasses
|
||||||
|
in scheduler (rdar://37836779, rdar://37836995, rdar://37837252,
|
||||||
|
rdar://37837581)
|
||||||
|
|
||||||
|
---
|
||||||
|
man/cups-files.conf.man.in | 10 ++
|
||||||
|
man/cupsd.conf.man.in | 8 --
|
||||||
|
scheduler/conf.c | 201 +++++++++++++++++++++++--------------
|
||||||
|
scheduler/job.c | 12 +++
|
||||||
|
scheduler/process.c | 16 +--
|
||||||
|
scheduler/server.c | 20 +++-
|
||||||
|
test/run-stp-tests.sh | 11 +-
|
||||||
|
7 files changed, 179 insertions(+), 99 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/cups-files.conf.man.in b/man/cups-files.conf.man.in
|
||||||
|
index 7b96d687d..baf3cb6af 100644
|
||||||
|
--- a/man/cups-files.conf.man.in
|
||||||
|
+++ b/man/cups-files.conf.man.in
|
||||||
|
@@ -153,6 +153,11 @@ The server name may be included in filenames using the string "%s", for example:
|
||||||
|
|
||||||
|
.fi
|
||||||
|
The default is "/var/log/cups/page_log".
|
||||||
|
+.\"#PassEnv
|
||||||
|
+.TP 5
|
||||||
|
+\fBPassEnv \fIvariable \fR[ ... \fIvariable \fR]
|
||||||
|
+Passes the specified environment variable(s) to child processes.
|
||||||
|
+Note: the standard CUPS filter and backend environment variables cannot be overridden using this directive.
|
||||||
|
.\"#RemoteRoot
|
||||||
|
.TP 5
|
||||||
|
\fBRemoteRoot \fIusername\fR
|
||||||
|
@@ -187,6 +192,11 @@ macOS uses its keychain database to store certificates and keys while other plat
|
||||||
|
\fBServerRoot \fIdirectory\fR
|
||||||
|
Specifies the directory containing the server configuration files.
|
||||||
|
The default is "/etc/cups".
|
||||||
|
+.\"#SetEnv
|
||||||
|
+.TP 5
|
||||||
|
+\fBSetEnv \fIvariable value\fR
|
||||||
|
+Set the specified environment variable to be passed to child processes.
|
||||||
|
+Note: the standard CUPS filter and backend environment variables cannot be overridden using this directive.
|
||||||
|
.\"#StateDir
|
||||||
|
.TP 5
|
||||||
|
\fBStateDir \fIdirectory\fR
|
||||||
|
diff --git a/man/cupsd.conf.man.in b/man/cupsd.conf.man.in
|
||||||
|
index 3ffc80e42..36c849398 100644
|
||||||
|
--- a/man/cupsd.conf.man.in
|
||||||
|
+++ b/man/cupsd.conf.man.in
|
||||||
|
@@ -349,10 +349,6 @@ The default is "1048576" (1MB).
|
||||||
|
\fBMultipleOperationTimeout \fIseconds\fR
|
||||||
|
Specifies the maximum amount of time to allow between files in a multiple file print job.
|
||||||
|
The default is "300" (5 minutes).
|
||||||
|
-.\"#PassEnv
|
||||||
|
-.TP 5
|
||||||
|
-\fBPassEnv \fIvariable \fR[ ... \fIvariable \fR]
|
||||||
|
-Passes the specified environment variable(s) to child processes.
|
||||||
|
.\"#Policy
|
||||||
|
.TP 5
|
||||||
|
\fB<Policy \fIname\fB> \fR... \fB</Policy>\fR
|
||||||
|
@@ -433,10 +429,6 @@ Specifies what information is included in the Server header of HTTP responses.
|
||||||
|
command.
|
||||||
|
"Full" reports "CUPS 2.0.0 (UNAME) IPP/2.0".
|
||||||
|
The default is "Minimal".
|
||||||
|
-.\"#SetEnv
|
||||||
|
-.TP 5
|
||||||
|
-\fBSetEnv \fIvariable value\fR
|
||||||
|
-Set the specified environment variable to be passed to child processes.
|
||||||
|
.\"#SSLListen
|
||||||
|
.TP 5
|
||||||
|
\fBSSLListen \fIipv4-address\fB:\fIport\fR
|
||||||
|
diff --git a/scheduler/conf.c b/scheduler/conf.c
|
||||||
|
index 67a91e7a6..b51c6060c 100644
|
||||||
|
--- a/scheduler/conf.c
|
||||||
|
+++ b/scheduler/conf.c
|
||||||
|
@@ -2929,13 +2929,10 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
|
||||||
|
/* Line from file */
|
||||||
|
temp[HTTP_MAX_BUFFER],
|
||||||
|
/* Temporary buffer for value */
|
||||||
|
- *value, /* Pointer to value */
|
||||||
|
- *valueptr; /* Pointer into value */
|
||||||
|
+ *value; /* Pointer to value */
|
||||||
|
int valuelen; /* Length of value */
|
||||||
|
http_addrlist_t *addrlist, /* Address list */
|
||||||
|
*addr; /* Current address */
|
||||||
|
- cups_file_t *incfile; /* Include file */
|
||||||
|
- char incname[1024]; /* Include filename */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -2950,28 +2947,7 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
|
||||||
|
* Decode the directive...
|
||||||
|
*/
|
||||||
|
|
||||||
|
- if (!_cups_strcasecmp(line, "Include") && value)
|
||||||
|
- {
|
||||||
|
- /*
|
||||||
|
- * Include filename
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
- if (value[0] == '/')
|
||||||
|
- strlcpy(incname, value, sizeof(incname));
|
||||||
|
- else
|
||||||
|
- snprintf(incname, sizeof(incname), "%s/%s", ServerRoot, value);
|
||||||
|
-
|
||||||
|
- if ((incfile = cupsFileOpen(incname, "rb")) == NULL)
|
||||||
|
- cupsdLogMessage(CUPSD_LOG_ERROR,
|
||||||
|
- "Unable to include config file \"%s\" - %s",
|
||||||
|
- incname, strerror(errno));
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- read_cupsd_conf(incfile);
|
||||||
|
- cupsFileClose(incfile);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- else if (!_cups_strcasecmp(line, "<Location") && value)
|
||||||
|
+ if (!_cups_strcasecmp(line, "<Location") && value)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* <Location path>
|
||||||
|
@@ -3367,31 +3343,6 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
|
||||||
|
cupsdLogMessage(CUPSD_LOG_WARN, "Unknown ServerTokens %s on line %d of %s.",
|
||||||
|
value, linenum, ConfigurationFile);
|
||||||
|
}
|
||||||
|
- else if (!_cups_strcasecmp(line, "PassEnv") && value)
|
||||||
|
- {
|
||||||
|
- /*
|
||||||
|
- * PassEnv variable [... variable]
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
- for (; *value;)
|
||||||
|
- {
|
||||||
|
- for (valuelen = 0; value[valuelen]; valuelen ++)
|
||||||
|
- if (_cups_isspace(value[valuelen]) || value[valuelen] == ',')
|
||||||
|
- break;
|
||||||
|
-
|
||||||
|
- if (value[valuelen])
|
||||||
|
- {
|
||||||
|
- value[valuelen] = '\0';
|
||||||
|
- valuelen ++;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- cupsdSetEnv(value, NULL);
|
||||||
|
-
|
||||||
|
- for (value += valuelen; *value; value ++)
|
||||||
|
- if (!_cups_isspace(*value) || *value != ',')
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
else if (!_cups_strcasecmp(line, "ServerAlias") && value)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
@@ -3420,30 +3371,6 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- else if (!_cups_strcasecmp(line, "SetEnv") && value)
|
||||||
|
- {
|
||||||
|
- /*
|
||||||
|
- * SetEnv variable value
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
- for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++);
|
||||||
|
-
|
||||||
|
- if (*valueptr)
|
||||||
|
- {
|
||||||
|
- /*
|
||||||
|
- * Found a value...
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
- while (isspace(*valueptr & 255))
|
||||||
|
- *valueptr++ = '\0';
|
||||||
|
-
|
||||||
|
- cupsdSetEnv(value, valueptr);
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- cupsdLogMessage(CUPSD_LOG_ERROR,
|
||||||
|
- "Missing value for SetEnv directive on line %d of %s.",
|
||||||
|
- linenum, ConfigurationFile);
|
||||||
|
- }
|
||||||
|
else if (!_cups_strcasecmp(line, "AccessLog") ||
|
||||||
|
!_cups_strcasecmp(line, "CacheDir") ||
|
||||||
|
!_cups_strcasecmp(line, "ConfigFilePerm") ||
|
||||||
|
@@ -3457,6 +3384,7 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
|
||||||
|
!_cups_strcasecmp(line, "LogFilePerm") ||
|
||||||
|
!_cups_strcasecmp(line, "LPDConfigFile") ||
|
||||||
|
!_cups_strcasecmp(line, "PageLog") ||
|
||||||
|
+ !_cups_strcasecmp(line, "PassEnv") ||
|
||||||
|
!_cups_strcasecmp(line, "Printcap") ||
|
||||||
|
!_cups_strcasecmp(line, "PrintcapFormat") ||
|
||||||
|
!_cups_strcasecmp(line, "RemoteRoot") ||
|
||||||
|
@@ -3466,6 +3394,7 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
|
||||||
|
!_cups_strcasecmp(line, "ServerKey") ||
|
||||||
|
!_cups_strcasecmp(line, "ServerKeychain") ||
|
||||||
|
!_cups_strcasecmp(line, "ServerRoot") ||
|
||||||
|
+ !_cups_strcasecmp(line, "SetEnv") ||
|
||||||
|
!_cups_strcasecmp(line, "SMBConfigFile") ||
|
||||||
|
!_cups_strcasecmp(line, "StateDir") ||
|
||||||
|
!_cups_strcasecmp(line, "SystemGroup") ||
|
||||||
|
@@ -3495,10 +3424,49 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
|
||||||
|
static int /* O - 1 on success, 0 on failure */
|
||||||
|
read_cups_files_conf(cups_file_t *fp) /* I - File to read from */
|
||||||
|
{
|
||||||
|
- int linenum; /* Current line number */
|
||||||
|
+ int i, /* Looping var */
|
||||||
|
+ linenum; /* Current line number */
|
||||||
|
char line[HTTP_MAX_BUFFER], /* Line from file */
|
||||||
|
*value; /* Value from line */
|
||||||
|
struct group *group; /* Group */
|
||||||
|
+ static const char * const prohibited_env[] =
|
||||||
|
+ { /* Prohibited environment variables */
|
||||||
|
+ "APPLE_LANGUAGE",
|
||||||
|
+ "AUTH_DOMAIN",
|
||||||
|
+ "AUTH_INFO_REQUIRED",
|
||||||
|
+ "AUTH_NEGOTIATE",
|
||||||
|
+ "AUTH_PASSWORD",
|
||||||
|
+ "AUTH_UID",
|
||||||
|
+ "AUTH_USERNAME",
|
||||||
|
+ "CHARSET",
|
||||||
|
+ "CLASS",
|
||||||
|
+ "CLASSIFICATION",
|
||||||
|
+ "CONTENT_TYPE",
|
||||||
|
+ "CUPS_CACHEDIR",
|
||||||
|
+ "CUPS_DATADIR",
|
||||||
|
+ "CUPS_DOCROOT",
|
||||||
|
+ "CUPS_FILETYPE",
|
||||||
|
+ "CUPS_FONTPATH",
|
||||||
|
+ "CUPS_MAX_MESSAGE",
|
||||||
|
+ "CUPS_REQUESTROOT",
|
||||||
|
+ "CUPS_SERVERBIN",
|
||||||
|
+ "CUPS_SERVERROOT",
|
||||||
|
+ "CUPS_STATEDIR",
|
||||||
|
+ "DEVICE_URI",
|
||||||
|
+ "FINAL_CONTENT_TYPE",
|
||||||
|
+ "HOME",
|
||||||
|
+ "LANG",
|
||||||
|
+ "PPD",
|
||||||
|
+ "PRINTER",
|
||||||
|
+ "PRINTER_INFO",
|
||||||
|
+ "PRINTER_LOCATION",
|
||||||
|
+ "PRINTER_STATE_REASONS",
|
||||||
|
+ "RIP_CACHE",
|
||||||
|
+ "SERVER_ADMIN",
|
||||||
|
+ "SOFTWARE",
|
||||||
|
+ "TMPDIR",
|
||||||
|
+ "USER"
|
||||||
|
+ };
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -3536,6 +3504,47 @@ read_cups_files_conf(cups_file_t *fp) /* I - File to read from */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ else if (!_cups_strcasecmp(line, "PassEnv") && value)
|
||||||
|
+ {
|
||||||
|
+ /*
|
||||||
|
+ * PassEnv variable [... variable]
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ int valuelen; /* Length of variable name */
|
||||||
|
+
|
||||||
|
+ for (; *value;)
|
||||||
|
+ {
|
||||||
|
+ for (valuelen = 0; value[valuelen]; valuelen ++)
|
||||||
|
+ if (_cups_isspace(value[valuelen]) || value[valuelen] == ',')
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ if (value[valuelen])
|
||||||
|
+ {
|
||||||
|
+ value[valuelen] = '\0';
|
||||||
|
+ valuelen ++;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < (int)(sizeof(prohibited_env) / sizeof(prohibited_env[0])); i ++)
|
||||||
|
+ {
|
||||||
|
+ if (!strcmp(value, prohibited_env[i]))
|
||||||
|
+ {
|
||||||
|
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Environment variable \"%s\" cannot be passed through on line %d of %s.", value, linenum, CupsFilesFile);
|
||||||
|
+
|
||||||
|
+ if (FatalErrors & CUPSD_FATAL_CONFIG)
|
||||||
|
+ return (0);
|
||||||
|
+ else
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (i >= (int)(sizeof(prohibited_env) / sizeof(prohibited_env[0])))
|
||||||
|
+ cupsdSetEnv(value, NULL);
|
||||||
|
+
|
||||||
|
+ for (value += valuelen; *value; value ++)
|
||||||
|
+ if (!_cups_isspace(*value) || *value != ',')
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
else if (!_cups_strcasecmp(line, "PrintcapFormat") && value)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
@@ -3581,6 +3590,46 @@ read_cups_files_conf(cups_file_t *fp) /* I - File to read from */
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ else if (!_cups_strcasecmp(line, "SetEnv") && value)
|
||||||
|
+ {
|
||||||
|
+ /*
|
||||||
|
+ * SetEnv variable value
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ char *valueptr; /* Pointer to environment variable value */
|
||||||
|
+
|
||||||
|
+ for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++);
|
||||||
|
+
|
||||||
|
+ if (*valueptr)
|
||||||
|
+ {
|
||||||
|
+ /*
|
||||||
|
+ * Found a value...
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ while (isspace(*valueptr & 255))
|
||||||
|
+ *valueptr++ = '\0';
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < (int)(sizeof(prohibited_env) / sizeof(prohibited_env[0])); i ++)
|
||||||
|
+ {
|
||||||
|
+ if (!strcmp(value, prohibited_env[i]))
|
||||||
|
+ {
|
||||||
|
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Environment variable \"%s\" cannot be set on line %d of %s.", value, linenum, CupsFilesFile);
|
||||||
|
+
|
||||||
|
+ if (FatalErrors & CUPSD_FATAL_CONFIG)
|
||||||
|
+ return (0);
|
||||||
|
+ else
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (i >= (int)(sizeof(prohibited_env) / sizeof(prohibited_env[0])))
|
||||||
|
+ cupsdSetEnv(value, valueptr);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ cupsdLogMessage(CUPSD_LOG_ERROR,
|
||||||
|
+ "Missing value for SetEnv directive on line %d of %s.",
|
||||||
|
+ linenum, ConfigurationFile);
|
||||||
|
+ }
|
||||||
|
else if (!_cups_strcasecmp(line, "SystemGroup") && value)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
diff --git a/scheduler/job.c b/scheduler/job.c
|
||||||
|
index 61cda44e2..5ced0b9d1 100644
|
||||||
|
--- a/scheduler/job.c
|
||||||
|
+++ b/scheduler/job.c
|
||||||
|
@@ -4779,6 +4779,18 @@ start_job(cupsd_job_t *job, /* I - Job ID */
|
||||||
|
job->profile = cupsdCreateProfile(job->id, 0);
|
||||||
|
job->bprofile = cupsdCreateProfile(job->id, 1);
|
||||||
|
|
||||||
|
+#ifdef HAVE_SANDBOX_H
|
||||||
|
+ if ((!job->profile || !job->bprofile) && UseSandboxing && Sandboxing != CUPSD_SANDBOXING_OFF)
|
||||||
|
+ {
|
||||||
|
+ /*
|
||||||
|
+ * Failure to create the sandbox profile means something really bad has
|
||||||
|
+ * happened and we need to shutdown immediately.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+#endif /* HAVE_SANDBOX_H */
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Create the status pipes and buffer...
|
||||||
|
*/
|
||||||
|
diff --git a/scheduler/process.c b/scheduler/process.c
|
||||||
|
index b8d49d8f0..3c1c6ba4f 100644
|
||||||
|
--- a/scheduler/process.c
|
||||||
|
+++ b/scheduler/process.c
|
||||||
|
@@ -98,9 +98,13 @@ cupsdCreateProfile(int job_id, /* I - Job ID or 0 for none */
|
||||||
|
|
||||||
|
if ((fp = cupsTempFile2(profile, sizeof(profile))) == NULL)
|
||||||
|
{
|
||||||
|
+ /*
|
||||||
|
+ * This should never happen, and is fatal when sandboxing is enabled.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d, allow_networking=%d) = NULL", job_id, allow_networking);
|
||||||
|
- cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create security profile: %s",
|
||||||
|
- strerror(errno));
|
||||||
|
+ cupsdLogMessage(CUPSD_LOG_EMERG, "Unable to create security profile: %s", strerror(errno));
|
||||||
|
+ kill(getpid(), SIGTERM);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -197,10 +201,8 @@ cupsdCreateProfile(int job_id, /* I - Job ID or 0 for none */
|
||||||
|
" #\"^%s/\"" /* TempDir/... */
|
||||||
|
" #\"^%s$\"" /* CacheDir */
|
||||||
|
" #\"^%s/\"" /* CacheDir/... */
|
||||||
|
- " #\"^%s$\"" /* StateDir */
|
||||||
|
- " #\"^%s/\"" /* StateDir/... */
|
||||||
|
"))\n",
|
||||||
|
- temp, temp, cache, cache, state, state);
|
||||||
|
+ temp, temp, cache, cache);
|
||||||
|
/* Read common folders */
|
||||||
|
cupsFilePrintf(fp,
|
||||||
|
"(allow file-read-data file-read-metadata\n"
|
||||||
|
@@ -242,8 +244,10 @@ cupsdCreateProfile(int job_id, /* I - Job ID or 0 for none */
|
||||||
|
" #\"^%s/\"" /* ServerBin/... */
|
||||||
|
" #\"^%s$\"" /* ServerRoot */
|
||||||
|
" #\"^%s/\"" /* ServerRoot/... */
|
||||||
|
+ " #\"^%s$\"" /* StateDir */
|
||||||
|
+ " #\"^%s/\"" /* StateDir/... */
|
||||||
|
"))\n",
|
||||||
|
- request, request, bin, bin, root, root);
|
||||||
|
+ request, request, bin, bin, root, root, state, state);
|
||||||
|
if (Sandboxing == CUPSD_SANDBOXING_RELAXED)
|
||||||
|
{
|
||||||
|
/* Limited write access to /Library/Printers/... */
|
||||||
|
diff --git a/scheduler/server.c b/scheduler/server.c
|
||||||
|
index cecbabe67..a4033791b 100644
|
||||||
|
--- a/scheduler/server.c
|
||||||
|
+++ b/scheduler/server.c
|
||||||
|
@@ -34,16 +34,28 @@ void
|
||||||
|
cupsdStartServer(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
- * Start color management (as needed)...
|
||||||
|
+ * Create the default security profile...
|
||||||
|
*/
|
||||||
|
|
||||||
|
- cupsdStartColor();
|
||||||
|
+ DefaultProfile = cupsdCreateProfile(0, 1);
|
||||||
|
+
|
||||||
|
+#ifdef HAVE_SANDBOX_H
|
||||||
|
+ if (!DefaultProfile && UseSandboxing && Sandboxing != CUPSD_SANDBOXING_OFF)
|
||||||
|
+ {
|
||||||
|
+ /*
|
||||||
|
+ * Failure to create the sandbox profile means something really bad has
|
||||||
|
+ * happened and we need to shutdown immediately.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+#endif /* HAVE_SANDBOX_H */
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * Create the default security profile...
|
||||||
|
+ * Start color management (as needed)...
|
||||||
|
*/
|
||||||
|
|
||||||
|
- DefaultProfile = cupsdCreateProfile(0, 1);
|
||||||
|
+ cupsdStartColor();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Startup all the networking stuff...
|
||||||
|
diff --git a/test/run-stp-tests.sh b/test/run-stp-tests.sh
|
||||||
|
index 7eb269a67..f83bd5d91 100755
|
||||||
|
--- a/test/run-stp-tests.sh
|
||||||
|
+++ b/test/run-stp-tests.sh
|
||||||
|
@@ -489,11 +489,6 @@ StrictConformance Yes
|
||||||
|
Browsing Off
|
||||||
|
Listen localhost:$port
|
||||||
|
Listen $BASE/sock
|
||||||
|
-PassEnv DYLD_LIBRARY_PATH
|
||||||
|
-PassEnv LD_LIBRARY_PATH
|
||||||
|
-PassEnv LD_PRELOAD
|
||||||
|
-PassEnv LOCALEDIR
|
||||||
|
-PassEnv SHLIB_PATH
|
||||||
|
MaxSubscriptions 3
|
||||||
|
MaxLogSize 0
|
||||||
|
AccessLogLevel actions
|
||||||
|
@@ -529,6 +524,12 @@ TempDir $BASE/spool/temp
|
||||||
|
AccessLog $BASE/log/access_log
|
||||||
|
ErrorLog $BASE/log/error_log
|
||||||
|
PageLog $BASE/log/page_log
|
||||||
|
+
|
||||||
|
+PassEnv DYLD_LIBRARY_PATH
|
||||||
|
+PassEnv LD_LIBRARY_PATH
|
||||||
|
+PassEnv LD_PRELOAD
|
||||||
|
+PassEnv LOCALEDIR
|
||||||
|
+PassEnv SHLIB_PATH
|
||||||
|
EOF
|
||||||
|
|
||||||
|
if test $ssltype != 0 -a `uname` = Darwin; then
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
@ -0,0 +1,62 @@
|
|||||||
|
From 9539c53065170e97836503074e770d7b5fbf9f83 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael R Sweet <michael.r.sweet@gmail.com>
|
||||||
|
Date: Tue, 16 Jul 2019 09:27:13 -0400
|
||||||
|
Subject: [PATCH] Fix lpadmin with cupsIPPSupplies and cupsSNMPSupplies (Issue
|
||||||
|
#5610)
|
||||||
|
|
||||||
|
---
|
||||||
|
CHANGES.md | 2 ++
|
||||||
|
systemv/lpadmin.c | 9 +++++++--
|
||||||
|
2 files changed, 9 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/systemv/lpadmin.c b/systemv/lpadmin.c
|
||||||
|
index f428368d4..ca6d386b2 100644
|
||||||
|
--- a/systemv/lpadmin.c
|
||||||
|
+++ b/systemv/lpadmin.c
|
||||||
|
@@ -1467,6 +1467,7 @@ set_printer_options(
|
||||||
|
(boolval = cupsGetOption("cupsIPPSupplies", num_options,
|
||||||
|
options)) != NULL)
|
||||||
|
{
|
||||||
|
+ ppdchanged = 1;
|
||||||
|
wrote_ipp_supplies = 1;
|
||||||
|
cupsFilePrintf(out, "*cupsIPPSupplies: %s\n",
|
||||||
|
(!_cups_strcasecmp(boolval, "true") ||
|
||||||
|
@@ -1477,6 +1478,7 @@ set_printer_options(
|
||||||
|
(boolval = cupsGetOption("cupsSNMPSupplies", num_options,
|
||||||
|
options)) != NULL)
|
||||||
|
{
|
||||||
|
+ ppdchanged = 1;
|
||||||
|
wrote_snmp_supplies = 1;
|
||||||
|
cupsFilePrintf(out, "*cupsSNMPSupplies: %s\n",
|
||||||
|
(!_cups_strcasecmp(boolval, "true") ||
|
||||||
|
@@ -1537,6 +1539,8 @@ set_printer_options(
|
||||||
|
(boolval = cupsGetOption("cupsIPPSupplies", num_options,
|
||||||
|
options)) != NULL)
|
||||||
|
{
|
||||||
|
+ ppdchanged = 1;
|
||||||
|
+
|
||||||
|
cupsFilePrintf(out, "*cupsIPPSupplies: %s\n",
|
||||||
|
(!_cups_strcasecmp(boolval, "true") ||
|
||||||
|
!_cups_strcasecmp(boolval, "yes") ||
|
||||||
|
@@ -1547,6 +1551,8 @@ set_printer_options(
|
||||||
|
(boolval = cupsGetOption("cupsSNMPSupplies", num_options,
|
||||||
|
options)) != NULL)
|
||||||
|
{
|
||||||
|
+ ppdchanged = 1;
|
||||||
|
+
|
||||||
|
cupsFilePrintf(out, "*cupsSNMPSupplies: %s\n",
|
||||||
|
(!_cups_strcasecmp(boolval, "true") ||
|
||||||
|
!_cups_strcasecmp(boolval, "yes") ||
|
||||||
|
@@ -1561,8 +1567,7 @@ set_printer_options(
|
||||||
|
* Do the request...
|
||||||
|
*/
|
||||||
|
|
||||||
|
- ippDelete(cupsDoFileRequest(http, request, "/admin/",
|
||||||
|
- ppdchanged ? tempfile : file));
|
||||||
|
+ ippDelete(cupsDoFileRequest(http, request, "/admin/", ppdchanged ? tempfile : file));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clean up temp files... (TODO: catch signals in case we CTRL-C during
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -0,0 +1,206 @@
|
|||||||
|
diff --git a/backend/ipp.c b/backend/ipp.c
|
||||||
|
index 32eb3aaa4..2a880bd75 100644
|
||||||
|
--- a/backend/ipp.c
|
||||||
|
+++ b/backend/ipp.c
|
||||||
|
@@ -3612,6 +3612,8 @@ update_reasons(ipp_attribute_t *attr, /* I - printer-state-reasons or NULL */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ cupsArrayDelete(new_reasons);
|
||||||
|
+
|
||||||
|
_cupsMutexUnlock(&report_mutex);
|
||||||
|
|
||||||
|
/*
|
||||||
|
diff --git a/cgi-bin/search.c b/cgi-bin/search.c
|
||||||
|
index 3956afc33..ad1f5ed0e 100644
|
||||||
|
--- a/cgi-bin/search.c
|
||||||
|
+++ b/cgi-bin/search.c
|
||||||
|
@@ -361,4 +362,5 @@ void
|
||||||
|
cgiFreeSearch(void *search) /* I - Search context */
|
||||||
|
{
|
||||||
|
regfree((regex_t *)search);
|
||||||
|
+ free(search);
|
||||||
|
}
|
||||||
|
diff --git a/cups/http-addrlist.c b/cups/http-addrlist.c
|
||||||
|
index 5d510140b..688901a7d 100644
|
||||||
|
--- a/cups/http-addrlist.c
|
||||||
|
+++ b/cups/http-addrlist.c
|
||||||
|
@@ -612,6 +613,7 @@ httpAddrGetList(const char *hostname, /* I - Hostname, IP address, or NULL for p
|
||||||
|
if (!temp)
|
||||||
|
{
|
||||||
|
httpAddrFreeList(first);
|
||||||
|
+ freeaddrinfo(results);
|
||||||
|
_cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
diff --git a/cups/http.c b/cups/http.c
|
||||||
|
index a9235b087..d9332cc83 100644
|
||||||
|
--- a/cups/http.c
|
||||||
|
+++ b/cups/http.c
|
||||||
|
@@ -3915,7 +3915,7 @@ http_create(
|
||||||
|
if ((http = calloc(sizeof(http_t), 1)) == NULL)
|
||||||
|
{
|
||||||
|
_cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
|
||||||
|
- httpAddrFreeList(addrlist);
|
||||||
|
+ httpAddrFreeList(myaddrlist);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/ppdc/ppdc-source.cxx b/ppdc/ppdc-source.cxx
|
||||||
|
index be24cebae..4e8cba7bb 100644
|
||||||
|
--- a/ppdc/ppdc-source.cxx
|
||||||
|
+++ b/ppdc/ppdc-source.cxx
|
||||||
|
@@ -2665,6 +2666,7 @@ ppdcSource::scan_file(ppdcFile *fp, // I - File to read
|
||||||
|
// Add it to the current option...
|
||||||
|
if (!o)
|
||||||
|
{
|
||||||
|
+ c->release();
|
||||||
|
_cupsLangPrintf(stderr,
|
||||||
|
_("ppdc: Choice found on line %d of %s with no "
|
||||||
|
"Option."), fp->line, fp->filename);
|
||||||
|
diff --git a/scheduler/cups-driverd.cxx b/scheduler/cups-driverd.cxx
|
||||||
|
index 657eee0a0..b518a9325 100644
|
||||||
|
--- a/scheduler/cups-driverd.cxx
|
||||||
|
+++ b/scheduler/cups-driverd.cxx
|
||||||
|
@@ -153,7 +153,7 @@ static ppd_info_t *add_ppd(const char *filename, const char *name,
|
||||||
|
size_t size, int model_number, int type,
|
||||||
|
const char *scheme);
|
||||||
|
static int cat_drv(const char *name, int request_id);
|
||||||
|
-static int cat_ppd(const char *name, int request_id);
|
||||||
|
+static void cat_ppd(const char *name, int request_id);
|
||||||
|
static int cat_static(const char *name, int request_id);
|
||||||
|
static int cat_tar(const char *name, int request_id);
|
||||||
|
static int compare_inodes(struct stat *a, struct stat *b);
|
||||||
|
@@ -163,12 +163,12 @@ static int compare_names(const ppd_info_t *p0,
|
||||||
|
const ppd_info_t *p1);
|
||||||
|
static int compare_ppds(const ppd_info_t *p0,
|
||||||
|
const ppd_info_t *p1);
|
||||||
|
-static int dump_ppds_dat(const char *filename);
|
||||||
|
+static void dump_ppds_dat(const char *filename);
|
||||||
|
static void free_array(cups_array_t *a);
|
||||||
|
static cups_file_t *get_file(const char *name, int request_id,
|
||||||
|
const char *subdir, char *buffer,
|
||||||
|
size_t bufsize, char **subfile);
|
||||||
|
-static int list_ppds(int request_id, int limit, const char *opt);
|
||||||
|
+static void list_ppds(int request_id, int limit, const char *opt);
|
||||||
|
static int load_drivers(cups_array_t *include,
|
||||||
|
cups_array_t *exclude);
|
||||||
|
static int load_drv(const char *filename, const char *name,
|
||||||
|
@@ -204,13 +204,13 @@ main(int argc, /* I - Number of command-line args */
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (argc == 3 && !strcmp(argv[1], "cat"))
|
||||||
|
- return (cat_ppd(argv[2], 0));
|
||||||
|
+ cat_ppd(argv[2], 0);
|
||||||
|
else if ((argc == 2 || argc == 3) && !strcmp(argv[1], "dump"))
|
||||||
|
- return (dump_ppds_dat(argv[2]));
|
||||||
|
+ dump_ppds_dat(argv[2]);
|
||||||
|
else if (argc == 4 && !strcmp(argv[1], "get"))
|
||||||
|
- return (cat_ppd(argv[3], atoi(argv[2])));
|
||||||
|
+ cat_ppd(argv[3], atoi(argv[2]));
|
||||||
|
else if (argc == 5 && !strcmp(argv[1], "list"))
|
||||||
|
- return (list_ppds(atoi(argv[2]), atoi(argv[3]), argv[4]));
|
||||||
|
+ list_ppds(atoi(argv[2]), atoi(argv[3]), argv[4]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fputs("Usage: cups-driverd cat ppd-name\n", stderr);
|
||||||
|
@@ -428,7 +428,7 @@ cat_drv(const char *name, /* I - PPD name */
|
||||||
|
* 'cat_ppd()' - Copy a PPD file to stdout.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-static int /* O - Exit code */
|
||||||
|
+static void
|
||||||
|
cat_ppd(const char *name, /* I - PPD name */
|
||||||
|
int request_id) /* I - Request ID for response? */
|
||||||
|
{
|
||||||
|
@@ -445,7 +445,7 @@ cat_ppd(const char *name, /* I - PPD name */
|
||||||
|
if (strstr(name, "../"))
|
||||||
|
{
|
||||||
|
fputs("ERROR: Invalid PPD name.\n", stderr);
|
||||||
|
- return (1);
|
||||||
|
+ exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
strlcpy(scheme, name, sizeof(scheme));
|
||||||
|
@@ -475,11 +475,11 @@ cat_ppd(const char *name, /* I - PPD name */
|
||||||
|
puts("Content-Type: application/ipp\n");
|
||||||
|
|
||||||
|
if (!scheme[0])
|
||||||
|
- return (cat_static(name, request_id));
|
||||||
|
+ exit(cat_static(name, request_id));
|
||||||
|
else if (!strcmp(scheme, "drv"))
|
||||||
|
- return (cat_drv(name, request_id));
|
||||||
|
+ exit(cat_drv(name, request_id));
|
||||||
|
else if (!strcmp(scheme, "file"))
|
||||||
|
- return (cat_tar(name, request_id));
|
||||||
|
+ exit(cat_tar(name, request_id));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
@@ -517,7 +517,7 @@ cat_ppd(const char *name, /* I - PPD name */
|
||||||
|
cupsdSendIPPTrailer();
|
||||||
|
}
|
||||||
|
|
||||||
|
- return (1);
|
||||||
|
+ exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -547,15 +547,15 @@ cat_ppd(const char *name, /* I - PPD name */
|
||||||
|
|
||||||
|
fprintf(stderr, "ERROR: [cups-driverd] Unable to execute \"%s\" - %s\n",
|
||||||
|
line, strerror(errno));
|
||||||
|
- return (1);
|
||||||
|
+ exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * Return with no errors...
|
||||||
|
+ * Exit with no errors...
|
||||||
|
*/
|
||||||
|
|
||||||
|
- return (0);
|
||||||
|
+ exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -778,7 +778,7 @@ compare_ppds(const ppd_info_t *p0, /* I - First PPD file */
|
||||||
|
* 'dump_ppds_dat()' - Dump the contents of the ppds.dat file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-static int /* O - Exit status */
|
||||||
|
+static void
|
||||||
|
dump_ppds_dat(const char *filename) /* I - Filename */
|
||||||
|
{
|
||||||
|
char temp[1024]; /* ppds.dat filename */
|
||||||
|
@@ -810,7 +810,7 @@ dump_ppds_dat(const char *filename) /* I - Filename */
|
||||||
|
ppd->record.make_and_model, ppd->record.device_id,
|
||||||
|
ppd->record.scheme);
|
||||||
|
|
||||||
|
- return (0);
|
||||||
|
+ exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1004,7 +1004,7 @@ get_file(const char *name, /* I - Name */
|
||||||
|
* 'list_ppds()' - List PPD files.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-static int /* O - Exit code */
|
||||||
|
+static void
|
||||||
|
list_ppds(int request_id, /* I - Request ID */
|
||||||
|
int limit, /* I - Limit */
|
||||||
|
const char *opt) /* I - Option argument */
|
||||||
|
@@ -1566,7 +1566,7 @@ list_ppds(int request_id, /* I - Request ID */
|
||||||
|
if (request_id)
|
||||||
|
cupsdSendIPPTrailer();
|
||||||
|
|
||||||
|
- return (0);
|
||||||
|
+ exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
@ -0,0 +1,56 @@
|
|||||||
|
diff --git a/backend/socket.c b/backend/socket.c
|
||||||
|
index 675061dd9..68379e95b 100644
|
||||||
|
--- a/backend/socket.c
|
||||||
|
+++ b/backend/socket.c
|
||||||
|
@@ -397,8 +397,10 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||||
|
lseek(print_fd, 0, SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
- tbytes = backendRunLoop(print_fd, device_fd, snmp_fd, &(addrlist->addr), 1,
|
||||||
|
- 0, backendNetworkSideCB);
|
||||||
|
+ if ((bytes = backendRunLoop(print_fd, device_fd, snmp_fd, &(addrlist->addr), 1, 0, backendNetworkSideCB)) < 0)
|
||||||
|
+ tbytes = -1;
|
||||||
|
+ else
|
||||||
|
+ tbytes = bytes;
|
||||||
|
|
||||||
|
if (print_fd != 0 && tbytes >= 0)
|
||||||
|
_cupsLangPrintFilter(stderr, "INFO", _("Print file sent."));
|
||||||
|
@@ -406,7 +408,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||||
|
|
||||||
|
fputs("STATE: +cups-waiting-for-job-completed\n", stderr);
|
||||||
|
|
||||||
|
- if (waiteof)
|
||||||
|
+ if (waiteof && tbytes >= 0)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Shutdown the socket and wait for the other end to finish...
|
||||||
|
@@ -443,7 +445,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
|
||||||
|
if (print_fd != 0)
|
||||||
|
close(print_fd);
|
||||||
|
|
||||||
|
- return (CUPS_BACKEND_OK);
|
||||||
|
+ return (tbytes >= 0 ? CUPS_BACKEND_OK : CUPS_BACKEND_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/scheduler/main.c b/scheduler/main.c
|
||||||
|
index 4b3914ade..472b9946d 100644
|
||||||
|
--- a/scheduler/main.c
|
||||||
|
+++ b/scheduler/main.c
|
||||||
|
@@ -1472,9 +1472,16 @@ process_children(void)
|
||||||
|
(!job->filters[i] && WIFEXITED(old_status)))
|
||||||
|
{ /* Backend and filter didn't crash */
|
||||||
|
if (job->filters[i])
|
||||||
|
+ {
|
||||||
|
job->status = status; /* Filter failed */
|
||||||
|
+ }
|
||||||
|
else
|
||||||
|
+ {
|
||||||
|
job->status = -status; /* Backend failed */
|
||||||
|
+
|
||||||
|
+ if (job->current_file < job->num_files)
|
||||||
|
+ cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_FORCE, "Canceling multi-file job due to backend failure.");
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (job->state_value == IPP_JOB_PROCESSING &&
|
@ -0,0 +1,64 @@
|
|||||||
|
From ffd290b4ab247f82722927ba9b21358daa16dbf1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rose <83477269+AtariDreams@users.noreply.github.com>
|
||||||
|
Date: Thu, 1 Jun 2023 11:33:39 -0400
|
||||||
|
Subject: [PATCH] Log result of httpGetHostname BEFORE closing the connection
|
||||||
|
|
||||||
|
httpClose frees the memory of con->http. This is problematic because httpGetHostname then tries to access the memory it points to.
|
||||||
|
|
||||||
|
We have to log the hostname first.
|
||||||
|
---
|
||||||
|
scheduler/client.c | 16 +++++++---------
|
||||||
|
1 file changed, 7 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/scheduler/client.c b/scheduler/client.c
|
||||||
|
index 91e441188..327473a4d 100644
|
||||||
|
--- a/scheduler/client.c
|
||||||
|
+++ b/scheduler/client.c
|
||||||
|
@@ -193,13 +193,11 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
|
||||||
|
/*
|
||||||
|
* Can't have an unresolved IP address with double-lookups enabled...
|
||||||
|
*/
|
||||||
|
-
|
||||||
|
- httpClose(con->http);
|
||||||
|
-
|
||||||
|
cupsdLogClient(con, CUPSD_LOG_WARN,
|
||||||
|
- "Name lookup failed - connection from %s closed!",
|
||||||
|
+ "Name lookup failed - closing connection from %s!",
|
||||||
|
httpGetHostname(con->http, NULL, 0));
|
||||||
|
|
||||||
|
+ httpClose(con->http);
|
||||||
|
free(con);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
@@ -235,11 +233,11 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
|
||||||
|
* with double-lookups enabled...
|
||||||
|
*/
|
||||||
|
|
||||||
|
- httpClose(con->http);
|
||||||
|
-
|
||||||
|
cupsdLogClient(con, CUPSD_LOG_WARN,
|
||||||
|
- "IP lookup failed - connection from %s closed!",
|
||||||
|
+ "IP lookup failed - closing connection from %s!",
|
||||||
|
httpGetHostname(con->http, NULL, 0));
|
||||||
|
+
|
||||||
|
+ httpClose(con->http);
|
||||||
|
free(con);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
@@ -256,11 +254,11 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
|
||||||
|
|
||||||
|
if (!hosts_access(&wrap_req))
|
||||||
|
{
|
||||||
|
- httpClose(con->http);
|
||||||
|
-
|
||||||
|
cupsdLogClient(con, CUPSD_LOG_WARN,
|
||||||
|
"Connection from %s refused by /etc/hosts.allow and "
|
||||||
|
"/etc/hosts.deny rules.", httpGetHostname(con->http, NULL, 0));
|
||||||
|
+
|
||||||
|
+ httpClose(con->http);
|
||||||
|
free(con);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
@ -0,0 +1,183 @@
|
|||||||
|
From 2c030c7a06e0c2b8227c7e85f5c58dfb339731d0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael R Sweet <michael.r.sweet@gmail.com>
|
||||||
|
Date: Thu, 15 Aug 2019 14:06:47 -0400
|
||||||
|
Subject: [PATCH] Multiple security/disclosure issues:
|
||||||
|
|
||||||
|
- CVE-2019-8696 and CVE-2019-8675: Fixed SNMP buffer overflows (rdar://51685251)
|
||||||
|
- Fixed IPP buffer overflow (rdar://50035411)
|
||||||
|
- Fixed memory disclosure issue in the scheduler (rdar://51373853)
|
||||||
|
- Fixed DoS issues in the scheduler (rdar://51373929)
|
||||||
|
|
||||||
|
diff --git a/cups/http.c b/cups/http.c
|
||||||
|
index 266a15791..fbb1bf13c 100644
|
||||||
|
--- a/cups/http.c
|
||||||
|
+++ b/cups/http.c
|
||||||
|
@@ -1860,7 +1860,7 @@ httpPrintf(http_t *http, /* I - HTTP connection */
|
||||||
|
...) /* I - Additional args as needed */
|
||||||
|
{
|
||||||
|
ssize_t bytes; /* Number of bytes to write */
|
||||||
|
- char buf[16384]; /* Buffer for formatted string */
|
||||||
|
+ char buf[65536]; /* Buffer for formatted string */
|
||||||
|
va_list ap; /* Variable argument pointer */
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1872,7 +1872,12 @@ httpPrintf(http_t *http, /* I - HTTP connection */
|
||||||
|
|
||||||
|
DEBUG_printf(("3httpPrintf: (" CUPS_LLFMT " bytes) %s", CUPS_LLCAST bytes, buf));
|
||||||
|
|
||||||
|
- if (http->data_encoding == HTTP_ENCODING_FIELDS)
|
||||||
|
+ if (bytes > (ssize_t)(sizeof(buf) - 1))
|
||||||
|
+ {
|
||||||
|
+ http->error = ENOMEM;
|
||||||
|
+ return (-1);
|
||||||
|
+ }
|
||||||
|
+ else if (http->data_encoding == HTTP_ENCODING_FIELDS)
|
||||||
|
return ((int)httpWrite2(http, buf, (size_t)bytes));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
diff --git a/cups/ipp.c b/cups/ipp.c
|
||||||
|
index 6fae52a00..1bd59cef1 100644
|
||||||
|
--- a/cups/ipp.c
|
||||||
|
+++ b/cups/ipp.c
|
||||||
|
@@ -4550,9 +4550,7 @@ ippSetValueTag(
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IPP_TAG_NAME :
|
||||||
|
- if (temp_tag != IPP_TAG_KEYWORD && temp_tag != IPP_TAG_URI &&
|
||||||
|
- temp_tag != IPP_TAG_URISCHEME && temp_tag != IPP_TAG_LANGUAGE &&
|
||||||
|
- temp_tag != IPP_TAG_MIMETYPE)
|
||||||
|
+ if (temp_tag != IPP_TAG_KEYWORD)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
(*attr)->value_tag = (ipp_tag_t)(IPP_TAG_NAME | ((*attr)->value_tag & IPP_TAG_CUPS_CONST));
|
||||||
|
@@ -4560,10 +4558,7 @@ ippSetValueTag(
|
||||||
|
|
||||||
|
case IPP_TAG_NAMELANG :
|
||||||
|
case IPP_TAG_TEXTLANG :
|
||||||
|
- if (value_tag == IPP_TAG_NAMELANG &&
|
||||||
|
- (temp_tag != IPP_TAG_NAME && temp_tag != IPP_TAG_KEYWORD &&
|
||||||
|
- temp_tag != IPP_TAG_URI && temp_tag != IPP_TAG_URISCHEME &&
|
||||||
|
- temp_tag != IPP_TAG_LANGUAGE && temp_tag != IPP_TAG_MIMETYPE))
|
||||||
|
+ if (value_tag == IPP_TAG_NAMELANG && (temp_tag != IPP_TAG_NAME && temp_tag != IPP_TAG_KEYWORD))
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
if (value_tag == IPP_TAG_TEXTLANG && temp_tag != IPP_TAG_TEXT)
|
||||||
|
diff --git a/cups/snmp.c b/cups/snmp.c
|
||||||
|
index 5cefee454..1d9da01f2 100644
|
||||||
|
--- a/cups/snmp.c
|
||||||
|
+++ b/cups/snmp.c
|
||||||
|
@@ -1233,6 +1233,9 @@ asn1_get_integer(
|
||||||
|
int value; /* Integer value */
|
||||||
|
|
||||||
|
|
||||||
|
+ if (*buffer >= bufend)
|
||||||
|
+ return (0);
|
||||||
|
+
|
||||||
|
if (length > sizeof(int))
|
||||||
|
{
|
||||||
|
(*buffer) += length;
|
||||||
|
@@ -1259,6 +1262,9 @@ asn1_get_length(unsigned char **buffer, /* IO - Pointer in buffer */
|
||||||
|
unsigned length; /* Length */
|
||||||
|
|
||||||
|
|
||||||
|
+ if (*buffer >= bufend)
|
||||||
|
+ return (0);
|
||||||
|
+
|
||||||
|
length = **buffer;
|
||||||
|
(*buffer) ++;
|
||||||
|
|
||||||
|
@@ -1301,6 +1307,9 @@ asn1_get_oid(
|
||||||
|
int number; /* OID number */
|
||||||
|
|
||||||
|
|
||||||
|
+ if (*buffer >= bufend)
|
||||||
|
+ return (0);
|
||||||
|
+
|
||||||
|
valend = *buffer + length;
|
||||||
|
oidptr = oid;
|
||||||
|
oidend = oid + oidsize - 1;
|
||||||
|
@@ -1349,9 +1358,12 @@ asn1_get_packed(
|
||||||
|
int value; /* Value */
|
||||||
|
|
||||||
|
|
||||||
|
+ if (*buffer >= bufend)
|
||||||
|
+ return (0);
|
||||||
|
+
|
||||||
|
value = 0;
|
||||||
|
|
||||||
|
- while ((**buffer & 128) && *buffer < bufend)
|
||||||
|
+ while (*buffer < bufend && (**buffer & 128))
|
||||||
|
{
|
||||||
|
value = (value << 7) | (**buffer & 127);
|
||||||
|
(*buffer) ++;
|
||||||
|
@@ -1379,6 +1391,9 @@ asn1_get_string(
|
||||||
|
char *string, /* I - String buffer */
|
||||||
|
size_t strsize) /* I - String buffer size */
|
||||||
|
{
|
||||||
|
+ if (*buffer >= bufend)
|
||||||
|
+ return (NULL);
|
||||||
|
+
|
||||||
|
if (length > (unsigned)(bufend - *buffer))
|
||||||
|
length = (unsigned)(bufend - *buffer);
|
||||||
|
|
||||||
|
@@ -1421,6 +1436,9 @@ asn1_get_type(unsigned char **buffer, /* IO - Pointer in buffer */
|
||||||
|
int type; /* Type */
|
||||||
|
|
||||||
|
|
||||||
|
+ if (*buffer >= bufend)
|
||||||
|
+ return (0);
|
||||||
|
+
|
||||||
|
type = **buffer;
|
||||||
|
(*buffer) ++;
|
||||||
|
|
||||||
|
diff --git a/scheduler/client.c b/scheduler/client.c
|
||||||
|
index 923a6e67a..f693e7c49 100644
|
||||||
|
--- a/scheduler/client.c
|
||||||
|
+++ b/scheduler/client.c
|
||||||
|
@@ -564,6 +564,17 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
|
||||||
|
|
||||||
|
cupsdLogClient(con, CUPSD_LOG_DEBUG2, "cupsdReadClient: error=%d, used=%d, state=%s, data_encoding=HTTP_ENCODING_%s, data_remaining=" CUPS_LLFMT ", request=%p(%s), file=%d", httpError(con->http), (int)httpGetReady(con->http), httpStateString(httpGetState(con->http)), httpIsChunked(con->http) ? "CHUNKED" : "LENGTH", CUPS_LLCAST httpGetRemaining(con->http), con->request, con->request ? ippStateString(ippGetState(con->request)) : "", con->file);
|
||||||
|
|
||||||
|
+ if (httpError(con->http) == EPIPE && !httpGetReady(con->http) && recv(httpGetFd(con->http), buf, 1, MSG_PEEK) < 1)
|
||||||
|
+ {
|
||||||
|
+ /*
|
||||||
|
+ * Connection closed...
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Closing on EOF.");
|
||||||
|
+ cupsdCloseClient(con);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (httpGetState(con->http) == HTTP_STATE_GET_SEND ||
|
||||||
|
httpGetState(con->http) == HTTP_STATE_POST_SEND ||
|
||||||
|
httpGetState(con->http) == HTTP_STATE_STATUS)
|
||||||
|
@@ -573,17 +584,6 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
|
||||||
|
* connection and we need to shut it down...
|
||||||
|
*/
|
||||||
|
|
||||||
|
- if (!httpGetReady(con->http) && recv(httpGetFd(con->http), buf, 1, MSG_PEEK) < 1)
|
||||||
|
- {
|
||||||
|
- /*
|
||||||
|
- * Connection closed...
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
- cupsdLogClient(con, CUPSD_LOG_DEBUG, "Closing on EOF.");
|
||||||
|
- cupsdCloseClient(con);
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
cupsdLogClient(con, CUPSD_LOG_DEBUG, "Closing on unexpected HTTP read state %s.", httpStateString(httpGetState(con->http)));
|
||||||
|
cupsdCloseClient(con);
|
||||||
|
return;
|
||||||
|
@@ -1950,6 +1950,7 @@ cupsdSendError(cupsd_client_t *con, /* I - Connection */
|
||||||
|
strlcpy(location, httpGetField(con->http, HTTP_FIELD_LOCATION), sizeof(location));
|
||||||
|
|
||||||
|
httpClearFields(con->http);
|
||||||
|
+ httpClearCookie(con->http);
|
||||||
|
|
||||||
|
httpSetField(con->http, HTTP_FIELD_LOCATION, location);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
@ -0,0 +1,562 @@
|
|||||||
|
diff --git a/cups/cups-private.h b/cups/cups-private.h
|
||||||
|
index 6fd66a9..1f66fd7 100644
|
||||||
|
--- a/cups/cups-private.h
|
||||||
|
+++ b/cups/cups-private.h
|
||||||
|
@@ -237,13 +237,9 @@ extern void _cupsBufferRelease(char *b);
|
||||||
|
|
||||||
|
extern http_t *_cupsConnect(void);
|
||||||
|
extern char *_cupsCreateDest(const char *name, const char *info, const char *device_id, const char *device_uri, char *uri, size_t urisize);
|
||||||
|
-extern int _cupsGet1284Values(const char *device_id,
|
||||||
|
- cups_option_t **values);
|
||||||
|
-extern const char *_cupsGetDestResource(cups_dest_t *dest, char *resource,
|
||||||
|
- size_t resourcesize);
|
||||||
|
-extern int _cupsGetDests(http_t *http, ipp_op_t op,
|
||||||
|
- const char *name, cups_dest_t **dests,
|
||||||
|
- cups_ptype_t type, cups_ptype_t mask);
|
||||||
|
+extern int _cupsGet1284Values(const char *device_id, cups_option_t **values);
|
||||||
|
+extern const char *_cupsGetDestResource(cups_dest_t *dest, unsigned flags, char *resource, size_t resourcesize);
|
||||||
|
+extern int _cupsGetDests(http_t *http, ipp_op_t op, const char *name, cups_dest_t **dests, cups_ptype_t type, cups_ptype_t mask);
|
||||||
|
extern const char *_cupsGetPassword(const char *prompt);
|
||||||
|
extern void _cupsGlobalLock(void);
|
||||||
|
extern _cups_globals_t *_cupsGlobals(void);
|
||||||
|
@@ -253,13 +249,10 @@ extern const char *_cupsGSSServiceName(void);
|
||||||
|
# endif /* HAVE_GSSAPI */
|
||||||
|
extern int _cupsNextDelay(int current, int *previous);
|
||||||
|
extern void _cupsSetDefaults(void);
|
||||||
|
-extern void _cupsSetError(ipp_status_t status, const char *message,
|
||||||
|
- int localize);
|
||||||
|
+extern void _cupsSetError(ipp_status_t status, const char *message, int localize);
|
||||||
|
extern void _cupsSetHTTPError(http_status_t status);
|
||||||
|
# ifdef HAVE_GSSAPI
|
||||||
|
-extern int _cupsSetNegotiateAuthString(http_t *http,
|
||||||
|
- const char *method,
|
||||||
|
- const char *resource);
|
||||||
|
+extern int _cupsSetNegotiateAuthString(http_t *http, const char *method, const char *resource);
|
||||||
|
# endif /* HAVE_GSSAPI */
|
||||||
|
extern char *_cupsUserDefault(char *name, size_t namesize);
|
||||||
|
|
||||||
|
diff --git a/cups/dest-options.c b/cups/dest-options.c
|
||||||
|
index 51705a5..cfa28ce 100644
|
||||||
|
--- a/cups/dest-options.c
|
||||||
|
+++ b/cups/dest-options.c
|
||||||
|
@@ -572,6 +572,7 @@ cupsCopyDestInfo(
|
||||||
|
cups_dest_t *dest) /* I - Destination */
|
||||||
|
{
|
||||||
|
cups_dinfo_t *dinfo; /* Destination information */
|
||||||
|
+ unsigned dflags; /* Destination flags */
|
||||||
|
ipp_t *request, /* Get-Printer-Attributes request */
|
||||||
|
*response; /* Supported attributes */
|
||||||
|
int tries, /* Number of tries so far */
|
||||||
|
@@ -581,6 +582,7 @@ cupsCopyDestInfo(
|
||||||
|
char resource[1024]; /* Resource path */
|
||||||
|
int version; /* IPP version */
|
||||||
|
ipp_status_t status; /* Status of request */
|
||||||
|
+ _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
|
||||||
|
static const char * const requested_attrs[] =
|
||||||
|
{ /* Requested attributes */
|
||||||
|
"job-template",
|
||||||
|
@@ -589,14 +591,25 @@ cupsCopyDestInfo(
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
- DEBUG_printf(("cupsCopyDestSupported(http=%p, dest=%p(%s))", (void *)http, (void *)dest, dest ? dest->name : ""));
|
||||||
|
+ DEBUG_printf(("cupsCopyDestInfo(http=%p, dest=%p(%s))", (void *)http, (void *)dest, dest ? dest->name : ""));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the default connection as needed...
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!http)
|
||||||
|
- http = _cupsConnect();
|
||||||
|
+ {
|
||||||
|
+ http = _cupsConnect();
|
||||||
|
+ dflags = CUPS_DEST_FLAGS_NONE;
|
||||||
|
+ }
|
||||||
|
+#ifdef AF_LOCAL
|
||||||
|
+ else if (strcmp(http->hostname, cg->server) || (httpAddrFamily(http->hostaddr) != AF_LOCAL && cg->ipp_port != httpAddrPort(http->hostaddr)))
|
||||||
|
+#else
|
||||||
|
+ else if (strcmp(http->hostname, cg->server) || cg->ipp_port != httpAddrPort(http->hostaddr))
|
||||||
|
+#endif /* AF_LOCAL */
|
||||||
|
+ dflags = CUPS_DEST_FLAGS_DEVICE;
|
||||||
|
+ else
|
||||||
|
+ dflags = CUPS_DEST_FLAGS_NONE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Range check input...
|
||||||
|
@@ -609,8 +622,11 @@ cupsCopyDestInfo(
|
||||||
|
* Get the printer URI and resource path...
|
||||||
|
*/
|
||||||
|
|
||||||
|
- if ((uri = _cupsGetDestResource(dest, resource, sizeof(resource))) == NULL)
|
||||||
|
+ if ((uri = _cupsGetDestResource(dest, dflags, resource, sizeof(resource))) == NULL)
|
||||||
|
+ {
|
||||||
|
+ DEBUG_puts("1cupsCopyDestInfo: Unable to get resource.");
|
||||||
|
return (NULL);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the supported attributes...
|
||||||
|
@@ -628,28 +644,25 @@ cupsCopyDestInfo(
|
||||||
|
*/
|
||||||
|
|
||||||
|
request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
|
||||||
|
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
|
||||||
|
- uri);
|
||||||
|
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
|
||||||
|
- "requesting-user-name", NULL, cupsUser());
|
||||||
|
- ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
|
||||||
|
- "requested-attributes",
|
||||||
|
- (int)(sizeof(requested_attrs) / sizeof(requested_attrs[0])),
|
||||||
|
- NULL, requested_attrs);
|
||||||
|
+
|
||||||
|
+ ippSetVersion(request, version / 10, version % 10);
|
||||||
|
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
|
||||||
|
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser());
|
||||||
|
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (int)(sizeof(requested_attrs) / sizeof(requested_attrs[0])), NULL, requested_attrs);
|
||||||
|
response = cupsDoRequest(http, request, resource);
|
||||||
|
status = cupsLastError();
|
||||||
|
|
||||||
|
if (status > IPP_STATUS_OK_IGNORED_OR_SUBSTITUTED)
|
||||||
|
{
|
||||||
|
- DEBUG_printf(("cupsCopyDestSupported: Get-Printer-Attributes for '%s' "
|
||||||
|
- "returned %s (%s)", dest->name, ippErrorString(status),
|
||||||
|
- cupsLastErrorString()));
|
||||||
|
+ DEBUG_printf(("1cupsCopyDestInfo: Get-Printer-Attributes for '%s' returned %s (%s)", dest->name, ippErrorString(status), cupsLastErrorString()));
|
||||||
|
|
||||||
|
ippDelete(response);
|
||||||
|
response = NULL;
|
||||||
|
|
||||||
|
- if (status == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED && version > 11)
|
||||||
|
+ if ((status == IPP_STATUS_ERROR_BAD_REQUEST || status == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED) && version > 11)
|
||||||
|
+ {
|
||||||
|
version = 11;
|
||||||
|
+ }
|
||||||
|
else if (status == IPP_STATUS_ERROR_BUSY)
|
||||||
|
{
|
||||||
|
sleep((unsigned)delay);
|
||||||
|
@@ -665,7 +678,10 @@ cupsCopyDestInfo(
|
||||||
|
while (!response && tries < 10);
|
||||||
|
|
||||||
|
if (!response)
|
||||||
|
+ {
|
||||||
|
+ DEBUG_puts("1cupsCopyDestInfo: Unable to get printer attributes.");
|
||||||
|
return (NULL);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate a cups_dinfo_t structure and return it...
|
||||||
|
@@ -678,6 +694,8 @@ cupsCopyDestInfo(
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ DEBUG_printf(("1cupsCopyDestInfo: version=%d, uri=\"%s\", resource=\"%s\".", version, uri, resource));
|
||||||
|
+
|
||||||
|
dinfo->version = version;
|
||||||
|
dinfo->uri = uri;
|
||||||
|
dinfo->resource = _cupsStrAlloc(resource);
|
||||||
|
diff --git a/cups/dest.c b/cups/dest.c
|
||||||
|
index 57a8dc9..3537572 100644
|
||||||
|
--- a/cups/dest.c
|
||||||
|
+++ b/cups/dest.c
|
||||||
|
@@ -1103,13 +1103,16 @@ cupsGetDest(const char *name, /* I - Destination name or @code NULL@ for the d
|
||||||
|
* '_cupsGetDestResource()' - Get the resource path and URI for a destination.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-const char * /* O - Printer URI */
|
||||||
|
+const char * /* O - URI */
|
||||||
|
_cupsGetDestResource(
|
||||||
|
cups_dest_t *dest, /* I - Destination */
|
||||||
|
+ unsigned flags, /* I - Destination flags */
|
||||||
|
char *resource, /* I - Resource buffer */
|
||||||
|
size_t resourcesize) /* I - Size of resource buffer */
|
||||||
|
{
|
||||||
|
- const char *uri; /* Printer URI */
|
||||||
|
+ const char *uri, /* URI */
|
||||||
|
+ *device_uri, /* Device URI */
|
||||||
|
+ *printer_uri; /* Printer URI */
|
||||||
|
char scheme[32], /* URI scheme */
|
||||||
|
userpass[256], /* Username and password (unused) */
|
||||||
|
hostname[256]; /* Hostname */
|
||||||
|
@@ -1132,25 +1135,46 @@ _cupsGetDestResource(
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * Grab the printer URI...
|
||||||
|
+ * Grab the printer and device URIs...
|
||||||
|
*/
|
||||||
|
|
||||||
|
- if ((uri = cupsGetOption("printer-uri-supported", dest->num_options, dest->options)) == NULL)
|
||||||
|
+ device_uri = cupsGetOption("device-uri", dest->num_options, dest->options);
|
||||||
|
+ printer_uri = cupsGetOption("printer-uri-supported", dest->num_options, dest->options);
|
||||||
|
+
|
||||||
|
+ DEBUG_printf(("1_cupsGetDestResource: device-uri=\"%s\", printer-uri-supported=\"%s\".", device_uri, printer_uri));
|
||||||
|
+
|
||||||
|
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
|
||||||
|
+ if (((flags & CUPS_DEST_FLAGS_DEVICE) || !printer_uri) && strstr(device_uri, "._tcp"))
|
||||||
|
{
|
||||||
|
- if ((uri = cupsGetOption("device-uri", dest->num_options, dest->options)) != NULL)
|
||||||
|
+ if ((device_uri = cups_dnssd_resolve(dest, device_uri, 5000, NULL, NULL, NULL)) != NULL)
|
||||||
|
{
|
||||||
|
-#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
|
||||||
|
- if (strstr(uri, "._tcp"))
|
||||||
|
- uri = cups_dnssd_resolve(dest, uri, 5000, NULL, NULL, NULL);
|
||||||
|
-#endif /* HAVE_DNSSD || HAVE_AVAHI */
|
||||||
|
+ DEBUG_printf(("1_cupsGetDestResource: Resolved device-uri=\"%s\".", device_uri));
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- if (uri)
|
||||||
|
+ else
|
||||||
|
{
|
||||||
|
- DEBUG_printf(("1_cupsGetDestResource: Resolved printer-uri-supported=\"%s\"", uri));
|
||||||
|
+ DEBUG_puts("1_cupsGetDestResource: Unable to resolve device.");
|
||||||
|
|
||||||
|
- uri = _cupsCreateDest(dest->name, cupsGetOption("printer-info", dest->num_options, dest->options), NULL, uri, resource, resourcesize);
|
||||||
|
+ if (resource)
|
||||||
|
+ *resource = '\0';
|
||||||
|
+
|
||||||
|
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOENT), 0);
|
||||||
|
+
|
||||||
|
+ return (NULL);
|
||||||
|
}
|
||||||
|
+ }
|
||||||
|
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
|
||||||
|
+
|
||||||
|
+ if (flags & CUPS_DEST_FLAGS_DEVICE)
|
||||||
|
+ {
|
||||||
|
+ uri = device_uri;
|
||||||
|
+ }
|
||||||
|
+ else if (printer_uri)
|
||||||
|
+ {
|
||||||
|
+ uri = printer_uri;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ uri = _cupsCreateDest(dest->name, cupsGetOption("printer-info", dest->num_options, dest->options), NULL, device_uri, resource, resourcesize);
|
||||||
|
|
||||||
|
if (uri)
|
||||||
|
{
|
||||||
|
@@ -1160,30 +1184,24 @@ _cupsGetDestResource(
|
||||||
|
|
||||||
|
uri = cupsGetOption("printer-uri-supported", dest->num_options, dest->options);
|
||||||
|
}
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- DEBUG_puts("1_cupsGetDestResource: No printer-uri-supported found.");
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (resource)
|
||||||
|
- *resource = '\0';
|
||||||
|
+ if (!uri)
|
||||||
|
+ {
|
||||||
|
+ DEBUG_puts("1_cupsGetDestResource: No printer-uri-supported or device-uri found.");
|
||||||
|
|
||||||
|
- _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOENT), 0);
|
||||||
|
+ if (resource)
|
||||||
|
+ *resource = '\0';
|
||||||
|
|
||||||
|
- return (NULL);
|
||||||
|
- }
|
||||||
|
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOENT), 0);
|
||||||
|
+
|
||||||
|
+ return (NULL);
|
||||||
|
}
|
||||||
|
- else
|
||||||
|
+ else if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), userpass, sizeof(userpass), hostname, sizeof(hostname), &port, resource, (int)resourcesize) < HTTP_URI_STATUS_OK)
|
||||||
|
{
|
||||||
|
- DEBUG_printf(("1_cupsGetDestResource: printer-uri-supported=\"%s\"", uri));
|
||||||
|
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad URI."), 1);
|
||||||
|
|
||||||
|
- if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme),
|
||||||
|
- userpass, sizeof(userpass), hostname, sizeof(hostname),
|
||||||
|
- &port, resource, (int)resourcesize) < HTTP_URI_STATUS_OK)
|
||||||
|
- {
|
||||||
|
- _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad printer-uri."), 1);
|
||||||
|
-
|
||||||
|
- return (NULL);
|
||||||
|
- }
|
||||||
|
+ return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_printf(("1_cupsGetDestResource: resource=\"%s\"", resource));
|
||||||
|
diff --git a/cups/testdest.c b/cups/testdest.c
|
||||||
|
index c5c2052..27060f6 100644
|
||||||
|
--- a/cups/testdest.c
|
||||||
|
+++ b/cups/testdest.c
|
||||||
|
@@ -43,9 +43,12 @@ int /* O - Exit status */
|
||||||
|
main(int argc, /* I - Number of command-line arguments */
|
||||||
|
char *argv[]) /* I - Command-line arguments */
|
||||||
|
{
|
||||||
|
+ int i; /* Looping var */
|
||||||
|
http_t *http; /* Connection to destination */
|
||||||
|
cups_dest_t *dest = NULL; /* Destination */
|
||||||
|
cups_dinfo_t *dinfo; /* Destination info */
|
||||||
|
+ unsigned dflags = CUPS_DEST_FLAGS_NONE;
|
||||||
|
+ /* Destination flags */
|
||||||
|
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
@@ -103,9 +106,17 @@ main(int argc, /* I - Number of command-line arguments */
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
- else if (!strncmp(argv[1], "ipp://", 6) || !strncmp(argv[1], "ipps://", 7))
|
||||||
|
- dest = cupsGetDestWithURI(NULL, argv[1]);
|
||||||
|
- else if (!strcmp(argv[1], "default"))
|
||||||
|
+
|
||||||
|
+ i = 1;
|
||||||
|
+ if (!strcmp(argv[i], "--device"))
|
||||||
|
+ {
|
||||||
|
+ dflags = CUPS_DEST_FLAGS_DEVICE;
|
||||||
|
+ i ++;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!strncmp(argv[i], "ipp://", 6) || !strncmp(argv[i], "ipps://", 7))
|
||||||
|
+ dest = cupsGetDestWithURI(NULL, argv[i]);
|
||||||
|
+ else if (!strcmp(argv[i], "default"))
|
||||||
|
{
|
||||||
|
dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, NULL, NULL);
|
||||||
|
if (dest && dest->instance)
|
||||||
|
@@ -114,67 +125,70 @@ main(int argc, /* I - Number of command-line arguments */
|
||||||
|
printf("default is \"%s\".\n", dest->name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
- dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, argv[1], NULL);
|
||||||
|
+ dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, argv[i], NULL);
|
||||||
|
|
||||||
|
if (!dest)
|
||||||
|
{
|
||||||
|
- printf("testdest: Unable to get destination \"%s\": %s\n", argv[1], cupsLastErrorString());
|
||||||
|
+ printf("testdest: Unable to get destination \"%s\": %s\n", argv[i], cupsLastErrorString());
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
- if ((http = cupsConnectDest(dest, CUPS_DEST_FLAGS_NONE, 30000, NULL, NULL, 0, NULL, NULL)) == NULL)
|
||||||
|
+ i ++;
|
||||||
|
+
|
||||||
|
+ if ((http = cupsConnectDest(dest, dflags, 30000, NULL, NULL, 0, NULL, NULL)) == NULL)
|
||||||
|
{
|
||||||
|
- printf("testdest: Unable to connect to destination \"%s\": %s\n", argv[1], cupsLastErrorString());
|
||||||
|
+ printf("testdest: Unable to connect to destination \"%s\": %s\n", dest->name, cupsLastErrorString());
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dinfo = cupsCopyDestInfo(http, dest)) == NULL)
|
||||||
|
{
|
||||||
|
- printf("testdest: Unable to get information for destination \"%s\": %s\n", argv[1], cupsLastErrorString());
|
||||||
|
+ printf("testdest: Unable to get information for destination \"%s\": %s\n", dest->name, cupsLastErrorString());
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (argc == 2 || (!strcmp(argv[2], "supported") && argc < 6))
|
||||||
|
+ if (i == argc || !strcmp(argv[i], "supported"))
|
||||||
|
{
|
||||||
|
- if (argc > 3)
|
||||||
|
- show_supported(http, dest, dinfo, argv[3], argv[4]);
|
||||||
|
+ i ++;
|
||||||
|
+
|
||||||
|
+ if ((i + 1) < argc)
|
||||||
|
+ show_supported(http, dest, dinfo, argv[i], argv[i + 1]);
|
||||||
|
else if (argc > 2)
|
||||||
|
- show_supported(http, dest, dinfo, argv[3], NULL);
|
||||||
|
+ show_supported(http, dest, dinfo, argv[i], NULL);
|
||||||
|
else
|
||||||
|
show_supported(http, dest, dinfo, NULL, NULL);
|
||||||
|
}
|
||||||
|
- else if (!strcmp(argv[2], "conflicts") && argc > 3)
|
||||||
|
+ else if (!strcmp(argv[i], "conflicts") && (i + 1) < argc)
|
||||||
|
{
|
||||||
|
- int i, /* Looping var */
|
||||||
|
- num_options = 0;/* Number of options */
|
||||||
|
+ int num_options = 0;/* Number of options */
|
||||||
|
cups_option_t *options = NULL;/* Options */
|
||||||
|
|
||||||
|
- for (i = 3; i < argc; i ++)
|
||||||
|
+ for (i ++; i < argc; i ++)
|
||||||
|
num_options = cupsParseOptions(argv[i], num_options, &options);
|
||||||
|
|
||||||
|
show_conflicts(http, dest, dinfo, num_options, options);
|
||||||
|
}
|
||||||
|
- else if (!strcmp(argv[2], "default") && argc == 4)
|
||||||
|
+ else if (!strcmp(argv[i], "default") && (i + 1) < argc)
|
||||||
|
{
|
||||||
|
- show_default(http, dest, dinfo, argv[3]);
|
||||||
|
+ show_default(http, dest, dinfo, argv[i + 1]);
|
||||||
|
}
|
||||||
|
- else if (!strcmp(argv[2], "localize") && argc < 6)
|
||||||
|
+ else if (!strcmp(argv[i], "localize"))
|
||||||
|
{
|
||||||
|
- if (argc > 3)
|
||||||
|
- localize(http, dest, dinfo, argv[3], argv[4]);
|
||||||
|
+ i ++;
|
||||||
|
+ if ((i + 1) < argc)
|
||||||
|
+ localize(http, dest, dinfo, argv[i], argv[i + 1]);
|
||||||
|
else if (argc > 2)
|
||||||
|
- localize(http, dest, dinfo, argv[3], NULL);
|
||||||
|
+ localize(http, dest, dinfo, argv[i], NULL);
|
||||||
|
else
|
||||||
|
localize(http, dest, dinfo, NULL, NULL);
|
||||||
|
}
|
||||||
|
- else if (!strcmp(argv[2], "media"))
|
||||||
|
+ else if (!strcmp(argv[i], "media"))
|
||||||
|
{
|
||||||
|
- int i; /* Looping var */
|
||||||
|
const char *name = NULL; /* Media name, if any */
|
||||||
|
unsigned flags = CUPS_MEDIA_FLAGS_DEFAULT;
|
||||||
|
/* Media selection flags */
|
||||||
|
|
||||||
|
- for (i = 3; i < argc; i ++)
|
||||||
|
+ for (i ++; i < argc; i ++)
|
||||||
|
{
|
||||||
|
if (!strcmp(argv[i], "borderless"))
|
||||||
|
flags = CUPS_MEDIA_FLAGS_BORDERLESS;
|
||||||
|
@@ -192,19 +206,19 @@ main(int argc, /* I - Number of command-line arguments */
|
||||||
|
|
||||||
|
show_media(http, dest, dinfo, flags, name);
|
||||||
|
}
|
||||||
|
- else if (!strcmp(argv[2], "print") && argc > 3)
|
||||||
|
+ else if (!strcmp(argv[i], "print") && (i + 1) < argc)
|
||||||
|
{
|
||||||
|
- int i, /* Looping var */
|
||||||
|
- num_options = 0;/* Number of options */
|
||||||
|
+ int num_options = 0;/* Number of options */
|
||||||
|
cups_option_t *options = NULL;/* Options */
|
||||||
|
+ const char *filename = argv[i + 1];
|
||||||
|
|
||||||
|
- for (i = 4; i < argc; i ++)
|
||||||
|
+ for (i += 2; i < argc; i ++)
|
||||||
|
num_options = cupsParseOptions(argv[i], num_options, &options);
|
||||||
|
|
||||||
|
- print_file(http, dest, dinfo, argv[3], num_options, options);
|
||||||
|
+ print_file(http, dest, dinfo, filename, num_options, options);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
- usage(argv[2]);
|
||||||
|
+ usage(argv[i]);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
@@ -740,9 +754,9 @@ usage(const char *arg) /* I - Argument for usage message */
|
||||||
|
printf("testdest: Unknown option \"%s\".\n", arg);
|
||||||
|
|
||||||
|
puts("Usage:");
|
||||||
|
- puts(" ./testdest name [operation ...]");
|
||||||
|
- puts(" ./testdest ipp://... [operation ...]");
|
||||||
|
- puts(" ./testdest ipps://... [operation ...]");
|
||||||
|
+ puts(" ./testdest [--device] name [operation ...]");
|
||||||
|
+ puts(" ./testdest [--device] ipp://... [operation ...]");
|
||||||
|
+ puts(" ./testdest [--device] ipps://... [operation ...]");
|
||||||
|
puts(" ./testdest --enum [grayscale] [color] [duplex] [staple] [small]\n"
|
||||||
|
" [medium] [large]");
|
||||||
|
puts("");
|
||||||
|
diff --git a/test/ippserver.c b/test/ippserver.c
|
||||||
|
index 38b304f..c593d3a 100644
|
||||||
|
--- a/test/ippserver.c
|
||||||
|
+++ b/test/ippserver.c
|
||||||
|
@@ -461,6 +461,7 @@ static AvahiClient *DNSSDClient = NULL;
|
||||||
|
#endif /* HAVE_DNSSD */
|
||||||
|
|
||||||
|
static int KeepFiles = 0,
|
||||||
|
+ MaxVersion = 20,
|
||||||
|
Verbosity = 0;
|
||||||
|
|
||||||
|
|
||||||
|
@@ -533,6 +534,23 @@ main(int argc, /* I - Number of command-line args */
|
||||||
|
pin = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
+ case 'V' : /* -V max-version */
|
||||||
|
+ i ++;
|
||||||
|
+ if (i >= argc)
|
||||||
|
+ usage(1);
|
||||||
|
+
|
||||||
|
+ if (!strcmp(argv[i], "2.2"))
|
||||||
|
+ MaxVersion = 22;
|
||||||
|
+ else if (!strcmp(argv[i], "2.1"))
|
||||||
|
+ MaxVersion = 21;
|
||||||
|
+ else if (!strcmp(argv[i], "2.0"))
|
||||||
|
+ MaxVersion = 20;
|
||||||
|
+ else if (!strcmp(argv[i], "1.1"))
|
||||||
|
+ MaxVersion = 11;
|
||||||
|
+ else
|
||||||
|
+ usage(1);
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
case 'a' : /* -a attributes-file */
|
||||||
|
i ++;
|
||||||
|
if (i >= argc)
|
||||||
|
@@ -1324,9 +1342,10 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
|
||||||
|
};
|
||||||
|
static const char * const versions[] =/* ipp-versions-supported values */
|
||||||
|
{
|
||||||
|
- "1.0",
|
||||||
|
"1.1",
|
||||||
|
- "2.0"
|
||||||
|
+ "2.0",
|
||||||
|
+ "2.1",
|
||||||
|
+ "2.2"
|
||||||
|
};
|
||||||
|
static const char * const features[] =/* ipp-features-supported values */
|
||||||
|
{
|
||||||
|
@@ -1738,7 +1757,12 @@ create_printer(const char *servername, /* I - Server hostname (NULL for default)
|
||||||
|
|
||||||
|
/* ipp-versions-supported */
|
||||||
|
if (!ippFindAttribute(printer->attrs, "ipp-versions-supported", IPP_TAG_ZERO))
|
||||||
|
- ippAddStrings(printer->attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "ipp-versions-supported", sizeof(versions) / sizeof(versions[0]), NULL, versions);
|
||||||
|
+ {
|
||||||
|
+ int num_versions = MaxVersion == 11 ? 1 : MaxVersion == 20 ? 2 : MaxVersion == 21 ? 3 : 4;
|
||||||
|
+ /* Number of supported versions */
|
||||||
|
+
|
||||||
|
+ ippAddStrings(printer->attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "ipp-versions-supported", num_versions, NULL, versions);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* job-account-id-default */
|
||||||
|
if (!ippFindAttribute(printer->attrs, "job-account-id-default", IPP_TAG_ZERO))
|
||||||
|
@@ -5800,15 +5824,24 @@ process_ipp(_ipp_client_t *client) /* I - Client */
|
||||||
|
* Return an error, since we only support IPP 1.x and 2.x.
|
||||||
|
*/
|
||||||
|
|
||||||
|
- respond_ipp(client, IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED,
|
||||||
|
- "Bad request version number %d.%d.", major, minor);
|
||||||
|
+ respond_ipp(client, IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED, "Bad request version number %d.%d.", major, minor);
|
||||||
|
+ }
|
||||||
|
+ else if ((major * 10 + minor) > MaxVersion)
|
||||||
|
+ {
|
||||||
|
+ if (httpGetState(client->http) != HTTP_STATE_POST_SEND)
|
||||||
|
+ httpFlush(client->http); /* Flush trailing (junk) data */
|
||||||
|
+
|
||||||
|
+ respond_http(client, HTTP_STATUS_BAD_REQUEST, NULL, NULL, 0);
|
||||||
|
+ return (0);
|
||||||
|
}
|
||||||
|
else if (ippGetRequestId(client->request) <= 0)
|
||||||
|
- respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST, "Bad request-id %d.",
|
||||||
|
- ippGetRequestId(client->request));
|
||||||
|
+ {
|
||||||
|
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST, "Bad request-id %d.", ippGetRequestId(client->request));
|
||||||
|
+ }
|
||||||
|
else if (!ippFirstAttribute(client->request))
|
||||||
|
- respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST,
|
||||||
|
- "No attributes in request.");
|
||||||
|
+ {
|
||||||
|
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST, "No attributes in request.");
|
||||||
|
+ }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
@@ -6877,8 +6910,7 @@ usage(int status) /* O - Exit status */
|
||||||
|
{
|
||||||
|
if (!status)
|
||||||
|
{
|
||||||
|
- puts(CUPS_SVERSION " - Copyright 2010-2015 by Apple Inc. All rights "
|
||||||
|
- "reserved.");
|
||||||
|
+ puts(CUPS_SVERSION " - Copyright (c) 2010-2018 by Apple Inc. All rights reserved.");
|
||||||
|
puts("");
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -6888,6 +6920,7 @@ usage(int status) /* O - Exit status */
|
||||||
|
puts("-2 Supports 2-sided printing (default=1-sided)");
|
||||||
|
puts("-M manufacturer Manufacturer name (default=Test)");
|
||||||
|
puts("-P PIN printing mode");
|
||||||
|
+ puts("-V max-version Set maximum supported IPP version");
|
||||||
|
puts("-a attributes-file Load printer attributes from file");
|
||||||
|
puts("-c command Run command for every print job");
|
||||||
|
printf("-d spool-directory Spool directory "
|
@ -0,0 +1,98 @@
|
|||||||
|
diff --git a/templates/admin.tmpl b/templates/admin.tmpl
|
||||||
|
index 101f960..5ebd813 100644
|
||||||
|
--- a/templates/admin.tmpl
|
||||||
|
+++ b/templates/admin.tmpl
|
||||||
|
@@ -27,9 +27,6 @@
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<FORM ACTION="/admin/" METHOD="POST"><INPUT TYPE="HIDDEN" NAME="org.cups.sid" VALUE="{$org.cups.sid}"><INPUT TYPE="HIDDEN" NAME="OP" VALUE="config-server"><INPUT TYPE="SUBMIT" VALUE="Edit Configuration File"></FORM>
|
||||||
|
- <FORM ACTION="/admin/log/access_log" METHOD="GET"><INPUT TYPE="SUBMIT" VALUE="View Access Log"></FORM>
|
||||||
|
- <FORM ACTION="/admin/log/error_log" METHOD="GET"><INPUT TYPE="SUBMIT" VALUE="View Error Log"></FORM>
|
||||||
|
- <FORM ACTION="/admin/log/page_log" METHOD="GET"><INPUT TYPE="SUBMIT" VALUE="View Page Log"></FORM>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
{SETTINGS_ERROR?<P>{SETTINGS_MESSAGE}</P>
|
||||||
|
diff --git a/templates/de/admin.tmpl b/templates/de/admin.tmpl
|
||||||
|
index fb2851a..f8ddeff 100644
|
||||||
|
--- a/templates/de/admin.tmpl
|
||||||
|
+++ b/templates/de/admin.tmpl
|
||||||
|
@@ -27,9 +27,6 @@
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<FORM ACTION="/admin/" METHOD="POST"><INPUT TYPE="HIDDEN" NAME="org.cups.sid" VALUE="{$org.cups.sid}"><INPUT TYPE="HIDDEN" NAME="OP" VALUE="config-server"><INPUT TYPE="SUBMIT" VALUE="Konfigurationsdatei bearbeiten"></FORM>
|
||||||
|
- <FORM ACTION="/admin/log/access_log" METHOD="GET"><INPUT TYPE="SUBMIT" VALUE="Zugriffsprotokoll anzeigen"></FORM>
|
||||||
|
- <FORM ACTION="/admin/log/error_log" METHOD="GET"><INPUT TYPE="SUBMIT" VALUE="Fehlerprotokoll anzeigen"></FORM>
|
||||||
|
- <FORM ACTION="/admin/log/page_log" METHOD="GET"><INPUT TYPE="SUBMIT" VALUE="Seitenprotokoll anzeigen"></FORM>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
{SETTINGS_ERROR?<P>{SETTINGS_MESSAGE}</P>
|
||||||
|
diff --git a/templates/es/admin.tmpl b/templates/es/admin.tmpl
|
||||||
|
index 097c65c..b83b1a0 100644
|
||||||
|
--- a/templates/es/admin.tmpl
|
||||||
|
+++ b/templates/es/admin.tmpl
|
||||||
|
@@ -27,9 +27,6 @@
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<FORM ACTION="/admin/" METHOD="POST"><INPUT TYPE="HIDDEN" NAME="org.cups.sid" VALUE="{$org.cups.sid}"><INPUT TYPE="HIDDEN" NAME="OP" VALUE="config-server"><INPUT TYPE="SUBMIT" VALUE="Editar archivo de configuración"></FORM>
|
||||||
|
- <FORM ACTION="/admin/log/access_log" METHOD="GET"><INPUT TYPE="SUBMIT" VALUE="Ver archivo de registro de accesos"></FORM>
|
||||||
|
- <FORM ACTION="/admin/log/error_log" METHOD="GET"><INPUT TYPE="SUBMIT" VALUE="Ver archivo de registro de errores"></FORM>
|
||||||
|
- <FORM ACTION="/admin/log/page_log" METHOD="GET"><INPUT TYPE="SUBMIT" VALUE="Ver archivo de registro de páginas"></FORM>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
{SETTINGS_ERROR?<P>{SETTINGS_MESSAGE}</P>
|
||||||
|
diff --git a/templates/fr/admin.tmpl b/templates/fr/admin.tmpl
|
||||||
|
index 2fcd9c5..e365ff3 100644
|
||||||
|
--- a/templates/fr/admin.tmpl
|
||||||
|
+++ b/templates/fr/admin.tmpl
|
||||||
|
@@ -27,9 +27,6 @@
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<FORM ACTION="/admin/" METHOD="POST"><INPUT TYPE="HIDDEN" NAME="org.cups.sid" VALUE="{$org.cups.sid}"><INPUT TYPE="HIDDEN" NAME="OP" VALUE="config-server"><INPUT TYPE="SUBMIT" VALUE="Éditer le fichier de configuration"></FORM>
|
||||||
|
- <FORM ACTION="/admin/log/access_log" METHOD="GET"><INPUT TYPE="SUBMIT" VALUE="Visualiser Access Log"></FORM>
|
||||||
|
- <FORM ACTION="/admin/log/error_log" METHOD="GET"><INPUT TYPE="SUBMIT" VALUE="Visualiser Error Log"></FORM>
|
||||||
|
- <FORM ACTION="/admin/log/page_log" METHOD="GET"><INPUT TYPE="SUBMIT" VALUE="Visualiser Page Log"></FORM>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
{SETTINGS_ERROR?<P>{SETTINGS_MESSAGE}</P>
|
||||||
|
diff --git a/templates/ja/admin.tmpl b/templates/ja/admin.tmpl
|
||||||
|
index 13d6f13..f5fa750 100644
|
||||||
|
--- a/templates/ja/admin.tmpl
|
||||||
|
+++ b/templates/ja/admin.tmpl
|
||||||
|
@@ -27,9 +27,6 @@
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<FORM ACTION="/admin/" METHOD="POST"><INPUT TYPE="HIDDEN" NAME="org.cups.sid" VALUE="{$org.cups.sid}"><INPUT TYPE="HIDDEN" NAME="OP" VALUE="config-server"><INPUT TYPE="SUBMIT" VALUE="設定ファイルの編集"></FORM>
|
||||||
|
- <FORM ACTION="/admin/log/access_log" METHOD="GET"><INPUT TYPE="SUBMIT" VALUE="アクセスログの表示"></FORM>
|
||||||
|
- <FORM ACTION="/admin/log/error_log" METHOD="GET"><INPUT TYPE="SUBMIT" VALUE="エラーログの表示"></FORM>
|
||||||
|
- <FORM ACTION="/admin/log/page_log" METHOD="GET"><INPUT TYPE="SUBMIT" VALUE="ページログの表示"></FORM>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
{SETTINGS_ERROR?<P>{SETTINGS_MESSAGE}</P>
|
||||||
|
diff --git a/templates/pt_BR/admin.tmpl b/templates/pt_BR/admin.tmpl
|
||||||
|
index b847bef..e11d889 100644
|
||||||
|
--- a/templates/pt_BR/admin.tmpl
|
||||||
|
+++ b/templates/pt_BR/admin.tmpl
|
||||||
|
@@ -27,9 +27,6 @@
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<FORM ACTION="/admin/" METHOD="POST"><INPUT TYPE="HIDDEN" NAME="org.cups.sid" VALUE="{$org.cups.sid}"><INPUT TYPE="HIDDEN" NAME="OP" VALUE="config-server"><INPUT TYPE="SUBMIT" VALUE="Editar arquivo de configuração"></FORM>
|
||||||
|
- <FORM ACTION="/admin/log/access_log" METHOD="GET"><INPUT TYPE="SUBMIT" VALUE="Ver log de acessos"></FORM>
|
||||||
|
- <FORM ACTION="/admin/log/error_log" METHOD="GET"><INPUT TYPE="SUBMIT" VALUE="Ver log de erros"></FORM>
|
||||||
|
- <FORM ACTION="/admin/log/page_log" METHOD="GET"><INPUT TYPE="SUBMIT" VALUE="Ver log de páginas"></FORM>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
{SETTINGS_ERROR?<P>{SETTINGS_MESSAGE}</P>
|
||||||
|
diff --git a/templates/ru/admin.tmpl b/templates/ru/admin.tmpl
|
||||||
|
index 49a168c..44b1493 100644
|
||||||
|
--- a/templates/ru/admin.tmpl
|
||||||
|
+++ b/templates/ru/admin.tmpl
|
||||||
|
@@ -26,9 +26,6 @@
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<FORM ACTION="/admin/" METHOD="POST"><INPUT TYPE="HIDDEN" NAME="org.cups.sid" VALUE="{$org.cups.sid}"><INPUT TYPE="HIDDEN" NAME="OP" VALUE="config-server"><INPUT TYPE="SUBMIT" VALUE="Редактировать конфигурационный файл"></FORM>
|
||||||
|
- <FORM ACTION="/admin/log/access_log" METHOD="GET"><INPUT TYPE="SUBMIT" VALUE="Показать журнал заданий"></FORM>
|
||||||
|
- <FORM ACTION="/admin/log/error_log" METHOD="GET"><INPUT TYPE="SUBMIT" VALUE="Показать журнал ошибок"></FORM>
|
||||||
|
- <FORM ACTION="/admin/log/page_log" METHOD="GET"><INPUT TYPE="SUBMIT" VALUE="Показать журнал страниц"></FORM>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
{SETTINGS_ERROR?<P>{SETTINGS_MESSAGE}</P>
|
@ -0,0 +1,31 @@
|
|||||||
|
From a0c8b9c9556882f00c68b9727a95a1b6d1452913 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael R Sweet <michael.r.sweet@gmail.com>
|
||||||
|
Date: Tue, 6 Dec 2022 09:04:01 -0500
|
||||||
|
Subject: [PATCH] Require authentication for CUPS-Get-Document.
|
||||||
|
|
||||||
|
---
|
||||||
|
conf/cupsd.conf.in | 8 +++++++-
|
||||||
|
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/conf/cupsd.conf.in b/conf/cupsd.conf.in
|
||||||
|
index b25884907..a07536f3e 100644
|
||||||
|
--- a/conf/cupsd.conf.in
|
||||||
|
+++ b/conf/cupsd.conf.in
|
||||||
|
@@ -68,7 +68,13 @@ IdleExitTimeout @EXIT_TIMEOUT@
|
||||||
|
Order deny,allow
|
||||||
|
</Limit>
|
||||||
|
|
||||||
|
- <Limit Send-Document Send-URI Hold-Job Release-Job Restart-Job Purge-Jobs Set-Job-Attributes Create-Job-Subscription Renew-Subscription Cancel-Subscription Get-Notifications Reprocess-Job Cancel-Current-Job Suspend-Current-Job Resume-Job Cancel-My-Jobs Close-Job CUPS-Move-Job CUPS-Get-Document>
|
||||||
|
+ <Limit Send-Document Send-URI Hold-Job Release-Job Restart-Job Purge-Jobs Set-Job-Attributes Create-Job-Subscription Renew-Subscription Cancel-Subscription Get-Notifications Reprocess-Job Cancel-Current-Job Suspend-Current-Job Resume-Job Cancel-My-Jobs Close-Job CUPS-Move-Job>
|
||||||
|
+ Require user @OWNER @SYSTEM
|
||||||
|
+ Order deny,allow
|
||||||
|
+ </Limit>
|
||||||
|
+
|
||||||
|
+ <Limit CUPS-Get-Document>
|
||||||
|
+ AuthType Default
|
||||||
|
Require user @OWNER @SYSTEM
|
||||||
|
Order deny,allow
|
||||||
|
</Limit>
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
@ -0,0 +1,22 @@
|
|||||||
|
diff --git a/scheduler/ipp.c b/scheduler/ipp.c
|
||||||
|
index 649995bb5..2396c9b58 100644
|
||||||
|
--- a/scheduler/ipp.c
|
||||||
|
+++ b/scheduler/ipp.c
|
||||||
|
@@ -4873,6 +4873,8 @@ copy_printer_attrs(
|
||||||
|
* and document-format attributes that may be provided by the client.
|
||||||
|
*/
|
||||||
|
|
||||||
|
+ _cupsRWLockRead(&printer->lock);
|
||||||
|
+
|
||||||
|
curtime = time(NULL);
|
||||||
|
|
||||||
|
if (!ra || cupsArrayFind(ra, "marker-change-time"))
|
||||||
|
@@ -5034,6 +5036,8 @@ copy_printer_attrs(
|
||||||
|
if (printer->ppd_attrs)
|
||||||
|
copy_attrs(con->response, printer->ppd_attrs, ra, IPP_TAG_ZERO, 0, NULL);
|
||||||
|
copy_attrs(con->response, CommonData, ra, IPP_TAG_ZERO, IPP_TAG_COPY, NULL);
|
||||||
|
+
|
||||||
|
+ _cupsRWUnlock(&printer->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,109 @@
|
|||||||
|
From 7271db11d27fe436f0c743bed3be8a5c6f93f2c2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael R Sweet <michael.r.sweet@gmail.com>
|
||||||
|
Date: Mon, 9 Apr 2018 09:50:19 -0400
|
||||||
|
Subject: [PATCH] Use cupsGetNamedDest for legacy printing APIs (Issue #5288)
|
||||||
|
|
||||||
|
---
|
||||||
|
cups/util.c | 59 +++++-----------------------
|
||||||
|
xcode/CUPS.xcodeproj/project.pbxproj | 6 ++-
|
||||||
|
2 files changed, 15 insertions(+), 50 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/cups/util.c b/cups/util.c
|
||||||
|
index ebc54d3cf..b15963e9e 100644
|
||||||
|
--- a/cups/util.c
|
||||||
|
+++ b/cups/util.c
|
||||||
|
@@ -21,19 +22,6 @@
|
||||||
|
#endif /* WIN32 || __EMX__ */
|
||||||
|
|
||||||
|
|
||||||
|
-/*
|
||||||
|
- * Enumeration data and callback...
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
-typedef struct _cups_createdata_s
|
||||||
|
-{
|
||||||
|
- const char *name; /* Destination name */
|
||||||
|
- cups_dest_t *dest; /* Matching destination */
|
||||||
|
-} _cups_createdata_t;
|
||||||
|
-
|
||||||
|
-static int cups_create_cb(_cups_createdata_t *data, unsigned flags, cups_dest_t *dest);
|
||||||
|
-
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
* 'cupsCancelJob()' - Cancel a print job on the default server.
|
||||||
|
*
|
||||||
|
@@ -168,7 +156,7 @@ cupsCreateJob(
|
||||||
|
{
|
||||||
|
int job_id = 0; /* job-id value */
|
||||||
|
ipp_status_t status; /* Create-Job status */
|
||||||
|
- _cups_createdata_t data; /* Enumeration data */
|
||||||
|
+ cups_dest_t *dest; /* Destination */
|
||||||
|
cups_dinfo_t *info; /* Destination information */
|
||||||
|
|
||||||
|
|
||||||
|
@@ -188,12 +176,7 @@ cupsCreateJob(
|
||||||
|
* Lookup the destination...
|
||||||
|
*/
|
||||||
|
|
||||||
|
- data.name = name;
|
||||||
|
- data.dest = NULL;
|
||||||
|
-
|
||||||
|
- cupsEnumDests(0, 1000, NULL, 0, 0, (cups_dest_cb_t)cups_create_cb, &data);
|
||||||
|
-
|
||||||
|
- if (!data.dest)
|
||||||
|
+ if ((dest = cupsGetNamedDest(http, name, NULL)) == NULL)
|
||||||
|
{
|
||||||
|
DEBUG_puts("1cupsCreateJob: Destination not found.");
|
||||||
|
_cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOENT), 0);
|
||||||
|
@@ -205,18 +188,18 @@ cupsCreateJob(
|
||||||
|
*/
|
||||||
|
|
||||||
|
DEBUG_puts("1cupsCreateJob: Querying destination info.");
|
||||||
|
- if ((info = cupsCopyDestInfo(http, data.dest)) == NULL)
|
||||||
|
+ if ((info = cupsCopyDestInfo(http, dest)) == NULL)
|
||||||
|
{
|
||||||
|
DEBUG_puts("1cupsCreateJob: Query failed.");
|
||||||
|
- cupsFreeDests(1, data.dest);
|
||||||
|
+ cupsFreeDests(1, dest);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
- status = cupsCreateDestJob(http, data.dest, info, &job_id, title, num_options, options);
|
||||||
|
+ status = cupsCreateDestJob(http, dest, info, &job_id, title, num_options, options);
|
||||||
|
DEBUG_printf(("1cupsCreateJob: cupsCreateDestJob returned %04x (%s)", status, ippErrorString(status)));
|
||||||
|
|
||||||
|
cupsFreeDestInfo(info);
|
||||||
|
- cupsFreeDests(1, data.dest);
|
||||||
|
+ cupsFreeDests(1, dest);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the job...
|
||||||
|
@@ -968,25 +951,3 @@ cupsStartDocument(
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
-
|
||||||
|
-/*
|
||||||
|
- * 'cups_create_cb()' - Find the destination for printing.
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
-static int /* O - 0 on match */
|
||||||
|
-cups_create_cb(
|
||||||
|
- _cups_createdata_t *data, /* I - Data from cupsCreateJob call */
|
||||||
|
- unsigned flags, /* I - Enumeration flags */
|
||||||
|
- cups_dest_t *dest) /* I - Destination */
|
||||||
|
-{
|
||||||
|
- DEBUG_printf(("2cups_create_cb(data=%p(%s), flags=%08x, dest=%p(%s))", (void *)data, data->name, flags, (void *)dest, dest->name));
|
||||||
|
-
|
||||||
|
- (void)flags;
|
||||||
|
-
|
||||||
|
- if (dest->instance || strcasecmp(data->name, dest->name))
|
||||||
|
- return (1);
|
||||||
|
-
|
||||||
|
- cupsCopyDest(dest, 0, &data->dest);
|
||||||
|
-
|
||||||
|
- return (0);
|
||||||
|
-}
|
||||||
|
--
|
||||||
|
2.35.1
|
||||||
|
|
@ -0,0 +1,48 @@
|
|||||||
|
From c5ad7aaf6c8063a39974c6b4a3cf59b7f912daae Mon Sep 17 00:00:00 2001
|
||||||
|
From: Bryan Mason <bmason@redhat.com>
|
||||||
|
Date: Tue, 27 Jun 2023 04:18:46 -0700
|
||||||
|
Subject: [PATCH 1/2] Use "purge-job" instead of "purge-jobs" when canceling a
|
||||||
|
single job (#742)
|
||||||
|
|
||||||
|
The command "cancel -x <job>" adds "purge-jobs true" to the Cancel-Job
|
||||||
|
operation; however, the correct attribute to use for Cancel-job is
|
||||||
|
"purge-job" (singular), not "purge-jobs" (plural). As a result, job
|
||||||
|
files are not removed from /var/spool/cups when "cancel -x <job>" is
|
||||||
|
executed.
|
||||||
|
|
||||||
|
This patch resolves the issue by adding "purge-job" when the IPP
|
||||||
|
operation is Cancel-Job and "purge-jobs" for other IPP operations
|
||||||
|
(Purge-Jobs, Cancel-Jobs, and Cancel-My-Jobs)
|
||||||
|
---
|
||||||
|
systemv/cancel.c | 8 +++++++-
|
||||||
|
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/systemv/cancel.c b/systemv/cancel.c
|
||||||
|
index 572f413e1..f5b8e12b5 100644
|
||||||
|
--- a/systemv/cancel.c
|
||||||
|
+++ b/systemv/cancel.c
|
||||||
|
@@ -260,6 +260,7 @@ main(int argc, /* I - Number of command-line arguments */
|
||||||
|
* attributes-natural-language
|
||||||
|
* printer-uri + job-id *or* job-uri
|
||||||
|
* [requesting-user-name]
|
||||||
|
+ * [purge-job] or [purge-jobs]
|
||||||
|
*/
|
||||||
|
|
||||||
|
request = ippNewRequest(op);
|
||||||
|
@@ -294,7 +295,12 @@ main(int argc, /* I - Number of command-line arguments */
|
||||||
|
"requesting-user-name", NULL, cupsUser());
|
||||||
|
|
||||||
|
if (purge)
|
||||||
|
- ippAddBoolean(request, IPP_TAG_OPERATION, "purge-jobs", (char)purge);
|
||||||
|
+ {
|
||||||
|
+ if (op == IPP_CANCEL_JOB)
|
||||||
|
+ ippAddBoolean(request, IPP_TAG_OPERATION, "purge-job", (char)purge);
|
||||||
|
+ else
|
||||||
|
+ ippAddBoolean(request, IPP_TAG_OPERATION, "purge-jobs", (char)purge);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do the request and get back a response...
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
@ -0,0 +1,16 @@
|
|||||||
|
diff --git a/cgi-bin/ipp-var.c b/cgi-bin/ipp-var.c
|
||||||
|
index 92f1501..7edc058 100644
|
||||||
|
--- a/cgi-bin/ipp-var.c
|
||||||
|
+++ b/cgi-bin/ipp-var.c
|
||||||
|
@@ -275,10 +275,7 @@ cgiMoveJobs(http_t *http, /* I - Connection to server */
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((user = getenv("REMOTE_USER")) == NULL)
|
||||||
|
- {
|
||||||
|
- puts("Status: 401\n");
|
||||||
|
- exit(0);
|
||||||
|
- }
|
||||||
|
+ user = "guest";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See if the user has already selected a new destination...
|
@ -0,0 +1,65 @@
|
|||||||
|
From 4ddeb8544e2e5c63a405d9e093ac24704f3deb03 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Dohnal <zdohnal@redhat.com>
|
||||||
|
Date: Tue, 21 Jul 2020 12:54:22 +0200
|
||||||
|
Subject: [PATCH] cups/dests.c: cupsGetNamedDest() - set
|
||||||
|
IPP_STATUS_ERROR_NOT_FOUND error if queue was not found lp.c/lpr.c: check for
|
||||||
|
IPP_STATUS_ERROR_NOT_FOUND and generate a proper message if hit
|
||||||
|
|
||||||
|
---
|
||||||
|
berkeley/lpr.c | 6 ++++++
|
||||||
|
cups/dest.c | 3 +++
|
||||||
|
systemv/lp.c | 6 ++++++
|
||||||
|
3 files changed, 15 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/berkeley/lpr.c b/berkeley/lpr.c
|
||||||
|
index 627fa6a4e..a8f78b881 100644
|
||||||
|
--- a/berkeley/lpr.c
|
||||||
|
+++ b/berkeley/lpr.c
|
||||||
|
@@ -234,6 +234,12 @@ main(int argc, /* I - Number of command-line arguments */
|
||||||
|
_cupsLangPrintf(stderr, _("%s: Error - add '/version=1.1' to server name."), argv[0]);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
+ else if (cupsLastError() == IPP_STATUS_ERROR_NOT_FOUND)
|
||||||
|
+ {
|
||||||
|
+ _cupsLangPrintf(stderr,
|
||||||
|
+ _("%s: Error - The printer or class does not exist."), argv[0]);
|
||||||
|
+ return (1);
|
||||||
|
+ }
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '#' : /* Number of copies */
|
||||||
|
diff --git a/cups/dest.c b/cups/dest.c
|
||||||
|
index cde987a09..2017792a7 100644
|
||||||
|
--- a/cups/dest.c
|
||||||
|
+++ b/cups/dest.c
|
||||||
|
@@ -1839,7 +1839,10 @@ cupsGetNamedDest(http_t *http, /* I - Connection to server or @code CUPS_HTT
|
||||||
|
cupsEnumDests(0, 1000, NULL, 0, 0, (cups_dest_cb_t)cups_name_cb, &data);
|
||||||
|
|
||||||
|
if (!data.dest)
|
||||||
|
+ {
|
||||||
|
+ _cupsSetError(IPP_STATUS_ERROR_NOT_FOUND, _("The printer or class does not exist."), 1);
|
||||||
|
return (NULL);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
dest = data.dest;
|
||||||
|
}
|
||||||
|
diff --git a/systemv/lp.c b/systemv/lp.c
|
||||||
|
index 298c15825..d918b4b14 100644
|
||||||
|
--- a/systemv/lp.c
|
||||||
|
+++ b/systemv/lp.c
|
||||||
|
@@ -161,6 +161,12 @@ main(int argc, /* I - Number of command-line arguments */
|
||||||
|
"name."), argv[0]);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
+ else if (cupsLastError() == IPP_STATUS_ERROR_NOT_FOUND)
|
||||||
|
+ {
|
||||||
|
+ _cupsLangPrintf(stderr,
|
||||||
|
+ _("%s: Error - The printer or class does not exist."), argv[0]);
|
||||||
|
+ return (1);
|
||||||
|
+ }
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'f' : /* Form */
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -0,0 +1,35 @@
|
|||||||
|
From 876fdc1c90a885a58644c8757bc1283c9fd5bcb7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Vasilis Liaskovitis <vliaskovitis@suse.com>
|
||||||
|
Date: Wed, 1 Mar 2023 13:46:28 +0100
|
||||||
|
Subject: [PATCH] cups/http-addr.c: Set listen backlog size to INT_MAX (fixes
|
||||||
|
#308)
|
||||||
|
|
||||||
|
Use a listen queue size of INT_MAX, which should default to the maximum
|
||||||
|
supported queue size on the system.
|
||||||
|
|
||||||
|
This avoids the problem of the listening backlog queue getting full when
|
||||||
|
there are too many requests at the same time. The problem was observed
|
||||||
|
with the previous backlog size (128) by customers when submitting large
|
||||||
|
batches of print jobs, resulting in some jobs getting lost.
|
||||||
|
|
||||||
|
Signed-off-by: Vasilis Liaskovitis <vliaskovitis@suse.com>
|
||||||
|
---
|
||||||
|
cups/http-addr.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/cups/http-addr.c b/cups/http-addr.c
|
||||||
|
index a61ee0449..6aeeb8074 100644
|
||||||
|
--- a/cups/http-addr.c
|
||||||
|
+++ b/cups/http-addr.c
|
||||||
|
@@ -249,7 +249,7 @@ httpAddrListen(http_addr_t *addr, /* I - Address to bind to */
|
||||||
|
* Listen...
|
||||||
|
*/
|
||||||
|
|
||||||
|
- if (listen(fd, 5))
|
||||||
|
+ if (listen(fd, INT_MAX))
|
||||||
|
{
|
||||||
|
_cupsSetHTTPError(HTTP_STATUS_ERROR);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
@ -0,0 +1,26 @@
|
|||||||
|
From 5e3107e734f06d410a490e8bc923dc3119f17671 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael R Sweet <michael.r.sweet@gmail.com>
|
||||||
|
Date: Wed, 17 May 2023 12:59:57 -0400
|
||||||
|
Subject: [PATCH] Consensus fix.
|
||||||
|
|
||||||
|
---
|
||||||
|
cups/string.c | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/cups/string.c b/cups/string.c
|
||||||
|
index 00454203c..b4fc12050 100644
|
||||||
|
--- a/cups/string.c
|
||||||
|
+++ b/cups/string.c
|
||||||
|
@@ -730,6 +731,9 @@ _cups_strlcpy(char *dst, /* O - Destination string */
|
||||||
|
size_t srclen; /* Length of source string */
|
||||||
|
|
||||||
|
|
||||||
|
+ if (size == 0)
|
||||||
|
+ return (0);
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Figure out how much room is needed...
|
||||||
|
*/
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -0,0 +1,55 @@
|
|||||||
|
From bdb1ca45454d90410031c4c2054005a995f76180 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Dohnal <zdohnal@redhat.com>
|
||||||
|
Date: Wed, 6 Apr 2022 15:04:45 +0200
|
||||||
|
Subject: [PATCH] cups/tls-gnutls.c: Use always GNUTLS_SHUT_WR
|
||||||
|
|
||||||
|
The current mode for `gnutls_bye()` in client use cases strictly
|
||||||
|
follows TLS v1.2 standard, which in this particular part says:
|
||||||
|
|
||||||
|
```
|
||||||
|
Unless some other fatal alert has been transmitted, each party is
|
||||||
|
required to send a close_notify alert before closing the write
|
||||||
|
side of the connection. The other party MUST respond with a
|
||||||
|
close_notify alert of its own and close down the connection immediately,
|
||||||
|
discarding any pending writes. It is not required for the initiator
|
||||||
|
of the close to wait for the responding close_notify alert before
|
||||||
|
closing the read side of the connection.
|
||||||
|
```
|
||||||
|
|
||||||
|
and waits for the other side of TLS connection to confirm the close.
|
||||||
|
|
||||||
|
Unfortunately it can undesired for reasons:
|
||||||
|
- we support switching of TLS versions in CUPS, and this mode strictly
|
||||||
|
follows TLS v1.2 - so for older version this behavior is not expected
|
||||||
|
and can cause delays
|
||||||
|
- even some TLS v1.2 implementations (like Windows Server 2016) don't
|
||||||
|
comply TLS v1.2 behavior even if it says it does - in that case,
|
||||||
|
encrypted printing takes 30s till HTTP timeout is reached, because the
|
||||||
|
other side didn't send confirmation
|
||||||
|
- AFAIU openssl's SSL_shutdown() doesn't make this TLS v1.2 difference,
|
||||||
|
so we could end up with two TLS implementations in CUPS which will
|
||||||
|
behave differently
|
||||||
|
|
||||||
|
Since the standard defines that waiting for confirmation is not required
|
||||||
|
and due the problems above, I would propose using GNUTLS_SHUT_WR mode
|
||||||
|
regardless of HTTP mode.
|
||||||
|
---
|
||||||
|
cups/tls-gnutls.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/cups/tls-gnutls.c b/cups/tls-gnutls.c
|
||||||
|
index c55995b2b..f87b4f4df 100644
|
||||||
|
--- a/cups/tls-gnutls.c
|
||||||
|
+++ b/cups/tls-gnutls.c
|
||||||
|
@@ -1667,7 +1667,7 @@ _httpTLSStop(http_t *http) /* I - Connection to server */
|
||||||
|
int error; /* Error code */
|
||||||
|
|
||||||
|
|
||||||
|
- error = gnutls_bye(http->tls, http->mode == _HTTP_MODE_CLIENT ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR);
|
||||||
|
+ error = gnutls_bye(http->tls, GNUTLS_SHUT_WR);
|
||||||
|
if (error != GNUTLS_E_SUCCESS)
|
||||||
|
_cupsSetError(IPP_STATUS_ERROR_INTERNAL, gnutls_strerror(errno), 0);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.35.1
|
||||||
|
|
@ -0,0 +1,43 @@
|
|||||||
|
diff -up cups-2.2.6/cups/http-addrlist.c.cupsgetjobs-pollhup cups-2.2.6/cups/http-addrlist.c
|
||||||
|
--- cups-2.2.6/cups/http-addrlist.c.cupsgetjobs-pollhup 2023-12-19 18:25:15.484637450 +0100
|
||||||
|
+++ cups-2.2.6/cups/http-addrlist.c 2023-12-19 18:28:57.129163387 +0100
|
||||||
|
@@ -313,6 +313,39 @@ httpAddrConnect2(
|
||||||
|
{
|
||||||
|
# ifdef HAVE_POLL
|
||||||
|
DEBUG_printf(("pfds[%d].revents=%x\n", i, pfds[i].revents));
|
||||||
|
+
|
||||||
|
+# ifdef _WIN32
|
||||||
|
+ if (((WSAGetLastError() == WSAEINPROGRESS) && (pfds[i].revents & POLLIN) && (pfds[i].revents & POLLOUT)) ||
|
||||||
|
+ ((pfds[i].revents & POLLHUP) && (pfds[i].revents & (POLLIN|POLLOUT))))
|
||||||
|
+# else
|
||||||
|
+ if (((errno == EINPROGRESS) && (pfds[i].revents & POLLIN) && (pfds[i].revents & POLLOUT)) ||
|
||||||
|
+ ((pfds[i].revents & POLLHUP) && (pfds[i].revents & (POLLIN|POLLOUT))))
|
||||||
|
+# endif /* _WIN32 */
|
||||||
|
+ {
|
||||||
|
+ // Some systems generate POLLIN or POLLOUT together with POLLHUP when doing
|
||||||
|
+ // asynchronous connections. The solution seems to be to use getsockopt to
|
||||||
|
+ // check the SO_ERROR value and ignore the POLLHUP if there is no error or
|
||||||
|
+ // the error is EINPROGRESS.
|
||||||
|
+
|
||||||
|
+ int sres, /* Return value from getsockopt() - 0, or -1 if error */
|
||||||
|
+ serr; /* Option SO_ERROR value */
|
||||||
|
+ socklen_t slen = sizeof(serr); /* Option value size */
|
||||||
|
+
|
||||||
|
+ sres = getsockopt(fds[i], SOL_SOCKET, SO_ERROR, &serr, &slen);
|
||||||
|
+
|
||||||
|
+ if (sres || serr)
|
||||||
|
+ {
|
||||||
|
+ pfds[i].revents |= POLLERR;
|
||||||
|
+# ifdef DEBUG
|
||||||
|
+ DEBUG_printf(("1httpAddrConnect2: getsockopt returned: %d with error: %s", sres, strerror(serr)));
|
||||||
|
+# endif
|
||||||
|
+ }
|
||||||
|
+ else if (pfds[i].revents && (pfds[i].revents & POLLHUP) && (pfds[i].revents & (POLLIN | POLLOUT)))
|
||||||
|
+ {
|
||||||
|
+ pfds[i].revents &= ~POLLHUP;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (pfds[i].revents && !(pfds[i].revents & (POLLERR | POLLHUP)))
|
||||||
|
# else
|
||||||
|
if (FD_ISSET(fds[i], &input_set) && !FD_ISSET(fds[i], &error_set))
|
@ -0,0 +1,35 @@
|
|||||||
|
From de4f8c196106033e4c372dce3e91b9d42b0b9444 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Dohnal <zdohnal@redhat.com>
|
||||||
|
Date: Thu, 26 May 2022 06:27:04 +0200
|
||||||
|
Subject: [PATCH] scheduler/cert.c: Fix string comparison (fixes
|
||||||
|
CVE-2022-26691)
|
||||||
|
|
||||||
|
The previous algorithm didn't expect the strings can have a different
|
||||||
|
length, so one string can be a substring of the other and such substring
|
||||||
|
was reported as equal to the longer string.
|
||||||
|
---
|
||||||
|
CHANGES.md | 1 +
|
||||||
|
scheduler/cert.c | 9 ++++++++-
|
||||||
|
2 files changed, 9 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/scheduler/cert.c b/scheduler/cert.c
|
||||||
|
index b268bf1b2..9b65b96c9 100644
|
||||||
|
--- a/scheduler/cert.c
|
||||||
|
+++ b/scheduler/cert.c
|
||||||
|
@@ -444,5 +444,12 @@ ctcompare(const char *a, /* I - First string */
|
||||||
|
b ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
- return (result);
|
||||||
|
+ /*
|
||||||
|
+ * The while loop finishes when *a == '\0' or *b == '\0'
|
||||||
|
+ * so after the while loop either both *a and *b == '\0',
|
||||||
|
+ * or one points inside a string, so when we apply bitwise OR on *a,
|
||||||
|
+ * *b and result, we get a non-zero return value if the compared strings don't match.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ return (result | *a | *b);
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.36.1
|
||||||
|
|
@ -0,0 +1,36 @@
|
|||||||
|
From db9cecdd932e58c51d2d659f63415ad47d151717 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Dohnal <zdohnal@redhat.com>
|
||||||
|
Date: Fri, 1 Sep 2023 17:11:54 +0200
|
||||||
|
Subject: [PATCH] scheduler/conf.c: Print to stderr if we don't open
|
||||||
|
cups-files.conf
|
||||||
|
|
||||||
|
In case cupsd can't open the cups-files.conf, the error message is lost
|
||||||
|
if journal and syslog don't exist or work on system (usually in
|
||||||
|
containers).
|
||||||
|
|
||||||
|
Log the error into stderr at this place to get the error message if
|
||||||
|
needed.
|
||||||
|
---
|
||||||
|
scheduler/conf.c | 6 +-----
|
||||||
|
1 file changed, 1 insertion(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/scheduler/conf.c b/scheduler/conf.c
|
||||||
|
index b18535162..4fa7eb1df 100644
|
||||||
|
--- a/scheduler/conf.c
|
||||||
|
+++ b/scheduler/conf.c
|
||||||
|
@@ -811,11 +811,7 @@ cupsdReadConfiguration(void)
|
||||||
|
cupsdLogMessage(CUPSD_LOG_INFO, "No %s, using defaults.", CupsFilesFile);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
-#ifdef HAVE_SYSTEMD_SD_JOURNAL_H
|
||||||
|
- sd_journal_print(LOG_ERR, "Unable to open \"%s\" - %s", CupsFilesFile, strerror(errno));
|
||||||
|
-#else
|
||||||
|
- syslog(LOG_LPR, "Unable to open \"%s\" - %s", CupsFilesFile, strerror(errno));
|
||||||
|
-#endif /* HAVE_SYSTEMD_SD_JOURNAL_H */
|
||||||
|
+ fprintf(stderr, "Unable to read \"%s\" - %s\n", CupsFilesFile, strerror(errno));
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
@ -0,0 +1,38 @@
|
|||||||
|
From 08e9b6e1f8497a8159d6bd7cd6dc96ae79a2e704 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Bryan Mason <bmason@redhat.com>
|
||||||
|
Date: Thu, 15 Jul 2021 16:26:27 -0700
|
||||||
|
Subject: [PATCH] scheduler/job.c: use gziptoany for raw files (not just raw
|
||||||
|
printers)
|
||||||
|
|
||||||
|
---
|
||||||
|
scheduler/job.c | 6 +++++-
|
||||||
|
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/scheduler/job.c b/scheduler/job.c
|
||||||
|
index d8c2efcc6..b448acda5 100644
|
||||||
|
--- a/scheduler/job.c
|
||||||
|
+++ b/scheduler/job.c
|
||||||
|
@@ -501,6 +501,7 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
|
||||||
|
int backroot; /* Run backend as root? */
|
||||||
|
int pid; /* Process ID of new filter process */
|
||||||
|
int banner_page; /* 1 if banner page, 0 otherwise */
|
||||||
|
+ int raw_file; /* 1 if file type is vnd.cups-raw */
|
||||||
|
int filterfds[2][2] = { { -1, -1 }, { -1, -1 } };
|
||||||
|
/* Pipes used between filters */
|
||||||
|
int envc; /* Number of environment variables */
|
||||||
|
@@ -746,8 +747,11 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
|
||||||
|
* Add decompression/raw filter as needed...
|
||||||
|
*/
|
||||||
|
|
||||||
|
+ raw_file = !strcmp(job->filetypes[job->current_file]->super, "application") &&
|
||||||
|
+ !strcmp(job->filetypes[job->current_file]->type, "vnd.cups-raw");
|
||||||
|
+
|
||||||
|
if ((job->compressions[job->current_file] && (!job->printer->remote || job->num_files == 1)) ||
|
||||||
|
- (!job->printer->remote && job->printer->raw && job->num_files > 1))
|
||||||
|
+ (!job->printer->remote && (job->printer->raw || raw_file) && job->num_files > 1))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Add gziptoany filter to the front of the list...
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -0,0 +1,10 @@
|
|||||||
|
diff --git a/scheduler/org.cups.cupsd.service.in b/scheduler/org.cups.cupsd.service.in
|
||||||
|
index 307d69b..add238b 100644
|
||||||
|
--- a/scheduler/org.cups.cupsd.service.in
|
||||||
|
+++ b/scheduler/org.cups.cupsd.service.in
|
||||||
|
@@ -10,4 +10,4 @@ Restart=on-failure
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
Also=cups.socket cups.path
|
||||||
|
-WantedBy=printer.target
|
||||||
|
+WantedBy=printer.target multi-user.target
|
@ -0,0 +1,95 @@
|
|||||||
|
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 */
|
||||||
|
- const AvahiAddress *address, /* I - Address (unused) */
|
||||||
|
+ const AvahiAddress *address, /* I - Address */
|
||||||
|
uint16_t port, /* I - Port number */
|
||||||
|
AvahiStringList *txt, /* I - TXT record */
|
||||||
|
AvahiLookupResultFlags flags, /* I - Lookup flags (unused) */
|
||||||
|
@@ -2493,39 +2493,62 @@ http_resolve_cb(
|
||||||
|
* getting the IP address of the .local name and then do reverse-lookups...
|
||||||
|
*/
|
||||||
|
|
||||||
|
- http_addrlist_t *addrlist, /* List of addresses */
|
||||||
|
- *addr; /* Current address */
|
||||||
|
+ http_addr_t addr;
|
||||||
|
+ size_t addrlen;
|
||||||
|
+ int error;
|
||||||
|
|
||||||
|
DEBUG_printf(("5http_resolve_cb: Looking up \"%s\".", hostTarget));
|
||||||
|
|
||||||
|
- snprintf(fqdn, sizeof(fqdn), "%d", ntohs(port));
|
||||||
|
- if ((addrlist = httpAddrGetList(hostTarget, AF_UNSPEC, fqdn)) != NULL)
|
||||||
|
+ switch (address->proto)
|
||||||
|
{
|
||||||
|
- for (addr = addrlist; addr; addr = addr->next)
|
||||||
|
+ case AVAHI_PROTO_INET:
|
||||||
|
+ addr.ipv4.sin_family = AF_INET;
|
||||||
|
+ addrlen = sizeof (addr.ipv4.sin_addr);
|
||||||
|
+ memcpy (&addr.ipv4.sin_addr, &address->data, addrlen);
|
||||||
|
+ break;
|
||||||
|
+ case AVAHI_PROTO_INET6:
|
||||||
|
+ addr.ipv6.sin6_family = AF_INET6;
|
||||||
|
+ addrlen = sizeof (addr.ipv6.sin6_addr);
|
||||||
|
+ memcpy (&addr.ipv6.sin6_addr, &address->data, addrlen);
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ DEBUG_printf(("8http_resolve_cb: unknown address family %d",
|
||||||
|
+ address->proto));
|
||||||
|
+ addrlen = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (addrlen > 0) {
|
||||||
|
+ error = getnameinfo(&addr.addr, httpAddrLength (&addr),
|
||||||
|
+ fqdn, sizeof(fqdn), NULL, 0, NI_NAMEREQD);
|
||||||
|
+
|
||||||
|
+ if (!error)
|
||||||
|
{
|
||||||
|
- int error = getnameinfo(&(addr->addr.addr), (socklen_t)httpAddrLength(&(addr->addr)), fqdn, sizeof(fqdn), NULL, 0, NI_NAMEREQD);
|
||||||
|
+ DEBUG_printf(("8http_resolve_cb: Found \"%s\".", fqdn));
|
||||||
|
|
||||||
|
- if (!error)
|
||||||
|
- {
|
||||||
|
- DEBUG_printf(("5http_resolve_cb: Found \"%s\".", fqdn));
|
||||||
|
+ if ((hostptr = fqdn + strlen(fqdn) - 6) <= fqdn ||
|
||||||
|
+ _cups_strcasecmp(hostptr, ".local"))
|
||||||
|
|
||||||
|
- if ((hostptr = fqdn + strlen(fqdn) - 6) <= fqdn ||
|
||||||
|
- _cups_strcasecmp(hostptr, ".local"))
|
||||||
|
- {
|
||||||
|
- hostTarget = fqdn;
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
+ {
|
||||||
|
+ hostTarget = fqdn;
|
||||||
|
}
|
||||||
|
+ } else {
|
||||||
|
+ avahi_address_snprint (fqdn, sizeof (fqdn), address);
|
||||||
|
+ hostTarget = fqdn;
|
||||||
|
+
|
||||||
|
#ifdef DEBUG
|
||||||
|
- else
|
||||||
|
- 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",
|
||||||
|
+ fqdn, error));
|
||||||
|
#endif /* DEBUG */
|
||||||
|
}
|
||||||
|
|
||||||
|
- httpAddrFreeList(addrlist);
|
||||||
|
}
|
||||||
|
+ } else {
|
||||||
|
+ /*
|
||||||
|
+ * Use the IP address that responded...
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ avahi_address_snprint (fqdn, sizeof (fqdn), address);
|
||||||
|
+ hostTarget = fqdn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||||
|
|
@ -0,0 +1,12 @@
|
|||||||
|
diff -Napur cups-2.2.6-old/scheduler/job.c cups-2.2.6-new/scheduler/job.c
|
||||||
|
--- cups-2.2.6-old/scheduler/job.c 2022-04-12 17:32:00.635282080 -0700
|
||||||
|
+++ cups-2.2.6-new/scheduler/job.c 2022-04-12 17:33:34.349452614 -0700
|
||||||
|
@@ -474,7 +474,7 @@ cupsdCleanJobs(void)
|
||||||
|
cupsdLogJob(job, CUPSD_LOG_DEBUG, "Removing from history.");
|
||||||
|
cupsdDeleteJob(job, CUPSD_JOB_PURGE);
|
||||||
|
}
|
||||||
|
- else if (job->file_time && job->file_time <= curtime)
|
||||||
|
+ else if (job->file_time && job->file_time <= curtime && job->num_files > 0)
|
||||||
|
{
|
||||||
|
cupsdLogJob(job, CUPSD_LOG_DEBUG, "Removing document files.");
|
||||||
|
remove_job_files(job);
|
@ -0,0 +1,61 @@
|
|||||||
|
Fix for CVE-2020-10001, which is a bug in the CUPS ippReadIO function when it
|
||||||
|
reads tagged string values (nameWithLanguage and textWithLanguage). The
|
||||||
|
previous code verified that the length of the sub-strings (language identifier
|
||||||
|
and name/text value) did not exceed the size of the allocated buffer (1 byte
|
||||||
|
larger than the maximum IPP value size of 32767 bytes), but did not validate
|
||||||
|
against the length of the actual IPP value.
|
||||||
|
|
||||||
|
The issues introduced by this vulnerability include:
|
||||||
|
|
||||||
|
- Potential information disclosure by copying uninitialized areas of memory into
|
||||||
|
an IPP string value.
|
||||||
|
- Potential Denial of Service by supplying/using invalid string values when
|
||||||
|
strict validation has been disabled by the system administrator.
|
||||||
|
|
||||||
|
This change ensures that:
|
||||||
|
|
||||||
|
1. The language identifier does not extend beyond the end of the IPP value.
|
||||||
|
2. The length of the name/text string is within the IPP value.
|
||||||
|
3. The name/text string is within the IPP value.
|
||||||
|
|
||||||
|
diff --git a/cups/ipp.c b/cups/ipp.c
|
||||||
|
index 3d529346c..adbb26fba 100644
|
||||||
|
--- a/cups/ipp.c
|
||||||
|
+++ b/cups/ipp.c
|
||||||
|
@@ -2866,7 +2866,8 @@ ippReadIO(void *src, /* I - Data source */
|
||||||
|
unsigned char *buffer, /* Data buffer */
|
||||||
|
string[IPP_MAX_TEXT],
|
||||||
|
/* Small string buffer */
|
||||||
|
- *bufptr; /* Pointer into buffer */
|
||||||
|
+ *bufptr, /* Pointer into buffer */
|
||||||
|
+ *bufend; /* End of buffer */
|
||||||
|
ipp_attribute_t *attr; /* Current attribute */
|
||||||
|
ipp_tag_t tag; /* Current tag */
|
||||||
|
ipp_tag_t value_tag; /* Current value tag */
|
||||||
|
@@ -3441,6 +3442,7 @@ ippReadIO(void *src, /* I - Data source */
|
||||||
|
}
|
||||||
|
|
||||||
|
bufptr = buffer;
|
||||||
|
+ bufend = buffer + n;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* text-with-language and name-with-language are composite
|
||||||
|
@@ -3454,7 +3456,7 @@ ippReadIO(void *src, /* I - Data source */
|
||||||
|
|
||||||
|
n = (bufptr[0] << 8) | bufptr[1];
|
||||||
|
|
||||||
|
- if ((bufptr + 2 + n) >= (buffer + IPP_BUF_SIZE) || n >= (int)sizeof(string))
|
||||||
|
+ if ((bufptr + 2 + n + 2) > bufend || n >= (int)sizeof(string))
|
||||||
|
{
|
||||||
|
_cupsSetError(IPP_STATUS_ERROR_INTERNAL,
|
||||||
|
_("IPP language length overflows value."), 1);
|
||||||
|
@@ -3481,7 +3483,7 @@ ippReadIO(void *src, /* I - Data source */
|
||||||
|
bufptr += 2 + n;
|
||||||
|
n = (bufptr[0] << 8) | bufptr[1];
|
||||||
|
|
||||||
|
- if ((bufptr + 2 + n) >= (buffer + IPP_BUF_SIZE))
|
||||||
|
+ if ((bufptr + 2 + n) > bufend)
|
||||||
|
{
|
||||||
|
_cupsSetError(IPP_STATUS_ERROR_INTERNAL,
|
||||||
|
_("IPP string length overflows value."), 1);
|
||||||
|
|
@ -0,0 +1,27 @@
|
|||||||
|
diff -up cups-1.5b1/backend/usb-unix.c.direct-usb cups-1.5b1/backend/usb-unix.c
|
||||||
|
--- cups-1.5b1/backend/usb-unix.c.direct-usb 2011-05-20 05:49:49.000000000 +0200
|
||||||
|
+++ cups-1.5b1/backend/usb-unix.c 2011-05-23 17:52:14.000000000 +0200
|
||||||
|
@@ -102,6 +102,9 @@ print_device(const char *uri, /* I - De
|
||||||
|
_cups_strncasecmp(hostname, "Minolta", 7);
|
||||||
|
#endif /* __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __DragonFly__ */
|
||||||
|
|
||||||
|
+ if (use_bc && !strncmp(uri, "usb:/dev/", 9))
|
||||||
|
+ use_bc = 0;
|
||||||
|
+
|
||||||
|
if ((device_fd = open_device(uri, &use_bc)) == -1)
|
||||||
|
{
|
||||||
|
if (getenv("CLASS") != NULL)
|
||||||
|
@@ -331,12 +334,7 @@ open_device(const char *uri, /* I - Dev
|
||||||
|
if (!strncmp(uri, "usb:/dev/", 9))
|
||||||
|
#ifdef __linux
|
||||||
|
{
|
||||||
|
- /*
|
||||||
|
- * Do not allow direct devices anymore...
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
- errno = ENODEV;
|
||||||
|
- return (-1);
|
||||||
|
+ return (open(uri + 4, O_RDWR | O_EXCL));
|
||||||
|
}
|
||||||
|
else if (!strncmp(uri, "usb://", 6))
|
||||||
|
{
|
@ -0,0 +1,13 @@
|
|||||||
|
diff --git a/scheduler/main.c b/scheduler/main.c
|
||||||
|
index 592531a..a6e2c3a 100644
|
||||||
|
--- a/scheduler/main.c
|
||||||
|
+++ b/scheduler/main.c
|
||||||
|
@@ -947,7 +947,7 @@ main(int argc, /* I - Number of command-line args */
|
||||||
|
* Write dirty config/state files...
|
||||||
|
*/
|
||||||
|
|
||||||
|
- if (DirtyCleanTime && current_time >= DirtyCleanTime && cupsArrayCount(Clients) == 0)
|
||||||
|
+ if (DirtyCleanTime && current_time >= DirtyCleanTime)
|
||||||
|
cupsdCleanDirty();
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
diff --git a/scheduler/client.c b/scheduler/client.c
|
||||||
|
index bf284e6..0382b01 100644
|
||||||
|
--- a/scheduler/client.c
|
||||||
|
+++ b/scheduler/client.c
|
||||||
|
@@ -1011,8 +1011,6 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
|
||||||
|
}
|
||||||
|
|
||||||
|
httpClearFields(con->http);
|
||||||
|
- httpSetField(con->http, HTTP_FIELD_ALLOW,
|
||||||
|
- "GET, HEAD, OPTIONS, POST, PUT");
|
||||||
|
httpSetField(con->http, HTTP_FIELD_CONTENT_LENGTH, "0");
|
||||||
|
|
||||||
|
if (!cupsdSendHeader(con, HTTP_STATUS_OK, NULL, CUPSD_AUTH_NONE))
|
@ -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)
|
@ -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
|
@ -0,0 +1,130 @@
|
|||||||
|
diff -up cups-2.2.5/backend/ipp.c.eggcups cups-2.2.5/backend/ipp.c
|
||||||
|
--- cups-2.2.5/backend/ipp.c.eggcups 2017-10-13 20:22:26.000000000 +0200
|
||||||
|
+++ cups-2.2.5/backend/ipp.c 2017-10-17 18:56:42.409024451 +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...
|
||||||
|
@@ -1743,6 +1807,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.2.5/backend/Makefile.eggcups cups-2.2.5/backend/Makefile
|
||||||
|
--- cups-2.2.5/backend/Makefile.eggcups 2017-10-17 18:56:42.409024451 +0200
|
||||||
|
+++ cups-2.2.5/backend/Makefile 2017-10-17 18:59:11.696781116 +0200
|
||||||
|
@@ -262,7 +262,7 @@ dnssd: dnssd.o ../cups/$(LIBCUPS) libbac
|
||||||
|
|
||||||
|
ipp: ipp.o ../cups/$(LIBCUPS) libbackend.a
|
||||||
|
echo Linking $@...
|
||||||
|
- $(LD_CC) $(LDFLAGS) -o ipp ipp.o libbackend.a $(LIBS)
|
||||||
|
+ $(LD_CC) $(LDFLAGS) -o ipp ipp.o libbackend.a $(LIBS) $(SERVERLIBS)
|
||||||
|
$(RM) http
|
||||||
|
$(LN) ipp http
|
||||||
|
|
||||||
|
diff -up cups-2.2.5/scheduler/subscriptions.c.eggcups cups-2.2.5/scheduler/subscriptions.c
|
||||||
|
--- cups-2.2.5/scheduler/subscriptions.c.eggcups 2017-10-13 20:22:26.000000000 +0200
|
||||||
|
+++ cups-2.2.5/scheduler/subscriptions.c 2017-10-17 18:56:42.409024451 +0200
|
||||||
|
@@ -1291,13 +1291,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;
|
||||||
|
|
||||||
|
@@ -1333,7 +1333,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);
|
@ -0,0 +1,25 @@
|
|||||||
|
diff --git a/cups/http-addrlist.c b/cups/http-addrlist.c
|
||||||
|
index e4ffc3d..a989055 100644
|
||||||
|
--- a/cups/http-addrlist.c
|
||||||
|
+++ b/cups/http-addrlist.c
|
||||||
|
@@ -240,7 +240,10 @@ httpAddrConnect2(
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!addrlist && nfds == 0)
|
||||||
|
+ {
|
||||||
|
+ errno = EHOSTDOWN;
|
||||||
|
break;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See if we can connect to any of the addresses so far...
|
||||||
|
@@ -371,6 +374,9 @@ httpAddrConnect2(
|
||||||
|
remaining -= 250;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (remaining <= 0)
|
||||||
|
+ errno = ETIMEDOUT;
|
||||||
|
+
|
||||||
|
while (nfds > 0)
|
||||||
|
{
|
||||||
|
nfds --;
|
@ -0,0 +1,877 @@
|
|||||||
|
diff --git a/backend/Makefile b/backend/Makefile
|
||||||
|
index 3038682..6642016 100644
|
||||||
|
--- a/backend/Makefile
|
||||||
|
+++ b/backend/Makefile
|
||||||
|
@@ -28,6 +28,7 @@ include ../Makedefs
|
||||||
|
RBACKENDS = \
|
||||||
|
ipp \
|
||||||
|
lpd \
|
||||||
|
+ failover \
|
||||||
|
$(DNSSD_BACKEND)
|
||||||
|
UBACKENDS = \
|
||||||
|
snmp \
|
||||||
|
@@ -51,6 +52,7 @@ LIBOBJS = \
|
||||||
|
OBJS = \
|
||||||
|
ipp.o \
|
||||||
|
lpd.o \
|
||||||
|
+ failover.o \
|
||||||
|
dnssd.o \
|
||||||
|
snmp.o \
|
||||||
|
socket.o \
|
||||||
|
@@ -275,6 +277,13 @@ lpd: lpd.o ../cups/$(LIBCUPS) libbackend.a
|
||||||
|
echo Linking $@...
|
||||||
|
$(LD_CC) $(LDFLAGS) -o lpd lpd.o libbackend.a $(LIBS)
|
||||||
|
|
||||||
|
+#
|
||||||
|
+# failover
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+failover: failover.o ../cups/$(LIBCUPS) libbackend.a
|
||||||
|
+ echo Linking $@...
|
||||||
|
+ $(LD_CC) $(LDFLAGS) -o failover failover.o libbackend.a $(LIBS)
|
||||||
|
|
||||||
|
#
|
||||||
|
# snmp
|
||||||
|
diff --git a/backend/failover.c b/backend/failover.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..9affd8f
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/backend/failover.c
|
||||||
|
@@ -0,0 +1,837 @@
|
||||||
|
+/*
|
||||||
|
+ * Failover Backend for the Common UNIX Printing System (CUPS).
|
||||||
|
+ *
|
||||||
|
+ * Copyright (c) 2014, Red Hat, Inc.
|
||||||
|
+ * All rights reserved.
|
||||||
|
+ *
|
||||||
|
+ * Redistribution and use in source and binary forms, with or without
|
||||||
|
+ * modification, are permitted provided that the following conditions
|
||||||
|
+ * are met:
|
||||||
|
+ *
|
||||||
|
+ * * Redistributions of source code must retain the above copyright
|
||||||
|
+ * notice, this list of conditions and the following disclaimer.
|
||||||
|
+ * * Redistributions in binary form must reproduce the above copyright
|
||||||
|
+ * notice, this list of conditions and the following disclaimer in the
|
||||||
|
+ * documentation and/or other materials provided with the distribution.
|
||||||
|
+ * * Neither the name of Red Hat, Inc. nor the names of its contributors
|
||||||
|
+ * may be used to endorse or promote products derived from this software
|
||||||
|
+ * without specific prior written permission.
|
||||||
|
+ *
|
||||||
|
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT,
|
||||||
|
+ * INC. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||||
|
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
+ * DAMAGE.
|
||||||
|
+ *
|
||||||
|
+ * Original version by Clark Hale, Red Hat, Inc.
|
||||||
|
+ *
|
||||||
|
+ * This backend presents a fake printer that will choose the first
|
||||||
|
+ * available printer from a list of IPP URIs.
|
||||||
|
+ *
|
||||||
|
+ * Option failover contains a comma separated list of IPP URIs. The
|
||||||
|
+ * URIs are attempted in-order.
|
||||||
|
+ *
|
||||||
|
+ * Option failover-retries contains an integer that indicates how many
|
||||||
|
+ * times to iterate through the failover list before completely
|
||||||
|
+ * failing.
|
||||||
|
+ *
|
||||||
|
+ * Contents:
|
||||||
|
+ * main() - Checks each printer in a failover list, and
|
||||||
|
+ * sends job data to the first available printer
|
||||||
|
+ * move_job() - Sends and IPP Move-Job request
|
||||||
|
+ * check_printer() - Checks a printer's attributes to see
|
||||||
|
+ * if it's enabled and accepting jobs
|
||||||
|
+ * read_config() - Read the backends configuration from
|
||||||
|
+ * options
|
||||||
|
+ * get_printer_attributes() - Sends an IPP Get-Attributes request to
|
||||||
|
+ * a URI
|
||||||
|
+ * sigterm_handler() - Handle SIGTERM that cancels the job
|
||||||
|
+ * password_cb() - Password call back used to disable password
|
||||||
|
+ * prompt
|
||||||
|
+ */
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <sys/wait.h>
|
||||||
|
+#include <cups/http-private.h>
|
||||||
|
+#include <cups/http.h>
|
||||||
|
+#include "backend-private.h"
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Return Values
|
||||||
|
+ */
|
||||||
|
+typedef enum fo_state_e
|
||||||
|
+{
|
||||||
|
+ FO_PRINTER_GOOD = 0,
|
||||||
|
+ FO_PRINTER_BAD,
|
||||||
|
+ FO_PRINTER_BUSY,
|
||||||
|
+ FO_AUTH_REQUIRED
|
||||||
|
+} fo_state_t;
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Constants
|
||||||
|
+ */
|
||||||
|
+#define FAILOVER_DEFAULT_RETRIES (3)
|
||||||
|
+#define FAILOVER_PASSWORD_RETRIES_MAX (3)
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Local Functions
|
||||||
|
+ */
|
||||||
|
+static int check_printer(const char *device_uri);
|
||||||
|
+static int read_config(cups_array_t *printer_array, int *retries,
|
||||||
|
+ const char *options);
|
||||||
|
+static int get_printer_attributes(const char *device_uri,
|
||||||
|
+ ipp_t **attributes);
|
||||||
|
+static int move_job(int jobid, const char *dest);
|
||||||
|
+static void sigterm_handler(int sig);
|
||||||
|
+static const char *password_cb(const char *);
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Global Variables
|
||||||
|
+ */
|
||||||
|
+static int job_canceled = 0; /* Job canceled */
|
||||||
|
+static char *password = NULL; /* password for device */
|
||||||
|
+static int password_retries = 0;
|
||||||
|
+static const char *auth_info_required = "none";
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * 'main()' - Checks each printer in a failover list, and
|
||||||
|
+ * sends job data to the first available printer
|
||||||
|
+ * Usage:
|
||||||
|
+ * printer-uri job-id user title copies options [file]
|
||||||
|
+ *
|
||||||
|
+ * The printer-uri option is not used, but it still required to fit
|
||||||
|
+ * to the backend(7) standards.
|
||||||
|
+ */
|
||||||
|
+int
|
||||||
|
+main(int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ const char *selected_uri = NULL; /* URI of selected printer */
|
||||||
|
+ const char *tmp_device_uri; /* Device URI to check */
|
||||||
|
+ cups_array_t *printer_array; /* Array of available printers */
|
||||||
|
+ int printer_count = 0; /* current printer array index */
|
||||||
|
+ int retry_max = 1; /* maximum retries before exit */
|
||||||
|
+ int retry_count = 0; /* current retry number */
|
||||||
|
+ int auth_failed_count = 0; /* auth failures per loop */
|
||||||
|
+ int rc = CUPS_BACKEND_OK;
|
||||||
|
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
|
||||||
|
+ struct sigaction action; /* Actions for POSIX signals */
|
||||||
|
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Check args
|
||||||
|
+ */
|
||||||
|
+ if (argc == 1)
|
||||||
|
+ {
|
||||||
|
+ /*
|
||||||
|
+ * print out discovery data
|
||||||
|
+ */
|
||||||
|
+ char *backendName;
|
||||||
|
+
|
||||||
|
+ if ((backendName = strrchr(argv[0], '/')) != NULL)
|
||||||
|
+ backendName++;
|
||||||
|
+ else
|
||||||
|
+ backendName = argv[0];
|
||||||
|
+
|
||||||
|
+ _cupsLangPrintf(stderr,"network %s \"Unknown\" \"%s (%s)\"\n",
|
||||||
|
+ backendName,
|
||||||
|
+ _cupsLangString(cupsLangDefault(), _("Failover Printer")),
|
||||||
|
+ backendName);
|
||||||
|
+
|
||||||
|
+ return (CUPS_BACKEND_OK);
|
||||||
|
+ }
|
||||||
|
+ else if (argc < 6)
|
||||||
|
+ {
|
||||||
|
+ _cupsLangPrintf(stderr,
|
||||||
|
+ _("Usage: %s job-id user title copies options [file]"),
|
||||||
|
+ argv[0]);
|
||||||
|
+ return (CUPS_BACKEND_STOP);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ fprintf(stderr, "DEBUG: Failover backend starting up.\n");
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Don't buffer status messages
|
||||||
|
+ */
|
||||||
|
+ setbuf(stderr, NULL);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Ignore SIGPIPE and catch SIGTERM signals...
|
||||||
|
+ */
|
||||||
|
+#ifdef HAVE_SIGSET
|
||||||
|
+ sigset(SIGPIPE, SIG_IGN);
|
||||||
|
+ sigset(SIGTERM, sigterm_handler);
|
||||||
|
+#elif defined(HAVE_SIGACTION)
|
||||||
|
+ memset(&action, 0, sizeof(action));
|
||||||
|
+ action.sa_handler = SIG_IGN;
|
||||||
|
+ sigaction(SIGPIPE, &action, NULL);
|
||||||
|
+
|
||||||
|
+ sigemptyset(&action.sa_mask);
|
||||||
|
+ sigaddset(&action.sa_mask, SIGTERM);
|
||||||
|
+ action.sa_handler = sigterm_handler;
|
||||||
|
+ sigaction(SIGTERM, &action, NULL);
|
||||||
|
+#else
|
||||||
|
+ signal(SIGPIPE, SIG_IGN);
|
||||||
|
+ signal(SIGTERM, sigterm_handler);
|
||||||
|
+#endif /* HAVE_SIGSET */
|
||||||
|
+
|
||||||
|
+ printer_array = cupsArrayNew(NULL, NULL);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Read Configuration
|
||||||
|
+ */
|
||||||
|
+ if ((rc = read_config(printer_array, &retry_max,
|
||||||
|
+ argv[5])) != CUPS_BACKEND_OK)
|
||||||
|
+ {
|
||||||
|
+ fprintf(stderr, "ERROR: Failed to read configuration options!\n");
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Main Retry Loop
|
||||||
|
+ */
|
||||||
|
+ for (retry_count = 0; retry_count < retry_max; retry_count++)
|
||||||
|
+ {
|
||||||
|
+ fprintf(stderr, "DEBUG: Retry loop #%d\n", retry_count + 1);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Reset Counters
|
||||||
|
+ */
|
||||||
|
+ printer_count = 0;
|
||||||
|
+ auth_failed_count = 0;
|
||||||
|
+
|
||||||
|
+ tmp_device_uri = (char *)cupsArrayFirst(printer_array);
|
||||||
|
+
|
||||||
|
+ do
|
||||||
|
+ {
|
||||||
|
+ if (job_canceled)
|
||||||
|
+ {
|
||||||
|
+ fprintf(stderr, "DEBUG: Job Canceled\n");
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ fprintf(stderr,"DEBUG: Checking printer #%d: %s\n",
|
||||||
|
+ printer_count+1, tmp_device_uri);
|
||||||
|
+
|
||||||
|
+ rc = check_printer(tmp_device_uri);
|
||||||
|
+
|
||||||
|
+ // Printer is available and not busy.
|
||||||
|
+ if ( rc == FO_PRINTER_GOOD )
|
||||||
|
+ {
|
||||||
|
+ selected_uri = tmp_device_uri;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ // Printer is busy
|
||||||
|
+ else if (rc == FO_PRINTER_BUSY)
|
||||||
|
+ {
|
||||||
|
+ fprintf(stderr, "DEBUG: Waiting for job to complete.\n");
|
||||||
|
+ sleep(2);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ // Authorization is required to access the printer.
|
||||||
|
+ else if (rc == FO_AUTH_REQUIRED)
|
||||||
|
+ {
|
||||||
|
+ auth_failed_count++;
|
||||||
|
+ fprintf(stderr, "DEBUG: auth_failed_count = %d\n", auth_failed_count);
|
||||||
|
+ }
|
||||||
|
+ // Printer is stopped or not accepting jobs
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ if (!printer_count)
|
||||||
|
+ fprintf(stderr, "INFO: Primary Printer, %s, not available. "
|
||||||
|
+ "Attempting Failovers...\n",
|
||||||
|
+ tmp_device_uri);
|
||||||
|
+ else
|
||||||
|
+ fprintf(stderr, "INFO: Failover Printer, %s, not available. "
|
||||||
|
+ "Attempting Failovers..\n",
|
||||||
|
+ tmp_device_uri);
|
||||||
|
+ printer_count++;
|
||||||
|
+ tmp_device_uri = (char *)cupsArrayNext(printer_array);
|
||||||
|
+ }
|
||||||
|
+ } while (tmp_device_uri != NULL);
|
||||||
|
+
|
||||||
|
+ if (selected_uri && !printer_count)
|
||||||
|
+ fprintf(stderr, "STATE: -primary-printer-failed\n");
|
||||||
|
+ else
|
||||||
|
+ fprintf(stderr, "STATE: +primary-printer-failed\n");
|
||||||
|
+
|
||||||
|
+ if (job_canceled)
|
||||||
|
+ {
|
||||||
|
+ fprintf(stderr, "DEBUG: Job Canceled\n");
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!selected_uri && auth_failed_count == printer_count)
|
||||||
|
+ {
|
||||||
|
+ fprintf(stderr, "ERROR: All failover printers failed with "
|
||||||
|
+ "authorization issues.\n");
|
||||||
|
+ rc = CUPS_BACKEND_AUTH_REQUIRED;
|
||||||
|
+ fprintf(stderr, "ATTR: auth-info-required=%s\n", auth_info_required);
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+ else if (!selected_uri && retry_count + 1 < retry_max)
|
||||||
|
+ {
|
||||||
|
+ fprintf(stderr, "INFO: No suitable printer found...retrying...\n");
|
||||||
|
+ sleep(2);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ else if (selected_uri)
|
||||||
|
+ {
|
||||||
|
+ fprintf(stderr, "DEBUG: Using printer, %s.\n", selected_uri);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!selected_uri)
|
||||||
|
+ {
|
||||||
|
+ fprintf(stderr, "ERROR: No suitable printer found. Aborting print\n");
|
||||||
|
+ rc = CUPS_BACKEND_FAILED;
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rc = move_job(atoi(argv[1]), selected_uri);
|
||||||
|
+
|
||||||
|
+ if (job_canceled)
|
||||||
|
+ rc = CUPS_BACKEND_OK;
|
||||||
|
+
|
||||||
|
+cleanup :
|
||||||
|
+ if (job_canceled)
|
||||||
|
+ rc = CUPS_BACKEND_OK;
|
||||||
|
+
|
||||||
|
+ tmp_device_uri = (char *)cupsArrayFirst(printer_array);
|
||||||
|
+ do
|
||||||
|
+ {
|
||||||
|
+ free((void *)tmp_device_uri);
|
||||||
|
+ } while ((tmp_device_uri = (char *)cupsArrayNext(printer_array)) != NULL);
|
||||||
|
+
|
||||||
|
+ cupsArrayDelete(printer_array);
|
||||||
|
+ sleep(2);
|
||||||
|
+ return (rc);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * 'check_printer()' - Checks the status of a remote printer and returns
|
||||||
|
+ * back a good/bad/busy status.
|
||||||
|
+ */
|
||||||
|
+int
|
||||||
|
+check_printer(const char *device_uri)
|
||||||
|
+{
|
||||||
|
+ ipp_t *attributes = NULL; /* attributes for device_uri */
|
||||||
|
+ ipp_attribute_t *tmp_attribute; /* for examining attribs */
|
||||||
|
+ int rc = FO_PRINTER_GOOD; /* return code */
|
||||||
|
+ char *reason; /* printer state reason */
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ fprintf(stderr, "DEBUG: Checking printer %s\n",device_uri);
|
||||||
|
+
|
||||||
|
+ rc = get_printer_attributes(device_uri, &attributes);
|
||||||
|
+ if ( rc != CUPS_BACKEND_OK )
|
||||||
|
+ {
|
||||||
|
+ fprintf(stderr, "DEBUG: Failed to get attributes from printer: %s\n",
|
||||||
|
+ device_uri);
|
||||||
|
+ if ( rc == CUPS_BACKEND_AUTH_REQUIRED )
|
||||||
|
+ return (FO_AUTH_REQUIRED);
|
||||||
|
+ else
|
||||||
|
+ return (FO_PRINTER_BAD);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Check if printer is accepting jobs
|
||||||
|
+ */
|
||||||
|
+ if ((tmp_attribute = ippFindAttribute(attributes,
|
||||||
|
+ "printer-is-accepting-jobs",
|
||||||
|
+ IPP_TAG_BOOLEAN)) != NULL &&
|
||||||
|
+ !tmp_attribute->values[0].boolean)
|
||||||
|
+ {
|
||||||
|
+ fprintf(stderr,
|
||||||
|
+ "DEBUG: Printer, %s, is not accepting jobs.\n",
|
||||||
|
+ device_uri);
|
||||||
|
+
|
||||||
|
+ rc = FO_PRINTER_BAD;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Check if printer is stopped or busy processing
|
||||||
|
+ */
|
||||||
|
+ if ((tmp_attribute = ippFindAttribute(attributes,
|
||||||
|
+ "printer-state",
|
||||||
|
+ IPP_TAG_ENUM)) != NULL)
|
||||||
|
+ {
|
||||||
|
+ // Printer Stopped
|
||||||
|
+ if ( tmp_attribute->values[0].integer == IPP_PRINTER_STOPPED )
|
||||||
|
+ {
|
||||||
|
+ fprintf(stderr, "DEBUG: Printer, %s, stopped.\n", device_uri);
|
||||||
|
+ rc = FO_PRINTER_BAD;
|
||||||
|
+ }
|
||||||
|
+ // Printer Busy
|
||||||
|
+ else if ( tmp_attribute->values[0].integer == IPP_PRINTER_PROCESSING )
|
||||||
|
+ {
|
||||||
|
+ fprintf(stderr, "DEBUG: Printer %s is busy.\n", device_uri);
|
||||||
|
+ rc = FO_PRINTER_BUSY;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Parse through the printer-state-reasons
|
||||||
|
+ */
|
||||||
|
+ if ((tmp_attribute = ippFindAttribute(attributes, "printer-state-reasons",
|
||||||
|
+ IPP_TAG_KEYWORD)) != NULL)
|
||||||
|
+ {
|
||||||
|
+ for (i = 0; i < tmp_attribute->num_values; i++)
|
||||||
|
+ {
|
||||||
|
+ reason = tmp_attribute->values[i].string.text;
|
||||||
|
+ int len = strlen(reason);
|
||||||
|
+
|
||||||
|
+ if (len > 8 && !strcmp(reason + len - 8, "-warning"))
|
||||||
|
+ {
|
||||||
|
+ fprintf(stderr, "DEBUG: Printer Supply Warning, %s\n", reason);
|
||||||
|
+ rc = FO_PRINTER_BAD;
|
||||||
|
+ }
|
||||||
|
+ else if (len > 6 && !strcmp(reason + len - 6, "-error"))
|
||||||
|
+ {
|
||||||
|
+ fprintf(stderr, "DEBUG: Printer Supply Error, %s\n", reason);
|
||||||
|
+ rc = FO_PRINTER_BAD;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return (rc);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * 'read_config()' - Parses the failover and failover-retries options
|
||||||
|
+ *
|
||||||
|
+ */
|
||||||
|
+static int
|
||||||
|
+read_config(cups_array_t *printer_array, int *retries, const char *options)
|
||||||
|
+{
|
||||||
|
+
|
||||||
|
+ const char *tmp; /* temporary ptr */
|
||||||
|
+ char *tok_tmp; /* temporary ptr for option parsing */
|
||||||
|
+ int jobopts_count = 0; /* number of options */
|
||||||
|
+ cups_option_t *jobopts = NULL; /* job options */
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ fprintf(stderr, "DEBUG: Reading Configuration.\n");
|
||||||
|
+ jobopts_count = cupsParseOptions(options, 0, &jobopts);
|
||||||
|
+
|
||||||
|
+ if (!jobopts_count)
|
||||||
|
+ {
|
||||||
|
+ fprintf(stderr,
|
||||||
|
+ "ERROR: No job options! Cannot find failover options!\n");
|
||||||
|
+ return (CUPS_BACKEND_STOP);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Get attributes from the primary printer
|
||||||
|
+ */
|
||||||
|
+ fprintf(stderr, "DEBUG: Searching for failover option.\n");
|
||||||
|
+
|
||||||
|
+ if ((tmp = cupsGetOption("failover", jobopts_count, jobopts)) != NULL)
|
||||||
|
+ {
|
||||||
|
+ fprintf(stderr, "DEBUG: Failover option contents: %s.\n", tmp);
|
||||||
|
+
|
||||||
|
+ tok_tmp = strdup(tmp);
|
||||||
|
+
|
||||||
|
+ tmp = strtok(tok_tmp, ",");
|
||||||
|
+ do
|
||||||
|
+ {
|
||||||
|
+ cupsArrayAdd(printer_array, strdup(tmp));
|
||||||
|
+ } while ((tmp = strtok(NULL,",")) != NULL);
|
||||||
|
+
|
||||||
|
+ free(tok_tmp);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ /*
|
||||||
|
+ * The queue is misconfigured, so return back CUPS_BACKEND_STOP
|
||||||
|
+ */
|
||||||
|
+ fprintf(stderr, "ERROR: failover option not specified!\n");
|
||||||
|
+ return (CUPS_BACKEND_STOP);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Get the failover-retries value, if it exists.
|
||||||
|
+ */
|
||||||
|
+ fprintf(stderr, "DEBUG: Searching for failover-retries option.\n");
|
||||||
|
+
|
||||||
|
+ if ((tmp = cupsGetOption("failover-retries",
|
||||||
|
+ jobopts_count, jobopts)) != NULL)
|
||||||
|
+ {
|
||||||
|
+ fprintf(stderr, "DEBUG: failover-retries option contents: %s.\n", tmp);
|
||||||
|
+ *retries = atoi(tmp);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ *retries = FAILOVER_DEFAULT_RETRIES;
|
||||||
|
+ fprintf(stderr, "DEBUG: Failed to get failover-retries option\n");
|
||||||
|
+ fprintf(stderr, "DEBUG: Defaulted to %d retries\n", *retries);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return (CUPS_BACKEND_OK);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * 'get_printer_attributes()' - Sends an IPP Get-Attributes request to
|
||||||
|
+ * a URI
|
||||||
|
+ */
|
||||||
|
+int
|
||||||
|
+get_printer_attributes(const char *device_uri, ipp_t **attributes)
|
||||||
|
+{
|
||||||
|
+ char uri[HTTP_MAX_URI]; /* Updated URI without login */
|
||||||
|
+ int version; /* IPP version */
|
||||||
|
+ char scheme[256]; /* Scheme in URI */
|
||||||
|
+ ipp_status_t ipp_status; /* Status of IPP request */
|
||||||
|
+ char hostname[1024]; /* Hostname */
|
||||||
|
+ char resource[1024]; /* Resource infoo */
|
||||||
|
+ char addrname[256]; /* Address name */
|
||||||
|
+ int port; /* IPP Port number */
|
||||||
|
+ char portname[255]; /* Port as string */
|
||||||
|
+ http_t *http; /* HTTP connection */
|
||||||
|
+ ipp_t *request; /* IPP request */
|
||||||
|
+ int rc = CUPS_BACKEND_OK; /* Return Code */
|
||||||
|
+ char username[256]; /* Username for device URI */
|
||||||
|
+ char *option_ptr; /* for parsing resource opts */
|
||||||
|
+ const char * const pattrs[] = /* Printer attributes wanted */
|
||||||
|
+ {
|
||||||
|
+ "printer-is-accepting-jobs",
|
||||||
|
+ "printer-state",
|
||||||
|
+ "printer-state-reasons"
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ if (job_canceled)
|
||||||
|
+ return (CUPS_BACKEND_OK);
|
||||||
|
+
|
||||||
|
+ fprintf(stderr, "DEBUG: Getting Printer Attributes.\n");
|
||||||
|
+ fprintf(stderr, "DEBUG: Device URL %s.\n", device_uri);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Parse device_uri
|
||||||
|
+ */
|
||||||
|
+ if (httpSeparateURI(HTTP_URI_CODING_ALL, device_uri, scheme, sizeof(scheme),
|
||||||
|
+ username, sizeof(username), hostname, sizeof(hostname),
|
||||||
|
+ &port, resource, sizeof(resource)) != HTTP_URI_OK)
|
||||||
|
+ {
|
||||||
|
+ fprintf(stderr, "ERROR: Problem parsing device_uri, %s\n", device_uri);
|
||||||
|
+ return (CUPS_BACKEND_STOP);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!port)
|
||||||
|
+ port = IPP_PORT;
|
||||||
|
+
|
||||||
|
+ sprintf(portname, "%d", port);
|
||||||
|
+
|
||||||
|
+ fprintf(stderr, "DEBUG: Getting Printer Attributes.\n");
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Configure password
|
||||||
|
+ */
|
||||||
|
+ cupsSetPasswordCB(password_cb);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * reset, in case a previous attempt for
|
||||||
|
+ * another printer left residue
|
||||||
|
+ */
|
||||||
|
+ cupsSetUser(NULL);
|
||||||
|
+ password = NULL;
|
||||||
|
+ password_retries = 0;
|
||||||
|
+
|
||||||
|
+ if (*username)
|
||||||
|
+ {
|
||||||
|
+ if ((password = strchr(username, ':')) != NULL)
|
||||||
|
+ {
|
||||||
|
+ *password = '\0';
|
||||||
|
+ password++;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ cupsSetUser(username);
|
||||||
|
+ }
|
||||||
|
+ else if (!getuid())
|
||||||
|
+ {
|
||||||
|
+ const char *username_env;
|
||||||
|
+
|
||||||
|
+ if ((username_env = getenv("AUTH_USERNAME")) != NULL)
|
||||||
|
+ {
|
||||||
|
+ cupsSetUser(username_env);
|
||||||
|
+ password = getenv("AUTH_PASSWORD");
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Try connecting to the remote server...
|
||||||
|
+ */
|
||||||
|
+ fprintf(stderr, "DEBUG: Connecting to %s:%d\n", hostname, port);
|
||||||
|
+ _cupsLangPuts(stderr, _("INFO: Connecting to printer...\n"));
|
||||||
|
+
|
||||||
|
+ http = httpConnectEncrypt(hostname, port, cupsEncryption());
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Deal the socket not being open.
|
||||||
|
+ */
|
||||||
|
+ if (!http)
|
||||||
|
+ {
|
||||||
|
+ int error = errno; /* Connection error */
|
||||||
|
+
|
||||||
|
+ switch (error)
|
||||||
|
+ {
|
||||||
|
+ case EHOSTDOWN :
|
||||||
|
+ _cupsLangPuts(stderr, _("WARNING: "
|
||||||
|
+ "The printer may not exist or "
|
||||||
|
+ "is unavailable at this time.\n"));
|
||||||
|
+ break;
|
||||||
|
+ case EHOSTUNREACH :
|
||||||
|
+ _cupsLangPuts(stderr, _("WARNING: "
|
||||||
|
+ "The printer is unreachable at this "
|
||||||
|
+ "time.\n"));
|
||||||
|
+ break;
|
||||||
|
+ case ECONNREFUSED :
|
||||||
|
+ _cupsLangPuts(stderr, _("WARNING: "
|
||||||
|
+ "Connection Refused.\n"));
|
||||||
|
+ break;
|
||||||
|
+ default :
|
||||||
|
+ fprintf(stderr, "DEBUG: Connection error: %s\n", strerror(errno));
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rc = CUPS_BACKEND_FAILED;
|
||||||
|
+ sleep(5);
|
||||||
|
+ goto prt_available_cleanup;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+#ifdef AF_INET6
|
||||||
|
+ if (http->hostaddr->addr.sa_family == AF_INET6)
|
||||||
|
+ fprintf(stderr, "DEBUG: Connected to [%s]:%d (IPv6)...\n",
|
||||||
|
+ httpAddrString(http->hostaddr, addrname, sizeof(addrname)),
|
||||||
|
+ ntohs(http->hostaddr->ipv6.sin6_port));
|
||||||
|
+ else
|
||||||
|
+#endif /* AF_INET6 */
|
||||||
|
+ if (http->hostaddr->addr.sa_family == AF_INET)
|
||||||
|
+ fprintf(stderr, "DEBUG: Connected to %s:%d (IPv4)...\n",
|
||||||
|
+ httpAddrString(http->hostaddr, addrname, sizeof(addrname)),
|
||||||
|
+ ntohs(http->hostaddr->ipv4.sin_port));
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Search the resource string for options.
|
||||||
|
+ * We only care about version, for the moment.
|
||||||
|
+ */
|
||||||
|
+ version = 11;
|
||||||
|
+
|
||||||
|
+ if ((option_ptr = strchr(resource, '?')) != NULL)
|
||||||
|
+ {
|
||||||
|
+ *option_ptr++ = '\0';
|
||||||
|
+
|
||||||
|
+ if ((option_ptr = strstr(option_ptr, "version="))!=NULL)
|
||||||
|
+ {
|
||||||
|
+ int minor; /* minor version from URI */
|
||||||
|
+ int major; /* major version from URI */
|
||||||
|
+ char *version_str; /* ipp version */
|
||||||
|
+
|
||||||
|
+ option_ptr += 8;
|
||||||
|
+ version_str = option_ptr;
|
||||||
|
+
|
||||||
|
+ while (*option_ptr && *option_ptr != '&' && *option_ptr != '+')
|
||||||
|
+ option_ptr++;
|
||||||
|
+
|
||||||
|
+ if (*option_ptr)
|
||||||
|
+ *option_ptr = '\0';
|
||||||
|
+
|
||||||
|
+ sscanf(version_str, "%d.%d", &major, &minor);
|
||||||
|
+
|
||||||
|
+ version = (major * 10) + minor;
|
||||||
|
+
|
||||||
|
+ switch(version)
|
||||||
|
+ {
|
||||||
|
+ case 10 :
|
||||||
|
+ case 11 :
|
||||||
|
+ case 20 :
|
||||||
|
+ case 21 :
|
||||||
|
+ fprintf(stderr,
|
||||||
|
+ "DEBUG: Set version to %d from URI\n",
|
||||||
|
+ version);
|
||||||
|
+ break;
|
||||||
|
+ default :
|
||||||
|
+ _cupsLangPrintf(stderr,
|
||||||
|
+ _("DEBUG: Invalid version, %d, from URI. "
|
||||||
|
+ "Using default of 1.1 \n"),
|
||||||
|
+ version);
|
||||||
|
+ version = 11;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Build a URI for the printer. We can't use the URI in argv[0]
|
||||||
|
+ * because it might contain username:password information...
|
||||||
|
+ */
|
||||||
|
+ if (httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), scheme, NULL,
|
||||||
|
+ hostname, port, resource) != HTTP_URI_OK)
|
||||||
|
+ {
|
||||||
|
+ fprintf(stderr, "ERROR: Problem assembling printer URI from host %s, "
|
||||||
|
+ "port %d, resource %s\n", hostname, port, resource);
|
||||||
|
+ return (CUPS_BACKEND_STOP);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Build the IPP request...
|
||||||
|
+ */
|
||||||
|
+ request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
|
||||||
|
+ request->request.op.version[0] = version / 10;
|
||||||
|
+ request->request.op.version[1] = version % 10;
|
||||||
|
+
|
||||||
|
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
|
||||||
|
+ NULL, uri);
|
||||||
|
+
|
||||||
|
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
|
||||||
|
+ "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]),
|
||||||
|
+ NULL, pattrs);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Do the request...
|
||||||
|
+ */
|
||||||
|
+ fputs("DEBUG: Getting supported attributes...\n", stderr);
|
||||||
|
+
|
||||||
|
+ fprintf(stderr, "DEBUG: IPP Request Structure Built.\n");
|
||||||
|
+
|
||||||
|
+ *attributes = cupsDoRequest(http, request, resource);
|
||||||
|
+ ipp_status = cupsLastError();
|
||||||
|
+
|
||||||
|
+ fprintf(stderr, "DEBUG: Get-Printer-Attributes: %s (%s)\n",
|
||||||
|
+ ippErrorString(ipp_status), cupsLastErrorString());
|
||||||
|
+
|
||||||
|
+ if (ipp_status > IPP_OK_CONFLICT)
|
||||||
|
+ {
|
||||||
|
+ fprintf(stderr, "DEBUG: Get-Printer-Attributes returned %s.\n",
|
||||||
|
+ ippErrorString(ipp_status));
|
||||||
|
+ switch(ipp_status)
|
||||||
|
+ {
|
||||||
|
+ case IPP_FORBIDDEN :
|
||||||
|
+ case IPP_NOT_AUTHORIZED :
|
||||||
|
+ _cupsLangPuts(stderr, _("ERROR: Not Authorized.\n"));
|
||||||
|
+ rc = CUPS_BACKEND_AUTH_REQUIRED;
|
||||||
|
+ break;
|
||||||
|
+ case IPP_PRINTER_BUSY :
|
||||||
|
+ case IPP_SERVICE_UNAVAILABLE :
|
||||||
|
+ _cupsLangPuts(stderr, _("ERROR: "
|
||||||
|
+ "The printer is not responding.\n"));
|
||||||
|
+ rc = CUPS_BACKEND_FAILED;
|
||||||
|
+ break;
|
||||||
|
+ case IPP_BAD_REQUEST :
|
||||||
|
+ case IPP_VERSION_NOT_SUPPORTED :
|
||||||
|
+ fprintf(stderr, "ERROR: Destination does not support IPP version %d\n",
|
||||||
|
+ version);
|
||||||
|
+ case IPP_NOT_FOUND :
|
||||||
|
+ _cupsLangPuts(stderr, _("ERROR: "
|
||||||
|
+ "The printer configuration is incorrect or the "
|
||||||
|
+ "printer no longer exists.\n"));
|
||||||
|
+ rc = CUPS_BACKEND_STOP;
|
||||||
|
+ break;
|
||||||
|
+ default :
|
||||||
|
+ rc = CUPS_BACKEND_FAILED;
|
||||||
|
+ }
|
||||||
|
+ goto prt_available_cleanup;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+prt_available_cleanup :
|
||||||
|
+ httpClose(http);
|
||||||
|
+ return (rc);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+move_job(int jobid, /* Job ID */
|
||||||
|
+ const char *dest) /* Destination ipp address */
|
||||||
|
+{
|
||||||
|
+ ipp_t *request; /* IPP Request */
|
||||||
|
+ char job_uri[HTTP_MAX_URI]; /* job-uri */
|
||||||
|
+
|
||||||
|
+ http_t* http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
|
||||||
|
+
|
||||||
|
+ if (!http)
|
||||||
|
+ {
|
||||||
|
+ _cupsLangPrintf(stderr,
|
||||||
|
+ _("failover: Unable to connect to server: %s\n"),
|
||||||
|
+ strerror(errno));
|
||||||
|
+ return (CUPS_BACKEND_FAILED);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Build a CUPS_MOVE_JOB request, which requires the following
|
||||||
|
+ * attributes:
|
||||||
|
+ *
|
||||||
|
+ * job-uri/printer-uri
|
||||||
|
+ * job-printer-uri
|
||||||
|
+ * requesting-user-name
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ request = ippNewRequest(CUPS_MOVE_JOB);
|
||||||
|
+
|
||||||
|
+ snprintf(job_uri, sizeof(job_uri), "ipp://localhost/jobs/%d", jobid);
|
||||||
|
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL,
|
||||||
|
+ job_uri);
|
||||||
|
+
|
||||||
|
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
|
||||||
|
+ "requesting-user-name",
|
||||||
|
+ NULL, cupsUser());
|
||||||
|
+
|
||||||
|
+ ippAddString(request, IPP_TAG_JOB, IPP_TAG_URI, "job-printer-uri",
|
||||||
|
+ NULL, dest);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Do the request and get back a response...
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ ippDelete(cupsDoRequest(http, request, "/jobs"));
|
||||||
|
+
|
||||||
|
+ httpClose(http);
|
||||||
|
+
|
||||||
|
+ if (cupsLastError() > IPP_OK_CONFLICT)
|
||||||
|
+ {
|
||||||
|
+ _cupsLangPrintf(stderr, "failover: %s\n", cupsLastErrorString());
|
||||||
|
+ return (CUPS_BACKEND_FAILED);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ return (CUPS_BACKEND_OK);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * 'sigterm_handler()' - handles a sigterm, i.e. job canceled
|
||||||
|
+ */
|
||||||
|
+static void
|
||||||
|
+sigterm_handler(int sig)
|
||||||
|
+{
|
||||||
|
+ if (!job_canceled)
|
||||||
|
+ {
|
||||||
|
+ write(2, "DEBUG: Got SIGTERM.\n", 20);
|
||||||
|
+ job_canceled = 1;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ /*
|
||||||
|
+ * Job has already been canceled, so just exit
|
||||||
|
+ */
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * 'password_cb()' - Disable the password prompt for cupsDoFileRequest().
|
||||||
|
+ */
|
||||||
|
+static const char * /* O - Password */
|
||||||
|
+password_cb(const char *prompt) /* I - Prompt (not used) */
|
||||||
|
+{
|
||||||
|
+ auth_info_required = "username,password";
|
||||||
|
+ password_retries++;
|
||||||
|
+
|
||||||
|
+ if(password_retries < FAILOVER_PASSWORD_RETRIES_MAX)
|
||||||
|
+ return (password);
|
||||||
|
+ else
|
||||||
|
+ return (NULL);
|
||||||
|
+}
|
@ -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;
|
||||||
|
|
@ -0,0 +1,371 @@
|
|||||||
|
diff --git a/cups/cups.h b/cups/cups.h
|
||||||
|
index 8f5c818..9d8c3a3 100644
|
||||||
|
--- a/cups/cups.h
|
||||||
|
+++ b/cups/cups.h
|
||||||
|
@@ -606,6 +606,9 @@ extern ssize_t cupsHashData(const char *algorithm, const void *data, size_t dat
|
||||||
|
extern int cupsAddIntegerOption(const char *name, int value, int num_options, cups_option_t **options) _CUPS_API_2_2_4;
|
||||||
|
extern int cupsGetIntegerOption(const char *name, int num_options, cups_option_t *options) _CUPS_API_2_2_4;
|
||||||
|
|
||||||
|
+/* New in CUPS 2.3 */
|
||||||
|
+extern const char *cupsHashString(const unsigned char *hash, size_t hashsize, char *buffer, size_t bufsize);
|
||||||
|
+
|
||||||
|
# ifdef __cplusplus
|
||||||
|
}
|
||||||
|
# endif /* __cplusplus */
|
||||||
|
diff --git a/cups/hash.c b/cups/hash.c
|
||||||
|
index ede5461..8ebe20b 100644
|
||||||
|
--- a/cups/hash.c
|
||||||
|
+++ b/cups/hash.c
|
||||||
|
@@ -21,6 +21,8 @@
|
||||||
|
# include <CommonCrypto/CommonDigest.h>
|
||||||
|
#elif defined(HAVE_GNUTLS)
|
||||||
|
# include <gnutls/crypto.h>
|
||||||
|
+#else
|
||||||
|
+# include "md5-private.h"
|
||||||
|
#endif /* __APPLE__ */
|
||||||
|
|
||||||
|
|
||||||
|
@@ -171,7 +173,9 @@ cupsHashData(const char *algorithm, /* I - Algorithm name */
|
||||||
|
unsigned char temp[64]; /* Temporary hash buffer */
|
||||||
|
size_t tempsize = 0; /* Truncate to this size? */
|
||||||
|
|
||||||
|
- if (!strcmp(algorithm, "sha"))
|
||||||
|
+ if (!strcmp(algorithm, "md5"))
|
||||||
|
+ alg = GNUTLS_DIG_MD5;
|
||||||
|
+ else if (!strcmp(algorithm, "sha"))
|
||||||
|
alg = GNUTLS_DIG_SHA1;
|
||||||
|
else if (!strcmp(algorithm, "sha2-224"))
|
||||||
|
alg = GNUTLS_DIG_SHA224;
|
||||||
|
@@ -219,10 +223,20 @@ cupsHashData(const char *algorithm, /* I - Algorithm name */
|
||||||
|
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
- * No hash support without CommonCrypto or GNU TLS...
|
||||||
|
+ * No hash support beyond MD5 without CommonCrypto or GNU TLS...
|
||||||
|
*/
|
||||||
|
|
||||||
|
- if (hashsize < 64)
|
||||||
|
+ if (!strcmp(algorithm, "md5"))
|
||||||
|
+ {
|
||||||
|
+ _cups_md5_state_t state; /* MD5 state info */
|
||||||
|
+
|
||||||
|
+ _cupsMD5Init(&state);
|
||||||
|
+ _cupsMD5Append(&state, data, datalen);
|
||||||
|
+ _cupsMD5Finish(&state, hash);
|
||||||
|
+
|
||||||
|
+ return (16);
|
||||||
|
+ }
|
||||||
|
+ else if (hashsize < 64)
|
||||||
|
goto too_small;
|
||||||
|
#endif /* __APPLE__ */
|
||||||
|
|
||||||
|
@@ -243,3 +257,51 @@ cupsHashData(const char *algorithm, /* I - Algorithm name */
|
||||||
|
_cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Hash buffer too small."), 1);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * 'cupsHashString()' - Format a hash value as a hexadecimal string.
|
||||||
|
+ *
|
||||||
|
+ * The passed buffer must be at least 2 * hashsize + 1 characters in length.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+const char * /* O - Formatted string */
|
||||||
|
+cupsHashString(
|
||||||
|
+ const unsigned char *hash, /* I - Hash */
|
||||||
|
+ size_t hashsize, /* I - Size of hash */
|
||||||
|
+ char *buffer, /* I - String buffer */
|
||||||
|
+ size_t bufsize) /* I - Size of string buffer */
|
||||||
|
+{
|
||||||
|
+ char *bufptr = buffer; /* Pointer into buffer */
|
||||||
|
+ static const char *hex = "0123456789abcdef";
|
||||||
|
+ /* Hex characters (lowercase!) */
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Range check input...
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ if (!hash || hashsize < 1 || !buffer || bufsize < (2 * hashsize + 1))
|
||||||
|
+ {
|
||||||
|
+ if (buffer)
|
||||||
|
+ *buffer = '\0';
|
||||||
|
+ return (NULL);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Loop until we've converted the whole hash...
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ while (hashsize > 0)
|
||||||
|
+ {
|
||||||
|
+ *bufptr++ = hex[*hash >> 4];
|
||||||
|
+ *bufptr++ = hex[*hash & 15];
|
||||||
|
+
|
||||||
|
+ hash ++;
|
||||||
|
+ hashsize --;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *bufptr = '\0';
|
||||||
|
+
|
||||||
|
+ return (buffer);
|
||||||
|
+}
|
||||||
|
diff --git a/cups/md5passwd.c b/cups/md5passwd.c
|
||||||
|
index a9817aa..c9ffe04 100644
|
||||||
|
--- a/cups/md5passwd.c
|
||||||
|
+++ b/cups/md5passwd.c
|
||||||
|
@@ -17,6 +17,7 @@
|
||||||
|
* Include necessary headers...
|
||||||
|
*/
|
||||||
|
|
||||||
|
+#include <cups/cups.h>
|
||||||
|
#include "http-private.h"
|
||||||
|
#include "string-private.h"
|
||||||
|
|
||||||
|
@@ -31,7 +32,6 @@ httpMD5(const char *username, /* I - User name */
|
||||||
|
const char *passwd, /* I - Password string */
|
||||||
|
char md5[33]) /* O - MD5 string */
|
||||||
|
{
|
||||||
|
- _cups_md5_state_t state; /* MD5 state info */
|
||||||
|
unsigned char sum[16]; /* Sum data */
|
||||||
|
char line[256]; /* Line to sum */
|
||||||
|
|
||||||
|
@@ -41,15 +41,13 @@ httpMD5(const char *username, /* I - User name */
|
||||||
|
*/
|
||||||
|
|
||||||
|
snprintf(line, sizeof(line), "%s:%s:%s", username, realm, passwd);
|
||||||
|
- _cupsMD5Init(&state);
|
||||||
|
- _cupsMD5Append(&state, (unsigned char *)line, (int)strlen(line));
|
||||||
|
- _cupsMD5Finish(&state, sum);
|
||||||
|
+ cupsHashData("md5", (unsigned char *)line, strlen(line), sum, sizeof(sum));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the sum...
|
||||||
|
*/
|
||||||
|
|
||||||
|
- return (httpMD5String(sum, md5));
|
||||||
|
+ return ((char *)cupsHashString(sum, sizeof(sum), md5, 33));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -65,7 +63,6 @@ httpMD5Final(const char *nonce, /* I - Server nonce value */
|
||||||
|
const char *resource, /* I - Resource path */
|
||||||
|
char md5[33]) /* IO - MD5 sum */
|
||||||
|
{
|
||||||
|
- _cups_md5_state_t state; /* MD5 state info */
|
||||||
|
unsigned char sum[16]; /* Sum data */
|
||||||
|
char line[1024]; /* Line of data */
|
||||||
|
char a2[33]; /* Hash of method and resource */
|
||||||
|
@@ -76,9 +73,7 @@ httpMD5Final(const char *nonce, /* I - Server nonce value */
|
||||||
|
*/
|
||||||
|
|
||||||
|
snprintf(line, sizeof(line), "%s:%s", method, resource);
|
||||||
|
- _cupsMD5Init(&state);
|
||||||
|
- _cupsMD5Append(&state, (unsigned char *)line, (int)strlen(line));
|
||||||
|
- _cupsMD5Finish(&state, sum);
|
||||||
|
+ cupsHashData("md5", (unsigned char *)line, strlen(line), sum, sizeof(sum));
|
||||||
|
httpMD5String(sum, a2);
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -88,12 +83,9 @@ httpMD5Final(const char *nonce, /* I - Server nonce value */
|
||||||
|
*/
|
||||||
|
|
||||||
|
snprintf(line, sizeof(line), "%s:%s:%s", md5, nonce, a2);
|
||||||
|
+ cupsHashData("md5", (unsigned char *)line, strlen(line), sum, sizeof(sum));
|
||||||
|
|
||||||
|
- _cupsMD5Init(&state);
|
||||||
|
- _cupsMD5Append(&state, (unsigned char *)line, (int)strlen(line));
|
||||||
|
- _cupsMD5Finish(&state, sum);
|
||||||
|
-
|
||||||
|
- return (httpMD5String(sum, md5));
|
||||||
|
+ return ((char *)cupsHashString(sum, sizeof(sum), md5, 33));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -106,23 +98,5 @@ httpMD5String(const unsigned char *sum, /* I - MD5 sum data */
|
||||||
|
char md5[33])
|
||||||
|
/* O - MD5 sum in hex */
|
||||||
|
{
|
||||||
|
- int i; /* Looping var */
|
||||||
|
- char *md5ptr; /* Pointer into MD5 string */
|
||||||
|
- static const char hex[] = "0123456789abcdef";
|
||||||
|
- /* Hex digits */
|
||||||
|
-
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * Convert the MD5 sum to hexadecimal...
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
- for (i = 16, md5ptr = md5; i > 0; i --, sum ++)
|
||||||
|
- {
|
||||||
|
- *md5ptr++ = hex[*sum >> 4];
|
||||||
|
- *md5ptr++ = hex[*sum & 15];
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- *md5ptr = '\0';
|
||||||
|
-
|
||||||
|
- return (md5);
|
||||||
|
+ return ((char *)cupsHashString(sum, 16, md5, 33));
|
||||||
|
}
|
||||||
|
diff --git a/scheduler/auth.c b/scheduler/auth.c
|
||||||
|
index 71df9dc..e7d0006 100644
|
||||||
|
--- a/scheduler/auth.c
|
||||||
|
+++ b/scheduler/auth.c
|
||||||
|
@@ -72,9 +72,6 @@ static int check_authref(cupsd_client_t *con, const char *right);
|
||||||
|
static int compare_locations(cupsd_location_t *a,
|
||||||
|
cupsd_location_t *b);
|
||||||
|
static cupsd_authmask_t *copy_authmask(cupsd_authmask_t *am, void *data);
|
||||||
|
-#if !HAVE_LIBPAM
|
||||||
|
-static char *cups_crypt(const char *pw, const char *salt);
|
||||||
|
-#endif /* !HAVE_LIBPAM */
|
||||||
|
static void free_authmask(cupsd_authmask_t *am, void *data);
|
||||||
|
#if HAVE_LIBPAM
|
||||||
|
static int pam_func(int, const struct pam_message **,
|
||||||
|
@@ -695,14 +692,14 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
|
||||||
|
* client...
|
||||||
|
*/
|
||||||
|
|
||||||
|
- pass = cups_crypt(password, pw->pw_passwd);
|
||||||
|
+ pass = crypt(password, pw->pw_passwd);
|
||||||
|
|
||||||
|
if (!pass || strcmp(pw->pw_passwd, pass))
|
||||||
|
{
|
||||||
|
# ifdef HAVE_SHADOW_H
|
||||||
|
if (spw)
|
||||||
|
{
|
||||||
|
- pass = cups_crypt(password, spw->sp_pwdp);
|
||||||
|
+ pass = crypt(password, spw->sp_pwdp);
|
||||||
|
|
||||||
|
if (pass == NULL || strcmp(spw->sp_pwdp, pass))
|
||||||
|
{
|
||||||
|
@@ -1988,129 +1985,6 @@ copy_authmask(cupsd_authmask_t *mask, /* I - Existing auth mask */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-#if !HAVE_LIBPAM
|
||||||
|
-/*
|
||||||
|
- * 'cups_crypt()' - Encrypt the password using the DES or MD5 algorithms,
|
||||||
|
- * as needed.
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
-static char * /* O - Encrypted password */
|
||||||
|
-cups_crypt(const char *pw, /* I - Password string */
|
||||||
|
- const char *salt) /* I - Salt (key) string */
|
||||||
|
-{
|
||||||
|
- if (!strncmp(salt, "$1$", 3))
|
||||||
|
- {
|
||||||
|
- /*
|
||||||
|
- * Use MD5 passwords without the benefit of PAM; this is for
|
||||||
|
- * Slackware Linux, and the algorithm was taken from the
|
||||||
|
- * old shadow-19990827/lib/md5crypt.c source code... :(
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
- int i; /* Looping var */
|
||||||
|
- unsigned long n; /* Output number */
|
||||||
|
- int pwlen; /* Length of password string */
|
||||||
|
- const char *salt_end; /* End of "salt" data for MD5 */
|
||||||
|
- char *ptr; /* Pointer into result string */
|
||||||
|
- _cups_md5_state_t state; /* Primary MD5 state info */
|
||||||
|
- _cups_md5_state_t state2; /* Secondary MD5 state info */
|
||||||
|
- unsigned char digest[16]; /* MD5 digest result */
|
||||||
|
- static char result[120]; /* Final password string */
|
||||||
|
-
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * Get the salt data between dollar signs, e.g. $1$saltdata$md5.
|
||||||
|
- * Get a maximum of 8 characters of salt data after $1$...
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
- for (salt_end = salt + 3; *salt_end && (salt_end - salt) < 11; salt_end ++)
|
||||||
|
- if (*salt_end == '$')
|
||||||
|
- break;
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * Compute the MD5 sum we need...
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
- pwlen = strlen(pw);
|
||||||
|
-
|
||||||
|
- _cupsMD5Init(&state);
|
||||||
|
- _cupsMD5Append(&state, (unsigned char *)pw, pwlen);
|
||||||
|
- _cupsMD5Append(&state, (unsigned char *)salt, salt_end - salt);
|
||||||
|
-
|
||||||
|
- _cupsMD5Init(&state2);
|
||||||
|
- _cupsMD5Append(&state2, (unsigned char *)pw, pwlen);
|
||||||
|
- _cupsMD5Append(&state2, (unsigned char *)salt + 3, salt_end - salt - 3);
|
||||||
|
- _cupsMD5Append(&state2, (unsigned char *)pw, pwlen);
|
||||||
|
- _cupsMD5Finish(&state2, digest);
|
||||||
|
-
|
||||||
|
- for (i = pwlen; i > 0; i -= 16)
|
||||||
|
- _cupsMD5Append(&state, digest, i > 16 ? 16 : i);
|
||||||
|
-
|
||||||
|
- for (i = pwlen; i > 0; i >>= 1)
|
||||||
|
- _cupsMD5Append(&state, (unsigned char *)((i & 1) ? "" : pw), 1);
|
||||||
|
-
|
||||||
|
- _cupsMD5Finish(&state, digest);
|
||||||
|
-
|
||||||
|
- for (i = 0; i < 1000; i ++)
|
||||||
|
- {
|
||||||
|
- _cupsMD5Init(&state);
|
||||||
|
-
|
||||||
|
- if (i & 1)
|
||||||
|
- _cupsMD5Append(&state, (unsigned char *)pw, pwlen);
|
||||||
|
- else
|
||||||
|
- _cupsMD5Append(&state, digest, 16);
|
||||||
|
-
|
||||||
|
- if (i % 3)
|
||||||
|
- _cupsMD5Append(&state, (unsigned char *)salt + 3, salt_end - salt - 3);
|
||||||
|
-
|
||||||
|
- if (i % 7)
|
||||||
|
- _cupsMD5Append(&state, (unsigned char *)pw, pwlen);
|
||||||
|
-
|
||||||
|
- if (i & 1)
|
||||||
|
- _cupsMD5Append(&state, digest, 16);
|
||||||
|
- else
|
||||||
|
- _cupsMD5Append(&state, (unsigned char *)pw, pwlen);
|
||||||
|
-
|
||||||
|
- _cupsMD5Finish(&state, digest);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * Copy the final sum to the result string and return...
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
- memcpy(result, salt, (size_t)(salt_end - salt));
|
||||||
|
- ptr = result + (salt_end - salt);
|
||||||
|
- *ptr++ = '$';
|
||||||
|
-
|
||||||
|
- for (i = 0; i < 5; i ++, ptr += 4)
|
||||||
|
- {
|
||||||
|
- n = ((((unsigned)digest[i] << 8) | (unsigned)digest[i + 6]) << 8);
|
||||||
|
-
|
||||||
|
- if (i < 4)
|
||||||
|
- n |= (unsigned)digest[i + 12];
|
||||||
|
- else
|
||||||
|
- n |= (unsigned)digest[5];
|
||||||
|
-
|
||||||
|
- to64(ptr, n, 4);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- to64(ptr, (unsigned)digest[11], 2);
|
||||||
|
- ptr += 2;
|
||||||
|
- *ptr = '\0';
|
||||||
|
-
|
||||||
|
- return (result);
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- /*
|
||||||
|
- * Use the standard crypt() function...
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
- return (crypt(pw, salt));
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-#endif /* !HAVE_LIBPAM */
|
||||||
|
-
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
* 'free_authmask()' - Free function for auth masks.
|
||||||
|
*/
|
@ -0,0 +1,110 @@
|
|||||||
|
diff --git a/scheduler/job.c b/scheduler/job.c
|
||||||
|
index 82ef2eb..5d5e3aa 100644
|
||||||
|
--- a/scheduler/job.c
|
||||||
|
+++ b/scheduler/job.c
|
||||||
|
@@ -448,10 +448,20 @@ cupsdCleanJobs(void)
|
||||||
|
curtime = time(NULL);
|
||||||
|
JobHistoryUpdate = 0;
|
||||||
|
|
||||||
|
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCleanJobs: curtime=%d", (int)curtime);
|
||||||
|
+
|
||||||
|
for (job = (cupsd_job_t *)cupsArrayFirst(Jobs);
|
||||||
|
job;
|
||||||
|
job = (cupsd_job_t *)cupsArrayNext(Jobs))
|
||||||
|
{
|
||||||
|
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCleanJobs: Job %d, state=%d, printer=%p, history_time=%d, file_time=%d", job->id, (int)job->state_value, (void *)job->printer, (int)job->history_time, (int)job->file_time);
|
||||||
|
+
|
||||||
|
+ if ((job->history_time && job->history_time < JobHistoryUpdate) || !JobHistoryUpdate)
|
||||||
|
+ JobHistoryUpdate = job->history_time;
|
||||||
|
+
|
||||||
|
+ if ((job->file_time && job->file_time < JobHistoryUpdate) || !JobHistoryUpdate)
|
||||||
|
+ JobHistoryUpdate = job->file_time;
|
||||||
|
+
|
||||||
|
if (job->state_value >= IPP_JOB_CANCELED && !job->printer)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
@@ -462,26 +472,14 @@ cupsdCleanJobs(void)
|
||||||
|
(job->history_time && job->history_time <= curtime))
|
||||||
|
{
|
||||||
|
cupsdLogJob(job, CUPSD_LOG_DEBUG, "Removing from history.");
|
||||||
|
- cupsdDeleteJob(job, CUPSD_JOB_PURGE);
|
||||||
|
+ cupsdDeleteJob(job, CUPSD_JOB_PURGE);
|
||||||
|
}
|
||||||
|
else if (job->file_time && job->file_time <= curtime)
|
||||||
|
{
|
||||||
|
cupsdLogJob(job, CUPSD_LOG_DEBUG, "Removing document files.");
|
||||||
|
- cupsdLogJob(job, CUPSD_LOG_DEBUG2, "curtime=%ld, job->file_time=%ld", (long)curtime, (long)job->file_time);
|
||||||
|
remove_job_files(job);
|
||||||
|
|
||||||
|
cupsdMarkDirty(CUPSD_DIRTY_JOBS);
|
||||||
|
-
|
||||||
|
- if (job->history_time < JobHistoryUpdate || !JobHistoryUpdate)
|
||||||
|
- JobHistoryUpdate = job->history_time;
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- if (job->history_time < JobHistoryUpdate || !JobHistoryUpdate)
|
||||||
|
- JobHistoryUpdate = job->history_time;
|
||||||
|
-
|
||||||
|
- if (job->file_time < JobHistoryUpdate || !JobHistoryUpdate)
|
||||||
|
- JobHistoryUpdate = job->file_time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1873,7 +1871,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
|
||||||
|
job->completed_time = attr->values[0].integer;
|
||||||
|
|
||||||
|
if (JobHistory < INT_MAX)
|
||||||
|
- job->history_time = attr->values[0].integer + JobHistory;
|
||||||
|
+ job->history_time = job->completed_time + JobHistory;
|
||||||
|
else
|
||||||
|
job->history_time = INT_MAX;
|
||||||
|
|
||||||
|
@@ -1884,7 +1882,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
|
||||||
|
JobHistoryUpdate = job->history_time;
|
||||||
|
|
||||||
|
if (JobFiles < INT_MAX)
|
||||||
|
- job->file_time = attr->values[0].integer + JobFiles;
|
||||||
|
+ job->file_time = job->completed_time + JobFiles;
|
||||||
|
else
|
||||||
|
job->file_time = INT_MAX;
|
||||||
|
|
||||||
|
@@ -3100,8 +3098,10 @@ cupsdUpdateJobs(void)
|
||||||
|
* Update history/file expiration times...
|
||||||
|
*/
|
||||||
|
|
||||||
|
+ job->completed_time = attr->values[0].integer;
|
||||||
|
+
|
||||||
|
if (JobHistory < INT_MAX)
|
||||||
|
- job->history_time = attr->values[0].integer + JobHistory;
|
||||||
|
+ job->history_time = job->completed_time + JobHistory;
|
||||||
|
else
|
||||||
|
job->history_time = INT_MAX;
|
||||||
|
|
||||||
|
@@ -3115,7 +3115,7 @@ cupsdUpdateJobs(void)
|
||||||
|
JobHistoryUpdate = job->history_time;
|
||||||
|
|
||||||
|
if (JobFiles < INT_MAX)
|
||||||
|
- job->file_time = attr->values[0].integer + JobFiles;
|
||||||
|
+ job->file_time = job->completed_time + JobFiles;
|
||||||
|
else
|
||||||
|
job->file_time = INT_MAX;
|
||||||
|
|
||||||
|
@@ -4909,7 +4909,7 @@ set_time(cupsd_job_t *job, /* I - Job to update */
|
||||||
|
job->completed_time = curtime;
|
||||||
|
|
||||||
|
if (JobHistory < INT_MAX && attr)
|
||||||
|
- job->history_time = attr->values[0].integer + JobHistory;
|
||||||
|
+ job->history_time = job->completed_time + JobHistory;
|
||||||
|
else
|
||||||
|
job->history_time = INT_MAX;
|
||||||
|
|
||||||
|
@@ -4917,7 +4917,7 @@ set_time(cupsd_job_t *job, /* I - Job to update */
|
||||||
|
JobHistoryUpdate = job->history_time;
|
||||||
|
|
||||||
|
if (JobFiles < INT_MAX && attr)
|
||||||
|
- job->file_time = curtime + JobFiles;
|
||||||
|
+ job->file_time = job->completed_time + JobFiles;
|
||||||
|
else
|
||||||
|
job->file_time = INT_MAX;
|
||||||
|
|
@ -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
|
@ -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 :
|
@ -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);
|
||||||
|
|
@ -0,0 +1,315 @@
|
|||||||
|
diff --git a/cgi-bin/admin.c b/cgi-bin/admin.c
|
||||||
|
index a604a8a..e678f24 100644
|
||||||
|
--- a/cgi-bin/admin.c
|
||||||
|
+++ b/cgi-bin/admin.c
|
||||||
|
@@ -974,6 +974,13 @@ do_am_printer(http_t *http, /* I - HTTP connection */
|
||||||
|
|
||||||
|
cgiSetVariable("TEMPLATE_NAME", template);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Set DEVICE_URI to the actual device uri, without make and model from
|
||||||
|
+ * html form.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ cgiSetVariable("DEVICE_URI", var);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1137,6 +1144,8 @@ do_am_printer(http_t *http, /* I - HTTP connection */
|
||||||
|
else if (!file &&
|
||||||
|
(!cgiGetVariable("PPD_NAME") || cgiGetVariable("SELECT_MAKE")))
|
||||||
|
{
|
||||||
|
+ int ipp_everywhere = !strncmp(var, "ipp://", 6) || !strncmp(var, "ipps://", 7) || (!strncmp(var, "dnssd://", 8) && (strstr(var, "_ipp._tcp") || strstr(var, "_ipps._tcp")));
|
||||||
|
+
|
||||||
|
if (modify && !cgiGetVariable("SELECT_MAKE"))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
@@ -1282,9 +1291,8 @@ do_am_printer(http_t *http, /* I - HTTP connection */
|
||||||
|
cgiStartHTML(title);
|
||||||
|
if (!cgiGetVariable("PPD_MAKE"))
|
||||||
|
cgiSetVariable("PPD_MAKE", cgiGetVariable("CURRENT_MAKE"));
|
||||||
|
- if (!modify)
|
||||||
|
- cgiSetVariable("CURRENT_MAKE_AND_MODEL",
|
||||||
|
- cgiGetArray("PPD_MAKE_AND_MODEL", 0));
|
||||||
|
+ if (ipp_everywhere)
|
||||||
|
+ cgiSetVariable("SHOW_IPP_EVERYWHERE", "1");
|
||||||
|
cgiCopyTemplateLang("choose-model.tmpl");
|
||||||
|
cgiEndHTML();
|
||||||
|
}
|
||||||
|
@@ -4219,6 +4227,11 @@ get_printer_ppd(const char *uri, /* I - Printer URI */
|
||||||
|
host[256], /* Hostname */
|
||||||
|
resource[256]; /* Resource path */
|
||||||
|
int port; /* Port number */
|
||||||
|
+ static const char * const pattrs[] = /* Printer attributes we need */
|
||||||
|
+ {
|
||||||
|
+ "all",
|
||||||
|
+ "media-col-database"
|
||||||
|
+ };
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -4259,6 +4272,7 @@ get_printer_ppd(const char *uri, /* I - Printer URI */
|
||||||
|
|
||||||
|
request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
|
||||||
|
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
|
||||||
|
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (int)(sizeof(pattrs) / sizeof(pattrs[0])), NULL, pattrs);
|
||||||
|
response = cupsDoRequest(http, request, resource);
|
||||||
|
|
||||||
|
if (!_ppdCreateFromIPP(buffer, bufsize, response))
|
||||||
|
diff --git a/cups/ppd-cache.c b/cups/ppd-cache.c
|
||||||
|
index e5f89ee..b8139c8 100644
|
||||||
|
--- a/cups/ppd-cache.c
|
||||||
|
+++ b/cups/ppd-cache.c
|
||||||
|
@@ -3089,8 +3089,8 @@ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */
|
||||||
|
cupsFilePrintf(fp, "*Manufacturer: \"%s\"\n", make);
|
||||||
|
cupsFilePrintf(fp, "*ModelName: \"%s\"\n", model);
|
||||||
|
cupsFilePrintf(fp, "*Product: \"(%s)\"\n", model);
|
||||||
|
- cupsFilePrintf(fp, "*NickName: \"%s\"\n", model);
|
||||||
|
- cupsFilePrintf(fp, "*ShortNickName: \"%s\"\n", model);
|
||||||
|
+ cupsFilePrintf(fp, "*NickName: \"%s - IPP Everywhere\"\n", model);
|
||||||
|
+ cupsFilePrintf(fp, "*ShortNickName: \"%s - IPP Everywhere\"\n", model);
|
||||||
|
|
||||||
|
if ((attr = ippFindAttribute(response, "color-supported", IPP_TAG_BOOLEAN)) != NULL && ippGetBoolean(attr, 0))
|
||||||
|
cupsFilePuts(fp, "*ColorDevice: True\n");
|
||||||
|
diff --git a/scheduler/ipp.c b/scheduler/ipp.c
|
||||||
|
index 5e9a985..4ed3c39 100644
|
||||||
|
--- a/scheduler/ipp.c
|
||||||
|
+++ b/scheduler/ipp.c
|
||||||
|
@@ -5829,6 +5829,12 @@ create_local_bg_thread(
|
||||||
|
ipp_t *request, /* Request to printer */
|
||||||
|
*response; /* Response from printer */
|
||||||
|
ipp_attribute_t *attr; /* Attribute in response */
|
||||||
|
+ ipp_status_t status; /* Status code */
|
||||||
|
+ static const char * const pattrs[] = /* Printer attributes we need */
|
||||||
|
+ {
|
||||||
|
+ "all",
|
||||||
|
+ "media-col-database"
|
||||||
|
+ };
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -5861,12 +5867,35 @@ create_local_bg_thread(
|
||||||
|
cupsdLogMessage(CUPSD_LOG_DEBUG, "%s: Connected to %s:%d, sending Get-Printer-Attributes request...", printer->name, host, port);
|
||||||
|
|
||||||
|
request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
|
||||||
|
+ ippSetVersion(request, 2, 0);
|
||||||
|
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, printer->device_uri);
|
||||||
|
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", NULL, "all");
|
||||||
|
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (int)(sizeof(pattrs) / sizeof(pattrs[0])), NULL, pattrs);
|
||||||
|
|
||||||
|
response = cupsDoRequest(http, request, resource);
|
||||||
|
+ status = cupsLastError();
|
||||||
|
+
|
||||||
|
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "%s: Get-Printer-Attributes returned %s (%s)", printer->name, ippErrorString(cupsLastError()), cupsLastErrorString());
|
||||||
|
+
|
||||||
|
+ if (status == IPP_STATUS_ERROR_BAD_REQUEST || status == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED)
|
||||||
|
+ {
|
||||||
|
+ /*
|
||||||
|
+ * Try request using IPP/1.1, in case we are talking to an old CUPS server or
|
||||||
|
+ * printer...
|
||||||
|
+ */
|
||||||
|
|
||||||
|
- cupsdLogMessage(CUPSD_LOG_DEBUG, "%s: Get-Printer-Attributes returned %s", printer->name, ippErrorString(cupsLastError()));
|
||||||
|
+ ippDelete(response);
|
||||||
|
+
|
||||||
|
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "%s: Re-sending Get-Printer-Attributes request using IPP/1.1...", printer->name);
|
||||||
|
+
|
||||||
|
+ request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
|
||||||
|
+ ippSetVersion(request, 1, 1);
|
||||||
|
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, printer->device_uri);
|
||||||
|
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", NULL, "all");
|
||||||
|
+
|
||||||
|
+ response = cupsDoRequest(http, request, resource);
|
||||||
|
+
|
||||||
|
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "%s: IPP/1.1 Get-Printer-Attributes returned %s (%s)", printer->name, ippErrorString(cupsLastError()), cupsLastErrorString());
|
||||||
|
+ }
|
||||||
|
|
||||||
|
// TODO: Grab printer icon file...
|
||||||
|
httpClose(http);
|
||||||
|
@@ -5877,6 +5906,8 @@ create_local_bg_thread(
|
||||||
|
|
||||||
|
if (_ppdCreateFromIPP(fromppd, sizeof(fromppd), response))
|
||||||
|
{
|
||||||
|
+ _cupsRWLockWrite(&printer->lock);
|
||||||
|
+
|
||||||
|
if ((!printer->info || !*(printer->info)) && (attr = ippFindAttribute(response, "printer-info", IPP_TAG_TEXT)) != NULL)
|
||||||
|
cupsdSetString(&printer->info, ippGetString(attr, 0, NULL));
|
||||||
|
|
||||||
|
@@ -5886,6 +5917,8 @@ create_local_bg_thread(
|
||||||
|
if ((!printer->geo_location || !*(printer->geo_location)) && (attr = ippFindAttribute(response, "printer-geo-location", IPP_TAG_URI)) != NULL)
|
||||||
|
cupsdSetString(&printer->geo_location, ippGetString(attr, 0, NULL));
|
||||||
|
|
||||||
|
+ _cupsRWUnlock(&printer->lock);
|
||||||
|
+
|
||||||
|
if ((from = cupsFileOpen(fromppd, "r")) == NULL)
|
||||||
|
{
|
||||||
|
cupsdLogMessage(CUPSD_LOG_ERROR, "%s: Unable to read generated PPD: %s", printer->name, strerror(errno));
|
||||||
|
diff --git a/systemv/lpadmin.c b/systemv/lpadmin.c
|
||||||
|
index bb53565..f3510ca 100644
|
||||||
|
--- a/systemv/lpadmin.c
|
||||||
|
+++ b/systemv/lpadmin.c
|
||||||
|
@@ -33,7 +33,7 @@ static int delete_printer_from_class(http_t *http, char *printer,
|
||||||
|
static int delete_printer_option(http_t *http, char *printer,
|
||||||
|
char *option);
|
||||||
|
static int enable_printer(http_t *http, char *printer);
|
||||||
|
-static char *get_printer_ppd(const char *uri, char *buffer, size_t bufsize);
|
||||||
|
+static char *get_printer_ppd(const char *uri, char *buffer, size_t bufsize, int *num_options, cups_option_t **options);
|
||||||
|
static cups_ptype_t get_printer_type(http_t *http, char *printer, char *uri,
|
||||||
|
size_t urisize);
|
||||||
|
static int set_printer_options(http_t *http, char *printer,
|
||||||
|
@@ -593,7 +593,7 @@ main(int argc, /* I - Number of command-line arguments */
|
||||||
|
|
||||||
|
if ((ppd_name = cupsGetOption("ppd-name", num_options, options)) != NULL && !strcmp(ppd_name, "everywhere") && (device_uri = cupsGetOption("device-uri", num_options, options)) != NULL)
|
||||||
|
{
|
||||||
|
- if ((file = get_printer_ppd(device_uri, evefile, sizeof(evefile))) == NULL)
|
||||||
|
+ if ((file = get_printer_ppd(device_uri, evefile, sizeof(evefile), &num_options, &options)) == NULL)
|
||||||
|
return (1);
|
||||||
|
|
||||||
|
num_options = cupsRemoveOption("ppd-name", num_options, &options);
|
||||||
|
@@ -1144,20 +1144,29 @@ enable_printer(http_t *http, /* I - Server connection */
|
||||||
|
* 'get_printer_ppd()' - Get an IPP Everywhere PPD file for the given URI.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-static char * /* O - Filename or NULL */
|
||||||
|
-get_printer_ppd(const char *uri, /* I - Printer URI */
|
||||||
|
- char *buffer, /* I - Filename buffer */
|
||||||
|
- size_t bufsize) /* I - Size of filename buffer */
|
||||||
|
+static char * /* O - Filename or NULL */
|
||||||
|
+get_printer_ppd(
|
||||||
|
+ const char *uri, /* I - Printer URI */
|
||||||
|
+ char *buffer, /* I - Filename buffer */
|
||||||
|
+ size_t bufsize, /* I - Size of filename buffer */
|
||||||
|
+ int *num_options, /* IO - Number of options */
|
||||||
|
+ cups_option_t **options) /* IO - Options */
|
||||||
|
{
|
||||||
|
http_t *http; /* Connection to printer */
|
||||||
|
ipp_t *request, /* Get-Printer-Attributes request */
|
||||||
|
*response; /* Get-Printer-Attributes response */
|
||||||
|
+ ipp_attribute_t *attr; /* Attribute from response */
|
||||||
|
char resolved[1024], /* Resolved URI */
|
||||||
|
scheme[32], /* URI scheme */
|
||||||
|
userpass[256], /* Username:password */
|
||||||
|
host[256], /* Hostname */
|
||||||
|
resource[256]; /* Resource path */
|
||||||
|
int port; /* Port number */
|
||||||
|
+ static const char * const pattrs[] = /* Attributes to use */
|
||||||
|
+ {
|
||||||
|
+ "all",
|
||||||
|
+ "media-col-database"
|
||||||
|
+ };
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -1198,9 +1207,26 @@ get_printer_ppd(const char *uri, /* I - Printer URI */
|
||||||
|
|
||||||
|
request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
|
||||||
|
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
|
||||||
|
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]), NULL, pattrs);
|
||||||
|
response = cupsDoRequest(http, request, resource);
|
||||||
|
|
||||||
|
- if (!_ppdCreateFromIPP(buffer, bufsize, response))
|
||||||
|
+ if (cupsLastError() >= IPP_STATUS_REDIRECTION_OTHER_SITE)
|
||||||
|
+ {
|
||||||
|
+ _cupsLangPrintf(stderr, _("%s: Unable to query printer: %s"), "lpadmin", cupsLastErrorString());
|
||||||
|
+ buffer[0] = '\0';
|
||||||
|
+ }
|
||||||
|
+ else if (_ppdCreateFromIPP(buffer, bufsize, response))
|
||||||
|
+ {
|
||||||
|
+ if (!cupsGetOption("printer-geo-location", *num_options, *options) && (attr = ippFindAttribute(response, "printer-geo-location", IPP_TAG_URI)) != NULL)
|
||||||
|
+ *num_options = cupsAddOption("printer-geo-location", ippGetString(attr, 0, NULL), *num_options, options);
|
||||||
|
+
|
||||||
|
+ if (!cupsGetOption("printer-info", *num_options, *options) && (attr = ippFindAttribute(response, "printer-info", IPP_TAG_TEXT)) != NULL)
|
||||||
|
+ *num_options = cupsAddOption("printer-info", ippGetString(attr, 0, NULL), *num_options, options);
|
||||||
|
+
|
||||||
|
+ if (!cupsGetOption("printer-location", *num_options, *options) && (attr = ippFindAttribute(response, "printer-location", IPP_TAG_TEXT)) != NULL)
|
||||||
|
+ *num_options = cupsAddOption("printer-location", ippGetString(attr, 0, NULL), *num_options, options);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
_cupsLangPrintf(stderr, _("%s: Unable to create PPD file: %s"), "lpadmin", strerror(errno));
|
||||||
|
|
||||||
|
ippDelete(response);
|
||||||
|
diff --git a/templates/choose-model.tmpl b/templates/choose-model.tmpl
|
||||||
|
index ee9338c..9c9b71f 100644
|
||||||
|
--- a/templates/choose-model.tmpl
|
||||||
|
+++ b/templates/choose-model.tmpl
|
||||||
|
@@ -39,6 +39,7 @@
|
||||||
|
<TD>
|
||||||
|
<SELECT NAME="PPD_NAME" SIZE="10">
|
||||||
|
{op=add-printer?:<OPTION VALUE="__no_change__" SELECTED>Current Driver - {current_make_and_model}</OPTION>:}
|
||||||
|
+{show_ipp_everywhere?<OPTION VALUE="everywhere" SELECTED>{current_make_and_model?{current_make_and_model} -:} IPP Everywhere ™</OPTION>:}
|
||||||
|
{[ppd_name]<OPTION VALUE="{ppd_name}" {op=modify-printer?:{?current_make_and_model={ppd_make_and_model}?SELECTED:}}>{ppd_make_and_model} ({ppd_natural_language})
|
||||||
|
}</SELECT>
|
||||||
|
</TD>
|
||||||
|
diff --git a/templates/de/choose-model.tmpl b/templates/de/choose-model.tmpl
|
||||||
|
index cb9b6f3..c73ccb2 100644
|
||||||
|
--- a/templates/de/choose-model.tmpl
|
||||||
|
+++ b/templates/de/choose-model.tmpl
|
||||||
|
@@ -39,6 +39,7 @@ Drucker {?printer_is_shared=?nicht:{?printer_is_shared=0?nicht:}} im Netzwerk fr
|
||||||
|
<TD>
|
||||||
|
<SELECT NAME="PPD_NAME" SIZE="10">
|
||||||
|
{op=add-printer?:<OPTION VALUE="__no_change__" SELECTED>Aktueller Treiber - {current_make_and_model}</OPTION>:}
|
||||||
|
+{show_ipp_everywhere?<OPTION VALUE="everywhere" SELECTED>{current_make_and_model?{current_make_and_model} -:} IPP Everywhere ™</OPTION>:}
|
||||||
|
{[ppd_name]<OPTION VALUE="{ppd_name}" {op=modify-printer?:{?current_make_and_model={ppd_make_and_model}?SELECTED:}}>{ppd_make_and_model} ({ppd_natural_language})
|
||||||
|
}</SELECT>
|
||||||
|
</TD>
|
||||||
|
diff --git a/templates/es/choose-model.tmpl b/templates/es/choose-model.tmpl
|
||||||
|
index 8a5a4ba..b5624f2 100644
|
||||||
|
--- a/templates/es/choose-model.tmpl
|
||||||
|
+++ b/templates/es/choose-model.tmpl
|
||||||
|
@@ -39,6 +39,7 @@
|
||||||
|
<TD>
|
||||||
|
<SELECT NAME="PPD_NAME" SIZE="10">
|
||||||
|
{op=add-printer?:<OPTION VALUE="__no_change__" SELECTED>Controlador actual - {current_make_and_model}</OPTION>:}
|
||||||
|
+{show_ipp_everywhere?<OPTION VALUE="everywhere" SELECTED>{current_make_and_model?{current_make_and_model} -:} IPP Everywhere ™</OPTION>:}
|
||||||
|
{[ppd_name]<OPTION VALUE="{ppd_name}" {op=modify-printer?:{?current_make_and_model={ppd_make_and_model}?SELECTED:}}>{ppd_make_and_model} ({ppd_natural_language})
|
||||||
|
}</SELECT>
|
||||||
|
</TD>
|
||||||
|
diff --git a/templates/fr/choose-model.tmpl b/templates/fr/choose-model.tmpl
|
||||||
|
index a4e771c..07cf93c 100644
|
||||||
|
--- a/templates/fr/choose-model.tmpl
|
||||||
|
+++ b/templates/fr/choose-model.tmpl
|
||||||
|
@@ -39,6 +39,7 @@
|
||||||
|
<TD>
|
||||||
|
<SELECT NAME="PPD_NAME" SIZE="10">
|
||||||
|
{op=add-printer?:<OPTION VALUE="__no_change__" SELECTED>Pilote courant - {current_make_and_model}</OPTION>:}
|
||||||
|
+{show_ipp_everywhere?<OPTION VALUE="everywhere" SELECTED>{current_make_and_model?{current_make_and_model} -:} IPP Everywhere ™</OPTION>:}
|
||||||
|
{[ppd_name]<OPTION VALUE="{ppd_name}" {op=modify-printer?:{?current_make_and_model={ppd_make_and_model}?SELECTED:}}>{ppd_make_and_model} ({ppd_natural_language})
|
||||||
|
}</SELECT>
|
||||||
|
</TD>
|
||||||
|
diff --git a/templates/ja/choose-model.tmpl b/templates/ja/choose-model.tmpl
|
||||||
|
index daf1375..6a6e4e4 100644
|
||||||
|
--- a/templates/ja/choose-model.tmpl
|
||||||
|
+++ b/templates/ja/choose-model.tmpl
|
||||||
|
@@ -39,6 +39,7 @@
|
||||||
|
<TD>
|
||||||
|
<SELECT NAME="PPD_NAME" SIZE="10">
|
||||||
|
{op=add-printer?:<OPTION VALUE="__no_change__" SELECTED>現在のドライバー - {current_make_and_model}</OPTION>:}
|
||||||
|
+{show_ipp_everywhere?<OPTION VALUE="everywhere" SELECTED>{current_make_and_model?{current_make_and_model} -:} IPP Everywhere ™</OPTION>:}
|
||||||
|
{[ppd_name]<OPTION VALUE="{ppd_name}" {op=modify-printer?:{?current_make_and_model={ppd_make_and_model}?SELECTED:}}>{ppd_make_and_model} ({ppd_natural_language})
|
||||||
|
}</SELECT>
|
||||||
|
</TD>
|
||||||
|
diff --git a/templates/pt_BR/choose-model.tmpl b/templates/pt_BR/choose-model.tmpl
|
||||||
|
index 55d8bd8..0ed6a3c 100644
|
||||||
|
--- a/templates/pt_BR/choose-model.tmpl
|
||||||
|
+++ b/templates/pt_BR/choose-model.tmpl
|
||||||
|
@@ -39,6 +39,7 @@
|
||||||
|
<TD>
|
||||||
|
<SELECT NAME="PPD_NAME" SIZE="10">
|
||||||
|
{op=add-printer?:<OPTION VALUE="__no_change__" SELECTED>Driver atual - {current_make_and_model}</OPTION>:}
|
||||||
|
+{show_ipp_everywhere?<OPTION VALUE="everywhere" SELECTED>{current_make_and_model?{current_make_and_model} -:} IPP Everywhere ™</OPTION>:}
|
||||||
|
{[ppd_name]<OPTION VALUE="{ppd_name}" {op=modify-printer?:{?current_make_and_model={ppd_make_and_model}?SELECTED:}}>{ppd_make_and_model} ({ppd_natural_language})
|
||||||
|
}</SELECT>
|
||||||
|
</TD>
|
||||||
|
diff --git a/templates/ru/choose-model.tmpl b/templates/ru/choose-model.tmpl
|
||||||
|
index 2f0d6d9..dedbd49 100644
|
||||||
|
--- a/templates/ru/choose-model.tmpl
|
||||||
|
+++ b/templates/ru/choose-model.tmpl
|
||||||
|
@@ -39,6 +39,7 @@
|
||||||
|
<TD>
|
||||||
|
<SELECT NAME="PPD_NAME" SIZE="10">
|
||||||
|
{op=add-printer?:<OPTION VALUE="__no_change__" SELECTED>Текущий драйвер - {current_make_and_model}</OPTION>:}
|
||||||
|
+{show_ipp_everywhere?<OPTION VALUE="everywhere" SELECTED>{current_make_and_model?{current_make_and_model} -:} IPP Everywhere ™</OPTION>:}
|
||||||
|
{[ppd_name]<OPTION VALUE="{ppd_name}" {op=modify-printer?:{?current_make_and_model={ppd_make_and_model}?SELECTED:}}>{ppd_make_and_model} ({ppd_natural_language})
|
||||||
|
}</SELECT>
|
||||||
|
</TD>
|
@ -0,0 +1,23 @@
|
|||||||
|
diff --git a/backend/ipp.c b/backend/ipp.c
|
||||||
|
index f8bf7e1..8440d2f 100644
|
||||||
|
--- a/backend/ipp.c
|
||||||
|
+++ b/backend/ipp.c
|
||||||
|
@@ -422,8 +422,7 @@ main(int argc, /* I - Number of command-line args */
|
||||||
|
* that way.
|
||||||
|
*/
|
||||||
|
|
||||||
|
- if (!getuid() && (value = getenv("AUTH_UID")) != NULL &&
|
||||||
|
- !getenv("AUTH_PASSWORD"))
|
||||||
|
+ if (!getuid() && (value = getenv("AUTH_UID")) != NULL)
|
||||||
|
{
|
||||||
|
uid_t uid = (uid_t)atoi(value);
|
||||||
|
/* User ID */
|
||||||
|
@@ -457,7 +456,7 @@ main(int argc, /* I - Number of command-line args */
|
||||||
|
|
||||||
|
# else /* No XPC, just try to run as the user ID */
|
||||||
|
if (uid > 0)
|
||||||
|
- seteuid(uid);
|
||||||
|
+ setuid(uid);
|
||||||
|
# endif /* HAVE_XPC */
|
||||||
|
}
|
||||||
|
#endif /* HAVE_GSSAPI */
|
@ -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);
|
@ -0,0 +1,100 @@
|
|||||||
|
diff --git a/scheduler/log.c b/scheduler/log.c
|
||||||
|
index 33cdac6..d66bbf9 100644
|
||||||
|
--- a/scheduler/log.c
|
||||||
|
+++ b/scheduler/log.c
|
||||||
|
@@ -597,51 +597,6 @@ cupsdLogJob(cupsd_job_t *job, /* I - Job */
|
||||||
|
if (level > LogLevel && LogDebugHistory <= 0)
|
||||||
|
return (1);
|
||||||
|
|
||||||
|
-#ifdef HAVE_SYSTEMD_SD_JOURNAL_H
|
||||||
|
- if (!strcmp(ErrorLog, "syslog"))
|
||||||
|
- {
|
||||||
|
- cupsd_printer_t *printer = job ? (job->printer ? job->printer : (job->dest ? cupsdFindDest(job->dest) : NULL)) : NULL;
|
||||||
|
- static const char * const job_states[] =
|
||||||
|
- { /* job-state strings */
|
||||||
|
- "Pending",
|
||||||
|
- "PendingHeld",
|
||||||
|
- "Processing",
|
||||||
|
- "ProcessingStopped",
|
||||||
|
- "Canceled",
|
||||||
|
- "Aborted",
|
||||||
|
- "Completed"
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- va_start(ap, message);
|
||||||
|
-
|
||||||
|
- do
|
||||||
|
- {
|
||||||
|
- va_copy(ap2, ap);
|
||||||
|
- status = format_log_line(message, ap2);
|
||||||
|
- va_end(ap2);
|
||||||
|
- }
|
||||||
|
- while (status == 0);
|
||||||
|
-
|
||||||
|
- va_end(ap);
|
||||||
|
-
|
||||||
|
- if (job)
|
||||||
|
- sd_journal_send("MESSAGE=%s", log_line,
|
||||||
|
- "PRIORITY=%i", log_levels[level],
|
||||||
|
- PWG_Event"=JobStateChanged",
|
||||||
|
- PWG_ServiceURI"=%s", printer ? printer->uri : "",
|
||||||
|
- PWG_JobID"=%d", job->id,
|
||||||
|
- PWG_JobState"=%s", job->state_value < IPP_JSTATE_PENDING ? "" : job_states[job->state_value - IPP_JSTATE_PENDING],
|
||||||
|
- PWG_JobImpressionsCompleted"=%d", ippGetInteger(job->impressions, 0),
|
||||||
|
- NULL);
|
||||||
|
- else
|
||||||
|
- sd_journal_send("MESSAGE=%s", log_line,
|
||||||
|
- "PRIORITY=%i", log_levels[level],
|
||||||
|
- NULL);
|
||||||
|
-
|
||||||
|
- return (1);
|
||||||
|
- }
|
||||||
|
-#endif /* HAVE_SYSTEMD_SD_JOURNAL_H */
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
* Format and write the log message...
|
||||||
|
*/
|
||||||
|
@@ -705,7 +660,43 @@ cupsdLogJob(cupsd_job_t *job, /* I - Job */
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
else if (level <= LogLevel)
|
||||||
|
+ {
|
||||||
|
+#ifdef HAVE_SYSTEMD_SD_JOURNAL_H
|
||||||
|
+ if (!strcmp(ErrorLog, "syslog"))
|
||||||
|
+ {
|
||||||
|
+ cupsd_printer_t *printer = job ? (job->printer ? job->printer : (job->dest ? cupsdFindDest(job->dest) : NULL)) : NULL;
|
||||||
|
+ static const char * const job_states[] =
|
||||||
|
+ { /* job-state strings */
|
||||||
|
+ "Pending",
|
||||||
|
+ "PendingHeld",
|
||||||
|
+ "Processing",
|
||||||
|
+ "ProcessingStopped",
|
||||||
|
+ "Canceled",
|
||||||
|
+ "Aborted",
|
||||||
|
+ "Completed"
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ if (job)
|
||||||
|
+ sd_journal_send("MESSAGE=%s", log_line,
|
||||||
|
+ "PRIORITY=%i", log_levels[level],
|
||||||
|
+ PWG_Event"=JobStateChanged",
|
||||||
|
+ PWG_ServiceURI"=%s", printer ? printer->uri : "",
|
||||||
|
+ PWG_JobID"=%d", job->id,
|
||||||
|
+ PWG_JobState"=%s", job->state_value < IPP_JSTATE_PENDING ? "" : job_states[job->state_value - IPP_JSTATE_PENDING],
|
||||||
|
+ PWG_JobImpressionsCompleted"=%d", ippGetInteger(job->impressions, 0),
|
||||||
|
+ NULL);
|
||||||
|
+ else
|
||||||
|
+ sd_journal_send("MESSAGE=%s", log_line,
|
||||||
|
+ "PRIORITY=%i", log_levels[level],
|
||||||
|
+ NULL);
|
||||||
|
+
|
||||||
|
+ return (1);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+#endif /* HAVE_SYSTEMD_SD_JOURNAL_H */
|
||||||
|
+
|
||||||
|
return (cupsdWriteErrorLog(level, log_line));
|
||||||
|
+ }
|
||||||
|
else
|
||||||
|
return (1);
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
diff -up cups-2.2b2/berkeley/lpr.c.lpr-help cups-2.2b2/berkeley/lpr.c
|
||||||
|
--- cups-2.2b2/berkeley/lpr.c.lpr-help 2016-06-24 17:43:35.000000000 +0200
|
||||||
|
+++ cups-2.2b2/berkeley/lpr.c 2016-06-27 15:11:30.646348752 +0200
|
||||||
|
@@ -18,6 +18,31 @@
|
||||||
|
#include <cups/cups-private.h>
|
||||||
|
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+usage (const char *name)
|
||||||
|
+{
|
||||||
|
+ _cupsLangPrintf(stdout,
|
||||||
|
+"Usage: %s [OPTION] [ file(s) ]\n"
|
||||||
|
+"Print files.\n\n"
|
||||||
|
+" -E force encryption\n"
|
||||||
|
+" -H server[:port] specify alternate server\n"
|
||||||
|
+" -C title, -J title, -T title\n"
|
||||||
|
+" set the job name\n\n"
|
||||||
|
+" -P destination/instance print to named printer\n"
|
||||||
|
+" -U username specify alternate username\n"
|
||||||
|
+" -# num-copies set number of copies\n"
|
||||||
|
+" -h disable banner printing\n"
|
||||||
|
+" -l print without filtering\n"
|
||||||
|
+" -m send email on completion\n"
|
||||||
|
+" -o option[=value] set a job option\n"
|
||||||
|
+" -p format text file with header\n"
|
||||||
|
+" -q hold job for printing\n"
|
||||||
|
+" -r delete files after printing\n"
|
||||||
|
+"\nWith no file given, read standard input.\n"
|
||||||
|
+, name);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* 'main()' - Parse options and send files for printing.
|
||||||
|
*/
|
||||||
|
@@ -281,6 +306,12 @@ main(int argc, /* I - Number of comm
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
+ if (!strcmp (argv[i], "--help"))
|
||||||
|
+ {
|
||||||
|
+ usage (argv[0]);
|
||||||
|
+ return (0);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
_cupsLangPrintf(stderr, _("%s: Error - unknown option \"%c\"."), argv[0], *opt);
|
||||||
|
return (1);
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,16 @@
|
|||||||
|
diff -up cups-1.5b1/cups-config.in.multilib cups-1.5b1/cups-config.in
|
||||||
|
--- cups-1.5b1/cups-config.in.multilib 2010-06-16 02:48:25.000000000 +0200
|
||||||
|
+++ cups-1.5b1/cups-config.in 2011-05-23 17:33:31.000000000 +0200
|
||||||
|
@@ -22,8 +22,10 @@ prefix=@prefix@
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
bindir=@bindir@
|
||||||
|
includedir=@includedir@
|
||||||
|
-libdir=@libdir@
|
||||||
|
-imagelibdir=@libdir@
|
||||||
|
+# Fetch libdir from gnutls's pkg-config script. This is a bit
|
||||||
|
+# of a cheat, but the cups-devel package requires gnutls-devel anyway.
|
||||||
|
+libdir=`pkg-config --variable=libdir gnutls`
|
||||||
|
+imagelibdir=`pkg-config --variable=libdir gnutls`
|
||||||
|
datarootdir=@datadir@
|
||||||
|
datadir=@datadir@
|
||||||
|
sysconfdir=@sysconfdir@
|
@ -0,0 +1,10 @@
|
|||||||
|
diff -up cups-2.2b2/config-scripts/cups-ssl.m4.no-export-ssllibs cups-2.2b2/config-scripts/cups-ssl.m4
|
||||||
|
--- cups-2.2b2/config-scripts/cups-ssl.m4.no-export-ssllibs 2016-06-27 15:06:22.299980753 +0200
|
||||||
|
+++ cups-2.2b2/config-scripts/cups-ssl.m4 2016-06-27 15:08:00.953154042 +0200
|
||||||
|
@@ -102,5 +102,5 @@ AC_SUBST(IPPALIASES)
|
||||||
|
AC_SUBST(SSLFLAGS)
|
||||||
|
AC_SUBST(SSLLIBS)
|
||||||
|
|
||||||
|
-EXPORT_SSLLIBS="$SSLLIBS"
|
||||||
|
+EXPORT_SSLLIBS=""
|
||||||
|
AC_SUBST(EXPORT_SSLLIBS)
|
@ -0,0 +1,18 @@
|
|||||||
|
diff -up cups-2.2.4/config-scripts/cups-manpages.m4.no-gzip-man cups-2.2.4/config-scripts/cups-manpages.m4
|
||||||
|
--- cups-2.2.4/config-scripts/cups-manpages.m4.no-gzip-man 2017-06-30 20:37:09.470034273 +0200
|
||||||
|
+++ cups-2.2.4/config-scripts/cups-manpages.m4 2017-06-30 20:39:15.982884832 +0200
|
||||||
|
@@ -53,10 +53,10 @@ case "$host_os_name" in
|
||||||
|
;;
|
||||||
|
linux* | gnu* | darwin*)
|
||||||
|
# Linux, GNU Hurd, and macOS
|
||||||
|
- MAN1EXT=1.gz
|
||||||
|
- MAN5EXT=5.gz
|
||||||
|
- MAN7EXT=7.gz
|
||||||
|
- MAN8EXT=8.gz
|
||||||
|
+ MAN1EXT=1
|
||||||
|
+ MAN5EXT=5
|
||||||
|
+ MAN7EXT=7
|
||||||
|
+ MAN8EXT=8
|
||||||
|
MAN8DIR=8
|
||||||
|
;;
|
||||||
|
*)
|
@ -0,0 +1,11 @@
|
|||||||
|
diff -up cups-1.5b1/scheduler/auth.c.peercred cups-1.5b1/scheduler/auth.c
|
||||||
|
--- cups-1.5b1/scheduler/auth.c.peercred 2011-05-20 05:49:49.000000000 +0200
|
||||||
|
+++ cups-1.5b1/scheduler/auth.c 2011-05-23 18:00:18.000000000 +0200
|
||||||
|
@@ -52,6 +52,7 @@
|
||||||
|
* Include necessary headers...
|
||||||
|
*/
|
||||||
|
|
||||||
|
+#define _GNU_SOURCE
|
||||||
|
#include "cupsd.h"
|
||||||
|
#include <grp.h>
|
||||||
|
#ifdef HAVE_SHADOW_H
|
@ -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)
|
||||||
|
{
|
@ -0,0 +1,42 @@
|
|||||||
|
diff --git a/cups/ppd.c b/cups/ppd.c
|
||||||
|
index ff52df2e..199cf034 100644
|
||||||
|
--- a/cups/ppd.c
|
||||||
|
+++ b/cups/ppd.c
|
||||||
|
@@ -1719,8 +1719,7 @@ _ppdOpen(
|
||||||
|
constraint->choice1, constraint->option2,
|
||||||
|
constraint->choice2))
|
||||||
|
{
|
||||||
|
- case 0 : /* Error */
|
||||||
|
- case 1 : /* Error */
|
||||||
|
+ default : /* Error */
|
||||||
|
pg->ppd_status = PPD_BAD_UI_CONSTRAINTS;
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
diff --git a/ppdc/ppdc-source.cxx b/ppdc/ppdc-source.cxx
|
||||||
|
index c25d4966..236c00db 100644
|
||||||
|
--- a/ppdc/ppdc-source.cxx
|
||||||
|
+++ b/ppdc/ppdc-source.cxx
|
||||||
|
@@ -1743,15 +1743,17 @@ ppdcSource::get_resolution(ppdcFile *fp)// I - File to read
|
||||||
|
|
||||||
|
switch (sscanf(name, "%dx%d", &xdpi, &ydpi))
|
||||||
|
{
|
||||||
|
- case 0 :
|
||||||
|
- _cupsLangPrintf(stderr,
|
||||||
|
- _("ppdc: Bad resolution name \"%s\" on line %d of "
|
||||||
|
- "%s."), name, fp->line, fp->filename);
|
||||||
|
- break;
|
||||||
|
case 1 :
|
||||||
|
ydpi = xdpi;
|
||||||
|
break;
|
||||||
|
- }
|
||||||
|
+ case 2 :
|
||||||
|
+ break;
|
||||||
|
+ default :
|
||||||
|
+ _cupsLangPrintf(stderr,
|
||||||
|
+ _("ppdc: Bad resolution name \"%s\" on line %d of "
|
||||||
|
+ "%s."), name, fp->line, fp->filename);
|
||||||
|
+ break;
|
||||||
|
+}
|
||||||
|
|
||||||
|
// Create the necessary PS commands...
|
||||||
|
snprintf(command, sizeof(command),
|
@ -0,0 +1,31 @@
|
|||||||
|
diff --git a/scheduler/colorman.c b/scheduler/colorman.c
|
||||||
|
index 8af4e5c..9bfdb0c 100644
|
||||||
|
--- a/scheduler/colorman.c
|
||||||
|
+++ b/scheduler/colorman.c
|
||||||
|
@@ -1083,7 +1083,7 @@ colord_create_profile(
|
||||||
|
|
||||||
|
dbus_message_iter_get_basic(&args, &profile_path);
|
||||||
|
cupsdLogMessage(CUPSD_LOG_DEBUG, "Created profile \"%s\".", profile_path);
|
||||||
|
- cupsArrayAdd(profiles, strdup(profile_path));
|
||||||
|
+ cupsArrayAdd(profiles, profile_path);
|
||||||
|
|
||||||
|
out:
|
||||||
|
|
||||||
|
diff --git a/scheduler/job.c b/scheduler/job.c
|
||||||
|
index 0223bee..47d4c72 100644
|
||||||
|
--- a/scheduler/job.c
|
||||||
|
+++ b/scheduler/job.c
|
||||||
|
@@ -1496,11 +1496,11 @@ cupsdDeleteJob(cupsd_job_t *job, /* I - Job */
|
||||||
|
job->num_files = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ unload_job(job);
|
||||||
|
+
|
||||||
|
if (job->history)
|
||||||
|
free_job_history(job);
|
||||||
|
|
||||||
|
- unload_job(job);
|
||||||
|
-
|
||||||
|
cupsArrayRemove(Jobs, job);
|
||||||
|
cupsArrayRemove(ActiveJobs, job);
|
||||||
|
cupsArrayRemove(PrintingJobs, job);
|
@ -0,0 +1,13 @@
|
|||||||
|
diff --git a/filter/rastertoepson.c b/filter/rastertoepson.c
|
||||||
|
index 4efe669..e8fe0c6 100644
|
||||||
|
--- a/filter/rastertoepson.c
|
||||||
|
+++ b/filter/rastertoepson.c
|
||||||
|
@@ -307,7 +307,7 @@ StartPage(
|
||||||
|
|
||||||
|
if (DotBytes)
|
||||||
|
{
|
||||||
|
- if ((LineBuffers[0] = calloc((size_t)DotBytes, header->cupsWidth * (size_t)(Shingling + 1))) == NULL)
|
||||||
|
+ if ((LineBuffers[0] = calloc((size_t)DotBytes, (header->cupsWidth + 7) * (size_t)(Shingling + 1))) == NULL)
|
||||||
|
{
|
||||||
|
fputs("ERROR: Unable to allocate memory\n", stderr);
|
||||||
|
exit(1);
|
@ -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);
|
@ -0,0 +1,20 @@
|
|||||||
|
diff --git a/scheduler/ipp.c b/scheduler/ipp.c
|
||||||
|
index e0dbc4a..5e9a985 100644
|
||||||
|
--- a/scheduler/ipp.c
|
||||||
|
+++ b/scheduler/ipp.c
|
||||||
|
@@ -9891,11 +9891,10 @@ restart_job(cupsd_client_t *con, /* I - Client connection */
|
||||||
|
cupsdLogJob(job, CUPSD_LOG_DEBUG,
|
||||||
|
"Restarted by \"%s\" with job-hold-until=%s.",
|
||||||
|
username, attr->values[0].string.text);
|
||||||
|
- cupsdSetJobHoldUntil(job, attr->values[0].string.text, 0);
|
||||||
|
-
|
||||||
|
- cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED | CUPSD_EVENT_JOB_STATE,
|
||||||
|
- NULL, job, "Job restarted by user with job-hold-until=%s",
|
||||||
|
- attr->values[0].string.text);
|
||||||
|
+ cupsdSetJobHoldUntil(job, attr->values[0].string.text, 1);
|
||||||
|
+ cupsdSetJobState(job, IPP_JOB_HELD, CUPSD_JOB_DEFAULT,
|
||||||
|
+ "Job restarted by user with job-hold-until=%s",
|
||||||
|
+ attr->values[0].string.text);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
@ -0,0 +1,52 @@
|
|||||||
|
diff --git a/doc/help/man-cupsd.conf.html b/doc/help/man-cupsd.conf.html
|
||||||
|
index 9082348..8ab1ce8 100644
|
||||||
|
--- a/doc/help/man-cupsd.conf.html
|
||||||
|
+++ b/doc/help/man-cupsd.conf.html
|
||||||
|
@@ -90,7 +90,7 @@ The default value is "30".
|
||||||
|
<dd style="margin-left: 5.0em">Specifies that a failed print job should be aborted (discarded) unless otherwise specified for the printer.
|
||||||
|
<dt><b>ErrorPolicy retry-job</b>
|
||||||
|
<dd style="margin-left: 5.0em">Specifies that a failed print job should be retried at a later time unless otherwise specified for the printer.
|
||||||
|
-<dt><b>ErrorPolicy retry-this-job</b>
|
||||||
|
+<dt><b>ErrorPolicy retry-current-job</b>
|
||||||
|
<dd style="margin-left: 5.0em">Specifies that a failed print job should be retried immediately unless otherwise specified for the printer.
|
||||||
|
<dt><b>ErrorPolicy stop-printer</b>
|
||||||
|
<dd style="margin-left: 5.0em">Specifies that a failed print job should stop the printer unless otherwise specified for the printer. The 'stop-printer' error policy is the default.
|
||||||
|
diff --git a/man/cupsd.conf.man.in b/man/cupsd.conf.man.in
|
||||||
|
index 53a028d..ba12b07 100644
|
||||||
|
--- a/man/cupsd.conf.man.in
|
||||||
|
+++ b/man/cupsd.conf.man.in
|
||||||
|
@@ -135,7 +135,7 @@ Specifies that a failed print job should be aborted (discarded) unless otherwise
|
||||||
|
\fBErrorPolicy retry-job\fR
|
||||||
|
Specifies that a failed print job should be retried at a later time unless otherwise specified for the printer.
|
||||||
|
.TP 5
|
||||||
|
-\fBErrorPolicy retry-this-job\fR
|
||||||
|
+\fBErrorPolicy retry-current-job\fR
|
||||||
|
Specifies that a failed print job should be retried immediately unless otherwise specified for the printer.
|
||||||
|
.TP 5
|
||||||
|
\fBErrorPolicy stop-printer\fR
|
||||||
|
diff --git a/man/cupsd.conf.man.in.privilege-escalation b/man/cupsd.conf.man.in.privilege-escalation
|
||||||
|
index ab89e15..130ea8a 100644
|
||||||
|
--- a/man/cupsd.conf.man.in.privilege-escalation
|
||||||
|
+++ b/man/cupsd.conf.man.in.privilege-escalation
|
||||||
|
@@ -135,7 +135,7 @@ Specifies that a failed print job should be aborted (discarded) unless otherwise
|
||||||
|
\fBErrorPolicy retry-job\fR
|
||||||
|
Specifies that a failed print job should be retried at a later time unless otherwise specified for the printer.
|
||||||
|
.TP 5
|
||||||
|
-\fBErrorPolicy retry-this-job\fR
|
||||||
|
+\fBErrorPolicy retry-current-job\fR
|
||||||
|
Specifies that a failed print job should be retried immediately unless otherwise specified for the printer.
|
||||||
|
.TP 5
|
||||||
|
\fBErrorPolicy stop-printer\fR
|
||||||
|
diff --git a/man/cupsd.conf.man.in.remove-weak-ciphers b/man/cupsd.conf.man.in.remove-weak-ciphers
|
||||||
|
index 5516780..35065ca 100644
|
||||||
|
--- a/man/cupsd.conf.man.in.remove-weak-ciphers
|
||||||
|
+++ b/man/cupsd.conf.man.in.remove-weak-ciphers
|
||||||
|
@@ -135,7 +135,7 @@ Specifies that a failed print job should be aborted (discarded) unless otherwise
|
||||||
|
\fBErrorPolicy retry-job\fR
|
||||||
|
Specifies that a failed print job should be retried at a later time unless otherwise specified for the printer.
|
||||||
|
.TP 5
|
||||||
|
-\fBErrorPolicy retry-this-job\fR
|
||||||
|
+\fBErrorPolicy retry-current-job\fR
|
||||||
|
Specifies that a failed print job should be retried immediately unless otherwise specified for the printer.
|
||||||
|
.TP 5
|
||||||
|
\fBErrorPolicy stop-printer\fR
|
@ -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,
|
@ -0,0 +1,193 @@
|
|||||||
|
diff -up cups-2.2rc1/scheduler/conf.c.serverbin-compat cups-2.2rc1/scheduler/conf.c
|
||||||
|
--- cups-2.2rc1/scheduler/conf.c.serverbin-compat 2016-08-08 20:06:00.000000000 +0200
|
||||||
|
+++ cups-2.2rc1/scheduler/conf.c 2016-08-09 09:58:21.324033645 +0200
|
||||||
|
@@ -609,6 +609,9 @@ cupsdReadConfiguration(void)
|
||||||
|
cupsdClearString(&ServerName);
|
||||||
|
cupsdClearString(&ServerAdmin);
|
||||||
|
cupsdSetString(&ServerBin, CUPS_SERVERBIN);
|
||||||
|
+#ifdef __x86_64__
|
||||||
|
+ cupsdSetString(&ServerBin_compat, "/usr/lib64/cups");
|
||||||
|
+#endif /* __x86_64__ */
|
||||||
|
cupsdSetString(&RequestRoot, CUPS_REQUESTS);
|
||||||
|
cupsdSetString(&CacheDir, CUPS_CACHEDIR);
|
||||||
|
cupsdSetString(&DataDir, CUPS_DATADIR);
|
||||||
|
@@ -1604,7 +1607,12 @@ cupsdReadConfiguration(void)
|
||||||
|
* Read the MIME type and conversion database...
|
||||||
|
*/
|
||||||
|
|
||||||
|
+#ifdef __x86_64__
|
||||||
|
+ snprintf(temp, sizeof(temp), "%s/filter:%s/filter", ServerBin,
|
||||||
|
+ ServerBin_compat);
|
||||||
|
+#else
|
||||||
|
snprintf(temp, sizeof(temp), "%s/filter", ServerBin);
|
||||||
|
+#endif
|
||||||
|
snprintf(mimedir, sizeof(mimedir), "%s/mime", DataDir);
|
||||||
|
|
||||||
|
MimeDatabase = mimeNew();
|
||||||
|
diff -up cups-2.2rc1/scheduler/conf.h.serverbin-compat cups-2.2rc1/scheduler/conf.h
|
||||||
|
--- cups-2.2rc1/scheduler/conf.h.serverbin-compat 2016-08-08 20:06:00.000000000 +0200
|
||||||
|
+++ cups-2.2rc1/scheduler/conf.h 2016-08-09 09:58:21.325033636 +0200
|
||||||
|
@@ -106,6 +106,10 @@ VAR char *ConfigurationFile VALUE(NULL)
|
||||||
|
/* Root directory for scheduler */
|
||||||
|
*ServerBin VALUE(NULL),
|
||||||
|
/* Root directory for binaries */
|
||||||
|
+#ifdef __x86_64__
|
||||||
|
+ *ServerBin_compat VALUE(NULL),
|
||||||
|
+ /* Compat directory for binaries */
|
||||||
|
+#endif /* __x86_64__ */
|
||||||
|
*StateDir VALUE(NULL),
|
||||||
|
/* Root directory for state data */
|
||||||
|
*RequestRoot VALUE(NULL),
|
||||||
|
diff -up cups-2.2rc1/scheduler/env.c.serverbin-compat cups-2.2rc1/scheduler/env.c
|
||||||
|
--- cups-2.2rc1/scheduler/env.c.serverbin-compat 2016-08-08 20:06:00.000000000 +0200
|
||||||
|
+++ cups-2.2rc1/scheduler/env.c 2016-08-09 09:58:21.325033636 +0200
|
||||||
|
@@ -212,8 +212,13 @@ cupsdUpdateEnv(void)
|
||||||
|
set_if_undefined("LD_PRELOAD", NULL);
|
||||||
|
set_if_undefined("NLSPATH", NULL);
|
||||||
|
if (find_env("PATH") < 0)
|
||||||
|
+#ifdef __x86_64__
|
||||||
|
+ cupsdSetEnvf("PATH", "%s/filter:%s/filter:" CUPS_BINDIR ":" CUPS_SBINDIR
|
||||||
|
+ ":/bin:/usr/bin", ServerBin, ServerBin_compat);
|
||||||
|
+#else /* ! defined(__x86_64__) */
|
||||||
|
cupsdSetEnvf("PATH", "%s/filter:" CUPS_BINDIR ":" CUPS_SBINDIR
|
||||||
|
":/bin:/usr/bin", ServerBin);
|
||||||
|
+#endif
|
||||||
|
set_if_undefined("SERVER_ADMIN", ServerAdmin);
|
||||||
|
set_if_undefined("SHLIB_PATH", NULL);
|
||||||
|
set_if_undefined("SOFTWARE", CUPS_MINIMAL);
|
||||||
|
diff -up cups-2.2rc1/scheduler/ipp.c.serverbin-compat cups-2.2rc1/scheduler/ipp.c
|
||||||
|
--- cups-2.2rc1/scheduler/ipp.c.serverbin-compat 2016-08-09 09:58:21.326033626 +0200
|
||||||
|
+++ cups-2.2rc1/scheduler/ipp.c 2016-08-09 10:10:16.266127629 +0200
|
||||||
|
@@ -2419,12 +2419,21 @@ add_printer(cupsd_client_t *con, /* I -
|
||||||
|
* Could not find device in list!
|
||||||
|
*/
|
||||||
|
|
||||||
|
+#ifdef __x86_64__
|
||||||
|
+ snprintf(srcfile, sizeof(srcfile), "%s/backend/%s", ServerBin_compat,
|
||||||
|
+ scheme);
|
||||||
|
+ if (access(srcfile, X_OK))
|
||||||
|
+ {
|
||||||
|
+#endif /* __x86_64__ */
|
||||||
|
send_ipp_status(con, IPP_NOT_POSSIBLE,
|
||||||
|
_("Bad device-uri scheme \"%s\"."), scheme);
|
||||||
|
if (!modify)
|
||||||
|
cupsdDeletePrinter(printer, 0);
|
||||||
|
|
||||||
|
return;
|
||||||
|
+#ifdef __x86_64__
|
||||||
|
+ }
|
||||||
|
+#endif /* __x86_64__ */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff -up cups-2.2rc1/scheduler/job.c.serverbin-compat cups-2.2rc1/scheduler/job.c
|
||||||
|
--- cups-2.2rc1/scheduler/job.c.serverbin-compat 2016-08-08 20:06:00.000000000 +0200
|
||||||
|
+++ cups-2.2rc1/scheduler/job.c 2016-08-09 09:58:21.327033616 +0200
|
||||||
|
@@ -1126,8 +1126,32 @@ cupsdContinueJob(cupsd_job_t *job) /* I
|
||||||
|
i ++, filter = (mime_filter_t *)cupsArrayNext(filters))
|
||||||
|
{
|
||||||
|
if (filter->filter[0] != '/')
|
||||||
|
- snprintf(command, sizeof(command), "%s/filter/%s", ServerBin,
|
||||||
|
- filter->filter);
|
||||||
|
+ {
|
||||||
|
+ snprintf(command, sizeof(command), "%s/filter/%s", ServerBin,
|
||||||
|
+ filter->filter);
|
||||||
|
+#ifdef __x86_64__
|
||||||
|
+ if (access(command, F_OK))
|
||||||
|
+ {
|
||||||
|
+ snprintf(command, sizeof(command), "%s/filter/%s",
|
||||||
|
+ ServerBin_compat, filter->filter);
|
||||||
|
+ if (!access(command, F_OK))
|
||||||
|
+ {
|
||||||
|
+ /* Not in the correct directory, but found it in the compat
|
||||||
|
+ * directory. Issue a warning. */
|
||||||
|
+ cupsdLogMessage(CUPSD_LOG_INFO,
|
||||||
|
+ "Filter '%s' not in %s/filter!",
|
||||||
|
+ filter->filter, ServerBin);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ /* Not in the compat directory either; make any error
|
||||||
|
+ * messages use the correct directory name then. */
|
||||||
|
+ snprintf(command, sizeof(command), "%s/filter/%s", ServerBin,
|
||||||
|
+ filter->filter);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+#endif /* __x86_64__ */
|
||||||
|
+ }
|
||||||
|
else
|
||||||
|
strlcpy(command, filter->filter, sizeof(command));
|
||||||
|
|
||||||
|
@@ -1283,6 +1307,28 @@ cupsdContinueJob(cupsd_job_t *job) /* I
|
||||||
|
{
|
||||||
|
cupsdClosePipe(job->back_pipes);
|
||||||
|
cupsdClosePipe(job->side_pipes);
|
||||||
|
+#ifdef __x86_64__
|
||||||
|
+ if (access(command, F_OK))
|
||||||
|
+ {
|
||||||
|
+ snprintf(command, sizeof(command), "%s/backend/%s", ServerBin_compat,
|
||||||
|
+ scheme);
|
||||||
|
+ if (!access(command, F_OK))
|
||||||
|
+ {
|
||||||
|
+ /* Not in the correct directory, but we found it in the compat
|
||||||
|
+ * directory. Issue a warning. */
|
||||||
|
+ cupsdLogMessage(CUPSD_LOG_INFO,
|
||||||
|
+ "Backend '%s' not in %s/backend!", scheme,
|
||||||
|
+ ServerBin);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ /* Not in the compat directory either; make any error
|
||||||
|
+ messages use the correct directory name then. */
|
||||||
|
+ snprintf(command, sizeof(command), "%s/backend/%s", ServerBin,
|
||||||
|
+ scheme);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+#endif /* __x86_64__ */
|
||||||
|
|
||||||
|
close(job->status_pipes[1]);
|
||||||
|
job->status_pipes[1] = -1;
|
||||||
|
diff -up cups-2.2rc1/scheduler/printers.c.serverbin-compat cups-2.2rc1/scheduler/printers.c
|
||||||
|
--- cups-2.2rc1/scheduler/printers.c.serverbin-compat 2016-08-08 20:06:00.000000000 +0200
|
||||||
|
+++ cups-2.2rc1/scheduler/printers.c 2016-08-09 09:58:21.327033616 +0200
|
||||||
|
@@ -967,9 +967,19 @@ cupsdLoadAllPrinters(void)
|
||||||
|
* Backend does not exist, stop printer...
|
||||||
|
*/
|
||||||
|
|
||||||
|
+#ifdef __x86_64__
|
||||||
|
+ snprintf(line, sizeof(line), "%s/backend/%s", ServerBin_compat,
|
||||||
|
+ p->device_uri);
|
||||||
|
+ if (access(line, 0))
|
||||||
|
+ {
|
||||||
|
+#endif /* __x86_64__ */
|
||||||
|
+
|
||||||
|
p->state = IPP_PRINTER_STOPPED;
|
||||||
|
snprintf(p->state_message, sizeof(p->state_message),
|
||||||
|
"Backend %s does not exist!", line);
|
||||||
|
+#ifdef __x86_64__
|
||||||
|
+ }
|
||||||
|
+#endif /* __x86_64__ */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -3481,8 +3491,20 @@ add_printer_filter(
|
||||||
|
else
|
||||||
|
snprintf(filename, sizeof(filename), "%s/filter/%s", ServerBin, program);
|
||||||
|
|
||||||
|
+#ifdef __x86_64__
|
||||||
|
+ if (_cupsFileCheck(filename, _CUPS_FILE_CHECK_PROGRAM, !RunUser,
|
||||||
|
+ cupsdLogFCMessage, p) == _CUPS_FILE_CHECK_MISSING) {
|
||||||
|
+ snprintf(filename, sizeof(filename), "%s/filter/%s", ServerBin_compat,
|
||||||
|
+ program);
|
||||||
|
+ if (_cupsFileCheck(filename, _CUPS_FILE_CHECK_PROGRAM, !RunUser,
|
||||||
|
+ cupsdLogFCMessage, p) == _CUPS_FILE_CHECK_MISSING)
|
||||||
|
+ snprintf(filename, sizeof(filename), "%s/filter/%s", ServerBin,
|
||||||
|
+ program);
|
||||||
|
+ }
|
||||||
|
+#else /* ! defined(__x86_64__) */
|
||||||
|
_cupsFileCheck(filename, _CUPS_FILE_CHECK_PROGRAM, !RunUser,
|
||||||
|
cupsdLogFCMessage, p);
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
@ -0,0 +1,13 @@
|
|||||||
|
diff --git a/scheduler/org.cups.cupsd.service.in b/scheduler/org.cups.cupsd.service.in
|
||||||
|
index 11e0662..6fb7a32 100644
|
||||||
|
--- a/scheduler/org.cups.cupsd.service.in
|
||||||
|
+++ b/scheduler/org.cups.cupsd.service.in
|
||||||
|
@@ -1,7 +1,7 @@
|
||||||
|
[Unit]
|
||||||
|
Description=CUPS Scheduler
|
||||||
|
Documentation=man:cupsd(8)
|
||||||
|
-After=network.target ypbind.service
|
||||||
|
+After=network.target nss-user-lookup.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=@sbindir@/cupsd -l
|
@ -0,0 +1,62 @@
|
|||||||
|
diff -up cups-2.0rc1/cups/tempfile.c.str3382 cups-2.0rc1/cups/tempfile.c
|
||||||
|
--- cups-2.0rc1/cups/tempfile.c.str3382 2014-07-31 02:58:00.000000000 +0200
|
||||||
|
+++ cups-2.0rc1/cups/tempfile.c 2014-09-12 14:06:42.560887827 +0200
|
||||||
|
@@ -27,6 +27,7 @@
|
||||||
|
# include <io.h>
|
||||||
|
#else
|
||||||
|
# include <unistd.h>
|
||||||
|
+# include <sys/types.h>
|
||||||
|
#endif /* WIN32 || __EMX__ */
|
||||||
|
|
||||||
|
|
||||||
|
@@ -48,7 +49,7 @@ cupsTempFd(char *filename, /* I - Point
|
||||||
|
char tmppath[1024]; /* Windows temporary directory */
|
||||||
|
DWORD curtime; /* Current time */
|
||||||
|
#else
|
||||||
|
- struct timeval curtime; /* Current time */
|
||||||
|
+ mode_t old_umask; /* Old umask before using mkstemp() */
|
||||||
|
#endif /* WIN32 */
|
||||||
|
|
||||||
|
|
||||||
|
@@ -98,32 +99,24 @@ cupsTempFd(char *filename, /* I - Point
|
||||||
|
*/
|
||||||
|
|
||||||
|
snprintf(filename, (size_t)len - 1, "%s/%05lx%08lx", tmpdir, GetCurrentProcessId(), curtime);
|
||||||
|
-#else
|
||||||
|
- /*
|
||||||
|
- * Get the current time of day...
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
- gettimeofday(&curtime, NULL);
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * Format a string using the hex time values...
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
- snprintf(filename, (size_t)len - 1, "%s/%05x%08x", tmpdir, (unsigned)getpid(), (unsigned)(curtime.tv_sec + curtime.tv_usec + tries));
|
||||||
|
-#endif /* WIN32 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open the file in "exclusive" mode, making sure that we don't
|
||||||
|
* stomp on an existing file or someone's symlink crack...
|
||||||
|
*/
|
||||||
|
|
||||||
|
-#ifdef WIN32
|
||||||
|
fd = open(filename, _O_CREAT | _O_RDWR | _O_TRUNC | _O_BINARY,
|
||||||
|
_S_IREAD | _S_IWRITE);
|
||||||
|
-#elif defined(O_NOFOLLOW)
|
||||||
|
- fd = open(filename, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
|
||||||
|
#else
|
||||||
|
- fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||||
|
+ /*
|
||||||
|
+ * Use the standard mkstemp() call to make a temporary filename
|
||||||
|
+ * securely. -- andrew.wood@jdplc.com
|
||||||
|
+ */
|
||||||
|
+ snprintf(filename, len - 1, "%s/cupsXXXXXX", tmpdir);
|
||||||
|
+
|
||||||
|
+ old_umask = umask(0077);
|
||||||
|
+ fd = mkstemp(filename);
|
||||||
|
+ umask(old_umask);
|
||||||
|
#endif /* WIN32 */
|
||||||
|
|
||||||
|
if (fd < 0 && errno != EEXIST)
|
@ -0,0 +1,30 @@
|
|||||||
|
diff -up cups-2.0rc1/cups/ppd.c.strict-ppd-line-length cups-2.0rc1/cups/ppd.c
|
||||||
|
--- cups-2.0rc1/cups/ppd.c.strict-ppd-line-length 2014-02-06 19:33:34.000000000 +0100
|
||||||
|
+++ cups-2.0rc1/cups/ppd.c 2014-09-12 18:07:44.227773710 +0200
|
||||||
|
@@ -2872,7 +2872,7 @@ ppd_read(cups_file_t *fp, /* I - Fil
|
||||||
|
*lineptr++ = (char)ch;
|
||||||
|
col ++;
|
||||||
|
|
||||||
|
- if (col > (PPD_MAX_LINE - 1))
|
||||||
|
+ if (col > (PPD_MAX_LINE - 1) && pg->ppd_conform == PPD_CONFORM_STRICT)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Line is too long...
|
||||||
|
@@ -2933,7 +2933,7 @@ ppd_read(cups_file_t *fp, /* I - Fil
|
||||||
|
{
|
||||||
|
col ++;
|
||||||
|
|
||||||
|
- if (col > (PPD_MAX_LINE - 1))
|
||||||
|
+ if (col > (PPD_MAX_LINE - 1) && pg->ppd_conform == PPD_CONFORM_STRICT)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Line is too long...
|
||||||
|
@@ -2992,7 +2992,7 @@ ppd_read(cups_file_t *fp, /* I - Fil
|
||||||
|
{
|
||||||
|
col ++;
|
||||||
|
|
||||||
|
- if (col > (PPD_MAX_LINE - 1))
|
||||||
|
+ if (col > (PPD_MAX_LINE - 1) && pg->ppd_conform == PPD_CONFORM_STRICT)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Line is too long...
|
@ -0,0 +1,141 @@
|
|||||||
|
diff -up cups-2.2.7/scheduler/ipp.c.substitute-bad-attrs cups-2.2.7/scheduler/ipp.c
|
||||||
|
--- cups-2.2.7/scheduler/ipp.c.substitute-bad-attrs 2018-04-03 15:55:45.974344993 +0200
|
||||||
|
+++ cups-2.2.7/scheduler/ipp.c 2018-04-03 16:15:06.723859881 +0200
|
||||||
|
@@ -164,6 +164,7 @@ cupsdProcessIPPRequest(
|
||||||
|
ipp_attribute_t *uri = NULL; /* Printer or job URI attribute */
|
||||||
|
ipp_attribute_t *username; /* requesting-user-name attr */
|
||||||
|
int sub_id; /* Subscription ID */
|
||||||
|
+ int valid = 1; /* Valid request? */
|
||||||
|
|
||||||
|
|
||||||
|
cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdProcessIPPRequest(%p[%d]): operation_id=%04x(%s)", con, con->number, con->request->request.op.operation_id, ippOpString(con->request->request.op.operation_id));
|
||||||
|
@@ -423,20 +424,55 @@ cupsdProcessIPPRequest(
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
- * OK, all the checks pass so far; make sure requesting-user-name is
|
||||||
|
- * not "root" from a remote host...
|
||||||
|
+ * OK, all the checks pass so far; validate "requesting-user-name"
|
||||||
|
+ * attribute value...
|
||||||
|
*/
|
||||||
|
|
||||||
|
- if ((username = ippFindAttribute(con->request, "requesting-user-name",
|
||||||
|
- IPP_TAG_NAME)) != NULL)
|
||||||
|
- {
|
||||||
|
- /*
|
||||||
|
- * Check for root user...
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
- if (!strcmp(username->values[0].string.text, "root") &&
|
||||||
|
- _cups_strcasecmp(con->http->hostname, "localhost") &&
|
||||||
|
- strcmp(con->username, "root"))
|
||||||
|
+ if ((username = ippFindAttribute(con->request, "requesting-user-name", IPP_TAG_ZERO)) != NULL)
|
||||||
|
+ {
|
||||||
|
+ /*
|
||||||
|
+ * Validate "requesting-user-name"...
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ if (username->group_tag != IPP_TAG_OPERATION && StrictConformance)
|
||||||
|
+ {
|
||||||
|
+ cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL, "%04X %s \"requesting-user-name\" attribute in wrong group.", IPP_STATUS_ERROR_BAD_REQUEST, con->http->hostname);
|
||||||
|
+ send_ipp_status(con, IPP_STATUS_ERROR_BAD_REQUEST, _("\"requesting-user-name\" attribute in wrong group."));
|
||||||
|
+ valid = 0;
|
||||||
|
+ }
|
||||||
|
+ else if (username->value_tag != IPP_TAG_NAME && username->value_tag != IPP_TAG_NAMELANG)
|
||||||
|
+ {
|
||||||
|
+ cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL, "%04X %s \"requesting-user-name\" attribute with wrong syntax.", IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES, con->http->hostname);
|
||||||
|
+ send_ipp_status(con, IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES, _("\"requesting-user-name\" attribute with wrong syntax."));
|
||||||
|
+ if ((attr = ippCopyAttribute(con->response, username, 0)) != NULL)
|
||||||
|
+ attr->group_tag = IPP_TAG_UNSUPPORTED_GROUP;
|
||||||
|
+ valid = 0;
|
||||||
|
+ }
|
||||||
|
+ else if (!ippValidateAttribute(username))
|
||||||
|
+ {
|
||||||
|
+ cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL, "%04X %s \"requesting-user-name\" attribute with bad value.", IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES, con->http->hostname);
|
||||||
|
+
|
||||||
|
+ if (StrictConformance)
|
||||||
|
+ {
|
||||||
|
+ /*
|
||||||
|
+ * Throw an error...
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ send_ipp_status(con, IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES, _("\"requesting-user-name\" attribute with wrong syntax."));
|
||||||
|
+ if ((attr = ippCopyAttribute(con->response, username, 0)) != NULL)
|
||||||
|
+ attr->group_tag = IPP_TAG_UNSUPPORTED_GROUP;
|
||||||
|
+ valid = 0;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ /*
|
||||||
|
+ * Map bad "requesting-user-name" to 'anonymous'...
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ ippSetString(con->request, &username, 0, "anonymous");
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else if (!strcmp(username->values[0].string.text, "root") && _cups_strcasecmp(con->http->hostname, "localhost") && strcmp(con->username, "root"))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Remote unauthenticated user masquerading as local root...
|
||||||
|
@@ -452,6 +488,8 @@ cupsdProcessIPPRequest(
|
||||||
|
else
|
||||||
|
sub_id = 0;
|
||||||
|
|
||||||
|
+ if (valid)
|
||||||
|
+ {
|
||||||
|
/*
|
||||||
|
* Then try processing the operation...
|
||||||
|
*/
|
||||||
|
@@ -655,6 +693,7 @@ cupsdProcessIPPRequest(
|
||||||
|
ippOpString(
|
||||||
|
con->request->request.op.operation_id));
|
||||||
|
break;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1615,27 +1654,34 @@ add_job(cupsd_client_t *con, /* I - Cl
|
||||||
|
_("Bad job-name value: Wrong type or count."));
|
||||||
|
if ((attr = ippCopyAttribute(con->response, attr, 0)) != NULL)
|
||||||
|
attr->group_tag = IPP_TAG_UNSUPPORTED_GROUP;
|
||||||
|
- return (NULL);
|
||||||
|
+
|
||||||
|
+ if (StrictConformance)
|
||||||
|
+ return (NULL);
|
||||||
|
+
|
||||||
|
+ /* Don't use invalid attribute */
|
||||||
|
+ ippDeleteAttribute(con->request, attr);
|
||||||
|
+
|
||||||
|
+ ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL, "Untitled");
|
||||||
|
}
|
||||||
|
else if (!ippValidateAttribute(attr))
|
||||||
|
{
|
||||||
|
send_ipp_status(con, IPP_ATTRIBUTES, _("Bad job-name value: %s"),
|
||||||
|
cupsLastErrorString());
|
||||||
|
+
|
||||||
|
if ((attr = ippCopyAttribute(con->response, attr, 0)) != NULL)
|
||||||
|
attr->group_tag = IPP_TAG_UNSUPPORTED_GROUP;
|
||||||
|
- return (NULL);
|
||||||
|
- }
|
||||||
|
|
||||||
|
- attr = ippFindAttribute(con->request, "requesting-user-name", IPP_TAG_NAME);
|
||||||
|
+ if (StrictConformance)
|
||||||
|
+ return (NULL);
|
||||||
|
|
||||||
|
- if (attr && !ippValidateAttribute(attr))
|
||||||
|
- {
|
||||||
|
- send_ipp_status(con, IPP_ATTRIBUTES, _("Bad requesting-user-name value: %s"), cupsLastErrorString());
|
||||||
|
- if ((attr = ippCopyAttribute(con->response, attr, 0)) != NULL)
|
||||||
|
- attr->group_tag = IPP_TAG_UNSUPPORTED_GROUP;
|
||||||
|
- return (NULL);
|
||||||
|
+ /* Don't use invalid attribute */
|
||||||
|
+ ippDeleteAttribute(con->request, attr);
|
||||||
|
+
|
||||||
|
+ ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL, "Untitled");
|
||||||
|
}
|
||||||
|
|
||||||
|
+ attr = ippFindAttribute(con->request, "requesting-user-name", IPP_TAG_NAME);
|
||||||
|
+
|
||||||
|
#ifdef WITH_LSPP
|
||||||
|
if (is_lspp_config())
|
||||||
|
{
|
@ -0,0 +1,48 @@
|
|||||||
|
diff -up cups-2.0.2/conf/cups-files.conf.in.LGOyhq cups-2.0.2/conf/cups-files.conf.in
|
||||||
|
--- cups-2.0.2/conf/cups-files.conf.in.LGOyhq 2015-02-10 13:51:24.912193296 +0100
|
||||||
|
+++ cups-2.0.2/conf/cups-files.conf.in 2015-02-10 13:52:49.400997262 +0100
|
||||||
|
@@ -7,7 +7,7 @@
|
||||||
|
#FatalErrors @CUPS_FATAL_ERRORS@
|
||||||
|
|
||||||
|
# Do we call fsync() after writing configuration or status files?
|
||||||
|
-#SyncOnClose No
|
||||||
|
+#SyncOnClose Yes
|
||||||
|
|
||||||
|
# Default user and group for filters/backends/helper programs; this cannot be
|
||||||
|
# any user or group that resolves to ID 0 for security reasons...
|
||||||
|
diff -up cups-2.0.2/doc/help/man-cups-files.conf.html.LGOyhq cups-2.0.2/doc/help/man-cups-files.conf.html
|
||||||
|
--- cups-2.0.2/doc/help/man-cups-files.conf.html.LGOyhq 2015-02-10 13:52:49.400997262 +0100
|
||||||
|
+++ cups-2.0.2/doc/help/man-cups-files.conf.html 2015-02-10 13:53:07.057747311 +0100
|
||||||
|
@@ -136,7 +136,7 @@ The default is "/etc/cups".
|
||||||
|
<dd style="margin-left: 5.0em">Specifies whether the scheduler calls
|
||||||
|
<b>fsync</b>(2)
|
||||||
|
after writing configuration or state files.
|
||||||
|
-The default is "No".
|
||||||
|
+The default is "Yes".
|
||||||
|
<dt><a name="SystemGroup"></a><b>SystemGroup </b><i>group-name </i>[ ... <i>group-name</i> ]
|
||||||
|
<dd style="margin-left: 5.0em">Specifies the group(s) to use for <i>@SYSTEM</i> group authentication.
|
||||||
|
The default contains "admin", "lpadmin", "root", "sys", and/or "system".
|
||||||
|
diff -up cups-2.0.2/man/cups-files.conf.man.in.LGOyhq cups-2.0.2/man/cups-files.conf.man.in
|
||||||
|
--- cups-2.0.2/man/cups-files.conf.man.in.LGOyhq 2015-02-10 13:52:49.400997262 +0100
|
||||||
|
+++ cups-2.0.2/man/cups-files.conf.man.in 2015-02-10 13:53:23.753510964 +0100
|
||||||
|
@@ -201,7 +201,7 @@ The default is "/etc/cups".
|
||||||
|
Specifies whether the scheduler calls
|
||||||
|
.BR fsync (2)
|
||||||
|
after writing configuration or state files.
|
||||||
|
-The default is "No".
|
||||||
|
+The default is "Yes".
|
||||||
|
.\"#SystemGroup
|
||||||
|
.TP 5
|
||||||
|
\fBSystemGroup \fIgroup-name \fR[ ... \fIgroup-name\fR ]
|
||||||
|
diff -up cups-2.0.2/scheduler/conf.c.LGOyhq cups-2.0.2/scheduler/conf.c
|
||||||
|
--- cups-2.0.2/scheduler/conf.c.LGOyhq 2015-02-10 13:51:24.991192177 +0100
|
||||||
|
+++ cups-2.0.2/scheduler/conf.c 2015-02-10 13:52:49.401997248 +0100
|
||||||
|
@@ -717,7 +717,7 @@ cupsdReadConfiguration(void)
|
||||||
|
RootCertDuration = 300;
|
||||||
|
Sandboxing = CUPSD_SANDBOXING_STRICT;
|
||||||
|
StrictConformance = FALSE;
|
||||||
|
- SyncOnClose = FALSE;
|
||||||
|
+ SyncOnClose = TRUE;
|
||||||
|
Timeout = DEFAULT_TIMEOUT;
|
||||||
|
WebInterface = CUPS_DEFAULT_WEBIF;
|
||||||
|
|
@ -0,0 +1,38 @@
|
|||||||
|
diff -up cups-1.5b1/conf/cups.password-auth.system-auth cups-1.5b1/conf/cups.password-auth
|
||||||
|
--- cups-1.5b1/conf/cups.password-auth.system-auth 2011-05-23 17:27:27.000000000 +0200
|
||||||
|
+++ cups-1.5b1/conf/cups.password-auth 2011-05-23 17:27:27.000000000 +0200
|
||||||
|
@@ -0,0 +1,4 @@
|
||||||
|
+#%PAM-1.0
|
||||||
|
+# Use password-auth common PAM configuration for the daemon
|
||||||
|
+auth include password-auth
|
||||||
|
+account include password-auth
|
||||||
|
diff -up cups-1.5b1/conf/cups.system-auth.system-auth cups-1.5b1/conf/cups.system-auth
|
||||||
|
--- cups-1.5b1/conf/cups.system-auth.system-auth 2011-05-23 17:27:27.000000000 +0200
|
||||||
|
+++ cups-1.5b1/conf/cups.system-auth 2011-05-23 17:27:27.000000000 +0200
|
||||||
|
@@ -0,0 +1,3 @@
|
||||||
|
+#%PAM-1.0
|
||||||
|
+auth include system-auth
|
||||||
|
+account include system-auth
|
||||||
|
diff -up cups-1.5b1/conf/Makefile.system-auth cups-1.5b1/conf/Makefile
|
||||||
|
--- cups-1.5b1/conf/Makefile.system-auth 2011-05-12 07:21:56.000000000 +0200
|
||||||
|
+++ cups-1.5b1/conf/Makefile 2011-05-23 17:27:27.000000000 +0200
|
||||||
|
@@ -90,10 +90,16 @@ install-data:
|
||||||
|
done
|
||||||
|
-if test x$(PAMDIR) != x; then \
|
||||||
|
$(INSTALL_DIR) -m 755 $(BUILDROOT)$(PAMDIR); \
|
||||||
|
- if test -r $(BUILDROOT)$(PAMDIR)/cups ; then \
|
||||||
|
- $(INSTALL_DATA) $(PAMFILE) $(BUILDROOT)$(PAMDIR)/cups.N ; \
|
||||||
|
+ if test -f /etc/pam.d/password-auth; then \
|
||||||
|
+ $(INSTALL_DATA) cups.password-auth $(BUILDROOT)$(PAMDIR)/cups; \
|
||||||
|
+ elif test -f /etc/pam.d/system-auth; then \
|
||||||
|
+ $(INSTALL_DATA) cups.system-auth $(BUILDROOT)$(PAMDIR)/cups; \
|
||||||
|
else \
|
||||||
|
- $(INSTALL_DATA) $(PAMFILE) $(BUILDROOT)$(PAMDIR)/cups ; \
|
||||||
|
+ if test -r $(BUILDROOT)$(PAMDIR)/cups ; then \
|
||||||
|
+ $(INSTALL_DATA) $(PAMFILE) $(BUILDROOT)$(PAMDIR)/cups.N ; \
|
||||||
|
+ else \
|
||||||
|
+ $(INSTALL_DATA) $(PAMFILE) $(BUILDROOT)$(PAMDIR)/cups ; \
|
||||||
|
+ fi ; \
|
||||||
|
fi ; \
|
||||||
|
fi
|
||||||
|
|
@ -0,0 +1,73 @@
|
|||||||
|
diff -up cups-2.2.5/scheduler/main.c.systemd-socket cups-2.2.5/scheduler/main.c
|
||||||
|
--- cups-2.2.5/scheduler/main.c.systemd-socket 2017-10-17 18:59:53.732431498 +0200
|
||||||
|
+++ cups-2.2.5/scheduler/main.c 2017-10-17 19:02:13.132275861 +0200
|
||||||
|
@@ -691,8 +691,16 @@ main(int argc, /* I - Number of comm
|
||||||
|
|
||||||
|
#ifdef HAVE_ONDEMAND
|
||||||
|
if (OnDemand)
|
||||||
|
+ {
|
||||||
|
cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL, "Scheduler started on demand.");
|
||||||
|
- else
|
||||||
|
+# ifdef HAVE_SYSTEMD
|
||||||
|
+ sd_notifyf(0, "READY=1\n"
|
||||||
|
+ "STATUS=Scheduler is running...\n"
|
||||||
|
+ "MAINPID=%lu",
|
||||||
|
+ (unsigned long) getpid());
|
||||||
|
+# endif /* HAVE_SYSTEMD */
|
||||||
|
+ } else
|
||||||
|
+
|
||||||
|
#endif /* HAVE_ONDEMAND */
|
||||||
|
if (fg)
|
||||||
|
cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL, "Scheduler started in foreground.");
|
||||||
|
diff -up cups-2.2.5/scheduler/org.cups.cupsd.path.in.systemd-socket cups-2.2.5/scheduler/org.cups.cupsd.path.in
|
||||||
|
--- cups-2.2.5/scheduler/org.cups.cupsd.path.in.systemd-socket 2017-10-13 20:22:26.000000000 +0200
|
||||||
|
+++ cups-2.2.5/scheduler/org.cups.cupsd.path.in 2017-10-17 18:59:53.732431498 +0200
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
[Unit]
|
||||||
|
Description=CUPS Scheduler
|
||||||
|
-PartOf=org.cups.cupsd.service
|
||||||
|
+PartOf=cups.service
|
||||||
|
|
||||||
|
[Path]
|
||||||
|
PathExists=@CUPS_CACHEDIR@/org.cups.cupsd
|
||||||
|
diff -up cups-2.2.5/scheduler/org.cups.cupsd.service.in.systemd-socket cups-2.2.5/scheduler/org.cups.cupsd.service.in
|
||||||
|
--- cups-2.2.5/scheduler/org.cups.cupsd.service.in.systemd-socket 2017-10-13 20:22:26.000000000 +0200
|
||||||
|
+++ cups-2.2.5/scheduler/org.cups.cupsd.service.in 2017-10-17 18:59:53.732431498 +0200
|
||||||
|
@@ -1,11 +1,13 @@
|
||||||
|
[Unit]
|
||||||
|
Description=CUPS Scheduler
|
||||||
|
Documentation=man:cupsd(8)
|
||||||
|
+After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=@sbindir@/cupsd -l
|
||||||
|
-Type=simple
|
||||||
|
+Type=notify
|
||||||
|
+Restart=on-failure
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
-Also=org.cups.cupsd.socket org.cups.cupsd.path
|
||||||
|
+Also=cups.socket cups.path
|
||||||
|
WantedBy=printer.target
|
||||||
|
diff -up cups-2.2.6/scheduler/org.cups.cupsd.socket.in.systemd-socket cups-2.2.6/scheduler/org.cups.cupsd.socket.in
|
||||||
|
--- cups-2.2.6/scheduler/org.cups.cupsd.socket.in.systemd-socket 2017-11-01 15:57:53.000000000 +0100
|
||||||
|
+++ cups-2.2.6/scheduler/org.cups.cupsd.socket.in 2018-09-19 12:38:00.630843246 +0200
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
[Unit]
|
||||||
|
Description=CUPS Scheduler
|
||||||
|
-PartOf=org.cups.cupsd.service
|
||||||
|
+PartOf=cups.service
|
||||||
|
|
||||||
|
[Socket]
|
||||||
|
ListenStream=@CUPS_DEFAULT_DOMAINSOCKET@
|
||||||
|
diff -up cups-2.2.6/scheduler/org.cups.cups-lpd.socket.systemd-socket cups-2.2.6/scheduler/org.cups.cups-lpd.socket
|
||||||
|
--- cups-2.2.6/scheduler/org.cups.cups-lpd.socket.systemd-socket 2017-11-01 15:57:53.000000000 +0100
|
||||||
|
+++ cups-2.2.6/scheduler/org.cups.cups-lpd.socket 2018-09-19 12:38:00.630843246 +0200
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
[Unit]
|
||||||
|
Description=CUPS LPD Server Socket
|
||||||
|
-PartOf=org.cups.cups-lpd.service
|
||||||
|
+PartOf=cups-lpd.service
|
||||||
|
|
||||||
|
[Socket]
|
||||||
|
ListenStream=515
|
@ -0,0 +1,51 @@
|
|||||||
|
diff -up cups-1.5b1/backend/usb-unix.c.uri-compat cups-1.5b1/backend/usb-unix.c
|
||||||
|
--- cups-1.5b1/backend/usb-unix.c.uri-compat 2011-05-24 15:59:05.000000000 +0200
|
||||||
|
+++ cups-1.5b1/backend/usb-unix.c 2011-05-24 16:02:03.000000000 +0200
|
||||||
|
@@ -63,11 +63,34 @@ print_device(const char *uri, /* I - De
|
||||||
|
int device_fd; /* USB device */
|
||||||
|
ssize_t tbytes; /* Total number of bytes written */
|
||||||
|
struct termios opts; /* Parallel port options */
|
||||||
|
+ char *fixed_uri = strdup (uri);
|
||||||
|
+ char *p;
|
||||||
|
|
||||||
|
|
||||||
|
(void)argc;
|
||||||
|
(void)argv;
|
||||||
|
|
||||||
|
+ p = strchr (fixed_uri, ':');
|
||||||
|
+ if (p++ != NULL)
|
||||||
|
+ {
|
||||||
|
+ char *e;
|
||||||
|
+ p += strspn (p, "/");
|
||||||
|
+ e = strchr (p, '/');
|
||||||
|
+ if (e > p)
|
||||||
|
+ {
|
||||||
|
+ size_t mfrlen = e - p;
|
||||||
|
+ e++;
|
||||||
|
+ if (!strncasecmp (e, p, mfrlen))
|
||||||
|
+ {
|
||||||
|
+ char *x = e + mfrlen;
|
||||||
|
+ if (!strncmp (x, "%20", 3))
|
||||||
|
+ /* Take mfr name out of mdl name for compatibility with
|
||||||
|
+ * Fedora 11 before bug #507244 was fixed. */
|
||||||
|
+ strcpy (e, x + 3); puts(fixed_uri);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Open the USB port device...
|
||||||
|
*/
|
||||||
|
@@ -107,10 +130,10 @@ print_device(const char *uri, /* I - De
|
||||||
|
_cups_strncasecmp(hostname, "Minolta", 7);
|
||||||
|
#endif /* __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __DragonFly__ */
|
||||||
|
|
||||||
|
- if (use_bc && !strncmp(uri, "usb:/dev/", 9))
|
||||||
|
+ if (use_bc && !strncmp(fixed_uri, "usb:/dev/", 9))
|
||||||
|
use_bc = 0;
|
||||||
|
|
||||||
|
- if ((device_fd = open_device(uri, &use_bc)) == -1)
|
||||||
|
+ if ((device_fd = open_device(fixed_uri, &use_bc)) == -1)
|
||||||
|
{
|
||||||
|
if (getenv("CLASS") != NULL)
|
||||||
|
{
|
@ -0,0 +1,52 @@
|
|||||||
|
diff -up cups-1.5b1/backend/usb-unix.c.usb-paperout cups-1.5b1/backend/usb-unix.c
|
||||||
|
--- cups-1.5b1/backend/usb-unix.c.usb-paperout 2011-05-24 15:51:39.000000000 +0200
|
||||||
|
+++ cups-1.5b1/backend/usb-unix.c 2011-05-24 15:51:39.000000000 +0200
|
||||||
|
@@ -30,6 +30,11 @@
|
||||||
|
|
||||||
|
#include <sys/select.h>
|
||||||
|
|
||||||
|
+#ifdef __linux
|
||||||
|
+#include <sys/ioctl.h>
|
||||||
|
+#include <linux/lp.h>
|
||||||
|
+#endif /* __linux */
|
||||||
|
+
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local functions...
|
||||||
|
@@ -334,7 +339,19 @@ open_device(const char *uri, /* I - Dev
|
||||||
|
if (!strncmp(uri, "usb:/dev/", 9))
|
||||||
|
#ifdef __linux
|
||||||
|
{
|
||||||
|
- return (open(uri + 4, O_RDWR | O_EXCL));
|
||||||
|
+ fd = open(uri + 4, O_RDWR | O_EXCL);
|
||||||
|
+
|
||||||
|
+ if (fd != -1)
|
||||||
|
+ {
|
||||||
|
+ /*
|
||||||
|
+ * Tell the driver to return from write() with errno==ENOSPACE
|
||||||
|
+ * on paper-out.
|
||||||
|
+ */
|
||||||
|
+ unsigned int t = 1;
|
||||||
|
+ ioctl (fd, LPABORT, &t);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return fd;
|
||||||
|
}
|
||||||
|
else if (!strncmp(uri, "usb://", 6))
|
||||||
|
{
|
||||||
|
@@ -400,7 +417,14 @@ open_device(const char *uri, /* I - Dev
|
||||||
|
if (!strcmp(uri, device_uri))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
- * Yes, return this file descriptor...
|
||||||
|
+ * Yes, tell the driver to return from write() with
|
||||||
|
+ * errno==ENOSPACE on paper-out.
|
||||||
|
+ */
|
||||||
|
+ unsigned int t = 1;
|
||||||
|
+ ioctl (fd, LPABORT, &t);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Return this file descriptor...
|
||||||
|
*/
|
||||||
|
|
||||||
|
fprintf(stderr, "DEBUG: Printer using device file \"%s\"...\n",
|
@ -0,0 +1,12 @@
|
|||||||
|
diff -up cups-1.6.3/cups/usersys.c.use-ipp1.1 cups-1.6.3/cups/usersys.c
|
||||||
|
--- cups-1.6.3/cups/usersys.c.use-ipp1.1 2013-07-12 11:41:45.368837618 +0200
|
||||||
|
+++ cups-1.6.3/cups/usersys.c 2013-07-12 11:41:45.391837299 +0200
|
||||||
|
@@ -366,7 +366,7 @@ cupsSetServer(const char *server) /* I -
|
||||||
|
cg->server_version = 22;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
- cg->server_version = 20;
|
||||||
|
+ cg->server_version = 11;
|
||||||
|
|
||||||
|
if (cg->server[0] != '/' && (port = strrchr(cg->server, ':')) != NULL &&
|
||||||
|
!strchr(port, ']') && isdigit(port[1] & 255))
|
@ -0,0 +1,28 @@
|
|||||||
|
diff --git a/backend/ipp.c b/backend/ipp.c
|
||||||
|
index 0a70a87..f8bf7e1 100644
|
||||||
|
--- a/backend/ipp.c
|
||||||
|
+++ b/backend/ipp.c
|
||||||
|
@@ -327,6 +327,7 @@ main(int argc, /* I - Number of command-line args */
|
||||||
|
get_job_attrs = 0, /* Does printer support Get-Job-Attributes? */
|
||||||
|
send_document = 0, /* Does printer support Send-Document? */
|
||||||
|
validate_job = 0, /* Does printer support Validate-Job? */
|
||||||
|
+ validation_retried = 0, /* Indicate whether Validate-Job was retried */
|
||||||
|
copies, /* Number of copies for job */
|
||||||
|
copies_remaining; /* Number of copies remaining */
|
||||||
|
const char *content_type, /* CONTENT_TYPE environment variable */
|
||||||
|
@@ -1597,7 +1598,15 @@ main(int argc, /* I - Number of command-line args */
|
||||||
|
ipp_status == IPP_BAD_REQUEST)
|
||||||
|
break;
|
||||||
|
else if (job_auth == NULL && ipp_status > IPP_BAD_REQUEST)
|
||||||
|
+ {
|
||||||
|
+ if (!validation_retried)
|
||||||
|
+ {
|
||||||
|
+ validation_retried = 1;
|
||||||
|
+ sleep(10);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
goto cleanup;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
@ -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)
|
||||||
|
{
|
@ -0,0 +1,12 @@
|
|||||||
|
diff -up cups-2.2.0/scheduler/org.cups.cupsd.service.in.ypbind cups-2.2.0/scheduler/org.cups.cupsd.service.in
|
||||||
|
--- cups-2.2.0/scheduler/org.cups.cupsd.service.in.ypbind 2017-09-22 16:51:39.053585694 +0200
|
||||||
|
+++ cups-2.2.0/scheduler/org.cups.cupsd.service.in 2017-09-22 16:52:02.588403584 +0200
|
||||||
|
@@ -1,7 +1,7 @@
|
||||||
|
[Unit]
|
||||||
|
Description=CUPS Scheduler
|
||||||
|
Documentation=man:cupsd(8)
|
||||||
|
-After=network.target
|
||||||
|
+After=network.target ypbind.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=@sbindir@/cupsd -l
|
@ -0,0 +1,5 @@
|
|||||||
|
/var/log/cups/*_log {
|
||||||
|
missingok
|
||||||
|
notifempty
|
||||||
|
sharedscripts
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
%_cups_serverbin %(/usr/bin/cups-config --serverbin)
|
@ -0,0 +1,51 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# This is a modified version of 'ncpprint'. It can now be used as a CUPS
|
||||||
|
# backend.
|
||||||
|
# Modifications:
|
||||||
|
# Copyright (C) 2002 Red Hat, inc
|
||||||
|
# Copyright (C) 2002 Tim Waugh
|
||||||
|
# Before modification: shipped as /usr/share/printconf/util/ncpprint
|
||||||
|
|
||||||
|
if [ -z "$*" ]
|
||||||
|
then
|
||||||
|
# This is where we would enumerate all the URIs we support.
|
||||||
|
# Patches welcome.
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
FILE=$6
|
||||||
|
if [ -z "$FILE" ]
|
||||||
|
then
|
||||||
|
FILE=-
|
||||||
|
fi
|
||||||
|
|
||||||
|
# $DEVICE_URI is 'ncp://[user:password@]server/queue'
|
||||||
|
URI=${DEVICE_URI#*://}
|
||||||
|
queue=${URI#*/}
|
||||||
|
URI=${URI%/$queue}
|
||||||
|
server=${URI#*@}
|
||||||
|
URI=${URI%$server}
|
||||||
|
URI=${URI%@}
|
||||||
|
if [ -n "$URI" ]
|
||||||
|
then
|
||||||
|
user=${URI%:*}
|
||||||
|
URI=${URI#$user}
|
||||||
|
password=${URI#:}
|
||||||
|
fi
|
||||||
|
|
||||||
|
#echo user: ${user-(none)}
|
||||||
|
#echo password: ${password-(none)}
|
||||||
|
#echo server: $server
|
||||||
|
#echo queue: $queue
|
||||||
|
|
||||||
|
if [ -n "$user" ]
|
||||||
|
then
|
||||||
|
if [ -n "$password" ]
|
||||||
|
then
|
||||||
|
/usr/bin/nprint -S "$server" -q "$queue" -U "$user" -P "$password" -N "$FILE" 2>/dev/null
|
||||||
|
else
|
||||||
|
/usr/bin/nprint -S "$server" -q "$queue" -U "$user" -n -N "$FILE" 2>/dev/null
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
/usr/bin/nprint -S "$server" -q "$queue" -N "$FILE" 2>/dev/null
|
||||||
|
fi
|
@ -0,0 +1,171 @@
|
|||||||
|
@PYTHON_SHEBANG@
|
||||||
|
|
||||||
|
"""
|
||||||
|
Upgrade script to enable authentication for CUPS-Get-Document in
|
||||||
|
default policy
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from shutil import copy
|
||||||
|
|
||||||
|
|
||||||
|
def get_cupsd_conf():
|
||||||
|
"""
|
||||||
|
Get all lines from cupsd.conf
|
||||||
|
"""
|
||||||
|
if not os.path.exists('/etc/cups/cupsd.conf'):
|
||||||
|
return None
|
||||||
|
|
||||||
|
lines = []
|
||||||
|
with open('/etc/cups/cupsd.conf', 'r') as conf:
|
||||||
|
lines = conf.readlines()
|
||||||
|
|
||||||
|
return lines
|
||||||
|
|
||||||
|
|
||||||
|
def get_default_policy(lines):
|
||||||
|
"""
|
||||||
|
Get the default policy lines
|
||||||
|
|
||||||
|
:param list lines: lines from cupsd.conf
|
||||||
|
"""
|
||||||
|
default_policy = []
|
||||||
|
in_policy = False
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
if not in_policy and not line.lstrip().startswith('<Policy default>'):
|
||||||
|
continue
|
||||||
|
|
||||||
|
default_policy.append(line)
|
||||||
|
|
||||||
|
if line.lstrip().startswith('</Policy>'):
|
||||||
|
return default_policy
|
||||||
|
|
||||||
|
in_policy = True
|
||||||
|
|
||||||
|
return default_policy
|
||||||
|
|
||||||
|
|
||||||
|
def get_limit_with_document(lines):
|
||||||
|
"""
|
||||||
|
Get <Limit> scope which defines CUPS-Get-Document operation
|
||||||
|
|
||||||
|
:param list lines: Lines containing the default policy
|
||||||
|
"""
|
||||||
|
limit = []
|
||||||
|
in_limit = False
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
if not in_limit and not line.lstrip().startswith('<Limit'):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if (not in_limit and line.lstrip().startswith('<Limit') and
|
||||||
|
not 'CUPS-Get-Document' in line.lstrip().split('#')[0][1:-1]):
|
||||||
|
continue
|
||||||
|
|
||||||
|
limit.append(line)
|
||||||
|
|
||||||
|
if line.lstrip().startswith('</Limit>'):
|
||||||
|
return limit
|
||||||
|
|
||||||
|
in_limit = True
|
||||||
|
|
||||||
|
return limit
|
||||||
|
|
||||||
|
|
||||||
|
def check_for_authtype(lines):
|
||||||
|
"""
|
||||||
|
Check if <Limit> defining CUPS-Get-Document defines
|
||||||
|
any authentication
|
||||||
|
|
||||||
|
:param list lines: Lines of <Limit> scope which defines CUPS-Get-Document
|
||||||
|
"""
|
||||||
|
for line in lines:
|
||||||
|
if line.lstrip().startswith('AuthType'):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def migrate_cupsd_conf(lines):
|
||||||
|
"""
|
||||||
|
Make changes to cupsd.conf contents to use authentication
|
||||||
|
for CUPS-Get-Document
|
||||||
|
|
||||||
|
:param list lines: Lines from cupsd.conf
|
||||||
|
"""
|
||||||
|
new_lines = []
|
||||||
|
in_policy = False
|
||||||
|
create_document_limit = False
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
if (in_policy and line.lstrip().startswith('<Limit') and
|
||||||
|
not line.lstrip().startswith('<Limit CUPS-Get-Document>') and
|
||||||
|
'CUPS-Get-Document' in line.lstrip().split('#')[0][1:-1]):
|
||||||
|
line = line.replace(' CUPS-Get-Document', '')
|
||||||
|
create_document_limit = True
|
||||||
|
|
||||||
|
if in_policy and line.lstrip().startswith('</Policy>') and create_document_limit:
|
||||||
|
new_lines.append('\n')
|
||||||
|
new_lines.append((len(line) - len(line.lstrip()) + 2) * ' ' +
|
||||||
|
'# added during upgrade\n')
|
||||||
|
new_lines.append((len(line) - len(line.lstrip()) + 2) * ' ' +
|
||||||
|
'<Limit CUPS-Get-Document>\n')
|
||||||
|
new_lines.append((len(line) - len(line.lstrip()) + 4) * ' ' +
|
||||||
|
'AuthType Default\n')
|
||||||
|
new_lines.append((len(line) - len(line.lstrip()) + 4) * ' ' +
|
||||||
|
'Require user @OWNER @SYSTEM\n')
|
||||||
|
new_lines.append((len(line) - len(line.lstrip()) + 4) * ' ' +
|
||||||
|
'Order deny,allow\n')
|
||||||
|
new_lines.append((len(line) - len(line.lstrip()) + 2) * ' ' +
|
||||||
|
'</Limit>\n')
|
||||||
|
create_document_limit = False
|
||||||
|
|
||||||
|
new_lines.append(line)
|
||||||
|
|
||||||
|
if not in_policy:
|
||||||
|
if line.lstrip().startswith('<Policy default>'):
|
||||||
|
in_policy = True
|
||||||
|
continue
|
||||||
|
|
||||||
|
if line.lstrip().startswith('<Limit CUPS-Get-Document>'):
|
||||||
|
new_lines.append((len(line) - len(line.lstrip()) + 2) * ' ' +
|
||||||
|
'# added during upgrade\n')
|
||||||
|
new_lines.append((len(line) - len(line.lstrip()) + 2) * ' ' +
|
||||||
|
'AuthType Default\n')
|
||||||
|
continue
|
||||||
|
|
||||||
|
if line.lstrip().startswith('</Policy>'):
|
||||||
|
in_policy = False
|
||||||
|
continue
|
||||||
|
|
||||||
|
return new_lines
|
||||||
|
|
||||||
|
|
||||||
|
def apply_changes(lines):
|
||||||
|
"""
|
||||||
|
Backup the original file if there is no .rpmsave already and
|
||||||
|
apply changes to the actual cupsd.conf
|
||||||
|
|
||||||
|
:param list lines: New lines for cupsd.conf
|
||||||
|
"""
|
||||||
|
if not os.path.exists('/etc/cups/cupsd.conf.rpmsave'):
|
||||||
|
copy('/etc/cups/cupsd.conf', '/etc/cups/cupsd.conf.rpmsave')
|
||||||
|
|
||||||
|
with open('/etc/cups/cupsd.conf', 'w') as conf:
|
||||||
|
conf.writelines(lines)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
content = get_cupsd_conf()
|
||||||
|
if content is None:
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if check_for_authtype(get_limit_with_document(get_default_policy(content))):
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
new_content = migrate_cupsd_conf(content)
|
||||||
|
|
||||||
|
apply_changes(new_content)
|
||||||
|
|
||||||
|
sys.exit(0)
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue