]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/dirsvc.c
Import CUPS 1.4svn-r7356.
[thirdparty/cups.git] / scheduler / dirsvc.c
index dd08c4b173fba532ee9acd36659dc56fc16b0028..507ecf2803c913be6f8311bca9c24d96fa04f990 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   Directory services routines for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  *   These coded instructions, statements, and computer programs are the
  *
  * Contents:
  *
- *   cupsdDeregisterPrinter()      - Stop sending broadcast information for a 
- *                                  local printer and remove any pending
- *                                   references to remote printers.
- *   cupsdLoadRemoteCache()        - Load the remote printer cache.
- *   cupsdRegisterPrinter()        - Start sending broadcast information for a
- *                                   printer update the broadcast contents.
- *   cupsdSaveRemoteCache()        - Save the remote printer cache.
- *   cupsdSendBrowseList()         - Send new browsing information as necessary.
- *   cupsdStartBrowsing()          - Start sending and receiving broadcast
- *                                   information.
- *   cupsdStartPolling()           - Start polling servers as needed.
- *   cupsdStopBrowsing()           - Stop sending and receiving broadcast
- *                                   information.
- *   cupsdStopPolling()            - Stop polling servers as needed.
- *   cupsdUpdateDNSSDBrowse()      - Handle DNS-SD queries.
- *   cupsdUpdateLDAPBrowse()       - Scan for new printers via LDAP...
- *   cupsdUpdateSLPBrowse()        - Get browsing information via SLP.
- *   dnssdBuildTxtRecord()         - Build a TXT record from printer info.
- *   dnssdDeregisterPrinter()      - Stop sending broadcast information for a
- *                                   printer.
- *   dnssdPackTxtRecord()          - Pack an array of key/value pairs into the
- *                                   TXT record format.
- *   dnssdRegisterCallback()       - DNSServiceRegister callback.
- *   dnssdRegisterPrinter()        - Start sending broadcast information for a
- *                                   printer or update the broadcast contents.
- *   dequote()                     - Remote quotes from a string.
- *   process_browse_data()         - Process new browse data.
- *   process_implicit_classes()    - Create/update implicit classes as needed.
- *   send_cups_browse()            - Send new browsing information using the
- *                                   CUPS protocol.
- *   send_ldap_browse()            - Send LDAP printer registrations.
- *   send_slp_browse()             - Register the specified printer with SLP.
- *   slp_attr_callback()           - SLP attribute callback 
- *   slp_dereg_printer()           - SLPDereg() the specified printer
- *   slp_get_attr()                - Get an attribute from an SLP registration.
- *   slp_reg_callback()            - Empty SLPRegReport.
- *   slp_url_callback()            - SLP service url callback
- *   update_cups_browse()          - Update the browse lists using the CUPS
- *                                   protocol.
- *   update_lpd()                  - Update the LPD configuration as needed.
- *   update_polling()              - Read status messages from the poll daemons.
- *   update_smb()                  - Update the SMB configuration as needed.
+ *   cupsdDeregisterPrinter()   - Stop sending broadcast information for a local
+ *                                printer and remove any pending references to
+ *                                remote printers.
+ *   cupsdLoadRemoteCache()     - Load the remote printer cache.
+ *   cupsdRegisterPrinter()     - Start sending broadcast information for a
+ *                                printer or update the broadcast contents.
+ *   cupsdRestartPolling()      - Restart polling servers as needed.
+ *   cupsdSaveRemoteCache()     - Save the remote printer cache.
+ *   cupsdSendBrowseList()      - Send new browsing information as necessary.
+ *   cupsdStartBrowsing()       - Start sending and receiving broadcast
+ *                                information.
+ *   cupsdStartPolling()        - Start polling servers as needed.
+ *   cupsdStopBrowsing()        - Stop sending and receiving broadcast
+ *                                information.
+ *   cupsdStopPolling()         - Stop polling servers as needed.
+ *   cupsdUpdateDNSSDBrowse()   - Handle DNS-SD queries.
+ *   cupsdUpdateLDAPBrowse()    - Scan for new printers via LDAP...
+ *   cupsdUpdateSLPBrowse()     - Get browsing information via SLP.
+ *   dequote()                  - Remote quotes from a string.
+ *   is_local_queue()           - Determine whether the URI points at a local
+ *                                queue.
+ *   process_browse_data()      - Process new browse data.
+ *   dnssdBuildTxtRecord()      - Build a TXT record from printer info.
+ *   dnssdDeregisterPrinter()   - Stop sending broadcast information for a
+ *                                printer.
+ *   dnssdPackTxtRecord()       - Pack an array of key/value pairs into the TXT
+ *                                record format.
+ *   dnssdRegisterCallback()    - DNSServiceRegister callback.
+ *   dnssdRegisterPrinter()     - Start sending broadcast information for a
+ *                                printer or update the broadcast contents.
+ *   process_implicit_classes() - Create/update implicit classes as needed.
+ *   send_cups_browse()         - Send new browsing information using the CUPS
+ *                                protocol.
+ *   send_ldap_browse()         - Send LDAP printer registrations.
+ *   send_slp_browse()          - Register the specified printer with SLP.
+ *   slp_attr_callback()        - SLP attribute callback
+ *   slp_dereg_printer()        - SLPDereg() the specified printer
+ *   slp_get_attr()             - Get an attribute from an SLP registration.
+ *   slp_reg_callback()         - Empty SLPRegReport.
+ *   slp_url_callback()         - SLP service url callback
+ *   update_cups_browse()       - Update the browse lists using the CUPS
+ *                                protocol.
+ *   update_lpd()               - Update the LPD configuration as needed.
+ *   update_polling()           - Read status messages from the poll daemons.
+ *   update_smb()               - Update the SMB configuration as needed.
  */
 
 /*
@@ -202,7 +205,7 @@ cupsdDeregisterPrinter(
   * Announce the deletion...
   */
 
