]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Fix crash when DNSSDHostName is NULL
authorTill Kamppeter <till.kamppeter@gmail.com>
Wed, 16 Mar 2022 17:02:09 +0000 (18:02 +0100)
committerZdenek Dohnal <zdohnal@redhat.com>
Thu, 16 Jun 2022 09:43:09 +0000 (11:43 +0200)
If cupsd is running without Browsing (when not sharing printers) the
global variable DNSSDHostName of the scheduler is not set, staying
NULL. Therefore the previous commit causes a crash with this
configuration of CUPS.

This commit does a NULL check on DNSSDHostName and falls back to
ServerName if needed, where it also does a NULL check and if this is
also NULL, it refrains from any attempt to correct the device URI's
hostname to "localhost".

As ServerName usually contains the server's hostname without ".local"
suffix but the device URIs coming from Avahi usually have a suffixed
host name (and there are also the ".local" and ".local." variants of
the suffix), we consider hostnames also as equal if one has the
suffix, the other not, or if we have the variants with and without
trailing dot.

In addition, there are also HAVE_DNSSD conditionals added around the
code using DNSSDHostName now.

scheduler/ipp.c

index e2bdb04d19f9cf3c5d135bca6d37e76554e84da2..1769ef8dcb68fa14d12f2e80df15e34ec5b22bd7 100644 (file)
@@ -5544,20 +5544,55 @@ create_local_printer(
 
  /*
   * Check device URI if it has the same hostname as we have, if so, replace
-  * the hostname by local host. This way we assure that local-only services
+  * the hostname by localhost. This way we assure that local-only services
   * like ipp-usb or Printer Applications always work.
+  *
+  * When comparing our hostname with the one in the device URI, consider
+  * names with ยจ.local(.)" suffix and names without suffix the same.
   */
 
-  httpSeparateURI(HTTP_URI_CODING_ALL, ptr,
-                 scheme, sizeof(scheme), userpass, sizeof(userpass), host,
-                 sizeof(host), &port, resource, sizeof(resource));
-  if (strcmp(host, DNSSDHostName) == 0)
-    ptr = "localhost";
+#ifdef HAVE_DNSSD
+  if (DNSSDHostName)
+    nameptr = DNSSDHostName;
+  else
+#endif
+  if (ServerName)
+    nameptr = ServerName;
+  else
+    nameptr = NULL;
+
+  if (nameptr)
+  {
+    int host_len,
+        server_name_len;
+
+    httpSeparateURI(HTTP_URI_CODING_ALL, ptr,
+                   scheme, sizeof(scheme), userpass, sizeof(userpass), host,
+                   sizeof(host), &port, resource, sizeof(resource));
+
+    host_len = strlen(host);
+    if (strcmp(host + host_len - 6, ".local") == 0)
+      host_len -= 6;
+    if (strcmp(host + host_len - 7, ".local.") == 0)
+      host_len -= 7;
+
+    server_name_len = strlen(nameptr);
+    if (strcmp(nameptr + server_name_len - 6, ".local") == 0)
+      server_name_len -= 6;
+    if (strcmp(nameptr + server_name_len - 7, ".local.") == 0)
+      server_name_len -= 7;
+
+    if (host_len == server_name_len && strncmp(host, nameptr, host_len) == 0)
+      ptr = "localhost";
+    else
+      ptr = host;
+
+    httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), scheme, userpass,
+                   ptr, port, resource);
+    cupsdSetDeviceURI(printer, uri);
+  }
   else
-    ptr = host;
-  httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), scheme, userpass,
-                 ptr, port, resource);
-  cupsdSetDeviceURI(printer, uri);
+    cupsdSetDeviceURI(printer, ptr);
 
   if (printer_geo_location)
     cupsdSetString(&printer->geo_location, ippGetString(printer_geo_location, 0, NULL));