]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/dirsvc.c
Import CUPS trunk (1.4svn) r7116.
[thirdparty/cups.git] / scheduler / dirsvc.c
index d9618adb50daf3f2d739ff89f3b26d64f0d09a1e..5303bf898ff7ba60486815475af9df503f3f6ff8 100644 (file)
@@ -1,25 +1,16 @@
 /*
- * "$Id: dirsvc.c 6590 2007-06-21 18:22:22Z mike $"
+ * "$Id: dirsvc.c 7003 2007-10-01 23:10:13Z mike $"
  *
  *   Directory services routines for the Common UNIX Printing System (CUPS).
  *
+ *   Copyright 2007 by Apple Inc.
  *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  *   These coded instructions, statements, and computer programs are the
- *   property of Easy Software Products and are protected by Federal
- *   copyright law.  Distribution and use rights are outlined in the file
- *   "LICENSE.txt" which should have been included with this file.  If this
- *   file is missing or damaged please contact Easy Software Products
- *   at:
- *
- *       Attn: CUPS Licensing Information
- *       Easy Software Products
- *       44141 Airport View Drive, Suite 204
- *       Hollywood, Maryland 20636 USA
- *
- *       Voice: (301) 373-9600
- *       EMail: cups-info@cups.org
- *         WWW: http://www.cups.org
+ *   property of Apple Inc. and are protected by Federal copyright
+ *   law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+ *   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/".
  *
  * Contents:
  *
@@ -62,7 +53,9 @@
  *   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.
  */
 
 /*
 
 #ifdef HAVE_DNSSD
 #  include <dns_sd.h>
-#  include <nameser.h>
-#  include <nameser.h>
-#  ifdef HAVE_COREFOUNDATION
-#    include <CoreFoundation/CoreFoundation.h>
-#  endif /* HAVE_COREFOUNDATION */
-#  ifdef HAVE_SYSTEMCONFIGURATION
-#    include <SystemConfiguration/SystemConfiguration.h>
-#  endif /* HAVE_SYSTEMCONFIGURATION */
+#  ifdef __APPLE__
+#    include <nameser.h>
+#    ifdef HAVE_COREFOUNDATION
+#      include <CoreFoundation/CoreFoundation.h>
+#    endif /* HAVE_COREFOUNDATION */
+#    ifdef HAVE_SYSTEMCONFIGURATION
+#      include <SystemConfiguration/SystemConfiguration.h>
+#    endif /* HAVE_SYSTEMCONFIGURATION */
+#  endif /* __APPLE__ */
 #endif /* HAVE_DNSSD */
 
 
@@ -97,7 +91,7 @@ static void   process_browse_data(const char *uri, const char *host,
                                    ipp_pstate_t state, const char *location,
                                    const char *info, const char *make_model,
                                    int num_attrs, cups_option_t *attrs);
-static void    process_implicit_classes(void);
+static void    process_implicit_classes(int *write_printcap);
 static void    send_cups_browse(cupsd_printer_t *p);
 #ifdef HAVE_LDAP
 static void    send_ldap_browse(cupsd_printer_t *p);
@@ -106,7 +100,9 @@ static void send_ldap_browse(cupsd_printer_t *p);
 static void    send_slp_browse(cupsd_printer_t *p);
 #endif /* HAVE_LIBSLP */
 static void    update_cups_browse(void);
+static void    update_lpd(int onoff);
 static void    update_polling(void);
+static void    update_smb(int onoff);
 
 
 #ifdef HAVE_OPENLDAP
