]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
<rdar://problem/15939788> Improve CUPS sandboxing
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Tue, 11 Feb 2014 15:06:01 +0000 (15:06 +0000)
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Tue, 11 Feb 2014 15:06:01 +0000 (15:06 +0000)
- Use separate profiles for filters and backends.
- Add Sandboxing configuration directive to control whether a strict or relaxed
  profile is used.
- The new strict profile is a whitelist profile that does not allow unlimited
  networking, among other things.

git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@11576 a1ca3aef-8c08-0410-bb20-df032aa958be

14 files changed:
doc/help/man-cups-files.conf.html
doc/help/ref-cups-files-conf.html.in
man/cups-files.conf.man.in
scheduler/conf.c
scheduler/conf.h
scheduler/cups-exec.c
scheduler/cupsd.h
scheduler/job.c
scheduler/job.h
scheduler/main.c
scheduler/process.c
scheduler/server.c
test/run-stp-tests.sh
xcode/CUPS.xcodeproj/project.pbxproj

index 3e30a9d98d5a47b35105bae38aeeebf3db1e48e8..b6d3afecdb8f27d4953d39876efa5e6a910d3256 100644 (file)
@@ -119,21 +119,26 @@ accesses.
 <dd>Specifies the directory to store print jobs and other HTTP request
 data.
 </dd>
-<dt>ServerBin directory
+<dt>Sandboxing off
 </dt>
 <dd></dd>
-<dd>Specifies the directory where backends, CGIs, daemons, and filters may
-be found.
+<dt>Sandboxing relaxed
+</dt>
+<dd></dd>
+<dt>Sandboxing strict
+</dt>
+<dd>Specifies the level of security sandboxing that is applied to print filters, backends, and other child processes of the scheduler. The default is "strict". (OS X only)
 </dd>
-<dt>ServerCertificate filename
+<dt>ServerBin directory
 </dt>
 <dd></dd>
-<dd>Specifies the encryption certificate to use.
+<dd>Specifies the directory where backends, CGIs, daemons, and filters may
+be found.
 </dd>
-<dt>ServerKey filename
+<dt>ServerKeychain path
 </dt>
 <dd></dd>
-<dd>Specifies the encryption key to use.
+<dd>Specifies the location of TLS certificates and private keys.
 </dd>
 <dt>ServerRoot directory
 </dt>
@@ -171,7 +176,7 @@ or state files. The default is No.
 <br>
 <a href='http://localhost:631/help'>http://localhost:631/help</a>
 <h2 class="title"><a name="COPYRIGHT">Copyright</a></h2>
-Copyright 2007-2013 by Apple Inc.
+Copyright 2007-2014 by Apple Inc.
 
 </body>
 </html>
index 70c996f4a3b7f2d6c2f636cad35b11764c1213b0..4b7003a51eec13bc74a441ffb6c2f916421eb277 100644 (file)
@@ -354,62 +354,55 @@ HREF="#ServerRoot"><CODE>ServerRoot</CODE></A> directory. The
 default request directory is <VAR>/var/spool/cups</VAR>.</P>
 
 
-<H2 CLASS="title"><A NAME="ServerBin">ServerBin</A></H2>
+<H2 CLASS="title"><SPAN CLASS="info">CUPS 2.0</SPAN><A NAME="Sandboxing">Sandboxing</A> (OS X Only)</H2>
 
 <H3>Examples</H3>
 
 <PRE CLASS="command">
-ServerBin /usr/lib/cups
-ServerBin /foo/bar/lib/cups
+Sandboxing off
+Sandboxing relaxed
+Sandboxing strict
 </PRE>
 
 <H3>Description</H3>
 
-<P>The <CODE>ServerBin</CODE> directive sets the directory for
-server-run executables. If an absolute path is not provided then
-it is assumed to be relative to the <A
-HREF="#ServerRoot"><CODE>ServerRoot</CODE></A> directory. The
-default executable directory is <VAR>/usr/lib/cups</VAR>,
-<VAR>/usr/lib32/cups</VAR>, or <VAR>/usr/libexec/cups</VAR>
-depending on the operating system.</P>
+<P>The <CODE>Sandboxing</CODE> directive sets the default level of security sandboxing that is applied to print filters, backend, and other child processes. The default value is <CODE>strict</CODE>. Sandboxing is currently only supported on OS X.</P>
 
 
-<H2 CLASS="title"><A NAME="ServerCertificate">ServerCertificate</A></H2>
+<H2 CLASS="title"><A NAME="ServerBin">ServerBin</A></H2>
 
 <H3>Examples</H3>
 
 <PRE CLASS="command">
-ServerCertificate /etc/cups/ssl/server.crt
+ServerBin /usr/lib/cups
+ServerBin /foo/bar/lib/cups
 </PRE>
 
 <H3>Description</H3>
 
-<P>The <CODE>ServerCertificate</CODE> directive specifies the
-location of the SSL certificate file used by the server when
-negotiating encrypted connections. The certificate must not be
-encrypted (password protected) since the scheduler normally runs
-in the background and will be unable to ask for a password.</P>
-
-<P>The default certificate file is
-<VAR>/etc/cups/ssl/server.crt</VAR>.</P>
+<P>The <CODE>ServerBin</CODE> directive sets the directory for
+server-run executables. If an absolute path is not provided then
+it is assumed to be relative to the <A
+HREF="#ServerRoot"><CODE>ServerRoot</CODE></A> directory. The
+default executable directory is <VAR>/usr/lib/cups</VAR>,
+<VAR>/usr/lib32/cups</VAR>, or <VAR>/usr/libexec/cups</VAR>
+depending on the operating system.</P>
 
 
-<H2 CLASS="title"><A NAME="ServerKey">ServerKey</A></H2>
+<H2 CLASS="title"><SPAN CLASS="info">CUPS 2.0</SPAN><A NAME="ServerKeychain">ServerKeychain</A></H2>
 
 <H3>Examples</H3>
 
 <PRE CLASS="command">
-ServerKey /etc/cups/ssl/server.key
+ServerKeychain /etc/cups/ssl
+ServerKeychain /Library/Keychains/system.keychain
 </PRE>
 
 <H3>Description</H3>
 
-<P>The <CODE>ServerKey</CODE> directive specifies the location of
-the SSL private key file used by the server when negotiating
-encrypted connections.</P>
+<P>The <CODE>ServerKeychain</CODE> directive specifies the location of TLS certificates and private keys used when negotiating encrypted connections.</P>
 
-<P>The default key file is
-<VAR>/etc/cups/ssl/server.crt</VAR>.</P>
+<P>The default keychain is system-specific.</P>
 
 
 <H2 CLASS="title"><A NAME="ServerRoot">ServerRoot</A></H2>
index c17490cf15aa493e85c2d4eed8e59a766784b3de..054227f271857c747781e033d48a0d008f6e18f0 100644 (file)
@@ -1,18 +1,18 @@
 .\"
 .\" "$Id$"
 .\"
-.\"   cupsd.conf man page for CUPS.
+.\" cupsd.conf man page for CUPS.
 .\"
-.\"   Copyright 2007-2013 by Apple Inc.
-.\"   Copyright 1997-2006 by Easy Software Products.
+.\" Copyright 2007-2014 by Apple Inc.
+.\" Copyright 1997-2006 by Easy Software Products.
 .\"
-.\"   These coded instructions, statements, and computer programs are the
-.\"   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/".
+.\" These coded instructions, statements, and computer programs are the
+.\" 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/".
 .\"
-.TH cups-files.conf 5 "CUPS" "26 July 2013" "Apple Inc."
+.TH cups-files.conf 5 "CUPS" "6 February 2014" "Apple Inc."
 .SH NAME
 cups-files.conf \- file and directory configuration file for cups
 .SH DESCRIPTION
@@ -105,18 +105,21 @@ RequestRoot directory
 Specifies the directory to store print jobs and other HTTP request
 data.
 .TP 5
+Sandboxing off
+.TP 5
+Sandboxing relaxed
+.TP 5
+Sandboxing strict
+Specifies the level of security sandboxing that is applied to print filters, backends, and other child processes of the scheduler. The default is "strict". (OS X only)
+.TP 5
 ServerBin directory
 .br
 Specifies the directory where backends, CGIs, daemons, and filters may
 be found.
 .TP 5
-ServerCertificate filename
-.br
-Specifies the encryption certificate to use.
-.TP 5
-ServerKey filename
+ServerKeychain path
 .br
