]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/dirsvc.c
Merge changes from CUPS 1.4svn-r8606.
[thirdparty/cups.git] / scheduler / dirsvc.c
index d876c5ac494281494c945c84f6a4d4c50bfd8d6f..11be5585e506a4d120b8db0620c319c23281f175 100644 (file)
@@ -38,6 +38,7 @@
  *   cupsdUpdateLDAPBrowse()    - Scan for new printers via LDAP...
  *   cupsdUpdateSLPBrowse()     - Get browsing information via SLP.
  *   dequote()                  - Remote quotes from a string.
+ *   dnssdAddAlias()            - Add a DNS-SD alias name.
  *   dnssdBuildTxtRecord()      - Build a TXT record from printer info.
  *   dnssdComparePrinters()     - Compare the registered names of two printers.
  *   dnssdDeregisterPrinter()   - Stop sending broadcast information for a
@@ -47,6 +48,7 @@
  *   dnssdRegisterCallback()    - DNSServiceRegister callback.
  *   dnssdRegisterPrinter()     - Start sending broadcast information for a
  *                                printer or update the broadcast contents.
+ *   dnssdStop()                - Stop all DNS-SD registrations.
  *   dnssdUpdate()              - Handle DNS-SD queries.
  *   get_hostconfig()           - Get an /etc/hostconfig service setting.
  *   is_local_queue()           - Determine whether the URI points at a local
@@ -154,6 +156,10 @@ static void        update_smb(int onoff);
 
 
 #ifdef HAVE_DNSSD
+#  ifdef HAVE_COREFOUNDATION
+static void    dnssdAddAlias(const void *key, const void *value,
+                             void *context);
+#  endif /* HAVE_COREFOUNDATION */
 static char    *dnssdBuildTxtRecord(int *txt_len, cupsd_printer_t *p,
                                     int for_lpd);
 static int     dnssdComparePrinters(cupsd_printer_t *a, cupsd_printer_t *b);
@@ -166,6 +172,7 @@ static void dnssdRegisterCallback(DNSServiceRef sdRef,
                                      const char *name, const char *regtype,
                                      const char *domain, void *context);
 static void    dnssdRegisterPrinter(cupsd_printer_t *p);
+static void    dnssdStop(void);
 static void    dnssdUpdate(void);
 #endif /* HAVE_DNSSD */
 
@@ -243,7 +250,8 @@ cupsdDeregisterPrinter(
                  removeit);
 
   if (!Browsing || !p->shared ||
-      (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)))
+      (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
+                  CUPS_PRINTER_SCANNER)))
     return;
 
  /*
@@ -673,7 +681,8 @@ cupsdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
                   p->name);
 
   if (!Browsing || !BrowseLocalProtocols ||
-      (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)))
+      (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
+                  CUPS_PRINTER_SCANNER)))
     return;
 
 #ifdef HAVE_LIBSLP
@@ -881,7 +890,8 @@ cupsdSendBrowseList(void)
     for (count = 0, p = (cupsd_printer_t *)cupsArrayFirst(Printers);
          count < max_count && p != NULL;
         p = (cupsd_printer_t *)cupsArrayNext(Printers))
-      if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)) &&
+      if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
+                       CUPS_PRINTER_SCANNER)) &&
           p->shared && p->browse_time < ut)
         count ++;
 
@@ -907,7 +917,8 @@ cupsdSendBrowseList(void)
 
       if (!p)
         break;
-      else if ((p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)) ||
+      else if ((p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
+                           CUPS_PRINTER_SCANNER)) ||
                !p->shared)
         continue;
       else if (p->browse_time < ut)
@@ -1662,7 +1673,8 @@ cupsdStartBrowsing(void)
   for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
        p;
        p = (cupsd_printer_t *)cupsArrayNext(Printers))
-    if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)))
+    if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
+                     CUPS_PRINTER_SCANNER)))
       cupsdRegisterPrinter(p);
 }
 
@@ -1746,7 +1758,7 @@ cupsdStartPolling(void)
     argv[1] = pollp->hostname;
 
     if (cupsdStartProcess(polld, argv, envp, -1, -1, statusfds[1], -1, -1,
-                          0, DefaultProfile, &(pollp->pid)) < 0)
+                          0, DefaultProfile, NULL, &(pollp->pid)) < 0)
     {
       cupsdLogMessage(CUPSD_LOG_ERROR,
                       "cupsdStartPolling: Unable to fork polling daemon - %s",
@@ -1790,7 +1802,8 @@ cupsdStopBrowsing(void)
   for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
        p;
        p = (cupsd_printer_t *)cupsArrayNext(Printers))
-    if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)))
+    if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
+                     CUPS_PRINTER_SCANNER)))
       cupsdDeregisterPrinter(p, 1);
 
  /*
@@ -1816,29 +1829,7 @@ cupsdStopBrowsing(void)
 
 #ifdef HAVE_DNSSD
   if ((BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDRef)
-  {
-    if (WebIFRef)
-    {
-      DNSServiceRefDeallocate(WebIFRef);
-      WebIFRef = NULL;
-    }
-
-    if (RemoteRef)
-    {
-      DNSServiceRefDeallocate(RemoteRef);
-      RemoteRef = NULL;
-    }
-
-    cupsdRemoveSelect(DNSServiceRefSockFD(DNSSDRef));
-
-    DNSServiceRefDeallocate(DNSSDRef);
-    DNSSDRef = NULL;
-
-    cupsArrayDelete(DNSSDPrinters);
-    DNSSDPrinters = NULL;
-
-    DNSSDPort = 0;
-  }
+    dnssdStop();
 #endif /* HAVE_DNSSD */
 
 #ifdef HAVE_LIBSLP