@@ -206,7 +202,7 @@ cupsdDeregisterPrinter(
   * Announce the deletion...
   */
 
-  if ((BrowseLocalProtocols & BROWSE_CUPS))
+  if ((BrowseLocalProtocols & BROWSE_CUPS) && BrowseSocket >= 0)
   {
     cups_ptype_t savedtype = p->type;  /* Saved printer type */
 
@@ -613,7 +609,7 @@ cupsdLoadRemoteCache(void)
   * Do auto-classing if needed...
   */
 
-  process_implicit_classes();
+  process_implicit_classes(NULL);
 }
 
 
@@ -798,6 +794,7 @@ cupsdSendBrowseList(void)
   cupsd_printer_t      *p;             /* Current printer */
   time_t               ut,             /* Minimum update time */
                        to;             /* Timeout time */
+  int                  write_printcap; /* Write the printcap file? */
 
 
   if (!Browsing || !BrowseLocalProtocols || !Printers)
@@ -869,7 +866,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
@@ -895,7 +892,7 @@ cupsdSendBrowseList(void)
   * Loop through all of the printers and send local updates as needed...
   */
 
-  for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
+  for (p = (cupsd_printer_t *)cupsArrayFirst(Printers), write_printcap = 0;
        p;
        p = (cupsd_printer_t *)cupsArrayNext(Printers))
   {
@@ -920,9 +917,13 @@ cupsdSendBrowseList(void)
         cupsArraySave(Printers);
         cupsdDeletePrinter(p, 1);
         cupsArrayRestore(Printers);
+       write_printcap = 1;
       }
     }
   }
+
+  if (write_printcap)
+    cupsdWritePrintcap();
 }
 
 
@@ -954,8 +955,8 @@ cupsdStartBrowsing(void)
       if ((BrowseSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
       {
        cupsdLogMessage(CUPSD_LOG_ERROR,
-                       "cupsdStartBrowsing: Unable to create broadcast "
-                       "socket - %s.", strerror(errno));
+                       "Unable to create broadcast socket - %s.",
+                       strerror(errno));
        BrowseLocalProtocols &= ~BROWSE_CUPS;
        BrowseRemoteProtocols &= ~BROWSE_CUPS;
        return;
@@ -973,8 +974,8 @@ cupsdStartBrowsing(void)
       if (bind(BrowseSocket, (struct sockaddr *)&addr, sizeof(addr)))
       {
        cupsdLogMessage(CUPSD_LOG_ERROR,
-                       "cupsdStartBrowsing: Unable to bind broadcast "
-                       "socket - %s.", strerror(errno));
+                       "Unable to bind broadcast socket - %s.",
+                       strerror(errno));
 
 #ifdef WIN32
        closesocket(BrowseSocket);
@@ -996,8 +997,7 @@ cupsdStartBrowsing(void)
     val = 1;
     if (setsockopt(BrowseSocket, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val)))
     {
-      cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "cupsdStartBrowsing: Unable to set broadcast mode - %s.",
+      cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to set broadcast mode - %s.",
                      strerror(errno));
 
 #ifdef WIN32
@@ -1077,6 +1077,24 @@ cupsdStartBrowsing(void)
       struct berval    bv = {0, ""};   /* SASL bind value */
 
 
+     /*
+      * Set the certificate file to use for encrypted LDAP sessions...
+      */
+
+      if (BrowseLDAPCACertFile)
+      {
+       cupsdLogMessage(CUPSD_LOG_DEBUG,
+                       "cupsdStartBrowsing: Setting CA certificate file \"%s\"",
+                       BrowseLDAPCACertFile);
+
+        if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
+                                 (void *)BrowseLDAPCACertFile))
+               != LDAP_SUCCESS)
+          cupsdLogMessage(CUPSD_LOG_ERROR,
+                          "Unable to set CA certificate file for LDAP "
+                         "connections: %d - %s", rc, ldap_err2string(rc));
+      }
+
      /*
       * LDAP stuff currently only supports ldapi EXTERNAL SASL binds...
       */
@@ -1129,6 +1147,16 @@ cupsdStartBrowsing(void)
   }
 #endif /* HAVE_OPENLDAP */
 
+ /*
+  * Enable LPD and SMB printer sharing as needed through external programs...
+  */
+
+  if (BrowseLocalProtocols & BROWSE_LPD)
+    update_lpd(1);
+
+  if (BrowseLocalProtocols & BROWSE_SMB)
+    update_smb(1);
+
  /*
   * Register the individual printers
   */
@@ -1309,6 +1337,16 @@ cupsdStopBrowsing(void)
     BrowseLDAPHandle = NULL;
   }
 #endif /* HAVE_OPENLDAP */
+
+ /*
+  * Disable LPD and SMB printer sharing as needed through external programs...
+  */
+
+  if (BrowseLocalProtocols & BROWSE_LPD)
+    update_lpd(0);
+
+  if (BrowseLocalProtocols & BROWSE_SMB)
+    update_smb(0);
 }
 
 