-Specifies the encryption key to use.
+Specifies the location of TLS certificates and private keys.
 .TP 5
 ServerRoot directory
 .br
@@ -146,7 +149,7 @@ Specifies the user name or ID that is used when running external programs.
 .br
 http://localhost:631/help
 .SH COPYRIGHT
-Copyright 2007-2013 by Apple Inc.
+Copyright 2007-2014 by Apple Inc.
 .\"
 .\" End of "$Id$".
 .\"
index ebd065b769a09e5b3329210a45f627fedc976822..123f775d6818e0cedf8990959aae4fb6af5b73d0 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Configuration routines for the CUPS scheduler.
  *
- * Copyright 2007-2013 by Apple Inc.
+ * Copyright 2007-2014 by Apple Inc.
  * Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  * These coded instructions, statements, and computer programs are the
@@ -707,6 +707,7 @@ cupsdReadConfiguration(void)
   NumSystemGroups          = 0;
   ReloadTimeout                   = DEFAULT_KEEPALIVE;
   RootCertDuration         = 300;
+  Sandboxing               = CUPSD_SANDBOXING_STRICT;
   StrictConformance        = FALSE;
   SyncOnClose              = FALSE;
   Timeout                  = DEFAULT_TIMEOUT;
@@ -3419,6 +3420,30 @@ read_cups_files_conf(cups_file_t *fp)    /* I - File to read from */
           return (0);
       }
     }
+    else if (!_cups_strcasecmp(line, "Sandboxing") && value)
+    {
+     /*
+      * Level of sandboxing?
+      */
+
+      if (!_cups_strcasecmp(value, "off"))
+      {
+        Sandboxing = CUPSD_SANDBOXING_OFF;
+        cupsdLogMessage(CUPSD_LOG_WARN, "Disabling sandboxing is not recommended (line %d of %s)", linenum, CupsFilesFile);
+      }
+      else if (!_cups_strcasecmp(value, "relaxed"))
+        Sandboxing = CUPSD_SANDBOXING_RELAXED;
+      else if (!_cups_strcasecmp(value, "strict"))
+        Sandboxing = CUPSD_SANDBOXING_STRICT;
+      else
+      {
+       cupsdLogMessage(CUPSD_LOG_ERROR,
+                       "Unknown Sandboxing \"%s\" on line %d of %s.",
+                       value, linenum, CupsFilesFile);
+        if (FatalErrors & CUPSD_FATAL_CONFIG)
+          return (0);
+      }
+    }
     else if (!_cups_strcasecmp(line, "SystemGroup") && value)
     {
      /*
index 949eb8bbe8c7ae78b90adba6fde828c57ee6d9d1..9d3caa2c41f1816ca09a63ccf1efc7f4be7665c8 100644 (file)
@@ -50,6 +50,13 @@ typedef enum
   CUPSD_TIME_USECS                     /* Standard format with microseconds */
 } cupsd_time_t;
 
+typedef enum
+{
+  CUPSD_SANDBOXING_OFF,                        /* No sandboxing */
+  CUPSD_SANDBOXING_RELAXED,            /* Relaxed sandboxing */
+  CUPSD_SANDBOXING_STRICT              /* Strict sandboxing */
+} cupsd_sandboxing_t;
+
 
 /*
  * FatalErrors flags...
@@ -174,6 +181,10 @@ VAR cupsd_loglevel_t       LogLevel                VALUE(CUPSD_LOG_WARN);
                                        /* Error log level */
 VAR cupsd_time_t       LogTimeFormat           VALUE(CUPSD_TIME_STANDARD);
                                        /* Log file time format */
+VAR cupsd_sandboxing_t Sandboxing              VALUE(CUPSD_SANDBOXING_STRICT);
+                                       /* Sandboxing level */
+VAR int                        UseSandboxing   VALUE(1);
+                                       /* Use sandboxing for child procs? */
 VAR int                        MaxClients              VALUE(100),
                                        /* Maximum number of clients */
                        MaxClientsPerHost       VALUE(0),