-  if ((BrowseLocalProtocols & BROWSE_CUPS))
+  if ((BrowseLocalProtocols & BROWSE_CUPS) && BrowseSocket >= 0)
   {
     cups_ptype_t savedtype = p->type;  /* Saved printer type */
 
@@ -329,7 +332,7 @@ cupsdLoadRemoteCache(void)
       {
         cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of remote.cache.", linenum);
-        return;
+        break;
       }
     }
     else if (!strcasecmp(line, "<Class") ||
@@ -370,7 +373,7 @@ cupsdLoadRemoteCache(void)
       {
         cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of remote.cache.", linenum);
-        return;
+        break;
       }
     }
     else if (!strcasecmp(line, "</Printer>") ||
@@ -390,14 +393,14 @@ cupsdLoadRemoteCache(void)
       {
         cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of remote.cache.", linenum);
-        return;
+        break;
       }
     }
     else if (!p)
     {
       cupsdLogMessage(CUPSD_LOG_ERROR,
                       "Syntax error on line %d of remote.cache.", linenum);
-      return;
+      break;
     }
     else if (!strcasecmp(line, "Info"))
     {
@@ -430,7 +433,7 @@ cupsdLoadRemoteCache(void)
       {
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of remote.cache.", linenum);
-       return;
+       break;
       }
     }
     else if (!strcasecmp(line, "Option") && value)
@@ -466,7 +469,7 @@ cupsdLoadRemoteCache(void)
       {
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of remote.cache.", linenum);
-       return;
+       break;
       }
     }
     else if (!strcasecmp(line, "StateMessage"))
@@ -498,7 +501,7 @@ cupsdLoadRemoteCache(void)
       {
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of remote.cache.", linenum);
-       return;
+       break;
       }
     }
     else if (!strcasecmp(line, "Type"))
@@ -509,7 +512,7 @@ cupsdLoadRemoteCache(void)
       {
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of remote.cache.", linenum);
-       return;
+       break;
       }
     }
     else if (!strcasecmp(line, "BrowseTime"))
@@ -525,7 +528,7 @@ cupsdLoadRemoteCache(void)
       {
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of remote.cache.", linenum);
-       return;
+       break;
       }
     }
     else if (!strcasecmp(line, "JobSheets"))
@@ -560,7 +563,7 @@ cupsdLoadRemoteCache(void)
       {
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of remote.cache.", linenum);
-       return;
+       break;
       }
     }
     else if (!strcasecmp(line, "AllowUser"))
@@ -574,7 +577,7 @@ cupsdLoadRemoteCache(void)
       {
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of remote.cache.", linenum);
-       return;
+       break;
       }
     }
     else if (!strcasecmp(line, "DenyUser"))
@@ -588,7 +591,7 @@ cupsdLoadRemoteCache(void)
       {
        cupsdLogMessage(CUPSD_LOG_ERROR,
                        "Syntax error on line %d of remote.cache.", linenum);
-       return;
+       break;
       }
     }
     else
@@ -866,7 +869,7 @@ cupsdSendBrowseList(void)
 
        p->browse_time = time(NULL);
 
-       if (BrowseLocalProtocols & BROWSE_CUPS)
+       if ((BrowseLocalProtocols & BROWSE_CUPS) && BrowseSocket >= 0)
           send_cups_browse(p);
 
 #ifdef HAVE_LIBSLP