@@ -1652,7 +1690,8 @@ process_browse_data(
     cups_option_t *attrs)              /* I - Attributes */
 {
   int          i;                      /* Looping var */
-  int          update;                 /* Update printer attributes? */
+  int          update,                 /* Update printer attributes? */
+               write_printcap;         /* Write the printcap file? */
   char         finaluri[HTTP_MAX_URI], /* Final URI for printer */
                name[IPP_MAX_NAME],     /* Name of printer */
                newname[IPP_MAX_NAME],  /* New name of printer */
@@ -1739,11 +1778,12 @@ process_browse_data(
   * See if we already have it listed in the Printers list, and add it if not...
   */
 
-  type   |= CUPS_PRINTER_REMOTE | CUPS_PRINTER_DISCOVERED;
-  type   &= ~CUPS_PRINTER_IMPLICIT;
-  update = 0;
-  hptr   = strchr(host, '.');
-  sptr   = strchr(ServerName, '.');
+  type           |= CUPS_PRINTER_REMOTE | CUPS_PRINTER_DISCOVERED;
+  type           &= ~CUPS_PRINTER_IMPLICIT;
+  update         = 0;
+  write_printcap = 0;
+  hptr           = strchr(host, '.');
+  sptr           = strchr(ServerName, '.');
 
   if (!ServerNameIsIP && sptr != NULL && hptr != NULL)
   {
@@ -1866,7 +1906,8 @@ process_browse_data(
       cupsdSetString(&p->device_uri, uri);
       cupsdSetString(&p->hostname, host);
 
-      update = 1;
+      update         = 1;
+      write_printcap = 1;
     }
   }
   else
@@ -1972,7 +2013,8 @@ process_browse_data(
       cupsdSetString(&p->uri, uri);
       cupsdSetString(&p->device_uri, uri);
 
-      update = 1;
+      write_printcap = 1;
+      update         = 1;
     }
   }
 
@@ -2031,7 +2073,8 @@ process_browse_data(
   if (info && (!p->info || strcmp(p->info, info)))
   {
     cupsdSetString(&p->info, info);
-    update = 1;
+    update         = 1;
+    write_printcap = 1;
   }
 
   if (!make_model || !make_model[0])
@@ -2096,6 +2139,7 @@ process_browse_data(
  
     cupsdDeletePrinter(p, 1);
     cupsdUpdateImplicitClasses();
+    write_printcap = 1;
   }
   else if (update)
   {
@@ -2120,6 +2164,7 @@ process_browse_data(
       if (p->type & CUPS_PRINTER_DEFAULT)
       {
         DefaultPrinter = p;
+       write_printcap = 1;
        break;
       }
   }
@@ -2128,13 +2173,14 @@ process_browse_data(
   * Do auto-classing if needed...
   */
 
-  process_implicit_classes();
+  process_implicit_classes(&write_printcap);
 
  /*
   * Update the printcap file...
   */
 
-  cupsdWritePrintcap();
+  if (write_printcap)
+    cupsdWritePrintcap();
 }
 
 
@@ -2624,7 +2670,8 @@ dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
  */
 
 static void
-process_implicit_classes(void)
+process_implicit_classes(
+    int *write_printcap)               /* O - Write printcap file? */
 {
   int          i;                      /* Looping var */
   int          update;                 /* Update printer attributes? */
@@ -2705,6 +2752,9 @@ process_implicit_classes(void)
 
         update = 1;
 
+       if (write_printcap)
+         *write_printcap = 1;
+
         cupsdLogMessage(CUPSD_LOG_DEBUG, "Added implicit class \"%s\"...",
                        name);
        cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED, p, NULL,
@@ -3771,6 +3821,90 @@ update_cups_browse(void)
 }
 
 
+/*
+ * 'update_lpd()' - Update the LPD configuration as needed.
+ */
+
+static void
+update_lpd(int onoff)                  /* - 1 = turn on, 0 = turn off */
+{
+  if (!LPDConfigFile)
+    return;
+
+  if (!strncmp(LPDConfigFile, "xinetd:///", 10))
+  {
+   /*
+    * Enable/disable LPD via the xinetd.d config file for cups-lpd...
+    */
+
+    char       newfile[1024];          /* New cups-lpd.N file */
+    cups_file_t        *ofp,                   /* Original file pointer */
+               *nfp;                   /* New file pointer */
+    char       line[1024];             /* Line from file */
+
+
+    snprintf(newfile, sizeof(newfile), "%s.N", LPDConfigFile + 9);
+
+    if ((ofp = cupsFileOpen(LPDConfigFile + 9, "r")) == NULL)
+    {
+      cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open \"%s\" - %s",
+                      LPDConfigFile + 9, strerror(errno));
+      return;
+    }
+
+    if ((nfp = cupsFileOpen(newfile, "w")) == NULL)
+    {
+      cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create \"%s\" - %s",
+                      newfile, strerror(errno));
+      cupsFileClose(ofp);
+      return;
+    }
+
+   /*
+    * Copy all of the lines from the cups-lpd file...
+    */
+
+    while (cupsFileGets(ofp, line, sizeof(line)))
+    {
+      if (line[0] == '{')
+      {
+        cupsFilePrintf(nfp, "%s\n", line);
+        snprintf(line, sizeof(line), "\tdisable = %s",
+                onoff ? "no" : "yes");
+      }
+      else if (strstr(line, "disable ="))
+        continue;
+
+      cupsFilePrintf(nfp, "%s\n", line);
+    }
+
+    cupsFileClose(nfp);
+    cupsFileClose(ofp);
+    rename(newfile, LPDConfigFile + 9);
+  }
+  else if (!strncmp(LPDConfigFile, "launchd:///", 11))
+  {
+   /*
+    * Enable/disable LPD 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] = LPDConfigFile + 10;
+    argv[4] = NULL;
+
+    cupsdStartProcess("/bin/launchctl", argv, envp, -1, -1, -1, -1, -1, 1, &pid);
+  }
+}
+
+
 /*
  * 'update_polling()' - Read status messages from the poll daemons.
  */
@@ -3802,5 +3936,90 @@ update_polling(void)
 
 
 /*
- * End of "$Id: dirsvc.c 6590 2007-06-21 18:22:22Z mike $".
+ * 'update_smb()' - Update the SMB configuration as needed.
+ */
+
+static void
+update_smb(int onoff)                  /* I - 1 = turn on, 0 = turn off */
+{
+  if (!SMBConfigFile)
+    return;
+
+  if (!strncmp(SMBConfigFile, "samba:///", 9))
+  {
+   /*
+    * Enable/disable SMB via the specified smb.conf config file...
+    */
+
+    char       newfile[1024];          /* New smb.conf.N file */
+    cups_file_t        *ofp,                   /* Original file pointer */
+               *nfp;                   /* New file pointer */
+    char       line[1024];             /* Line from file */
+    int                in_printers;            /* In [printers] section? */
+
+
+    snprintf(newfile, sizeof(newfile), "%s.N", SMBConfigFile + 8);
+
+    if ((ofp = cupsFileOpen(SMBConfigFile + 8, "r")) == NULL)
+    {
+      cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open \"%s\" - %s",
+                      SMBConfigFile + 8, strerror(errno));
+      return;
+    }
+
+    if ((nfp = cupsFileOpen(newfile, "w")) == NULL)
+    {
+      cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create \"%s\" - %s",
+                      newfile, strerror(errno));
+      cupsFileClose(ofp);
+      return;
+    }
+
+   /*
+    * Copy all of the lines from the smb.conf file...
+    */
+
+    in_printers = 0;
+
+    while (cupsFileGets(ofp, line, sizeof(line)))
+    {
+      if (in_printers && strstr(line, "printable ="))
+        snprintf(line, sizeof(line), "    printable = %s",
+                onoff ? "yes" : "no");
+
+      cupsFilePrintf(nfp, "%s\n", line);
+
+      if (line[0] == '[')
+        in_printers = !strcmp(line, "[printers]");
+    }
+
+    cupsFileClose(nfp);
+    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);
+  }
+}
+
+
+/*
+ * End of "$Id: dirsvc.c 7003 2007-10-01 23:10:13Z mike $".
  */