index 0d8a764d78f78d77358019d2b6f3720b0cc0cf8a..ecbc6bbc64c9e2569ba60dc2515ddcd4c69fe1dd 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <cups/string-private.h>
+#include <cups/file.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/stat.h>
@@ -66,21 +67,6 @@ main(int  argc,                              /* I - Number of command-line args */
   fcntl(3, F_SETFL, O_NDELAY);
   fcntl(4, F_SETFL, O_NDELAY);
 
-#ifdef HAVE_SANDBOX_H
- /*
-  * Run in a separate security profile...
-  */
-
-  if (strcmp(argv[1], "none") &&
-      sandbox_init(argv[1], SANDBOX_NAMED_EXTERNAL, &sandbox_error))
-  {
-    fprintf(stderr, "DEBUG: sandbox_init failed: %s (%s)\n", sandbox_error,
-           strerror(errno));
-    sandbox_free_error(sandbox_error);
-    return (1);
-  }
-#endif /* HAVE_SANDBOX_H */
-
  /*
   * Change UID, GID, and nice value...
   */
@@ -106,18 +92,42 @@ main(int  argc,                            /* I - Number of command-line args */
 
   umask(077);
 
+#ifdef HAVE_SANDBOX_H
  /*
-  * Execute the program...
+  * Run in a separate security profile...
   */
 
-  execv(argv[5], argv + 6);
+  if (strcmp(argv[1], "none") &&
+      sandbox_init(argv[1], SANDBOX_NAMED_EXTERNAL, &sandbox_error))
+  {
+    cups_file_t        *fp;                    /* File */
+    char       line[1024];             /* Line from file */
+    int                linenum = 0;            /* Line number in file */
+
+    fprintf(stderr, "DEBUG: sandbox_init failed: %s (%s)\n", sandbox_error,
+           strerror(errno));
+    sandbox_free_error(sandbox_error);
+
+    if ((fp = cupsFileOpen(argv[1], "r")) != NULL)
+    {
+      while (cupsFileGets(fp, line, sizeof(line)))
+      {
+        linenum ++;
+        fprintf(stderr, "DEBUG: %4d  %s\n", linenum, line);
+      }
+      cupsFileClose(fp);
+    }
+
+    return (100 + EINVAL);
+  }
+#endif /* HAVE_SANDBOX_H */
 
  /*
   * If we get here, execv() failed...
   */
 
   fprintf(stderr, "DEBUG: execv failed: %s\n", strerror(errno));
-  return (1);
+  return (errno + 100);
 }
 
 
index ddd642b8db754bae8e354c05cf6e6ebe18b5cdf9..12806624605968abb96037e87a744491dd80c67f 100644 (file)
@@ -1,16 +1,16 @@
 /*
  * "$Id$"
  *
- *   Main header file for the CUPS scheduler.
+ * Main header file for the CUPS scheduler.
  *
- *   Copyright 2007-2013 by Apple Inc.
- *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2014 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
- *   These coded instructions, statements, and computer programs are the
- *   property of Apple Inc. and are protected by Federal copyright
- *   law.  Distribution and use rights are outlined in the file "LICENSE.txt"
- *   "LICENSE" which should have been included with this file.  If this
- *   file is missing or damaged, see the license at "http://www.cups.org/".
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+ * "LICENSE" which should have been included with this file.  If this
+ * file is missing or damaged, see the license at "http://www.cups.org/".
  */
 
 
@@ -144,10 +144,8 @@ typedef void (*cupsd_selfunc_t)(void *data);
  * Globals...
  */
 
-VAR int                        TestConfigFile  VALUE(0),
+VAR int                        TestConfigFile  VALUE(0);
                                        /* Test the cupsd.conf file? */
-                       UseProfiles     VALUE(1);
-                                       /* Use security profiles for child procs? */
 VAR int                        MaxFDs          VALUE(0);
                                        /* Maximum number of files */
 
@@ -203,7 +201,7 @@ extern void         cupsdSetStringf(char **s, const char *f, ...)
                        __attribute__ ((__format__ (__printf__, 2, 3)));
 
 /* process.c */
-extern void            *cupsdCreateProfile(int job_id);
+extern void            *cupsdCreateProfile(int job_id, int allow_networking);
 extern void            cupsdDestroyProfile(void *profile);
 extern int             cupsdEndProcess(int pid, int force);
 extern const char      *cupsdFinishProcess(int pid, char *name, int namelen,
index 42a39bf65300059a552ee4a96eac99f4c341c88d..2af8785ce1063e6e7f2bfbb1a0540e880a07fe5b 100644 (file)
@@ -1218,7 +1218,7 @@ cupsdContinueJob(cupsd_job_t *job)        /* I - Job */
       pid = cupsdStartProcess(command, argv, envp, filterfds[!slot][0],
                              filterfds[slot][1], job->status_pipes[1],
                              job->back_pipes[1], job->side_pipes[1],
-                             backroot, job->profile, job, &(job->backend));
+                             backroot, job->bprofile, job, &(job->backend));
 
       if (pid == 0)
       {
@@ -2963,6 +2963,8 @@ finalize_job(cupsd_job_t *job,            /* I - Job */
 
   cupsdDestroyProfile(job->profile);
   job->profile = NULL;
+  cupsdDestroyProfile(job->bprofile);
+  job->bprofile = NULL;
 
  /*
   * Clear the unresponsive job watchdog timers...
@@ -4504,8 +4506,9 @@ start_job(cupsd_job_t     *job,           /* I - Job ID */
   * Setup the last exit status and security profiles...
   */
 
-  job->status  = 0;
-  job->profile = cupsdCreateProfile(job->id);
+  job->status   = 0;
+  job->profile  = cupsdCreateProfile(job->id, 0);
+  job->bprofile = cupsdCreateProfile(job->id, 1);
 
  /*
   * Create the status pipes and buffer...
@@ -4522,6 +4525,8 @@ start_job(cupsd_job_t     *job,           /* I - Job ID */
 
     cupsdDestroyProfile(job->profile);
     job->profile = NULL;
+    cupsdDestroyProfile(job->bprofile);
+    job->bprofile = NULL;
     return;
   }
 
@@ -4547,6 +4552,8 @@ start_job(cupsd_job_t     *job,           /* I - Job ID */
 
     cupsdDestroyProfile(job->profile);
     job->profile = NULL;
+    cupsdDestroyProfile(job->bprofile);
+    job->bprofile = NULL;
     return;
   }
 
@@ -4576,6 +4583,8 @@ start_job(cupsd_job_t     *job,           /* I - Job ID */
 
     cupsdDestroyProfile(job->profile);
     job->profile = NULL;
+    cupsdDestroyProfile(job->bprofile);
+    job->bprofile = NULL;
     return;
   }
 
index 29032263bf20b4938f1bc6d43b286af390261de2..d13bb97b37778ba009b6baec38c44ab128172dd9 100644 (file)
@@ -78,7 +78,8 @@ struct cupsd_job_s                    /**** Job request ****/
   char                 *auth_env[3],   /* AUTH_xxx environment variables,
                                          * if any */
                        *auth_uid;      /* AUTH_UID environment variable */
-  void                 *profile;       /* Security profile */
+  void                 *profile,       /* Security profile for filters */
+                       *bprofile;      /* Security profile for backend */
   cups_array_t         *history;       /* Debug log history */
   int                  progress;       /* Printing progress */
   int                  num_keywords;   /* Number of PPD keywords */
index 162c4df486cf6c76f011d22ba2b5d2abbffb6857..2cd89c996ab129eee6806a2bdc50fdb5ab7fb897 100644 (file)
@@ -243,9 +243,8 @@ main(int  argc,                             /* I - Number of command-line args */
              break;
 
           case 'P' : /* Disable security profiles */
-              fputs("cupsd: -P (disable security profiles) is for internal "
-                    "testing use only!\n", stderr);
-             UseProfiles = 0;
+              fputs("cupsd: -P (disable sandboxing) is for internal testing use only.\n", stderr);
+             UseSandboxing = 0;
              break;
 
           case 's' : /* Set cups-files.conf location */
index 97da1eaa231987e65d0f10e8f67b6faba63e54fc..e01f639c8e8ecba085dd19bcf031d961498b1607 100644 (file)
@@ -62,34 +62,36 @@ static char *cupsd_requote(char *dst, const char *src, size_t dstsize);
  */
 
 void *                                 /* O - Profile or NULL on error */
-cupsdCreateProfile(int job_id)         /* I - Job ID or 0 for none */
+cupsdCreateProfile(int job_id,         /* I - Job ID or 0 for none */
+                   int allow_networking)/* I - Allow networking off machine? */
 {
 #ifdef HAVE_SANDBOX_H
-  cups_file_t  *fp;                    /* File pointer */
-  char         profile[1024],          /* File containing the profile */
-               cache[1024],            /* Quoted CacheDir */
-               request[1024],          /* Quoted RequestRoot */
-               root[1024],             /* Quoted ServerRoot */
-               temp[1024];             /* Quoted TempDir */
-  const char   *nodebug;               /* " (with no-log)" for no debug */
-
-
-  if (!UseProfiles)
+  cups_file_t          *fp;            /* File pointer */
+  char                 profile[1024],  /* File containing the profile */
+                       bin[1024],      /* Quoted ServerBin */
+                       cache[1024],    /* Quoted CacheDir */
+                       domain[1024],   /* Domain socket, if any */
+                       request[1024],  /* Quoted RequestRoot */
+                       root[1024],     /* Quoted ServerRoot */
+                       temp[1024];     /* Quoted TempDir */
+  const char           *nodebug;       /* " (with no-log)" for no debug */
+  cupsd_listener_t     *lis;           /* Current listening socket */
+
+
+  if (!UseSandboxing || Sandboxing == CUPSD_SANDBOXING_OFF)
   {
    /*
     * Only use sandbox profiles as root...
     */
 
-    cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d) = NULL",
-                    job_id);
+    cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d, allow_networking=%d) = NULL", job_id, allow_networking);
 
     return (NULL);
   }
 
   if ((fp = cupsTempFile2(profile, sizeof(profile))) == NULL)
   {
-    cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d) = NULL",
-                    job_id);
+    cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d, allow_networking=%d) = NULL", job_id, allow_networking);
     cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create security profile: %s",
                     strerror(errno));
     return (NULL);
@@ -98,6 +100,7 @@ cupsdCreateProfile(int job_id)               /* I - Job ID or 0 for none */
   fchown(cupsFileNumber(fp), RunUser, Group);
   fchmod(cupsFileNumber(fp), 0640);
 
+  cupsd_requote(bin, ServerBin, sizeof(bin));
   cupsd_requote(cache, CacheDir, sizeof(cache));
   cupsd_requote(request, RequestRoot, sizeof(request));
   cupsd_requote(root, ServerRoot, sizeof(root));
@@ -106,10 +109,22 @@ cupsdCreateProfile(int job_id)            /* I - Job ID or 0 for none */
   nodebug = LogLevel < CUPSD_LOG_DEBUG ? " (with no-log)" : "";
 
   cupsFilePuts(fp, "(version 1)\n");
-  cupsFilePuts(fp, "(allow default)\n");
+  if (Sandboxing == CUPSD_SANDBOXING_STRICT)
+    cupsFilePuts(fp, "(deny default)\n");
+  else
+    cupsFilePuts(fp, "(allow default)\n");
+  if (LogLevel >= CUPSD_LOG_DEBUG)
+    cupsFilePuts(fp, "(debug deny)\n");
+  cupsFilePuts(fp, "(import \"system.sb\")\n");
+  cupsFilePuts(fp, "(system-network)\n");
+  cupsFilePuts(fp, "(allow mach-per-user-lookup)\n");
+  cupsFilePuts(fp, "(allow ipc-posix-sem)\n");
+  cupsFilePuts(fp, "(allow ipc-posix-shm)\n");
+  cupsFilePuts(fp, "(allow ipc-sysv-shm)\n");
+  cupsFilePuts(fp, "(allow mach-lookup)\n");
   cupsFilePrintf(fp,
-                 "(deny file-write* file-read-data file-read-metadata\n"
-                 "  (regex"
+                "(deny file-write* file-read-data file-read-metadata\n"
+                "  (regex"
                 " #\"^%s$\""           /* RequestRoot */
                 " #\"^%s/\""           /* RequestRoot/... */
                 ")%s)\n",
@@ -136,13 +151,18 @@ cupsdCreateProfile(int job_id)            /* I - Job ID or 0 for none */
                 " #\"^/System/\""
                 ")%s)\n",
                 root, root, nodebug);