@@ -1248,7 +1251,7 @@ cupsdStartPolling(void)
     argv[1] = pollp->hostname;
 
     if (cupsdStartProcess(polld, argv, envp, -1, -1, statusfds[1], -1, -1,
-                          0, &(pollp->pid)) < 0)
+                          0, DefaultProfile, &(pollp->pid)) < 0)
     {
       cupsdLogMessage(CUPSD_LOG_ERROR,
                       "cupsdStartPolling: Unable to fork polling daemon - %s",
@@ -1817,9 +1820,9 @@ process_browse_data(
     if (hptr && !*hptr)
       *hptr = '.';                     /* Resource FQDN */
 
-    if ((p = cupsdFindClass(name)) == NULL && BrowseShortNames)
+    if ((p = cupsdFindDest(name)) == NULL && BrowseShortNames)
     {
-      if ((p = cupsdFindClass(resource + 9)) != NULL)
+      if ((p = cupsdFindDest(resource + 9)) != NULL)
       {
         if (p->hostname && strcasecmp(p->hostname, host))
        {
@@ -1924,9 +1927,9 @@ process_browse_data(
     if (hptr && !*hptr)
       *hptr = '.';                     /* Resource FQDN */
 
-    if ((p = cupsdFindPrinter(name)) == NULL && BrowseShortNames)
+    if ((p = cupsdFindDest(name)) == NULL && BrowseShortNames)
     {
-      if ((p = cupsdFindPrinter(resource + 10)) != NULL)
+      if ((p = cupsdFindDest(resource + 10)) != NULL)
       {
         if (p->hostname && strcasecmp(p->hostname, host))
        {
@@ -2445,10 +2448,12 @@ dnssdRegisterCallback(
     const char         *domain,        /* I - Domain. ".local" for now */
     void               *context)       /* I - User-defined context */
 {
-  (void)context;
+  cupsd_printer_t *p = (cupsd_printer_t *)context;
+                                       /* Current printer */
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, 
-                 "dnssdRegisterCallback(%s, %s)", name, regtype);
+
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdRegisterCallback(%s, %s) for %s",
+                  name, regtype, p->name);
 
   if (errorCode)
   {
@@ -2456,6 +2461,14 @@ dnssdRegisterCallback(
                    "DNSServiceRegister failed with error %d", (int)errorCode);
     return;
   }
+  else if (strcasecmp(name, p->reg_name))
+  {
+    cupsdLogMessage(CUPSD_LOG_INFO, "Using service name \"%s\" for \"%s\"",
+                    name, p->name);
+
+    cupsdSetString(&p->reg_name, name);
+    LastEvent |= CUPSD_EVENT_PRINTER_MODIFIED;
+  }
 }
 
 
@@ -2473,10 +2486,15 @@ dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
                        *name;          /* Service name */
   int                  txt_len,        /* TXT record length */
                        port;           /* IPP port number */
-  char                 str_buffer[1024];
+  char                 resource[1024], /* Resource path for printer */
+                       str_buffer[1024];
                                        /* C-string buffer */
   const char           *computerName;  /* Computer name c-string ptr */
   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 */
 #ifdef HAVE_COREFOUNDATION_H
   CFStringRef          computerNameRef;/* Computer name CFString */
   CFStringEncoding     nameEncoding;   /* Computer name encoding */
@@ -2570,6 +2588,26 @@ dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
       }
     }
 
+   /*
+    * 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;
+
    /*
     * Use the _fax subtype for fax queues...
     */
@@ -2577,11 +2615,13 @@ dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
     regtype = (p->type & CUPS_PRINTER_FAX) ? dnssdIPPFaxRegType :
                                              dnssdIPPRegType;
 
-    cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdRegisterPrinter(%s) type is \"%s\"",
-                    p->name, regtype);
+
+    cupsdLogMessage(CUPSD_LOG_DEBUG, 
+                   "dnssdRegisterPrinter(%s) type, domain is \"%s\", \"%s\"",
+                   p->name, regtype, domain ? domain : "(null)");
 
     se = DNSServiceRegister(&p->dnssd_ipp_ref, 0, 0, name, regtype, 
-                           NULL, NULL, htons(port), txt_len, txt_record,
+                           domain, NULL, htons(port), txt_len, txt_record,
                            dnssdRegisterCallback, p);
 
    /*
@@ -3653,7 +3693,7 @@ update_cups_browse(void)
       * Access from localhost (127.0.0.1) is always allowed...
       */
 
-      auth = AUTH_ALLOW;
+      auth = CUPSD_AUTH_ALLOW;
     }
     else
     {
@@ -3664,39 +3704,39 @@ update_cups_browse(void)
       switch (BrowseACL->order_type)
       {
         default :
-           auth = AUTH_DENY;   /* anti-compiler-warning-code */
+           auth = CUPSD_AUTH_DENY;     /* anti-compiler-warning-code */
            break;
 
-       case AUTH_ALLOW : /* Order Deny,Allow */
-            auth = AUTH_ALLOW;
+       case CUPSD_AUTH_ALLOW : /* Order Deny,Allow */
+            auth = CUPSD_AUTH_ALLOW;
 
             if (cupsdCheckAuth(address, srcname, len,
                          BrowseACL->num_deny, BrowseACL->deny))
-             auth = AUTH_DENY;
+             auth = CUPSD_AUTH_DENY;
 
             if (cupsdCheckAuth(address, srcname, len,
                          BrowseACL->num_allow, BrowseACL->allow))
-             auth = AUTH_ALLOW;
+             auth = CUPSD_AUTH_ALLOW;
            break;
 
-       case AUTH_DENY : /* Order Allow,Deny */
-            auth = AUTH_DENY;
+       case CUPSD_AUTH_DENY : /* Order Allow,Deny */
+            auth = CUPSD_AUTH_DENY;
 
             if (cupsdCheckAuth(address, srcname, len,
                          BrowseACL->num_allow, BrowseACL->allow))
-             auth = AUTH_ALLOW;
+             auth = CUPSD_AUTH_ALLOW;
 
             if (cupsdCheckAuth(address, srcname, len,
                          BrowseACL->num_deny, BrowseACL->deny))
-             auth = AUTH_DENY;
+             auth = CUPSD_AUTH_DENY;
            break;
       }
     }
   }
   else
-    auth = AUTH_ALLOW;
+    auth = CUPSD_AUTH_ALLOW;
 
-  if (auth == AUTH_DENY)
+  if (auth == CUPSD_AUTH_DENY)
   {
     cupsdLogMessage(CUPSD_LOG_DEBUG,
                     "update_cups_browse: Refused %d bytes from %s", bytes,
@@ -3872,16 +3912,15 @@ update_lpd(int onoff)                   /* - 1 = turn on, 0 = turn off */
         snprintf(line, sizeof(line), "\tdisable = %s",
                 onoff ? "no" : "yes");
       }
-      else if (strstr(line, "disable ="))
-        continue;
-
-      cupsFilePrintf(nfp, "%s\n", line);
+      else if (!strstr(line, "disable ="))
+        cupsFilePrintf(nfp, "%s\n", line);
     }
 
     cupsFileClose(nfp);
     cupsFileClose(ofp);
     rename(newfile, LPDConfigFile + 9);
   }
+#ifdef __APPLE__
   else if (!strncmp(LPDConfigFile, "launchd:///", 11))
   {
    /*
@@ -3900,8 +3939,12 @@ update_lpd(int onoff)                    /* - 1 = turn on, 0 = turn off */
     argv[3] = LPDConfigFile + 10;
     argv[4] = NULL;
 
-    cupsdStartProcess("/bin/launchctl", argv, envp, -1, -1, -1, -1, -1, 1, &pid);
+    cupsdStartProcess("/bin/launchctl", argv, envp, -1, -1, -1, -1, -1, 1,
+                      NULL, &pid);
   }
+#endif /* __APPLE__ */
+  else
+    cupsdLogMessage(CUPSD_LOG_INFO, "Unknown LPDConfigFile scheme!");
 }
 
 
@@ -3997,26 +4040,8 @@ update_smb(int onoff)                    /* I - 1 = turn on, 0 = turn off */
     cupsFileClose(ofp);
     rename(newfile, SMBConfigFile + 8);
   }
-  else if (!strncmp(SMBConfigFile, "launchd:///", 11))
-  {
-   /*
-    * Enable/disable SMB via the launchctl command...
-    */
-
-    char       *argv[5],               /* Arguments for command */
-               *envp[MAX_ENV];         /* Environment for command */
-    int                pid;                    /* Process ID */
-
-
-    cupsdLoadEnv(envp, (int)(sizeof(envp) / sizeof(envp[0])));
-    argv[0] = (char *)"launchctl";
-    argv[1] = (char *)(onoff ? "load" : "unload");
-    argv[2] = (char *)"-w";
-    argv[3] = SMBConfigFile + 10;
-    argv[4] = NULL;
-
-    cupsdStartProcess("/bin/launchctl", argv, envp, -1, -1, -1, -1, -1, 1, &pid);
-  }
+  else
+    cupsdLogMessage(CUPSD_LOG_INFO, "Unknown SMBConfigFile scheme!");
 }