]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/process.c
Fix another "new logging" bug for journald only this time (STR #4690)
[thirdparty/cups.git] / scheduler / process.c
index e01f639c8e8ecba085dd19bcf031d961498b1607..1f45368abc3d8eecbebf71e19c1bac776c7cff13 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Process management routines for the CUPS scheduler.
  *
- * Copyright 2007-2014 by Apple Inc.
+ * Copyright 2007-2015 by Apple Inc.
  * Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  * These coded instructions, statements, and computer programs are the
 #  include <spawn.h>
 extern char **environ;
 #endif /* HAVE_POSIX_SPAWN */
+#ifdef HAVE_POSIX_SPAWN
+#  if !defined(__OpenBSD__) || OpenBSD >= 201505
+#    define USE_POSIX_SPAWN 1
+#  else
+#    define USE_POSIX_SPAWN 0
+#  endif /* !__OpenBSD__ || */
+#else
+#  define USE_POSIX_SPAWN 0
+#endif /* HAVE_POSIX_SPAWN */
 
 
 /*
@@ -73,6 +82,7 @@ cupsdCreateProfile(int job_id,                /* I - Job ID or 0 for none */
                        domain[1024],   /* Domain socket, if any */
                        request[1024],  /* Quoted RequestRoot */
                        root[1024],     /* Quoted ServerRoot */
+                       state[1024],    /* Quoted StateDir */
                        temp[1024];     /* Quoted TempDir */
   const char           *nodebug;       /* " (with no-log)" for no debug */
   cupsd_listener_t     *lis;           /* Current listening socket */
@@ -104,6 +114,7 @@ cupsdCreateProfile(int job_id,              /* I - Job ID or 0 for none */
   cupsd_requote(cache, CacheDir, sizeof(cache));
   cupsd_requote(request, RequestRoot, sizeof(request));
   cupsd_requote(root, ServerRoot, sizeof(root));
+  cupsd_requote(state, StateDir, sizeof(state));
   cupsd_requote(temp, TempDir, sizeof(temp));
 
   nodebug = LogLevel < CUPSD_LOG_DEBUG ? " (with no-log)" : "";
@@ -122,13 +133,6 @@ cupsdCreateProfile(int job_id,             /* I - Job ID or 0 for none */
   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"
-                " #\"^%s$\""           /* RequestRoot */
-                " #\"^%s/\""           /* RequestRoot/... */
-                ")%s)\n",
-                request, request, nodebug);
   if (!RunUser)
     cupsFilePrintf(fp,
                   "(deny file-write* file-read-data file-read-metadata\n"
@@ -163,6 +167,31 @@ cupsdCreateProfile(int job_id,             /* I - Job ID or 0 for none */
                 "))\n",
                 request);
   /* Read and write TempDir, CacheDir, and other common folders */
+  cupsFilePuts(fp,
+              "(allow file-write* file-read-data file-read-metadata\n"
+              "  (regex"
+              " #\"^/private/var/db/\""
+              " #\"^/private/var/folders/\""
+              " #\"^/private/var/lib/\""
+              " #\"^/private/var/log/\""
+              " #\"^/private/var/mysql/\""
+              " #\"^/private/var/run/\""
+              " #\"^/private/var/spool/\""
+              " #\"^/Library/Application Support/\""
+              " #\"^/Library/Caches/\""
+              " #\"^/Library/Logs/\""
+              " #\"^/Library/Preferences/\""
+              " #\"^/Library/WebServer/\""
+              " #\"^/Users/Shared/\""
+              "))\n");
+  cupsFilePrintf(fp,
+                "(deny file-write*\n"
+                "       (regex #\"^%s$\")%s)\n",
+                request, nodebug);
+  cupsFilePrintf(fp,
+                "(deny file-write* file-read-data file-read-metadata\n"
+                "       (regex #\"^%s/\")%s)\n",
+                request, nodebug);
   cupsFilePrintf(fp,
                  "(allow file-write* file-read-data file-read-metadata\n"
                  "  (regex"
@@ -170,31 +199,45 @@ cupsdCreateProfile(int job_id,            /* I - Job ID or 0 for none */
                 " #\"^%s/\""           /* TempDir/... */
                 " #\"^%s$\""           /* CacheDir */
                 " #\"^%s/\""           /* CacheDir/... */
-                " #\"^/private/var/folders/\""
-                " #\"^/Library/Application Support/\""
-                " #\"^/Library/Caches/\""
-                " #\"^/Library/Preferences/\""
-                " #\"^/Users/Shared/\""
+                " #\"^%s$\""           /* StateDir */
+                " #\"^%s/\""           /* StateDir/... */
                 "))\n",
-                temp, temp, cache, cache);
+                temp, temp, cache, cache, state, state);
   /* Read common folders */
   cupsFilePrintf(fp,
                  "(allow file-read-data file-read-metadata\n"
-                 "  (literal \"/private/etc/services\")\n"
                  "  (regex"
+                 " #\"^/AppleInternal$\""
+                 " #\"^/AppleInternal/\""
                  " #\"^/bin$\""                /* /bin */
                  " #\"^/bin/\""                /* /bin/... */
+                 " #\"^/private$\""
+                 " #\"^/private/etc$\""
+                 " #\"^/private/etc/\""
+                 " #\"^/private/tmp$\""
+                 " #\"^/private/tmp/\""
+                 " #\"^/private/var$\""
+                 " #\"^/private/var/db$\""
+                 " #\"^/private/var/folders$\""
+                 " #\"^/private/var/lib$\""
+                 " #\"^/private/var/log$\""
+                 " #\"^/private/var/mysql$\""
+                 " #\"^/private/var/run$\""
+                 " #\"^/private/var/spool$\""
+                 " #\"^/private/var/tmp$\""
+                 " #\"^/private/var/tmp/\""
                  " #\"^/usr/bin$\""    /* /usr/bin */
                  " #\"^/usr/bin/\""    /* /usr/bin/... */
                  " #\"^/usr/libexec/cups$\""   /* /usr/libexec/cups */
                  " #\"^/usr/libexec/cups/\""   /* /usr/libexec/cups/... */
+                 " #\"^/usr/libexec/fax$\""    /* /usr/libexec/fax */
+                 " #\"^/usr/libexec/fax/\""    /* /usr/libexec/fax/... */
                  " #\"^/usr/sbin$\""   /* /usr/sbin */
                  " #\"^/usr/sbin/\""   /* /usr/sbin/... */
-                " #\"^/Library/Caches$\""
-                " #\"^/Library/Fonts$\""
-                " #\"^/Library/Fonts/\""
-                " #\"^/Library/Printers$\""
-                " #\"^/Library/Printers/.*$\""
+                " #\"^/Library$\""     /* /Library */
+                " #\"^/Library/\""     /* /Library/... */
+                " #\"^/System$\""      /* /System */
+                " #\"^/System/\""      /* /System/... */
                 " #\"^%s/Library$\""   /* RequestRoot/Library */
                 " #\"^%s/Library/\""   /* RequestRoot/Library/... */
                 " #\"^%s$\""           /* ServerBin */
@@ -220,19 +263,9 @@ cupsdCreateProfile(int job_id,             /* I - Job ID or 0 for none */
                   " #\"^/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);
+  /* Allow execution of child processes as long as the programs are not in a user directory */
+  cupsFilePuts(fp, "(allow process*)\n");
+  cupsFilePuts(fp, "(deny process-exec (regex #\"^/Users/\"))\n");
   if (RunUser && getenv("CUPS_TESTROOT"))
   {
     /* Allow source directory access in "make test" environment */
@@ -253,13 +286,14 @@ cupsdCreateProfile(int job_id,            /* I - Job ID or 0 for none */
                   " #\"^%s/\""         /* CUPS_TESTROOT/... */
                   "))\n",
                   testroot);
+    cupsFilePrintf(fp, "(allow sysctl*)\n");
   }
   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",
+                   "       (regex #\"^%s/([ac]%05d|d%05d-[0-9][0-9][0-9])$\"))\n",
                   request, job_id, job_id);
   }
   else
@@ -270,9 +304,12 @@ cupsdCreateProfile(int job_id,             /* I - Job ID or 0 for none */
                 "  (literal \"/usr/sbin/sendmail\")\n"
                 "  (with no-sandbox))\n");
   }
-  /* Allow outbound networking to local mDNSResponder and cupsd */
+  /* Allow access to Bluetooth, USB, and notify_post. */
+  cupsFilePuts(fp, "(allow iokit*)\n");
+  cupsFilePuts(fp, "(allow distributed-notification-post)\n");
+  /* Allow outbound networking to local services */
   cupsFilePuts(fp, "(allow network-outbound"
-                  "\n       (literal \"/private/var/run/mDNSResponder\")");
+                  "\n       (regex #\"^/private/var/run/\" #\"^/private/tmp/\" #\"^/private/var/tmp/\")");
   for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
        lis;
        lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
@@ -287,16 +324,25 @@ cupsdCreateProfile(int job_id,            /* I - Job ID or 0 for none */
   {
     /* Allow TCP and UDP networking off the machine... */
     cupsFilePuts(fp, "\n       (remote tcp))\n");
+    cupsFilePuts(fp, "(allow network-bind)\n"); /* for LPD resvport */
     cupsFilePuts(fp, "(allow network*\n"
                     "       (local udp \"*:*\")\n"
                     "       (remote udp \"*:*\"))\n");
+
+    /* Also allow access to device files... */
+    cupsFilePuts(fp, "(allow file-write* file-read-data file-read-metadata file-ioctl\n"
+                     "       (regex #\"^/dev/\"))\n");
+
+    /* And allow kernel extensions to be loaded, e.g., SMB */
+    cupsFilePuts(fp, "(allow system-kext-load)\n");
   }
   else
   {
-    /* Only allow SNMP (UDP) off the machine... */
+    /* Only allow SNMP (UDP) and LPD (TCP) off the machine... */
     cupsFilePuts(fp, ")\n");
     cupsFilePuts(fp, "(allow network-outbound\n"
-                    "       (remote udp \"*:161\"))\n");
+                    "       (remote udp \"*:161\")"
+                    "       (remote tcp \"*:515\"))\n");
     cupsFilePuts(fp, "(allow network-inbound\n"
                     "       (local udp \"localhost:*\"))\n");
   }
@@ -369,10 +415,10 @@ cupsdEndProcess(int pid,          /* I - Process ID */
  */
 
 const char *                           /* O - Process name */
-cupsdFinishProcess(int  pid,           /* I - Process ID */
-                   char *name,         /* I - Name buffer */
-                  int  namelen,        /* I - Size of name buffer */
-                  int  *job_id)        /* O - Job ID pointer or NULL */
+cupsdFinishProcess(int    pid,         /* I - Process ID */
+                   char   *name,       /* I - Name buffer */
+                  size_t namelen,      /* I - Size of name buffer */
+                  int    *job_id)      /* O - Job ID pointer or NULL */
 {
   cupsd_proc_t key,                    /* Search key */
                *proc;                  /* Matching process */
@@ -397,10 +443,7 @@ cupsdFinishProcess(int  pid,               /* I - Process ID */
     strlcpy(name, "unknown", namelen);
   }
 
-  cupsdLogMessage(CUPSD_LOG_DEBUG2,
-                 "cupsdFinishProcess(pid=%d, name=%p, namelen=%d, "
-                 "job_id=%p(%d)) = \"%s\"", pid, name, namelen, job_id,
-                 job_id ? *job_id : 0, name);
+  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFinishProcess(pid=%d, name=%p, namelen=" CUPS_LLFMT ", job_id=%p(%d)) = \"%s\"", pid, name, CUPS_LLCAST namelen, job_id, job_id ? *job_id : 0, name);
 
   return (name);
 }
@@ -427,20 +470,20 @@ cupsdStartProcess(
 {
   int          i;                      /* Looping var */
   const char   *exec_path = command;   /* Command to be exec'd */
-  char         *real_argv[107],        /* Real command-line arguments */
-               cups_exec[1024];        /* Path to "cups-exec" program */
+  char         *real_argv[110],        /* Real command-line arguments */
+               cups_exec[1024],        /* Path to "cups-exec" program */
+               user_str[16],           /* User string */
+               group_str[16],          /* Group string */
+               nice_str[16];           /* FilterNice string */
   uid_t                user;                   /* Command UID */
   cupsd_proc_t *proc;                  /* New process record */
-#ifdef HAVE_POSIX_SPAWN
+#if USE_POSIX_SPAWN
   posix_spawn_file_actions_t actions;  /* Spawn file actions */
   posix_spawnattr_t attrs;             /* Spawn attributes */
-  char         user_str[16],           /* User string */
-               group_str[16],          /* Group string */
-               nice_str[16];           /* FilterNice string */
-#endif /* HAVE_POSIX_SPAWN */
-#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+  sigset_t     defsignals;             /* Default signals */
+#elif defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
   struct sigaction action;             /* POSIX signal handler */
-#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+#endif /* USE_POSIX_SPAWN */
 #if defined(__APPLE__)
   char         processPath[1024],      /* CFProcessPath environment variable */
                linkpath[1024];         /* Link path for symlinks... */
@@ -504,9 +547,9 @@ cupsdStartProcess(
   * Use helper program when we have a sandbox profile...
   */
 
-#ifndef HAVE_POSIX_SPAWN
+#if !USE_POSIX_SPAWN
   if (profile)
-#endif /* !HAVE_POSIX_SPAWN */
+#endif /* !USE_POSIX_SPAWN */
   {
     snprintf(cups_exec, sizeof(cups_exec), "%s/daemon/cups-exec", ServerBin);
     snprintf(user_str, sizeof(user_str), "%d", user);
@@ -514,18 +557,21 @@ cupsdStartProcess(
     snprintf(nice_str, sizeof(nice_str), "%d", FilterNice);
 
     real_argv[0] = cups_exec;
-    real_argv[1] = profile;
-    real_argv[2] = user_str;
-    real_argv[3] = group_str;
+    real_argv[1] = (char *)"-g";
+    real_argv[2] = group_str;
+    real_argv[3] = (char *)"-n";
     real_argv[4] = nice_str;
-    real_argv[5] = (char *)command;
+    real_argv[5] = (char *)"-u";
+    real_argv[6] = user_str;
+    real_argv[7] = profile ? profile : "none";
+    real_argv[8] = (char *)command;
 
     for (i = 0;
-         i < (int)(sizeof(real_argv) / sizeof(real_argv[0]) - 7) && argv[i];
+         i < (int)(sizeof(real_argv) / sizeof(real_argv[0]) - 10) && argv[i];
         i ++)
-      real_argv[i + 6] = argv[i];
+      real_argv[i + 9] = argv[i];
 
-    real_argv[i + 6] = NULL;
+    real_argv[i + 9] = NULL;
 
     argv      = real_argv;
     exec_path = cups_exec;
@@ -539,21 +585,28 @@ cupsdStartProcess(
       cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStartProcess: argv[%d] = \"%s\"", i, argv[i]);
   }
 
-#ifdef HAVE_POSIX_SPAWN
+#if USE_POSIX_SPAWN
  /*
   * Setup attributes and file actions for the spawn...
   */
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStartProcess: Setting spawn attributes.");
+  sigemptyset(&defsignals);
+  sigaddset(&defsignals, SIGTERM);
+  sigaddset(&defsignals, SIGCHLD);
+  sigaddset(&defsignals, SIGPIPE);
+
   posix_spawnattr_init(&attrs);
   posix_spawnattr_setflags(&attrs, POSIX_SPAWN_SETPGROUP | POSIX_SPAWN_SETSIGDEF);
+  posix_spawnattr_setpgroup(&attrs, 0);
+  posix_spawnattr_setsigdefault(&attrs, &defsignals);
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStartProcess: Setting file actions.");
   posix_spawn_file_actions_init(&actions);
   if (infd != 0)
   {
     if (infd < 0)
-      posix_spawn_file_actions_addopen(&actions, 0, "/dev/null", O_WRONLY, 0);
+      posix_spawn_file_actions_addopen(&actions, 0, "/dev/null", O_RDONLY, 0);
     else
       posix_spawn_file_actions_adddup2(&actions, infd, 0);
   }
@@ -755,7 +808,7 @@ cupsdStartProcess(
   }
 
   cupsdReleaseSignals();
-#endif /* HAVE_POSIX_SPAWN */
+#endif /* USE_POSIX_SPAWN */
 
   if (*pid)
   {