@@ -1915,9 +1906,10 @@ cupsdUpdateDNSSDName(void)
   DNSServiceErrorType error;           /* Error from service creation */
   char         webif[1024];            /* Web interface share name */
 #ifdef HAVE_COREFOUNDATION_H
-  CFStringRef  nameRef;                /* Computer name CFString */
+  SCDynamicStoreRef sc;                        /* Context for dynamic store */
+  CFDictionaryRef btmm;                        /* Back-to-My-Mac domains */
+  CFStringRef  nameRef;                /* Host name CFString */
   char         nameBuffer[1024];       /* C-string buffer */
-  CFStringEncoding nameEncoding;       /* Computer name encoding */
 #endif /* HAVE_COREFOUNDATION_H */
 
 
@@ -1926,6 +1918,7 @@ cupsdUpdateDNSSDName(void)
   * enabled...
   */
 
+
   if (!DNSSDPort)
     return;
 
@@ -1934,21 +1927,68 @@ cupsdUpdateDNSSDName(void)
   */
 
 #ifdef HAVE_COREFOUNDATION_H
-  cupsdClearString(&DNSSDName);
+  sc = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("cupsd"), NULL, NULL);
 
-  if ((nameRef = SCDynamicStoreCopyComputerName(NULL,
-                                               &nameEncoding)) != NULL)
+  if (sc)
   {
-    if (CFStringGetCString(nameRef, nameBuffer, sizeof(nameBuffer),
-                          kCFStringEncodingUTF8))
-      cupsdSetString(&DNSSDName, nameBuffer);
+   /*
+    * Get the computer name from the dynamic store...
+    */
 
-    CFRelease(nameRef);
-  }
+    cupsdClearString(&DNSSDName);
 
-#else
-  cupsdSetString(&DNSSDName, ServerName);
+    if ((nameRef = SCDynamicStoreCopyLocalHostName(sc)) != NULL)
+    {
+      if (CFStringGetCString(nameRef, nameBuffer, sizeof(nameBuffer),
+                            kCFStringEncodingUTF8))
+      {
+        cupsdLogMessage(CUPSD_LOG_DEBUG,
+                       "Dynamic store host name is \"%s\".", nameBuffer);
+       cupsdSetString(&DNSSDName, nameBuffer);
+      }
+
+      CFRelease(nameRef);
+    }
+
+    if (!DNSSDName)
+    {
+     /*
+      * Use the ServerName instead...
+      */
+
+      cupsdLogMessage(CUPSD_LOG_DEBUG,
+                      "Using ServerName \"%s\" as host name.", ServerName);
+      cupsdSetString(&DNSSDName, ServerName);
+    }
+
+   /*
+    * Get any Back-to-My-Mac domains and add them as aliases...
+    */
+
+    cupsdFreeAliases(DNSSDAlias);
+    DNSSDAlias = NULL;
+
+    btmm = SCDynamicStoreCopyValue(sc, CFSTR("Setup:/Network/BackToMyMac"));
+    if (btmm && CFGetTypeID(btmm) == CFDictionaryGetTypeID())
+    {
+      cupsdLogMessage(CUPSD_LOG_DEBUG, "%d Back to My Mac aliases to add.",
+                     (int)CFDictionaryGetCount(btmm));
+      CFDictionaryApplyFunction(btmm, dnssdAddAlias, NULL);
+    }
+    else if (btmm)
+      cupsdLogMessage(CUPSD_LOG_ERROR,
+                     "Bad Back to My Mac data in dynamic store!");
+    else
+      cupsdLogMessage(CUPSD_LOG_DEBUG, "No Back to My Mac aliases to add.");
+
+    if (btmm)
+      CFRelease(btmm);
+
+    CFRelease(sc);
+  }
+  else
 #endif /* HAVE_COREFOUNDATION_H */
+  cupsdSetString(&DNSSDName, ServerName);
 
  /*
   * Then (re)register the web interface if enabled...
@@ -2219,6 +2259,41 @@ dequote(char       *d,                   /* I - Destination string */
 
 
 #ifdef HAVE_DNSSD
+#  ifdef HAVE_COREFOUNDATION
+/*
+ * 'dnssdAddAlias()' - Add a DNS-SD alias name.
+ */
+
+static void
+dnssdAddAlias(const void *key,         /* I - Key */
+              const void *value,       /* I - Value (domain) */
+             void       *context)      /* I - Unused */
+{
+  char valueStr[1024],                 /* Domain string */
+       hostname[1024];                 /* Complete hostname */
+
+
+  (void)context;
+
+  if (CFGetTypeID((CFStringRef)value) == CFStringGetTypeID() &&
+      CFStringGetCString((CFStringRef)value, valueStr, sizeof(valueStr),
+                         kCFStringEncodingUTF8))
+  {
+    snprintf(hostname, sizeof(hostname), "%s.%s", DNSSDName, valueStr);
+    if (!DNSSDAlias)
+      DNSSDAlias = cupsArrayNew(NULL, NULL);
+
+    cupsdAddAlias(DNSSDAlias, hostname);
+    cupsdLogMessage(CUPSD_LOG_DEBUG, "Added Back to My Mac ServerAlias %s",
+                   hostname);
+  }
+  else
+    cupsdLogMessage(CUPSD_LOG_ERROR,
+                    "Bad Back to My Mac domain in dynamic store!");
+}
+#  endif /* HAVE_COREFOUNDATION */
+
+
 /*
  * 'dnssdBuildTxtRecord()' - Build a TXT record from printer info.
  */
@@ -2565,12 +2640,7 @@ dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
                        *nameptr;       /* Pointer into name */
   int                  ipp_len,        /* IPP TXT record length */
                        printer_len;    /* LPD TXT record length */
-  char                 resource[1024]; /* Resource path for printer */
   const char           *regtype;       /* Registration type */
-  const char           *domain;        /* Registration domain */
-  cupsd_location_t     *location,      /* Printer location */
-                       *policy;        /* Operation policy for Print-Job */
-  unsigned             address[4];     /* INADDR_ANY address */
 
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdRegisterPrinter(%s) %s", p->name,
@@ -2616,26 +2686,6 @@ dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
     cupsArrayAdd(DNSSDPrinters, p);
   }
 
- /*
-  * If 'Allow printing from the Internet' is enabled (i.e. from any address)
-  * let dnssd decide on the domain, otherwise restrict it to ".local".
-  */
-
-  if (p->type & CUPS_PRINTER_CLASS)
-    snprintf(resource, sizeof(resource), "/classes/%s", p->name);
-  else
-    snprintf(resource, sizeof(resource), "/printers/%s", p->name);
-
-  address[0] = address[1] = address[2] = address[3] = 0;
-  location   = cupsdFindBest(resource, HTTP_POST);
-  policy     = cupsdFindPolicyOp(p->op_policy_ptr, IPP_PRINT_JOB);
-
-  if ((location && !cupsdCheckAccess(address, "", 0, location)) ||
-      (policy && !cupsdCheckAccess(address, "", 0, policy)))
-    domain = "local.";
-  else
-    domain = NULL;
-
  /*
   * Register IPP and (optionally) LPD...
   */