-  /* Specifically allow applications to stat RequestRoot */
+  /* Specifically allow applications to stat RequestRoot and some other system folders */
   cupsFilePrintf(fp,
                  "(allow file-read-metadata\n"
                  "  (regex"
+                " #\"^/$\""            /* / */
+                " #\"^/usr$\""         /* /usr */
+                " #\"^/Library$\""     /* /Library */
+                " #\"^/Library/Printers$\""    /* /Library/Printers */
                 " #\"^%s$\""           /* RequestRoot */
                 "))\n",
                 request);
+  /* Read and write TempDir, CacheDir, and other common folders */
   cupsFilePrintf(fp,
                  "(allow file-write* file-read-data file-read-metadata\n"
                  "  (regex"
@@ -150,29 +170,93 @@ cupsdCreateProfile(int job_id)            /* I - Job ID or 0 for none */
                 " #\"^%s/\""           /* TempDir/... */
                 " #\"^%s$\""           /* CacheDir */
                 " #\"^%s/\""           /* CacheDir/... */
-                " #\"^%s/Library$\""   /* RequestRoot/Library */
-                " #\"^%s/Library/\""   /* RequestRoot/Library/... */
+                " #\"^/private/var/folders/\""
                 " #\"^/Library/Application Support/\""
                 " #\"^/Library/Caches/\""
                 " #\"^/Library/Preferences/\""
-                " #\"^/Library/Printers/.*/\""
                 " #\"^/Users/Shared/\""
                 "))\n",
-                temp, temp, cache, cache, request, request);
+                temp, temp, cache, cache);
+  /* Read common folders */
   cupsFilePrintf(fp,
-                "(deny file-write*\n"
+                 "(allow file-read-data file-read-metadata\n"
+                 "  (literal \"/private/etc/services\")\n"
+                 "  (regex"
+                 " #\"^/bin$\""                /* /bin */
+                 " #\"^/bin/\""                /* /bin/... */
+                 " #\"^/usr/bin$\""    /* /usr/bin */
+                 " #\"^/usr/bin/\""    /* /usr/bin/... */
+                 " #\"^/usr/libexec/cups$\""   /* /usr/libexec/cups */
+                 " #\"^/usr/libexec/cups/\""   /* /usr/libexec/cups/... */
+                 " #\"^/usr/sbin$\""   /* /usr/sbin */
+                 " #\"^/usr/sbin/\""   /* /usr/sbin/... */
+                " #\"^/Library/Caches$\""
+                " #\"^/Library/Fonts$\""
+                " #\"^/Library/Fonts/\""
+                " #\"^/Library/Printers$\""
+                " #\"^/Library/Printers/.*$\""
+                " #\"^%s/Library$\""   /* RequestRoot/Library */
+                " #\"^%s/Library/\""   /* RequestRoot/Library/... */
+                " #\"^%s$\""           /* ServerBin */
+                " #\"^%s/\""           /* ServerBin/... */
+                " #\"^%s$\""           /* ServerRoot */
+                " #\"^%s/\""           /* ServerRoot/... */
+                "))\n",
+                request, request, bin, bin, root, root);
+  if (Sandboxing == CUPSD_SANDBOXING_RELAXED)
+  {
+    /* Limited write access to /Library/Printers/... */
+    cupsFilePuts(fp,
+                "(allow file-write*\n"
                 "  (regex"
-                " #\"^/Library/Printers/PPDs$\""
-                " #\"^/Library/Printers/PPDs/\""
-                " #\"^/Library/Printers/PPD Plugins$\""
-                " #\"^/Library/Printers/PPD Plugins/\""
-                ")%s)\n", nodebug);
-  if (job_id)
+                " #\"^/Library/Printers/.*/\""
+                "))\n");
+    cupsFilePrintf(fp,
+                  "(deny file-write*\n"
+                  "  (regex"
+                  " #\"^/Library/Printers/PPDs$\""
+                  " #\"^/Library/Printers/PPDs/\""
+                  " #\"^/Library/Printers/PPD Plugins$\""
+                  " #\"^/Library/Printers/PPD Plugins/\""
+                  ")%s)\n", nodebug);
+  }
+  /* Allow execution of child processes */
+  cupsFilePuts(fp, "(allow process-fork)\n");
+  cupsFilePrintf(fp,
+                 "(allow process-exec\n"
+                 "  (regex"
+                 " #\"^/bin/\""                /* /bin/... */
+                 " #\"^/usr/bin/\""    /* /usr/bin/... */
+                 " #\"^/usr/libexec/cups/\""   /* /usr/libexec/cups/... */
+                 " #\"^/usr/sbin/\""   /* /usr/sbin/... */
+                " #\"^%s/\""           /* ServerBin/... */
+                " #\"^/Library/Printers/.*/\""
+                "))\n",
+                bin);
+  if (RunUser && getenv("CUPS_TESTROOT"))
   {
-   /*
-    * Allow job filters to read the spool file(s)...
-    */
+    /* Allow source directory access in "make test" environment */
+    char       testroot[1024];         /* Root directory of test files */
 
+    cupsd_requote(testroot, getenv("CUPS_TESTROOT"), sizeof(testroot));
+
+    cupsFilePrintf(fp,
+                  "(allow file-write* file-read-data file-read-metadata\n"
+                  "  (regex"
+                  " #\"^%s$\""         /* CUPS_TESTROOT */
+                  " #\"^%s/\""         /* CUPS_TESTROOT/... */
+                  "))\n",
+                  testroot, testroot);
+    cupsFilePrintf(fp,
+                  "(allow process-exec\n"
+                  "  (regex"
+                  " #\"^%s/\""         /* CUPS_TESTROOT/... */
+                  "))\n",
+                  testroot);
+  }
+  if (job_id)
+  {
+    /* Allow job filters to read the current job files... */
     cupsFilePrintf(fp,
                    "(allow file-read-data file-read-metadata\n"
                    "  (regex #\"^%s/([ac]%05d|d%05d-[0-9][0-9][0-9])$\"))\n",
@@ -180,26 +264,49 @@ cupsdCreateProfile(int job_id)            /* I - Job ID or 0 for none */
   }
   else
   {
-   /*
-    * Allow email notifications from notifiers...
-    */
-
+    /* Allow email notifications from notifiers... */
     cupsFilePuts(fp,
                 "(allow process-exec\n"
                 "  (literal \"/usr/sbin/sendmail\")\n"
-                "  (with no-sandbox)\n"
-                ")\n");
+                "  (with no-sandbox))\n");
+  }
+  /* Allow outbound networking to local mDNSResponder and cupsd */
+  cupsFilePuts(fp, "(allow network-outbound"
+                  "\n       (literal \"/private/var/run/mDNSResponder\")");
+  for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
+       lis;
+       lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
+  {
+    if (httpAddrFamily(&(lis->address)) == AF_LOCAL)
+    {
+      httpAddrString(&(lis->address), domain, sizeof(domain));
+      cupsFilePrintf(fp, "\n       (literal \"%s\")", domain);
+    }
+  }
+  if (allow_networking)
+  {
+    /* Allow TCP and UDP networking off the machine... */
+    cupsFilePuts(fp, "\n       (remote tcp))\n");
+    cupsFilePuts(fp, "(allow network*\n"
+                    "       (local udp \"*:*\")\n"
+                    "       (remote udp \"*:*\"))\n");
+  }
+  else
+  {
+    /* Only allow SNMP (UDP) off the machine... */
+    cupsFilePuts(fp, ")\n");
+    cupsFilePuts(fp, "(allow network-outbound\n"
+                    "       (remote udp \"*:161\"))\n");
+    cupsFilePuts(fp, "(allow network-inbound\n"
+                    "       (local udp \"localhost:*\"))\n");
   }
-
   cupsFileClose(fp);
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d) = \"%s\"",
-                  job_id, profile);
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d,allow_networking=%d) = \"%s\"", job_id, allow_networking, profile);
   return ((void *)strdup(profile));
 
 #else
-  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d) = NULL",
-                  job_id);
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d, allow_networking=%d) = NULL", job_id, allow_networking);
 
   return (NULL);
 #endif /* HAVE_SANDBOX_H */
