diff --git a/cups-resolv_reload.patch b/cups-resolv_reload.patch index 9a053e0..7da32fd 100644 --- a/cups-resolv_reload.patch +++ b/cups-resolv_reload.patch @@ -1,7 +1,7 @@ diff -up cups-2.1.4/cups/auth.c.resolv_reload cups-2.1.4/cups/auth.c --- cups-2.1.4/cups/auth.c.resolv_reload 2016-06-14 19:45:32.000000000 +0200 -+++ cups-2.1.4/cups/auth.c 2017-04-05 17:36:21.812611389 +0200 -@@ -522,6 +522,16 @@ cups_gss_getname( ++++ cups-2.1.4/cups/auth.c 2017-04-27 10:31:13.430082002 +0200 +@@ -522,6 +522,18 @@ cups_gss_getname( DEBUG_printf(("7cups_gss_getname(http=%p, service_name=\"%s\")", http, service_name)); @@ -11,17 +11,19 @@ diff -up cups-2.1.4/cups/auth.c.resolv_reload cups-2.1.4/cups/auth.c + * If so, reload resolver. + */ + -+ http_resolv_check_t status; ++ dns_resolver_reload_rv retval; + -+ status = httpCheckResolv(); ++ retval = dnsReloadResolver(); ++ if (retval.status == DNS_RESOLVER_RELOAD_ERROR) ++ DEBUG_printf(("1cups_gss_getname: dnsReloadResolver() failed - %s.", strerror(retval.errnum))); +#endif /* HAVE_RES_INIT */ /* * Get the hostname... diff -up cups-2.1.4/cups/http-addr.c.resolv_reload cups-2.1.4/cups/http-addr.c ---- cups-2.1.4/cups/http-addr.c.resolv_reload 2017-04-05 17:36:21.798611527 +0200 -+++ cups-2.1.4/cups/http-addr.c 2017-04-05 17:36:21.812611389 +0200 -@@ -364,6 +364,17 @@ httpAddrLookup( +--- cups-2.1.4/cups/http-addr.c.resolv_reload 2017-04-27 10:31:13.415082133 +0200 ++++ cups-2.1.4/cups/http-addr.c 2017-04-27 10:31:13.431081993 +0200 +@@ -364,6 +364,20 @@ httpAddrLookup( #ifdef HAVE_RES_INIT /* @@ -29,20 +31,23 @@ diff -up cups-2.1.4/cups/http-addr.c.resolv_reload cups-2.1.4/cups/http-addr.c + * If so, reload resolver and set need_res_init to 0. + */ + -+ http_resolv_check_t status; ++ dns_resolver_reload_rv retval; + -+ status = httpCheckResolv(); ++ retval = dnsReloadResolver(); + -+ if (status == HTTP_RESOLV_CHECK_RELOADED && cg->need_res_init == 1) ++ if (retval.status == DNS_RESOLVER_RELOAD_RELOADED && cg->need_res_init == 1) + cg->need_res_init = 0; ++ ++ if (retval.status == DNS_RESOLVER_RELOAD_ERROR) ++ DEBUG_printf(("1httpAddrLookup: dnsReloadResolver() failed - %s.", strerror(retval.errnum))); + /* * STR #2920: Initialize resolver after failure in cups-polld * * If the previous lookup failed, re-initialize the resolver to prevent diff -up cups-2.1.4/cups/http-addrlist.c.resolv_reload cups-2.1.4/cups/http-addrlist.c ---- cups-2.1.4/cups/http-addrlist.c.resolv_reload 2017-04-05 17:36:21.781611694 +0200 -+++ cups-2.1.4/cups/http-addrlist.c 2017-04-05 17:36:21.813611379 +0200 -@@ -414,6 +414,17 @@ httpAddrGetList(const char *hostname, /* +--- cups-2.1.4/cups/http-addrlist.c.resolv_reload 2017-04-27 10:31:13.400082264 +0200 ++++ cups-2.1.4/cups/http-addrlist.c 2017-04-27 10:31:13.431081993 +0200 +@@ -414,6 +414,20 @@ httpAddrGetList(const char *hostname, /* #ifdef HAVE_RES_INIT /* @@ -50,78 +55,136 @@ diff -up cups-2.1.4/cups/http-addrlist.c.resolv_reload cups-2.1.4/cups/http-addr + * If so, reload resolver and set cg->need_res_init to 0 + */ + -+ http_resolv_check_t status; ++ dns_resolver_reload_rv retval; + -+ status = httpCheckResolv(); ++ retval = dnsReloadResolver(); + -+ if (status == HTTP_RESOLV_CHECK_RELOADED && cg->need_res_init == 1) ++ if (retval.status == DNS_RESOLVER_RELOAD_RELOADED && cg->need_res_init == 1) + cg->need_res_init = 0; ++ ++ if (retval.status == DNS_RESOLVER_RELOAD_ERROR) ++ DEBUG_printf(("1httpAddrGetList: dnsReloadResolver() failed - %s.", strerror(retval.errnum))); + /* * STR #2920: Initialize resolver after failure in cups-polld * * If the previous lookup failed, re-initialize the resolver to prevent diff -up cups-2.1.4/cups/http.c.resolv_reload cups-2.1.4/cups/http.c ---- cups-2.1.4/cups/http.c.resolv_reload 2016-06-14 19:45:32.000000000 +0200 -+++ cups-2.1.4/cups/http.c 2017-04-05 17:53:16.856712660 +0200 -@@ -109,6 +109,9 @@ static const char * const http_fields[] - "Allow", - "Server" - }; -+#ifdef HAVE_RES_INIT -+time_t resolv_conf_modtime = 0; -+#endif /* HAVE_RES_INIT */ - - - /* -@@ -4848,6 +4851,45 @@ http_write_chunk(http_t *http, /* I - return (bytes); +--- cups-2.1.4/cups/http.c.resolv_reload 2017-04-27 10:31:13.433081976 +0200 ++++ cups-2.1.4/cups/http.c 2017-04-27 10:32:39.450330261 +0200 +@@ -4849,6 +4849,110 @@ http_write_chunk(http_t *http, /* I } + +#ifdef HAVE_RES_INIT +/* + * Function to check modification time of resolv.conf. + * If time is changed, it reloads resolver. -+ * If /etc/resolv.conf doesn't exist, it tries to reload local resolver. -+ * If even reloading local resolver doesn't work, it ends with error. ++ * If /etc/resolv.conf doesn't exist, it tries to reload resolver with local nameserver, if it wasn't reloaded before ++ * If even reloading resolver with local nameserver doesn't work, it ends with error. ++ * Global variable resolv_conf_modtime is set to -1 before the first call of this function - this is for prevention of resolver's reloading when cupsd is just started and resolv.conf exists - cupsd has current configuration in that case. + */ + -+http_resolv_check_t -+httpCheckResolv() ++dns_resolver_reload_rv ++dnsReloadResolver() +{ -+ http_resolv_check_t status = HTTP_RESOLV_CHECK_OK; -+ struct stat resolv_conf_status; ++ dns_resolver_reload_rv retval, lstat_retval, stat_retval, res_init_retval; ++ struct stat resolv_conf_stat, resolv_conf_lstat, resolv_conf_status; ++ retval.status = DNS_RESOLVER_RELOAD_OK; ++ retval.errnum = 0; ++ stat_retval.errnum = 0; ++ lstat_retval.errnum = 0; ++ res_init_retval.errnum = 0; + -+ status = stat(HTTP_RESOLV_CONF_PATH, &resolv_conf_status); ++ /* Variable to store /etc/resolv.conf modification time - initialized by actual time*/ ++ static time_t resolv_conf_modtime = -1; + -+ /* /etc/resolv.conf couldn't be stated because it doesn't exist, try resolver on localhost */ -+ if (status == HTTP_RESOLV_CHECK_ERROR && errno == ENOENT) ++ /* This part of code is to ensure we get modification time of symlink and original file - we will decide which is newer later */ ++ stat_retval.status = stat(DNS_RESOLV_CONF_PATH, &resolv_conf_stat); ++ stat_retval.errnum = errno; ++ lstat_retval.status = lstat(DNS_RESOLV_CONF_PATH, &resolv_conf_lstat); ++ lstat_retval.errnum = errno; ++ ++ /* symlink /etc/resolv.conf or original file couldn't be stated because it doesn't exist, try resolver on localhost ++ * Covers cases: ++ * - resolv.conf and original file existed and it doesn't now - resolv_conf_modtime has different value than 0 - reload resolver with local nameserver ++ * - resolv.conf and original file didn't exist and still doesn't exist - resolv_conf_modtime is set to 0 - do nothing ++ */ ++ if (stat_retval.status == -1 && lstat_retval.status == -1 && stat_retval.errnum == ENOENT && lstat_retval.errnum == ENOENT) ++ { ++ /* if resolv_conf_modtime is set to 0, it means previous reload was for resolver with local nameserver - no need to reload again */ ++ if (resolv_conf_modtime != 0) ++ { ++ res_init_retval.status = res_init(); ++ res_init_retval.errnum = errno; ++ if (res_init_retval.status == 0) ++ { ++ resolv_conf_modtime = 0; ++ retval.status = DNS_RESOLVER_RELOAD_RELOADED; ++ } ++ else ++ retval.status = res_init_retval.status; ++ ++ retval.errnum = res_init_retval.errnum; ++ } ++ else ++ { ++ retval.status = DNS_RESOLVER_RELOAD_OK; ++ retval.errnum = ENOENT; ++ } ++ ++ return (retval); ++ } ++ ++ /* If stat ends with different errno, return status - it should return both statuses and errnos, but for simplification it returns only stat */ ++ if (stat_retval.status == -1 && lstat_retval.status == -1) + { -+ status = res_init(); -+ return(status); ++ retval.errnum = stat_retval.errnum; ++ retval.status = stat_retval.status; ++ return (retval); + } + -+ /* If stat ends with different errno, return status */ -+ if (status == HTTP_RESOLV_CHECK_ERROR) -+ return (status); ++ /* Here we compare modification times from lstat and stat to decide which is newer - if they are equal, lstat modification time is used. We are checking only stat() errno, because case with errors in both lstat() and stat() functions is checked before */ ++ if (stat_retval.errnum == 0) ++ if (resolv_conf_stat.st_mtime > resolv_conf_lstat.st_mtime) ++ resolv_conf_status = resolv_conf_stat; ++ else ++ resolv_conf_status = resolv_conf_lstat; ++ else ++ resolv_conf_status = resolv_conf_lstat; + -+ if (resolv_conf_modtime != 0 && resolv_conf_status.st_mtime != resolv_conf_modtime) ++ /* If /etc/resolv.conf exists and modification times are different, reload resolver. ++ * Covers cases: ++ * - resolv.conf or original file exists and it was modified - resolv_conf_modtime has different value than resolv_conf_status.st_mtime - reload resolver with nameserver from /etc/resolv.conf ++ * - resolv.conf or original file didn't exist and it does now - resolv_conf_modtime is set to 0 and resolv_conf_status.st_mtime has value - reload resolver with nameserver form /etc/resolv.conf ++ * - resolv.conf or original file exists and it wasn't modified - resolv_conf_modtime is equal to resolv_conf_status.st_mtime - do nothing ++ */ ++ if (resolv_conf_status.st_mtime != resolv_conf_modtime) + { -+ res_init(); ++ res_init_retval.status = res_init(); ++ res_init_retval.errnum = errno; ++ if (res_init_retval.status == 0) ++ { ++ retval.status = DNS_RESOLVER_RELOAD_RELOADED; ++ } ++ else ++ retval.status = res_init_retval.status; + -+ status = HTTP_RESOLV_CHECK_RELOADED; ++ retval.errnum = res_init_retval.errnum; + } + + resolv_conf_modtime = resolv_conf_status.st_mtime; + -+ return (status); ++ return (retval); +} +#endif /* HAVE_RES_INIT */ - ++ ++ /* * End of "$Id: http.c 12970 2015-11-13 20:02:51Z msweet $". + */ diff -up cups-2.1.4/cups/http.h.resolv_reload cups-2.1.4/cups/http.h --- cups-2.1.4/cups/http.h.resolv_reload 2016-06-14 19:45:32.000000000 +0200 -+++ cups-2.1.4/cups/http.h 2017-04-05 17:36:21.814611369 +0200 ++++ cups-2.1.4/cups/http.h 2017-04-27 10:35:32.279819884 +0200 @@ -57,6 +57,12 @@ typedef off_t ssize_t; /* @private@ */ # define SO_PEERCRED LOCAL_PEERCRED # endif /* LOCAL_PEERCRED && !SO_PEERCRED */ @@ -154,7 +217,7 @@ diff -up cups-2.1.4/cups/http.h.resolv_reload cups-2.1.4/cups/http.h # define HTTP_MAX_BUFFER 2048 /* Max length of data buffer */ # define HTTP_MAX_VALUE 256 /* Max header field value length */ +# ifdef HAVE_RES_INIT -+# define HTTP_RESOLV_CONF_PATH "/etc/resolv.conf" /* Path to resolv.conf */ ++# define DNS_RESOLV_CONF_PATH "/etc/resolv.conf" /* Path to resolv.conf */ +# endif /* HAVE_RES_INIT */ @@ -164,80 +227,99 @@ diff -up cups-2.1.4/cups/http.h.resolv_reload cups-2.1.4/cups/http.h } http_version_t; +#ifdef HAVE_RES_INIT -+typedef enum http_resolv_check_e ++typedef enum dns_resolver_reload_e +{ -+ HTTP_RESOLV_CHECK_ERROR = -1, -+ HTTP_RESOLV_CHECK_OK = 0, -+ HTTP_RESOLV_CHECK_RELOADED = 1 -+} http_resolv_check_t; ++ DNS_RESOLVER_RELOAD_ERROR = -1, ++ DNS_RESOLVER_RELOAD_OK = 0, ++ DNS_RESOLVER_RELOAD_RELOADED = 1 ++} dns_resolver_reload_t; +#endif /* HAVE_RES_INIT */ + typedef union _http_addr_u /**** Socket address union, which **** makes using IPv6 and other **** address types easier and -@@ -646,6 +671,11 @@ extern void httpShutdown(http_t *http) - extern const char *httpStateString(http_state_t state) _CUPS_API_2_0; - extern const char *httpURIStatusString(http_uri_status_t status) _CUPS_API_2_0; +@@ -446,6 +471,13 @@ typedef struct http_credential_s /**** H + typedef int (*http_timeout_cb_t)(http_t *http, void *user_data); + /**** HTTP timeout callback @since CUPS 1.5/OS X 10.7@ ****/ + ++#ifdef HAVE_RES_INIT ++typedef struct dns_resolver_reload_retval ++{ ++ dns_resolver_reload_t status; ++ int errnum; ++} dns_resolver_reload_rv; ++#endif /* HAVE_RES_INIT */ + + + /* +@@ -592,6 +624,11 @@ extern http_version_t httpGetVersion(htt + extern int httpReconnect2(http_t *http, int msec, int *cancel) + _CUPS_API_1_6; +/**** Prototype of function to check modification time of /etc/resolv.conf ****/ +#ifdef HAVE_RES_INIT -+extern http_resolv_check_t httpCheckResolv(); ++extern dns_resolver_reload_rv dnsReloadResolver(); +#endif /* HAVE_RES_INIT */ + - /* - * C++ magic... - */ + + /**** New in CUPS 1.7/OS X 10.9 ****/ + extern http_t *httpAcceptConnection(int fd, int blocking) diff -up cups-2.1.4/cups/http-support.c.resolv_reload cups-2.1.4/cups/http-support.c ---- cups-2.1.4/cups/http-support.c.resolv_reload 2017-04-05 17:36:21.795611556 +0200 -+++ cups-2.1.4/cups/http-support.c 2017-04-05 17:36:21.814611369 +0200 -@@ -2266,6 +2266,16 @@ http_resolve_cb( +--- cups-2.1.4/cups/http-support.c.resolv_reload 2017-04-27 10:31:13.411082168 +0200 ++++ cups-2.1.4/cups/http-support.c 2017-04-27 10:31:13.434081967 +0200 +@@ -2266,6 +2266,18 @@ http_resolve_cb( http_addrlist_t *addrlist, /* List of addresses */ *addr; /* Current address */ +#ifdef HAVE_RES_INIT + /* -+ * Check if resolv.conf is modified, if so, reload resolver -+ */ ++ * Check if resolv.conf is modified, if so, reload resolver ++ */ + -+ http_resolv_check_t status; ++ dns_resolver_reload_rv retval; + -+ status = httpCheckResolv(); ++ retval = dnsReloadResolver(); ++ if (retval.status == DNS_RESOLVER_RELOAD_ERROR) ++ DEBUG_printf(("1http_resolve_cb: dnsReloadResolver() failed - %s.", strerror(retval.errnum))); +#endif /* HAVE_RES_INIT */ + DEBUG_printf(("8http_resolve_cb: Looking up \"%s\".", hostTarget)); snprintf(fqdn, sizeof(fqdn), "%d", ntohs(port)); diff -up cups-2.1.4/scheduler/conf.c.resolv_reload cups-2.1.4/scheduler/conf.c ---- cups-2.1.4/scheduler/conf.c.resolv_reload 2017-04-05 17:36:21.810611409 +0200 -+++ cups-2.1.4/scheduler/conf.c 2017-04-05 17:36:21.815611359 +0200 -@@ -939,6 +939,12 @@ cupsdReadConfiguration(void) +--- cups-2.1.4/scheduler/conf.c.resolv_reload 2017-04-27 10:31:13.429082011 +0200 ++++ cups-2.1.4/scheduler/conf.c 2017-04-27 10:31:13.435081958 +0200 +@@ -939,6 +939,15 @@ cupsdReadConfiguration(void) if (!RemotePort) BrowseLocalProtocols = 0; /* Disable sharing - no remote access */ +#ifdef HAVE_RES_INIT -+ http_resolv_check_t res_status; /* Return status of httpCheckResolv() */ ++ dns_resolver_reload_rv retval; /* Return status of dnsReloadResolver() */ + -+ res_status = httpCheckResolv(); ++ retval = dnsReloadResolver(); ++ ++ if (retval.status == DNS_RESOLVER_RELOAD_ERROR) ++ syslog(LOG_LPR, "1cupsdReadConfiguration: dnsReloadResolver() failed - %s.", strerror(retval.errnum)); +#endif /* HAVE_RES_INIT */ + /* * See if the ServerName is an IP address... */ diff -up cups-2.1.4/scheduler/main.c.resolv_reload cups-2.1.4/scheduler/main.c ---- cups-2.1.4/scheduler/main.c.resolv_reload 2017-04-05 17:36:21.805611458 +0200 -+++ cups-2.1.4/scheduler/main.c 2017-04-05 17:39:05.278005085 +0200 -@@ -141,6 +141,14 @@ main(int argc, /* I - Number of comm +--- cups-2.1.4/scheduler/main.c.resolv_reload 2017-04-27 10:31:13.421082081 +0200 ++++ cups-2.1.4/scheduler/main.c 2017-04-27 10:31:13.435081958 +0200 +@@ -140,6 +140,14 @@ main(int argc, /* I - Number of comm + long tmo_delay; /* Time before it must be called */ #endif /* HAVE_AVAHI */ - +#ifdef HAVE_RES_INIT -+ http_resolv_check_t status; /* Return status from httpCheckResolv() */ ++ dns_resolver_reload_rv retval; /* Return status from dnsReloadResolver() */ + -+ status = httpCheckResolv(); -+ if (status == HTTP_RESOLV_CHECK_ERROR) -+ fputs("cupsd: Cannot reload a resolver, using old configuration now.\n", stderr); ++ retval = dnsReloadResolver(); ++ if (retval.status == DNS_RESOLVER_RELOAD_ERROR) ++ fprintf(stderr, "cupsd: Cannot reload a resolver - %s , using old configuration now.\n", strerror(retval.errnum)); +#endif /* HAVE_RES_INIT */ + + #ifdef HAVE_GETEUID /* - * Check for setuid invocation, which we do not support! diff --git a/cups.spec b/cups.spec index 05ee60a..cbc45e9 100644 --- a/cups.spec +++ b/cups.spec @@ -15,7 +15,7 @@ Summary: CUPS printing system Name: cups Epoch: 1 Version: 2.1.4 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv2 Url: http://www.cups.org/ Source0: http://www.cups.org/software/%{VERSION}/cups-%{VERSION}-source.tar.gz @@ -623,6 +623,9 @@ rm -f %{cups_serverbin}/backend/smb %{_mandir}/man5/ipptoolfile.5.gz %changelog +* Thu Apr 27 2017 Zdenek Dohnal - 1:2.1.4-7 +- copying cups-resolv_reload.patch from RHEL + * Wed Apr 05 2017 Zdenek Dohnal - 1:2.1.4-6 - fixing issue with #1437065 - makes res_init() call to local resolver and keeps error message, but no hard exit for cupsd