@@ -2686,9 +2736,8 @@ dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
                                              "_ipp._tcp,_cups";
 
     cupsdLogMessage(CUPSD_LOG_DEBUG, 
-                   "Registering DNS-SD printer %s with name \"%s\", "
-                   "type \"%s\", and domain \"%s\"", p->name, name, regtype,
-                   domain ? domain : "(null)");
+                   "Registering DNS-SD printer %s with name \"%s\" and "
+                   "type \"%s\"", p->name, name, regtype);
 
    /*
     * Register the queue, dropping characters as needed until we succeed...
@@ -2700,7 +2749,7 @@ dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
     {
       p->ipp_ref = DNSSDRef;
       if ((se = DNSServiceRegister(&p->ipp_ref, kDNSServiceFlagsShareConnection,
-                                   0, name, regtype, domain, NULL,
+                                   0, name, regtype, NULL, NULL,
                                   htons(DNSSDPort), ipp_len, ipp_txt,
                                   dnssdRegisterCallback,
                                   p)) == kDNSServiceErr_BadParam)
@@ -2783,14 +2832,13 @@ dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
       */
 
       cupsdLogMessage(CUPSD_LOG_DEBUG, 
-                     "Registering DNS-SD printer %s with name \"%s\", "
-                     "type \"_printer._tcp\", and domain \"%s\"", p->name,
-                     name, domain ? domain : "(null)");
+                     "Registering DNS-SD printer %s with name \"%s\" and "
+                     "type \"_printer._tcp\"", p->name, name);
 
       p->printer_ref = DNSSDRef;
       if ((se = DNSServiceRegister(&p->printer_ref,
                                    kDNSServiceFlagsShareConnection,
-                                  0, name, "_printer._tcp", domain, NULL,
+                                  0, name, "_printer._tcp", NULL, NULL,
                                   htons(515), printer_len, printer_txt,
                                   dnssdRegisterCallback,
                                   p)) == kDNSServiceErr_NoError)
@@ -2811,6 +2859,53 @@ dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
 }
 
 
+/*
+ * 'dnssdStop()' - Stop all DNS-SD registrations.
+ */
+
+static void
+dnssdStop(void)
+{
+  cupsd_printer_t      *p;             /* Current printer */
+
+
+ /*
+  * De-register the individual printers
+  */
+
+  for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
+       p;
+       p = (cupsd_printer_t *)cupsArrayNext(Printers))
+    dnssdDeregisterPrinter(p);
+
+ /*
+  * Shutdown the rest of the service refs...
+  */
+
+  if (WebIFRef)
+  {
+    DNSServiceRefDeallocate(WebIFRef);
+    WebIFRef = NULL;
+  }
+
+  if (RemoteRef)
+  {
+    DNSServiceRefDeallocate(RemoteRef);
+    RemoteRef = NULL;
+  }
+
+  cupsdRemoveSelect(DNSServiceRefSockFD(DNSSDRef));
+
+  DNSServiceRefDeallocate(DNSSDRef);
+  DNSSDRef = NULL;
+
+  cupsArrayDelete(DNSSDPrinters);
+  DNSSDPrinters = NULL;
+
+  DNSSDPort = 0;
+}
+
+
 /*
  * 'dnssdUpdate()' - Handle DNS-SD queries.
  */
@@ -2822,9 +2917,12 @@ dnssdUpdate(void)
 
 
   if ((sdErr = DNSServiceProcessResult(DNSSDRef)) != kDNSServiceErr_NoError)
+  {
     cupsdLogMessage(CUPSD_LOG_ERROR,
                     "DNS Service Discovery registration error %d!",
                    sdErr);
+    dnssdStop();
+  }
 }
 #endif /* HAVE_DNSSD */
 
@@ -3509,6 +3607,18 @@ process_implicit_classes(void)
       else
        len = strlen(p->name);
 
+      if (len >= sizeof(name))
+      {
+       /*
+       * If the printer name length somehow is greater than we normally allow,
+       * skip this printer...
+       */
+
+       len = 0;
+       cupsArrayRestore(Printers);
+       continue;
+      }
+
       strncpy(name, p->name, len);
       name[len] = '\0';
       offset    = 0;
@@ -5231,7 +5341,7 @@ update_lpd(int onoff)                     /* - 1 = turn on, 0 = turn off */
     argv[4] = NULL;
 
     cupsdStartProcess("/bin/launchctl", argv, envp, -1, -1, -1, -1, -1, 1,
-                      NULL, &pid);
+                      NULL, NULL, &pid);
   }
 #endif /* __APPLE__ */
   else
@@ -5253,8 +5363,13 @@ update_polling(void)
 
   while ((ptr = cupsdStatBufUpdate(PollStatusBuffer, &loglevel,
                                    message, sizeof(message))) != NULL)
+  {
+    if (loglevel == CUPSD_LOG_INFO)
+      cupsdLogMessage(CUPSD_LOG_INFO, "%s", message);
+
     if (!strchr(PollStatusBuffer->buffer, '\n'))
       break;
+  }
 
   if (ptr == NULL && !PollStatusBuffer->bufused)
   {