@@ -402,7 +509,7 @@ cupsdStartProcess(
 #endif /* !HAVE_POSIX_SPAWN */
   {
     snprintf(cups_exec, sizeof(cups_exec), "%s/daemon/cups-exec", ServerBin);
-    snprintf(user_str, sizeof(user_str), "%d", User);
+    snprintf(user_str, sizeof(user_str), "%d", user);
     snprintf(group_str, sizeof(group_str), "%d", Group);
     snprintf(nice_str, sizeof(nice_str), "%d", FilterNice);
 
index 3dc580e535f71901598a7880aef795e90d1c1d42..a83e7c40d3d288f24719b14bcf3cdd0800764bfc 100644 (file)
@@ -54,7 +54,7 @@ cupsdStartServer(void)
   * Create the default security profile...
   */
 
-  DefaultProfile = cupsdCreateProfile(0);
+  DefaultProfile = cupsdCreateProfile(0, 1);
 
  /*
   * Startup all the networking stuff...
index af8d594675e69bc2cf524164f5cb9a1fe50c5498..8569bf45f3ac8d7fd2fecfb50bb2cf42cb989efc 100755 (executable)
@@ -2,17 +2,17 @@
 #
 # "$Id$"
 #
-#   Perform the complete set of IPP compliance tests specified in the
-#   CUPS Software Test Plan.
+# Perform the complete set of IPP compliance tests specified in the
+# CUPS Software Test Plan.
 #
-#   Copyright 2007-2013 by Apple Inc.
-#   Copyright 1997-2007 by Easy Software Products, all rights reserved.
+# Copyright 2007-2014 by Apple Inc.
+# Copyright 1997-2007 by Easy Software Products, all rights reserved.
 #
-#   These coded instructions, statements, and computer programs are the
-#   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/".
+# These coded instructions, statements, and computer programs are the
+# 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/".
 #
 
 argcount=$#
@@ -192,6 +192,13 @@ fi
 port=8631
 cwd=`pwd`
 root=`dirname $cwd`
+CUPS_TESTROOT="$root"; export CUPS_TESTROOT
+
+if test -d /private/tmp; then
+       BASE=/private/tmp/cups-$user
+else
+       BASE=/tmp/cups-$user
+fi
 
 #
 # Make sure that the LPDEST and PRINTER environment variables are
@@ -223,12 +230,12 @@ echo ""
 
 case "$usevalgrind" in
        Y* | y*)
-               VALGRIND="valgrind --tool=memcheck --log-file=/tmp/cups-$user/log/valgrind.%p --error-limit=no --leak-check=yes --trace-children=yes --read-var-info=yes"
+               VALGRIND="valgrind --tool=memcheck --log-file=$BASE/log/valgrind.%p --error-limit=no --leak-check=yes --trace-children=yes --read-var-info=yes"
                if test `uname` = Darwin; then
                        VALGRIND="$VALGRIND --dsymutil=yes"
                fi
                export VALGRIND
-               echo "Using Valgrind; log files can be found in /tmp/cups-$user/log..."
+               echo "Using Valgrind; log files can be found in $BASE/log..."
                ;;
 
        *)
@@ -257,15 +264,15 @@ echo ""
 
 case "$usedebugprintfs" in
        Y* | y*)
-               echo "Enabling debug printfs (level 5); log files can be found in /tmp/cups-$user/log..."
-               CUPS_DEBUG_LOG="/tmp/cups-$user/log/debug_printfs.%d"; export CUPS_DEBUG_LOG
+               echo "Enabling debug printfs (level 5); log files can be found in $BASE/log..."
+               CUPS_DEBUG_LOG="$BASE/log/debug_printfs.%d"; export CUPS_DEBUG_LOG
                CUPS_DEBUG_LEVEL=5; export CUPS_DEBUG_LEVEL
                CUPS_DEBUG_FILTER='^(http|_http|ipp|_ipp|cups.*Request|cupsGetResponse|cupsSend).*$'; export CUPS_DEBUG_FILTER
                ;;
 
        0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9)
-               echo "Enabling debug printfs (level $usedebugprintfs); log files can be found in /tmp/cups-$user/log..."
-               CUPS_DEBUG_LOG="/tmp/cups-$user/log/debug_printfs.%d"; export CUPS_DEBUG_LOG
+               echo "Enabling debug printfs (level $usedebugprintfs); log files can be found in $BASE/log..."
+               CUPS_DEBUG_LOG="$BASE/log/debug_printfs.%d"; export CUPS_DEBUG_LOG
                CUPS_DEBUG_LEVEL="$usedebugprintfs"; export CUPS_DEBUG_LEVEL
                CUPS_DEBUG_FILTER='^(http|_http|ipp|_ipp|cups.*Request|cupsGetResponse|cupsSend).*$'; export CUPS_DEBUG_FILTER
                ;;
@@ -280,67 +287,67 @@ esac
 
 echo "Creating directories for test..."
 
-rm -rf /tmp/cups-$user
-mkdir /tmp/cups-$user
-mkdir /tmp/cups-$user/bin
-mkdir /tmp/cups-$user/bin/backend
-mkdir /tmp/cups-$user/bin/driver
-mkdir /tmp/cups-$user/bin/filter
-mkdir /tmp/cups-$user/certs
-mkdir /tmp/cups-$user/share
-mkdir /tmp/cups-$user/share/banners
-mkdir /tmp/cups-$user/share/drv
-mkdir /tmp/cups-$user/share/locale
+rm -rf $BASE
+mkdir $BASE
+mkdir $BASE/bin
+mkdir $BASE/bin/backend
+mkdir $BASE/bin/driver
+mkdir $BASE/bin/filter
+mkdir $BASE/certs
+mkdir $BASE/share
+mkdir $BASE/share/banners
+mkdir $BASE/share/drv
+mkdir $BASE/share/locale
 for file in ../locale/cups_*.po; do
        loc=`basename $file .po | cut -c 6-`
-       mkdir /tmp/cups-$user/share/locale/$loc
-       ln -s $root/locale/cups_$loc.po /tmp/cups-$user/share/locale/$loc
-       ln -s $root/locale/ppdc_$loc.po /tmp/cups-$user/share/locale/$loc
+       mkdir $BASE/share/locale/$loc
+       ln -s $root/locale/cups_$loc.po $BASE/share/locale/$loc
+       ln -s $root/locale/ppdc_$loc.po $BASE/share/locale/$loc
 done
-mkdir /tmp/cups-$user/share/mime
-mkdir /tmp/cups-$user/share/model
-mkdir /tmp/cups-$user/share/ppdc
-mkdir /tmp/cups-$user/interfaces
-mkdir /tmp/cups-$user/log
-mkdir /tmp/cups-$user/ppd
-mkdir /tmp/cups-$user/spool
-mkdir /tmp/cups-$user/spool/temp
-mkdir /tmp/cups-$user/ssl
-
-ln -s $root/backend/dnssd /tmp/cups-$user/bin/backend
-ln -s $root/backend/http /tmp/cups-$user/bin/backend
-ln -s $root/backend/ipp /tmp/cups-$user/bin/backend
-ln -s $root/backend/lpd /tmp/cups-$user/bin/backend
-ln -s $root/backend/mdns /tmp/cups-$user/bin/backend
-ln -s $root/backend/pseudo /tmp/cups-$user/bin/backend
-ln -s $root/backend/snmp /tmp/cups-$user/bin/backend
-ln -s $root/backend/socket /tmp/cups-$user/bin/backend
-ln -s $root/backend/usb /tmp/cups-$user/bin/backend
-ln -s $root/cgi-bin /tmp/cups-$user/bin
-ln -s $root/monitor /tmp/cups-$user/bin
-ln -s $root/notifier /tmp/cups-$user/bin
-ln -s $root/scheduler /tmp/cups-$user/bin/daemon
-ln -s $root/filter/commandtops /tmp/cups-$user/bin/filter
-ln -s $root/filter/gziptoany /tmp/cups-$user/bin/filter
-ln -s $root/filter/pstops /tmp/cups-$user/bin/filter
-ln -s $root/filter/rastertoepson /tmp/cups-$user/bin/filter
-ln -s $root/filter/rastertohp /tmp/cups-$user/bin/filter
-ln -s $root/filter/rastertolabel /tmp/cups-$user/bin/filter
-ln -s $root/filter/rastertopwg /tmp/cups-$user/bin/filter
-
-ln -s $root/data/classified /tmp/cups-$user/share/banners
-ln -s $root/data/confidential /tmp/cups-$user/share/banners
-ln -s $root/data/secret /tmp/cups-$user/share/banners
-ln -s $root/data/standard /tmp/cups-$user/share/banners
-ln -s $root/data/topsecret /tmp/cups-$user/share/banners
-ln -s $root/data/unclassified /tmp/cups-$user/share/banners
-ln -s $root/data /tmp/cups-$user/share
-ln -s $root/ppdc/sample.drv /tmp/cups-$user/share/drv
-ln -s $root/conf/mime.types /tmp/cups-$user/share/mime
-ln -s $root/conf/mime.convs /tmp/cups-$user/share/mime
-ln -s $root/data/*.h /tmp/cups-$user/share/ppdc
-ln -s $root/data/*.defs /tmp/cups-$user/share/ppdc
-ln -s $root/templates /tmp/cups-$user/share
+mkdir $BASE/share/mime
+mkdir $BASE/share/model
+mkdir $BASE/share/ppdc
+mkdir $BASE/interfaces
+mkdir $BASE/log
+mkdir $BASE/ppd
+mkdir $BASE/spool
+mkdir $BASE/spool/temp
+mkdir $BASE/ssl
+
+ln -s $root/backend/dnssd $BASE/bin/backend
+ln -s $root/backend/http $BASE/bin/backend
+ln -s $root/backend/ipp $BASE/bin/backend
+ln -s $root/backend/lpd $BASE/bin/backend
+ln -s $root/backend/mdns $BASE/bin/backend
+ln -s $root/backend/pseudo $BASE/bin/backend
+ln -s $root/backend/snmp $BASE/bin/backend
+ln -s $root/backend/socket $BASE/bin/backend
+ln -s $root/backend/usb $BASE/bin/backend
+ln -s $root/cgi-bin $BASE/bin
+ln -s $root/monitor $BASE/bin
+ln -s $root/notifier $BASE/bin
+ln -s $root/scheduler $BASE/bin/daemon
+ln -s $root/filter/commandtops $BASE/bin/filter
+ln -s $root/filter/gziptoany $BASE/bin/filter
+ln -s $root/filter/pstops $BASE/bin/filter
+ln -s $root/filter/rastertoepson $BASE/bin/filter
+ln -s $root/filter/rastertohp $BASE/bin/filter
+ln -s $root/filter/rastertolabel $BASE/bin/filter
+ln -s $root/filter/rastertopwg $BASE/bin/filter
+
+ln -s $root/data/classified $BASE/share/banners
+ln -s $root/data/confidential $BASE/share/banners
+ln -s $root/data/secret $BASE/share/banners
+ln -s $root/data/standard $BASE/share/banners
+ln -s $root/data/topsecret $BASE/share/banners
+ln -s $root/data/unclassified $BASE/share/banners
+ln -s $root/data $BASE/share
+ln -s $root/ppdc/sample.drv $BASE/share/drv
+ln -s $root/conf/mime.types $BASE/share/mime
+ln -s $root/conf/mime.convs $BASE/share/mime
+ln -s $root/data/*.h $BASE/share/ppdc
+ln -s $root/data/*.defs $BASE/share/ppdc
+ln -s $root/templates $BASE/share
 
 #
 # Local filters and configuration files...
@@ -358,7 +365,7 @@ instfilter() {
 
        for dir in /usr/libexec/cups/filter /usr/lib/cups/filter; do
                if test -x "$dir/$src"; then
-                       ln -s "$dir/$src" "/tmp/cups-$user/bin/filter/$dst"
+                       ln -s "$dir/$src" "$BASE/bin/filter/$dst"
                        return
                fi
        done
@@ -366,10 +373,10 @@ instfilter() {
        # Source filter not present, create a dummy filter
        case $format in
                passthru)
-                       ln -s gziptoany "/tmp/cups-$user/bin/filter/$dst"
+                       ln -s gziptoany "$BASE/bin/filter/$dst"
                        ;;
                pdf)
-                       cat >"/tmp/cups-$user/bin/filter/$dst" <<EOF
+                       cat >"$BASE/bin/filter/$dst" <<EOF
 #!/bin/sh
 case "\$5" in
        *media=a4* | *media=iso_a4* | *PageSize=A4*)
@@ -380,10 +387,10 @@ case "\$5" in
                ;;
 esac
 EOF
-                       chmod +x "/tmp/cups-$user/bin/filter/$dst"
+                       chmod +x "$BASE/bin/filter/$dst"
                        ;;
                ps)
-                       cat >"/tmp/cups-$user/bin/filter/$dst" <<EOF
+                       cat >"$BASE/bin/filter/$dst" <<EOF
 #!/bin/sh
 case "\$5" in
        *media=a4* | *media=iso_a4* | *PageSize=A4*)
@@ -394,10 +401,10 @@ case "\$5" in
                ;;
 esac
 EOF
-                       chmod +x "/tmp/cups-$user/bin/filter/$dst"
+                       chmod +x "$BASE/bin/filter/$dst"
                        ;;
                raster)
-                       cat >"/tmp/cups-$user/bin/filter/$dst" <<EOF
+                       cat >"$BASE/bin/filter/$dst" <<EOF
 #!/bin/sh
 case "\$5" in
        *media=a4* | *media=iso_a4* | *PageSize=A4*)
@@ -408,12 +415,12 @@ case "\$5" in
                ;;
 esac
 EOF
-                       chmod +x "/tmp/cups-$user/bin/filter/$dst"
+                       chmod +x "$BASE/bin/filter/$dst"
                        ;;
        esac
 }
 
-ln -s $root/test/test.convs /tmp/cups-$user/share/mime
+ln -s $root/test/test.convs $BASE/share/mime
 
 if test `uname` = Darwin; then
        instfilter cgbannertopdf bannertopdf pdf
@@ -435,7 +442,7 @@ else
        instfilter texttopdf texttopdf pdf
 
        if test -d /usr/share/cups/charsets; then
-               ln -s /usr/share/cups/charsets /tmp/cups-$user/share
+               ln -s /usr/share/cups/charsets $BASE/share
        fi
 fi
 
@@ -451,11 +458,11 @@ else
        encryption=""
 fi
 
-cat >/tmp/cups-$user/cupsd.conf <<EOF
+cat >$BASE/cupsd.conf <<EOF
 StrictConformance Yes
 Browsing Off
 Listen localhost:$port
-Listen /tmp/cups-$user/sock
+Listen $BASE/sock
 PassEnv LOCALEDIR
 PassEnv DYLD_INSERT_LIBRARIES
 MaxSubscriptions 3
@@ -474,29 +481,29 @@ $encryption
 EOF
 
 if test $testtype = 0; then
-       echo WebInterface yes >>/tmp/cups-$user/cupsd.conf
+       echo WebInterface yes >>$BASE/cupsd.conf
 fi
 
-cat >/tmp/cups-$user/cups-files.conf <<EOF
+cat >$BASE/cups-files.conf <<EOF
 FileDevice yes
 Printcap
 User $user
-ServerRoot /tmp/cups-$user
-StateDir /tmp/cups-$user
-ServerBin /tmp/cups-$user/bin
-CacheDir /tmp/cups-$user/share
-DataDir /tmp/cups-$user/share
-FontPath /tmp/cups-$user/share/fonts
+ServerRoot $BASE
+StateDir $BASE
+ServerBin $BASE/bin
+CacheDir $BASE/share
+DataDir $BASE/share
+FontPath $BASE/share/fonts
 DocumentRoot $root/doc
-RequestRoot /tmp/cups-$user/spool
-TempDir /tmp/cups-$user/spool/temp
-AccessLog /tmp/cups-$user/log/access_log
-ErrorLog /tmp/cups-$user/log/error_log
-PageLog /tmp/cups-$user/log/page_log
+RequestRoot $BASE/spool
+TempDir $BASE/spool/temp
+AccessLog $BASE/log/access_log
+ErrorLog $BASE/log/error_log
+PageLog $BASE/log/page_log
 EOF
 
 if test $ssltype != 0 -a `uname` = Darwin; then
-       echo "ServerKeychain $HOME/Library/Keychains/login.keychain" >> /tmp/cups-$user/cups-files.conf
+       echo "ServerKeychain $HOME/Library/Keychains/login.keychain" >> $BASE/cups-files.conf
 fi
 
 #
@@ -507,7 +514,7 @@ echo "Creating printers.conf for test..."
 
 i=1
 while test $i -le $nprinters1; do
-       cat >>/tmp/cups-$user/printers.conf <<EOF
+       cat >>$BASE/printers.conf <<EOF
 <Printer test-$i>
 Accepting Yes
 DeviceURI file:/dev/null
@@ -519,13 +526,13 @@ StateMessage Printer $1 is idle.
 </Printer>
 EOF
 
-       cp testps.ppd /tmp/cups-$user/ppd/test-$i.ppd
+       cp testps.ppd $BASE/ppd/test-$i.ppd
 
        i=`expr $i + 1`
 done
 
 while test $i -le $nprinters2; do
-       cat >>/tmp/cups-$user/printers.conf <<EOF
+       cat >>$BASE/printers.conf <<EOF
 <Printer test-$i>
 Accepting Yes
 DeviceURI file:/dev/null
@@ -540,10 +547,10 @@ EOF
        i=`expr $i + 1`
 done
 
-if test -f /tmp/cups-$user/printers.conf; then
-       cp /tmp/cups-$user/printers.conf /tmp/cups-$user/printers.conf.orig
+if test -f $BASE/printers.conf; then
+       cp $BASE/printers.conf $BASE/printers.conf.orig
 else
-       touch /tmp/cups-$user/printers.conf.orig
+       touch $BASE/printers.conf.orig
 fi
 
 #
@@ -584,16 +591,16 @@ export SHLIB_PATH
 
 CUPS_DISABLE_APPLE_DEFAULT=yes; export CUPS_DISABLE_APPLE_DEFAULT
 CUPS_SERVER=localhost:8631; export CUPS_SERVER
-CUPS_SERVERROOT=/tmp/cups-$user; export CUPS_SERVERROOT
-CUPS_STATEDIR=/tmp/cups-$user; export CUPS_STATEDIR
-CUPS_DATADIR=/tmp/cups-$user/share; export CUPS_DATADIR
-LOCALEDIR=/tmp/cups-$user/share/locale; export LOCALEDIR
+CUPS_SERVERROOT=$BASE; export CUPS_SERVERROOT
+CUPS_STATEDIR=$BASE; export CUPS_STATEDIR
+CUPS_DATADIR=$BASE/share; export CUPS_DATADIR
+LOCALEDIR=$BASE/share/locale; export LOCALEDIR
 
 #
 # Set a new home directory to avoid getting user options mixed in...
 #
 
-HOME=/tmp/cups-$user
+HOME=$BASE
 export HOME
 
 #
@@ -611,14 +618,14 @@ export LC_MESSAGES
 #
 
 echo "Starting scheduler:"
-echo "    $VALGRIND ../scheduler/cupsd -c /tmp/cups-$user/cupsd.conf -f >/tmp/cups-$user/log/debug_log 2>&1 &"
+echo "    $VALGRIND ../scheduler/cupsd -c $BASE/cupsd.conf -f >$BASE/log/debug_log 2>&1 &"
 echo ""
 
 if test `uname` = Darwin -a "x$VALGRIND" = x; then
        DYLD_INSERT_LIBRARIES=/usr/lib/libgmalloc.dylib
-       ../scheduler/cupsd -c /tmp/cups-$user/cupsd.conf -f >/tmp/cups-$user/log/debug_log 2>&1 &
+       ../scheduler/cupsd -c $BASE/cupsd.conf -f >$BASE/log/debug_log 2>&1 &
 else
-       $VALGRIND ../scheduler/cupsd -c /tmp/cups-$user/cupsd.conf -f >/tmp/cups-$user/log/debug_log 2>&1 &
+       $VALGRIND ../scheduler/cupsd -c $BASE/cupsd.conf -f >$BASE/log/debug_log 2>&1 &
 fi
 
 cupsd=$!
@@ -629,7 +636,7 @@ if test "x$testtype" = x0; then
        echo ""
 
        # Create a helper script to run programs with...
-       runcups="/tmp/cups-$user/runcups"
+       runcups="$BASE/runcups"
 
        echo "#!/bin/sh" >$runcups
        echo "# Helper script for running CUPS test instance." >>$runcups
@@ -687,7 +694,7 @@ done
 #
 
 date=`date "+%Y-%m-%d"`
-strfile=/tmp/cups-$user/cups-str-2.0-$date-$user.html
+strfile=$BASE/cups-str-2.0-$date-$user.html
 
 rm -f $strfile
 cat str-header.html >$strfile
@@ -782,7 +789,7 @@ echo ""
 echo "<H2>Summary</H2>" >>$strfile
 
 # Job control files
-count=`ls -1 /tmp/cups-$user/spool | wc -l`
+count=`ls -1 $BASE/spool | wc -l`
 count=`expr $count - 1`
 if test $count != 0; then
        echo "FAIL: $count job control files were not purged."
@@ -794,7 +801,7 @@ else
 fi
 
 # Pages printed on Test1 (within 1 page for timing-dependent cancel issues)
-count=`$GREP '^Test1 ' /tmp/cups-$user/log/page_log | awk 'BEGIN{count=0}{count=count+$7}END{print count}'`
+count=`$GREP '^Test1 ' $BASE/log/page_log | awk 'BEGIN{count=0}{count=count+$7}END{print count}'`
 expected=`expr $pjobs \* 2 + 34`
 expected2=`expr $expected + 2`
 if test $count -lt $expected -a $count -gt $expected2; then
@@ -807,7 +814,7 @@ else
 fi
 
 # Paged printed on Test2
-count=`$GREP '^Test2 ' /tmp/cups-$user/log/page_log | awk 'BEGIN{count=0}{count=count+$7}END{print count}'`
+count=`$GREP '^Test2 ' $BASE/log/page_log | awk 'BEGIN{count=0}{count=count+$7}END{print count}'`
 expected=`expr $pjobs \* 2 + 3`
 if test $count != $expected; then
        echo "FAIL: Printer 'Test2' produced $count page(s), expected $expected."
@@ -819,7 +826,7 @@ else
 fi
 
 # Paged printed on Test3
-count=`$GREP '^Test3 ' /tmp/cups-$user/log/page_log | grep -v total | awk 'BEGIN{count=0}{count=count+$7}END{print count}'`
+count=`$GREP '^Test3 ' $BASE/log/page_log | grep -v total | awk 'BEGIN{count=0}{count=count+$7}END{print count}'`
 expected=2
 if test $count != $expected; then
        echo "FAIL: Printer 'Test3' produced $count page(s), expected $expected."
@@ -831,7 +838,7 @@ else
 fi
 
 # Requests logged
-count=`wc -l /tmp/cups-$user/log/access_log | awk '{print $1}'`
+count=`wc -l $BASE/log/access_log | awk '{print $1}'`
 expected=`expr 37 + 18 + 28 + $pjobs \* 8 + $pprinters \* $pjobs \* 4`
 if test $count != $expected; then
        echo "FAIL: $count requests logged, expected $expected."
@@ -843,11 +850,11 @@ else
 fi
 
 # Did CUPS-Get-Default get logged?
-if $GREP -q CUPS-Get-Default /tmp/cups-$user/log/access_log; then
+if $GREP -q CUPS-Get-Default $BASE/log/access_log; then
        echo "FAIL: CUPS-Get-Default logged with 'AccessLogLevel actions'"
        echo "<P>FAIL: CUPS-Get-Default logged with 'AccessLogLevel actions'</P>" >>$strfile
        echo "<PRE>" >>$strfile
-       $GREP CUPS-Get-Default /tmp/cups-$user/log/access_log | sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' >>$strfile
+       $GREP CUPS-Get-Default $BASE/log/access_log | sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' >>$strfile
        echo "</PRE>" >>$strfile
        fail=`expr $fail + 1`
 else
@@ -856,13 +863,13 @@ else
 fi
 
 # Emergency log messages
-count=`$GREP '^X ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'`
+count=`$GREP '^X ' $BASE/log/error_log | wc -l | awk '{print $1}'`
 if test $count != 0; then
        echo "FAIL: $count emergency messages, expected 0."
-       $GREP '^X ' /tmp/cups-$user/log/error_log
+       $GREP '^X ' $BASE/log/error_log
        echo "<P>FAIL: $count emergency messages, expected 0.</P>" >>$strfile
        echo "<PRE>" >>$strfile
-       $GREP '^X ' /tmp/cups-$user/log/error_log | sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' >>$strfile
+       $GREP '^X ' $BASE/log/error_log | sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' >>$strfile
        echo "</PRE>" >>$strfile
        fail=`expr $fail + 1`
 else
@@ -871,13 +878,13 @@ else
 fi
 
 # Alert log messages
-count=`$GREP '^A ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'`
+count=`$GREP '^A ' $BASE/log/error_log | wc -l | awk '{print $1}'`
 if test $count != 0; then
        echo "FAIL: $count alert messages, expected 0."
-       $GREP '^A ' /tmp/cups-$user/log/error_log
+       $GREP '^A ' $BASE/log/error_log
        echo "<P>FAIL: $count alert messages, expected 0.</P>" >>$strfile
        echo "<PRE>" >>$strfile
-       $GREP '^A ' /tmp/cups-$user/log/error_log | sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' >>$strfile
+       $GREP '^A ' $BASE/log/error_log | sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' >>$strfile
        echo "</PRE>" >>$strfile
        fail=`expr $fail + 1`
 else
@@ -886,13 +893,13 @@ else
 fi
 
 # Critical log messages
-count=`$GREP '^C ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'`
+count=`$GREP '^C ' $BASE/log/error_log | wc -l | awk '{print $1}'`
 if test $count != 0; then
        echo "FAIL: $count critical messages, expected 0."
-       $GREP '^C ' /tmp/cups-$user/log/error_log
+       $GREP '^C ' $BASE/log/error_log
        echo "<P>FAIL: $count critical messages, expected 0.</P>" >>$strfile
        echo "<PRE>" >>$strfile
-       $GREP '^C ' /tmp/cups-$user/log/error_log | sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' >>$strfile
+       $GREP '^C ' $BASE/log/error_log | sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' >>$strfile
        echo "</PRE>" >>$strfile
        fail=`expr $fail + 1`
 else
@@ -901,13 +908,13 @@ else
 fi
 
 # Error log messages
-count=`$GREP '^E ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'`
+count=`$GREP '^E ' $BASE/log/error_log | wc -l | awk '{print $1}'`
 if test $count != 33; then
        echo "FAIL: $count error messages, expected 33."
-       $GREP '^E ' /tmp/cups-$user/log/error_log
+       $GREP '^E ' $BASE/log/error_log
        echo "<P>FAIL: $count error messages, expected 33.</P>" >>$strfile
        echo "<PRE>" >>$strfile
-       $GREP '^E ' /tmp/cups-$user/log/error_log | sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' >>$strfile
+       $GREP '^E ' $BASE/log/error_log | sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' >>$strfile
        echo "</PRE>" >>$strfile
        fail=`expr $fail + 1`
 else
@@ -916,13 +923,13 @@ else
 fi
 
 # Warning log messages
-count=`$GREP '^W ' /tmp/cups-$user/log/error_log | $GREP -v CreateProfile | wc -l | awk '{print $1}'`
+count=`$GREP '^W ' $BASE/log/error_log | $GREP -v CreateProfile | wc -l | awk '{print $1}'`
 if test $count != 9; then
        echo "FAIL: $count warning messages, expected 9."
-       $GREP '^W ' /tmp/cups-$user/log/error_log
+       $GREP '^W ' $BASE/log/error_log
        echo "<P>FAIL: $count warning messages, expected 9.</P>" >>$strfile
        echo "<PRE>" >>$strfile
-       $GREP '^W ' /tmp/cups-$user/log/error_log | sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' >>$strfile
+       $GREP '^W ' $BASE/log/error_log | sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' >>$strfile
        echo "</PRE>" >>$strfile
        fail=`expr $fail + 1`
 else
@@ -931,13 +938,13 @@ else
 fi
 
 # Notice log messages
-count=`$GREP '^N ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'`
+count=`$GREP '^N ' $BASE/log/error_log | wc -l | awk '{print $1}'`
 if test $count != 0; then
        echo "FAIL: $count notice messages, expected 0."
-       $GREP '^N ' /tmp/cups-$user/log/error_log
+       $GREP '^N ' $BASE/log/error_log
        echo "<P>FAIL: $count notice messages, expected 0.</P>" >>$strfile
        echo "<PRE>" >>$strfile
-       $GREP '^N ' /tmp/cups-$user/log/error_log | sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' >>$strfile
+       $GREP '^N ' $BASE/log/error_log | sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' >>$strfile
        echo "</PRE>" >>$strfile
        fail=`expr $fail + 1`
 else
@@ -946,7 +953,7 @@ else
 fi
 
 # Info log messages
-count=`$GREP '^I ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'`
+count=`$GREP '^I ' $BASE/log/error_log | wc -l | awk '{print $1}'`
 if test $count = 0; then
        echo "FAIL: $count info messages, expected more than 0."
        echo "<P>FAIL: $count info messages, expected more than 0.</P>" >>$strfile
@@ -957,7 +964,7 @@ else
 fi
 
 # Debug log messages
-count=`$GREP '^D ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'`
+count=`$GREP '^D ' $BASE/log/error_log | wc -l | awk '{print $1}'`
 if test $count = 0; then
        echo "FAIL: $count debug messages, expected more than 0."
        echo "<P>FAIL: $count debug messages, expected more than 0.</P>" >>$strfile
@@ -968,7 +975,7 @@ else
 fi
 
 # Debug2 log messages
-count=`$GREP '^d ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'`
+count=`$GREP '^d ' $BASE/log/error_log | wc -l | awk '{print $1}'`
 if test $count = 0; then
        echo "FAIL: $count debug2 messages, expected more than 0."
        echo "<P>FAIL: $count debug2 messages, expected more than 0.</P>" >>$strfile
@@ -981,17 +988,17 @@ fi
 # Log files...
 echo "<H2>access_log</H2>" >>$strfile
 echo "<PRE>" >>$strfile
-sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' /tmp/cups-$user/log/access_log >>$strfile
+sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' $BASE/log/access_log >>$strfile
 echo "</PRE>" >>$strfile
 
 echo "<H2>error_log</H2>" >>$strfile
 echo "<PRE>" >>$strfile
-$GREP -v '^d' /tmp/cups-$user/log/error_log | sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' >>$strfile
+$GREP -v '^d' $BASE/log/error_log | sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' >>$strfile
 echo "</PRE>" >>$strfile
 
 echo "<H2>page_log</H2>" >>$strfile
 echo "<PRE>" >>$strfile
-sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' /tmp/cups-$user/log/page_log >>$strfile
+sed -e '1,$s/&/&amp;/g' -e '1,$s/</&lt;/g' $BASE/log/page_log >>$strfile
 echo "</PRE>" >>$strfile
 
 #
@@ -1004,13 +1011,13 @@ echo ""
 
 if test $fail != 0; then
        echo "$fail tests failed."
-       cp /tmp/cups-$user/log/error_log error_log-$date-$user
+       cp $BASE/log/error_log error_log-$date-$user
        cp $strfile .
 else
        echo "All tests were successful."
 fi
 
-echo "Log files can be found in /tmp/cups-$user/log."
+echo "Log files can be found in $BASE/log."
 echo "A HTML report was created in $strfile."
 echo ""
 
index ed3354a19bbb3df706ea1d87a79399b518b63684..ef3689cc13a1431a8e0d09d83f6270d7b925e3be 100644 (file)
                728FB7F11536167A005426E1 /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 728FB7EF1536167A005426E1 /* libiconv.dylib */; };
                728FB7F21536167A005426E1 /* libresolv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 728FB7F01536167A005426E1 /* libresolv.dylib */; };
                72C16CB9137B195D007E4BF4 /* file.c in Sources */ = {isa = PBXBuildFile; fileRef = 72C16CB8137B195D007E4BF4 /* file.c */; };
+               72CEF95618A966E000FA9B81 /* libcups.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 72220EAE1333047D00FCA411 /* libcups.dylib */; };
                72CF95E318A13543000FCAE4 /* dest-job.c in Sources */ = {isa = PBXBuildFile; fileRef = 72CF95E018A13543000FCAE4 /* dest-job.c */; };
                72CF95E418A13543000FCAE4 /* dest-localization.c in Sources */ = {isa = PBXBuildFile; fileRef = 72CF95E118A13543000FCAE4 /* dest-localization.c */; };
                72CF95E518A13543000FCAE4 /* dest-options.c in Sources */ = {isa = PBXBuildFile; fileRef = 72CF95E218A13543000FCAE4 /* dest-options.c */; };
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               72CEF95618A966E000FA9B81 /* libcups.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };