]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/conf.c
Fix source file header text duplication text duplication.
[thirdparty/cups.git] / scheduler / conf.c
index 28cfbd24c481be3df147561ea3bbbdd011890eca..3cde8bd2989e527642003a32c41e85294f5a9040 100644 (file)
@@ -1,39 +1,14 @@
 /*
- * "$Id: conf.c 9352 2010-11-06 04:55:26Z mike $"
+ * Configuration routines for the CUPS scheduler.
  *
- *   Configuration routines for the CUPS scheduler.
+ * Copyright 2007-2016 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
- *   Copyright 2007-2012 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/".
- *
- * Contents:
- *
- *   cupsdAddAlias()         - Add a host alias.
- *   cupsdCheckPermissions()  - Fix the mode and ownership of a file or
- *                             directory.
- *   cupsdDefaultAuthType()   - Get the default AuthType.
- *   cupsdFreeAliases()       - Free all of the alias entries.
- *   cupsdReadConfiguration() - Read the cupsd.conf file.
- *   get_address()           - Get an address + port number from a line.
- *   get_addr_and_mask()      - Get an IP address and netmask.
- *   mime_error_cb()         - Log a MIME error.
- *   parse_aaa()             - Parse authentication, authorization, and access
- *                             control lines.
- *   parse_fatal_errors()     - Parse FatalErrors values in a string.
- *   parse_groups()          - Parse system group names in a string.
- *   parse_protocols()       - Parse browse protocols in a string.
- *   parse_variable()        - Parse a variable line.
- *   read_cupsd_conf()       - Read the cupsd.conf configuration file.
- *   read_cups_files_conf()   - Read the cups-files.conf configuration file.
- *   read_location()         - Read a <Location path> definition.
- *   read_policy()           - Read a <Policy name> definition.
- *   set_policy_defaults()    - Set default policy values as needed.
+ * 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
+ * missing or damaged, see the license at "http://www.cups.org/".
  */
 
 /*
 #include <stdarg.h>
 #include <grp.h>
 #include <sys/utsname.h>
+#ifdef HAVE_ASL_H
+#  include <asl.h>
+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+#  define SD_JOURNAL_SUPPRESS_LOCATION
+#  include <systemd/sd-journal.h>
+#endif /* HAVE_ASL_H */
 #include <syslog.h>
 
 #ifdef HAVE_LIBPAPER
@@ -70,7 +51,8 @@ typedef enum
   CUPSD_VARTYPE_TIME,                  /* Time interval option */
   CUPSD_VARTYPE_STRING,                        /* String option */
   CUPSD_VARTYPE_BOOLEAN,               /* Boolean option */
-  CUPSD_VARTYPE_PATHNAME               /* File/directory name option */
+  CUPSD_VARTYPE_PATHNAME,              /* File/directory name option */
+  CUPSD_VARTYPE_PERM                   /* File/directory permissions */
 } cupsd_vartype_t;
 
 typedef struct
@@ -107,13 +89,16 @@ static const cupsd_var_t   cupsd_vars[] =
 #ifdef HAVE_GSSAPI
   { "GSSServiceName",          &GSSServiceName,        CUPSD_VARTYPE_STRING },
 #endif /* HAVE_GSSAPI */
+#ifdef HAVE_ONDEMAND
+  { "IdleExitTimeout",         &IdleExitTimeout,       CUPSD_VARTYPE_TIME },
+#endif /* HAVE_ONDEMAND */
   { "JobKillDelay",            &JobKillDelay,          CUPSD_VARTYPE_TIME },
   { "JobRetryLimit",           &JobRetryLimit,         CUPSD_VARTYPE_INTEGER },
   { "JobRetryInterval",                &JobRetryInterval,      CUPSD_VARTYPE_TIME },
   { "KeepAliveTimeout",                &KeepAliveTimeout,      CUPSD_VARTYPE_TIME },
   { "KeepAlive",               &KeepAlive,             CUPSD_VARTYPE_BOOLEAN },
 #ifdef HAVE_LAUNCHD
-  { "LaunchdTimeout",          &LaunchdTimeout,        CUPSD_VARTYPE_TIME },
+  { "LaunchdTimeout",          &IdleExitTimeout,       CUPSD_VARTYPE_TIME },
 #endif /* HAVE_LAUNCHD */
   { "LimitRequestBody",                &MaxRequestSize,        CUPSD_VARTYPE_INTEGER },
   { "ListenBackLog",           &ListenBackLog,         CUPSD_VARTYPE_INTEGER },
@@ -127,7 +112,7 @@ static const cupsd_var_t    cupsd_vars[] =
   { "MaxJobs",                 &MaxJobs,               CUPSD_VARTYPE_INTEGER },
   { "MaxJobsPerPrinter",       &MaxJobsPerPrinter,     CUPSD_VARTYPE_INTEGER },
   { "MaxJobsPerUser",          &MaxJobsPerUser,        CUPSD_VARTYPE_INTEGER },
-  { "MaxJobTime",              &MaxJobTime,            CUPSD_VARTYPE_INTEGER },
+  { "MaxJobTime",              &MaxJobTime,            CUPSD_VARTYPE_TIME },
   { "MaxLeaseDuration",                &MaxLeaseDuration,      CUPSD_VARTYPE_TIME },
   { "MaxLogSize",              &MaxLogSize,            CUPSD_VARTYPE_INTEGER },
   { "MaxRequestSize",          &MaxRequestSize,        CUPSD_VARTYPE_INTEGER },
@@ -152,13 +137,16 @@ static const cupsd_var_t  cupsfiles_vars[] =
 {
   { "AccessLog",               &AccessLog,             CUPSD_VARTYPE_STRING },
   { "CacheDir",                        &CacheDir,              CUPSD_VARTYPE_STRING },
-  { "ConfigFilePerm",          &ConfigFilePerm,        CUPSD_VARTYPE_INTEGER },
+  { "ConfigFilePerm",          &ConfigFilePerm,        CUPSD_VARTYPE_PERM },
+#ifdef HAVE_SSL
+  { "CreateSelfSignedCerts",   &CreateSelfSignedCerts, CUPSD_VARTYPE_BOOLEAN },
+#endif /* HAVE_SSL */
   { "DataDir",                 &DataDir,               CUPSD_VARTYPE_STRING },
   { "DocumentRoot",            &DocumentRoot,          CUPSD_VARTYPE_STRING },
   { "ErrorLog",                        &ErrorLog,              CUPSD_VARTYPE_STRING },
   { "FileDevice",              &FileDevice,            CUPSD_VARTYPE_BOOLEAN },
   { "FontPath",                        &FontPath,              CUPSD_VARTYPE_STRING },
-  { "LogFilePerm",             &LogFilePerm,           CUPSD_VARTYPE_INTEGER },
+  { "LogFilePerm",             &LogFilePerm,           CUPSD_VARTYPE_PERM },
   { "LPDConfigFile",           &LPDConfigFile,         CUPSD_VARTYPE_STRING },
   { "PageLog",                 &PageLog,               CUPSD_VARTYPE_STRING },
   { "Printcap",                        &Printcap,              CUPSD_VARTYPE_STRING },
@@ -166,14 +154,12 @@ static const cupsd_var_t  cupsfiles_vars[] =
   { "RequestRoot",             &RequestRoot,           CUPSD_VARTYPE_STRING },
   { "ServerBin",               &ServerBin,             CUPSD_VARTYPE_PATHNAME },
 #ifdef HAVE_SSL
-  { "ServerCertificate",       &ServerCertificate,     CUPSD_VARTYPE_PATHNAME },
-#  if defined(HAVE_LIBSSL) || defined(HAVE_GNUTLS)
-  { "ServerKey",               &ServerKey,             CUPSD_VARTYPE_PATHNAME },
-#  endif /* HAVE_LIBSSL || HAVE_GNUTLS */
+  { "ServerKeychain",          &ServerKeychain,        CUPSD_VARTYPE_PATHNAME },
 #endif /* HAVE_SSL */
   { "ServerRoot",              &ServerRoot,            CUPSD_VARTYPE_PATHNAME },
   { "SMBConfigFile",           &SMBConfigFile,         CUPSD_VARTYPE_STRING },
   { "StateDir",                        &StateDir,              CUPSD_VARTYPE_STRING },
+  { "SyncOnClose",             &SyncOnClose,           CUPSD_VARTYPE_BOOLEAN },
 #ifdef HAVE_AUTHORIZATION_H
   { "SystemGroupAuthKey",      &SystemGroupAuthKey,    CUPSD_VARTYPE_STRING },
 #endif /* HAVE_AUTHORIZATION_H */
@@ -249,9 +235,9 @@ int                                 /* O - 0 on success, -1 on error, 1 on warning */
 cupsdCheckPermissions(
     const char *filename,              /* I - File/directory name */
     const char *suffix,                        /* I - Additional file/directory name */
-    int        mode,                   /* I - Permissions */
-    int        user,                   /* I - Owner */
-    int        group,                  /* I - Group */
+    mode_t     mode,                   /* I - Permissions */
+    uid_t      user,                   /* I - Owner */
+    gid_t      group,                  /* I - Group */
     int        is_dir,                 /* I - 1 = directory, 0 = file */
     int        create_dir)             /* I - 1 = create directory, -1 = create w/o logging, 0 = not */
 {
@@ -290,8 +276,11 @@ cupsdCheckPermissions(
                          "Unable to create directory \"%s\" - %s", filename,
                          strerror(errno));
         else
-         syslog(LOG_ERR, "Unable to create directory \"%s\" - %s", filename,
-                strerror(errno));
+#ifdef HAVE_SYSTEMD_SD_JOURNAL_H
+         sd_journal_print(LOG_ERR, "Unable to create directory \"%s\" - %s", filename, strerror(errno));
+#else
+         syslog(LOG_ERR, "Unable to create directory \"%s\" - %s", filename, strerror(errno));
+#endif /* HAVE_SYSTEMD_SD_JOURNAL_H */
 
         return (-1);
       }
@@ -328,7 +317,11 @@ cupsdCheckPermissions(
     if (create_dir >= 0)
       cupsdLogMessage(CUPSD_LOG_ERROR, "\"%s\" is not a directory.", filename);
     else
+#ifdef HAVE_SYSTEMD_SD_JOURNAL_H
+      sd_journal_print(LOG_ERR, "\"%s\" is not a directory.", filename);
+#else
       syslog(LOG_ERR, "\"%s\" is not a directory.", filename);
+#endif /* HAVE_SYSTEMD_SD_JOURNAL_H */
 
     return (-1);
   }
@@ -357,8 +350,11 @@ cupsdCheckPermissions(
                        "Unable to change ownership of \"%s\" - %s", filename,
                        strerror(errno));
       else
-       syslog(LOG_ERR, "Unable to change ownership of \"%s\" - %s", filename,
-              strerror(errno));
+#ifdef HAVE_SYSTEMD_SD_JOURNAL_H
+       sd_journal_print(LOG_ERR, "Unable to change ownership of \"%s\" - %s", filename, strerror(errno));
+#else
+       syslog(LOG_ERR, "Unable to change ownership of \"%s\" - %s", filename, strerror(errno));
+#endif /* HAVE_SYSTEMD_SD_JOURNAL_H */
 
       return (1);
     }
@@ -377,8 +373,11 @@ cupsdCheckPermissions(
                        "Unable to change permissions of \"%s\" - %s", filename,
                        strerror(errno));
       else
-       syslog(LOG_ERR, "Unable to change permissions of \"%s\" - %s", filename,
-              strerror(errno));
+#ifdef HAVE_SYSTEMD_SD_JOURNAL_H
+       sd_journal_print(LOG_ERR, "Unable to change permissions of \"%s\" - %s", filename, strerror(errno));
+#else
+       syslog(LOG_ERR, "Unable to change permissions of \"%s\" - %s", filename, strerror(errno));
+#endif /* HAVE_SYSTEMD_SD_JOURNAL_H */
 
       return (1);
     }
@@ -428,7 +427,7 @@ cupsdDefaultAuthType(void)
   * to use it...
   */
 
-  if (gss_init_sec_context == NULL)
+  if (&gss_init_sec_context == NULL)
     return (default_auth_type = CUPSD_AUTH_BASIC);
 #  endif /* __APPLE__ */
 
@@ -612,12 +611,13 @@ cupsdReadConfiguration(void)
   ClassifyOverride  = 0;
 
 #ifdef HAVE_SSL
-#  ifdef HAVE_CDSASSL
-  cupsdSetString(&ServerCertificate, "/Library/Keychains/System.keychain");
+#  ifdef HAVE_GNUTLS
+  cupsdSetString(&ServerKeychain, "ssl");
 #  else
-  cupsdSetString(&ServerCertificate, "ssl/server.crt");
-  cupsdSetString(&ServerKey, "ssl/server.key");
-#  endif /* HAVE_CDSASSL */
+  cupsdSetString(&ServerKeychain, "/Library/Keychains/System.keychain");
+#  endif /* HAVE_GNUTLS */
+
+  _httpTLSSetOptions(0);
 #endif /* HAVE_SSL */
 
   language = cupsLangDefault();
@@ -706,8 +706,8 @@ cupsdReadConfiguration(void)
   FatalErrors              = parse_fatal_errors(CUPS_DEFAULT_FATAL_ERRORS);
   default_auth_type        = CUPSD_AUTH_BASIC;
 #ifdef HAVE_SSL
+  CreateSelfSignedCerts    = TRUE;
   DefaultEncryption        = HTTP_ENCRYPT_REQUIRED;
-  SSLOptions               = CUPSD_SSL_NONE;
 #endif /* HAVE_SSL */
   DirtyCleanInterval       = DEFAULT_KEEPALIVE;
   JobKillDelay             = DEFAULT_TIMEOUT;
@@ -733,7 +733,9 @@ cupsdReadConfiguration(void)
   NumSystemGroups          = 0;
   ReloadTimeout                   = DEFAULT_KEEPALIVE;
   RootCertDuration         = 300;
+  Sandboxing               = CUPSD_SANDBOXING_STRICT;
   StrictConformance        = FALSE;
+  SyncOnClose              = FALSE;
   Timeout                  = DEFAULT_TIMEOUT;
   WebInterface             = CUPS_DEFAULT_WEBIF;
 
@@ -776,9 +778,9 @@ cupsdReadConfiguration(void)
   DefaultLeaseDuration       = 86400;
   MaxLeaseDuration           = 0;
 
-#ifdef HAVE_LAUNCHD
-  LaunchdTimeout = 10;
-#endif /* HAVE_LAUNCHD */
+#ifdef HAVE_ONDEMAND
+  IdleExitTimeout = 60;
+#endif /* HAVE_ONDEMAND */
 
  /*
   * Setup environment variables...
@@ -801,8 +803,11 @@ cupsdReadConfiguration(void)
       if (TestConfigFile)
         printf("\"%s\" contains errors.\n", CupsFilesFile);
       else
-        syslog(LOG_LPR, "Unable to read \"%s\" due to errors.",
-               CupsFilesFile);
+#ifdef HAVE_SYSTEMD_SD_JOURNAL_H
+       sd_journal_print(LOG_ERR, "Unable to read \"%s\" due to errors.", CupsFilesFile);
+#else
+        syslog(LOG_LPR, "Unable to read \"%s\" due to errors.", CupsFilesFile);
+#endif /* HAVE_SYSTEMD_SD_JOURNAL_H */
 
       return (0);
     }
@@ -811,8 +816,12 @@ cupsdReadConfiguration(void)
     cupsdLogMessage(CUPSD_LOG_INFO, "No %s, using defaults.", CupsFilesFile);
   else
   {
-    syslog(LOG_LPR, "Unable to open \"%s\": %s", CupsFilesFile,
-          strerror(errno));
+#ifdef HAVE_SYSTEMD_SD_JOURNAL_H
+    sd_journal_print(LOG_ERR, "Unable to open \"%s\" - %s", CupsFilesFile, strerror(errno));
+#else
+    syslog(LOG_LPR, "Unable to open \"%s\" - %s", CupsFilesFile, strerror(errno));
+#endif /* HAVE_SYSTEMD_SD_JOURNAL_H */
+
     return (0);
   }
 
@@ -825,8 +834,12 @@ cupsdReadConfiguration(void)
 
   if ((fp = cupsFileOpen(ConfigurationFile, "r")) == NULL)
   {
-    syslog(LOG_LPR, "Unable to open \"%s\": %s", ConfigurationFile,
-          strerror(errno));
+#ifdef HAVE_SYSTEMD_SD_JOURNAL_H
+    sd_journal_print(LOG_ERR, "Unable to open \"%s\" - %s", ConfigurationFile, strerror(errno));
+#else
+    syslog(LOG_LPR, "Unable to open \"%s\" - %s", ConfigurationFile, strerror(errno));
+#endif /* HAVE_SYSTEMD_SD_JOURNAL_H */
+
     return (0);
   }
 
@@ -839,8 +852,11 @@ cupsdReadConfiguration(void)
     if (TestConfigFile)
       printf("\"%s\" contains errors.\n", ConfigurationFile);
     else
-      syslog(LOG_LPR, "Unable to read \"%s\" due to errors.",
-            ConfigurationFile);
+#ifdef HAVE_SYSTEMD_SD_JOURNAL_H
+      sd_journal_print(LOG_ERR, "Unable to read \"%s\" due to errors.", ConfigurationFile);
+#else
+      syslog(LOG_LPR, "Unable to read \"%s\" due to errors.", ConfigurationFile);
+#endif /* HAVE_SYSTEMD_SD_JOURNAL_H */
 
     return (0);
   }
@@ -967,25 +983,24 @@ cupsdReadConfiguration(void)
   * Open the system log for cupsd if necessary...
   */
 
-#ifdef HAVE_VSYSLOG
+  if (!LogStderr)
+  {
+    if (!strcmp(AccessLog, "stderr"))
+      cupsdSetString(&AccessLog, "syslog");
+
+    if (!strcmp(ErrorLog, "stderr"))
+      cupsdSetString(&ErrorLog, "syslog");
+
+    if (!strcmp(PageLog, "stderr"))
+      cupsdSetString(&PageLog, "syslog");
+  }
+
+#if defined(HAVE_VSYSLOG) && !defined(HAVE_ASL_H) && !defined(HAVE_SYSTEMD_SD_JOURNAL_H)
   if (!strcmp(AccessLog, "syslog") ||
       !strcmp(ErrorLog, "syslog") ||
       !strcmp(PageLog, "syslog"))
     openlog("cupsd", LOG_PID | LOG_NOWAIT | LOG_NDELAY, LOG_LPR);
-#endif /* HAVE_VSYSLOG */
-
- /*
-  * Make sure each of the log files exists and gets rotated as necessary...
-  */
-
-  if (strcmp(AccessLog, "syslog"))
-    cupsdCheckLogFile(&AccessFile, AccessLog);
-
-  if (strcmp(ErrorLog, "syslog"))
-    cupsdCheckLogFile(&ErrorFile, ErrorLog);
-
-  if (strcmp(PageLog, "syslog"))
-    cupsdCheckLogFile(&PageFile, PageLog);
+#endif /* HAVE_VSYSLOG && !HAVE_ASL_H && !HAVE_SYSTEMD_SD_JOURNAL_H */
 
  /*
   * Log the configuration file that was used...
@@ -1012,8 +1027,11 @@ cupsdReadConfiguration(void)
       * Log the error and reset the group to a safe value...
       */
 
-      cupsdLogMessage(CUPSD_LOG_NOTICE,
+      cupsdLogMessage(CUPSD_LOG_ERROR,
                       "Group and SystemGroup cannot use the same groups.");
+      if (FatalErrors & (CUPSD_FATAL_CONFIG | CUPSD_FATAL_PERMISSIONS))
+        return (0);
+
       cupsdLogMessage(CUPSD_LOG_INFO, "Resetting Group to \"nobody\"...");
 
       group = getgrnam("nobody");
@@ -1081,24 +1099,15 @@ cupsdReadConfiguration(void)
     cupsdSetStringf(&CacheDir, "%s/%s", ServerRoot, CacheDir);
 
 #ifdef HAVE_SSL
-  if (ServerCertificate[0] != '/')
-    cupsdSetStringf(&ServerCertificate, "%s/%s", ServerRoot, ServerCertificate);
-
-  if (!strncmp(ServerRoot, ServerCertificate, strlen(ServerRoot)) &&
-      cupsdCheckPermissions(ServerCertificate, NULL, 0600, RunUser, Group,
-                            0, 0) < 0 &&
-      (FatalErrors & CUPSD_FATAL_PERMISSIONS))
-    return (0);
-
-#  if defined(HAVE_LIBSSL) || defined(HAVE_GNUTLS)
-  if (ServerKey[0] != '/')
-    cupsdSetStringf(&ServerKey, "%s/%s", ServerRoot, ServerKey);
-
-  if (!strncmp(ServerRoot, ServerKey, strlen(ServerRoot)) &&
-      cupsdCheckPermissions(ServerKey, NULL, 0600, RunUser, Group, 0, 0) < 0 &&
-      (FatalErrors & CUPSD_FATAL_PERMISSIONS))
-    return (0);
-#  endif /* HAVE_LIBSSL || HAVE_GNUTLS */
+  if (!_cups_strcasecmp(ServerKeychain, "internal"))
+    cupsdClearString(&ServerKeychain);
+  else if (ServerKeychain[0] != '/')
+    cupsdSetStringf(&ServerKeychain, "%s/%s", ServerRoot, ServerKeychain);
+
+  cupsdLogMessage(CUPSD_LOG_DEBUG, "Using keychain \"%s\" for server name \"%s\".", ServerKeychain ? ServerKeychain : "internal", ServerName);
+  if (!CreateSelfSignedCerts)
+    cupsdLogMessage(CUPSD_LOG_DEBUG, "Self-signed TLS certificate generation is disabled.");
+  cupsSetServerCredentials(ServerKeychain, ServerName, CreateSelfSignedCerts);
 #endif /* HAVE_SSL */
 
  /*
@@ -1110,7 +1119,7 @@ cupsdReadConfiguration(void)
 
   if ((cupsdCheckPermissions(RequestRoot, NULL, 0710, RunUser,
                             Group, 1, 1) < 0 ||
-       cupsdCheckPermissions(CacheDir, NULL, 0775, RunUser,
+       cupsdCheckPermissions(CacheDir, NULL, 0770, RunUser,
                             Group, 1, 1) < 0 ||
        cupsdCheckPermissions(temp, NULL, 0775, RunUser,
                             Group, 1, 1) < 0 ||
@@ -1186,6 +1195,8 @@ cupsdReadConfiguration(void)
     cupsdSetStringf(&TempDir, "%s/tmp", RequestRoot);
   }
 
+  setenv("TMPDIR", TempDir, 1);
+
  /*
   * Make sure the temporary directory has the right permissions...
   */
@@ -1209,6 +1220,19 @@ cupsdReadConfiguration(void)
 
   cupsdUpdateEnv();
 
+  /*
+   * Validate the default error policy...
+   */
+
+  if (strcmp(ErrorPolicy, "retry-current-job") &&
+      strcmp(ErrorPolicy, "abort-job") &&
+      strcmp(ErrorPolicy, "retry-job") &&
+      strcmp(ErrorPolicy, "stop-printer"))
+  {
+    cupsdLogMessage(CUPSD_LOG_ALERT, "Invalid ErrorPolicy \"%s\", resetting to \"stop-printer\".", ErrorPolicy);
+    cupsdSetString(&ErrorPolicy, "stop-printer");
+  }
+
  /*
   * Update default paper size setting as needed...
   */
@@ -1331,6 +1355,7 @@ cupsdReadConfiguration(void)
       cupsdAddString(&(p->job_attrs), "job-name");
       cupsdAddString(&(p->job_attrs), "job-originating-host-name");
       cupsdAddString(&(p->job_attrs), "job-originating-user-name");
+      cupsdAddString(&(p->job_attrs), "phone");
 
       cupsdLogMessage(CUPSD_LOG_INFO, "SubscriptionPrivateAccess default");
       cupsdAddString(&(p->sub_access), "@OWNER");
@@ -1539,7 +1564,7 @@ cupsdReadConfiguration(void)
     if (!mimeType(MimeDatabase, "application", "octet-stream"))
       NumMimeTypes ++;
 
-    if ((MimeTypes = calloc(NumMimeTypes, sizeof(const char *))) == NULL)
+    if ((MimeTypes = calloc((size_t)NumMimeTypes, sizeof(const char *))) == NULL)
     {
       cupsdLogMessage(CUPSD_LOG_ERROR,
                       "Unable to allocate memory for %d MIME types.",
@@ -1813,7 +1838,8 @@ get_addr_and_mask(const char *value,      /* I - String from config file */
        * Merge everything into a 32-bit IPv4 address in ip[3]...
        */
 
-       ip[3] = (((((val[0] << 8) | val[1]) << 8) | val[2]) << 8) | val[3];
+       ip[3] = ((((((unsigned)val[0] << 8) | (unsigned)val[1]) << 8) |
+                (unsigned)val[2]) << 8) | (unsigned)val[3];
 
        if (ipcount < 4)
          mask[3] = (0xffffffff << (32 - 8 * ipcount)) & 0xffffffff;
@@ -1881,7 +1907,8 @@ get_addr_and_mask(const char *value,      /* I - String from config file */
     * Merge everything into a 32-bit IPv4 address in ip[3]...
     */
 
-    ip[3] = (((((val[0] << 8) | val[1]) << 8) | val[2]) << 8) | val[3];
+    ip[3] = ((((((unsigned)val[0] << 8) | (unsigned)val[1]) << 8) |
+             (unsigned)val[2]) << 8) | (unsigned)val[3];
 
     if (ipcount < 4)
       mask[3] = (0xffffffff << (32 - 8 * ipcount)) & 0xffffffff;
@@ -1908,7 +1935,8 @@ get_addr_and_mask(const char *value,      /* I - String from config file */
                  mask + 3) != 4)
         return (0);
 
-      mask[3] |= ((((mask[0] << 8) | mask[1]) << 8) | mask[2]) << 8;
+      mask[3] |= (((((unsigned)mask[0] << 8) | (unsigned)mask[1]) << 8) |
+                  (unsigned)mask[2]) << 8;
       mask[0] = mask[1] = mask[2] = 0;
     }
     else
@@ -2031,8 +2059,8 @@ parse_aaa(cupsd_location_t *loc,  /* I - Location */
     else if (!_cups_strcasecmp(value, "always"))
     {
       cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "Encryption value \"%s\" on line %d is invalid in this "
-                     "context. Using \"required\" instead.", value, linenum);
+                      "Encryption value \"%s\" on line %d of %s is invalid in this "
+                     "context. Using \"required\" instead.", value, linenum, ConfigurationFile);
 
       loc->encryption = HTTP_ENCRYPT_REQUIRED;
     }
@@ -2043,7 +2071,7 @@ parse_aaa(cupsd_location_t *loc,  /* I - Location */
     else
     {
       cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "Unknown Encryption value %s on line %d.", value, linenum);
+                      "Unknown Encryption value %s on line %d of %s.", value, linenum, ConfigurationFile);
       return (0);
     }
   }
@@ -2059,8 +2087,8 @@ parse_aaa(cupsd_location_t *loc,  /* I - Location */
       loc->order_type = CUPSD_AUTH_DENY;
     else
     {
-      cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown Order value %s on line %d.",
-                     value, linenum);
+      cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown Order value %s on line %d of %s.",
+                     value, linenum, ConfigurationFile);
       return (0);
     }
   }
@@ -2162,8 +2190,8 @@ parse_aaa(cupsd_location_t *loc,  /* I - Location */
 
        if (!get_addr_and_mask(value, ip, mask))
        {
-         cupsdLogMessage(CUPSD_LOG_ERROR, "Bad netmask value %s on line %d.",
-                         value, linenum);
+         cupsdLogMessage(CUPSD_LOG_ERROR, "Bad netmask value %s on line %d of %s.",
+                         value, linenum, ConfigurationFile);
          return (0);
        }
 
@@ -2198,20 +2226,6 @@ parse_aaa(cupsd_location_t *loc, /* I - Location */
       if (loc->level == CUPSD_AUTH_ANON)
        loc->level = CUPSD_AUTH_USER;
     }
-    else if (!_cups_strcasecmp(value, "digest"))
-    {
-      loc->type = CUPSD_AUTH_DIGEST;
-
-      if (loc->level == CUPSD_AUTH_ANON)
-       loc->level = CUPSD_AUTH_USER;
-    }
-    else if (!_cups_strcasecmp(value, "basicdigest"))
-    {
-      loc->type = CUPSD_AUTH_BASICDIGEST;
-
-      if (loc->level == CUPSD_AUTH_ANON)
-       loc->level = CUPSD_AUTH_USER;
-    }
     else if (!_cups_strcasecmp(value, "default"))
     {
       loc->type = CUPSD_AUTH_DEFAULT;
@@ -2231,8 +2245,8 @@ parse_aaa(cupsd_location_t *loc,  /* I - Location */
     else
     {
       cupsdLogMessage(CUPSD_LOG_WARN,
-                      "Unknown authorization type %s on line %d.",
-                     value, linenum);
+                      "Unknown authorization type %s on line %d of %s.",
+                     value, linenum, ConfigurationFile);
       return (0);
     }
   }
@@ -2258,8 +2272,8 @@ parse_aaa(cupsd_location_t *loc,  /* I - Location */
 
       cupsdLogMessage(CUPSD_LOG_WARN,
                       "\"AuthClass %s\" is deprecated; consider using "
-                     "\"Require valid-user\" on line %d.",
-                     value, linenum);
+                     "\"Require valid-user\" on line %d of %s.",
+                     value, linenum, ConfigurationFile);
     }
     else if (!_cups_strcasecmp(value, "group"))
     {
@@ -2267,8 +2281,8 @@ parse_aaa(cupsd_location_t *loc,  /* I - Location */
 
       cupsdLogMessage(CUPSD_LOG_WARN,
                       "\"AuthClass %s\" is deprecated; consider using "
-                     "\"Require user @groupname\" on line %d.",
-                     value, linenum);
+                     "\"Require user @groupname\" on line %d of %s.",
+                     value, linenum, ConfigurationFile);
     }
     else if (!_cups_strcasecmp(value, "system"))
     {
@@ -2278,14 +2292,14 @@ parse_aaa(cupsd_location_t *loc,        /* I - Location */
 
       cupsdLogMessage(CUPSD_LOG_WARN,
                       "\"AuthClass %s\" is deprecated; consider using "
-                     "\"Require user @SYSTEM\" on line %d.",
-                     value, linenum);
+                     "\"Require user @SYSTEM\" on line %d of %s.",
+                     value, linenum, ConfigurationFile);
     }
     else
     {
       cupsdLogMessage(CUPSD_LOG_WARN,
-                      "Unknown authorization class %s on line %d.",
-                     value, linenum);
+                      "Unknown authorization class %s on line %d of %s.",
+                     value, linenum, ConfigurationFile);
       return (0);
     }
   }
@@ -2295,8 +2309,8 @@ parse_aaa(cupsd_location_t *loc,  /* I - Location */
 
     cupsdLogMessage(CUPSD_LOG_WARN,
                     "\"AuthGroupName %s\" directive is deprecated; consider "
-                   "using \"Require user @%s\" on line %d.",
-                   value, value, linenum);
+                   "using \"Require user @%s\" on line %d of %s.",
+                   value, value, linenum, ConfigurationFile);
   }
   else if (!_cups_strcasecmp(line, "Require"))
   {
@@ -2322,8 +2336,8 @@ parse_aaa(cupsd_location_t *loc,  /* I - Location */
       loc->level = CUPSD_AUTH_GROUP;
     else
     {
-      cupsdLogMessage(CUPSD_LOG_WARN, "Unknown Require type %s on line %d.",
-                     value, linenum);
+      cupsdLogMessage(CUPSD_LOG_WARN, "Unknown Require type %s on line %d of %s.",
+                     value, linenum, ConfigurationFile);
       return (0);
     }
 
@@ -2385,8 +2399,8 @@ parse_aaa(cupsd_location_t *loc,  /* I - Location */
       loc->satisfy = CUPSD_AUTH_SATISFY_ANY;
     else
     {
-      cupsdLogMessage(CUPSD_LOG_WARN, "Unknown Satisfy value %s on line %d.",
-                      value, linenum);
+      cupsdLogMessage(CUPSD_LOG_WARN, "Unknown Satisfy value %s on line %d of %s.",
+                      value, linenum, ConfigurationFile);
       return (0);
     }
   }
@@ -2711,6 +2725,41 @@ parse_variable(
        }
        break;
 
+    case CUPSD_VARTYPE_PERM :
+       if (!value)
+       {
+         cupsdLogMessage(CUPSD_LOG_ERROR,
+                         "Missing permissions value for %s on line %d of %s.",
+                         line, linenum, filename);
+          return (0);
+       }
+       else if (!isdigit(*value & 255))
+       {
+        /* TODO: Add chmod UGO syntax support */
+         cupsdLogMessage(CUPSD_LOG_ERROR,
+                         "Bad permissions value for %s on line %d of %s.",
+                         line, linenum, filename);
+          return (0);
+       }
+       else
+       {
+         int n = strtol(value, NULL, 8);
+                                       /* Permissions value */
+
+         if (n < 0)
+         {
+           cupsdLogMessage(CUPSD_LOG_ERROR,
+                           "Bad negative permissions value for %s on line %d of "
+                           "%s.", line, linenum, filename);
+           return (0);
+         }
+         else
+         {
+           *((mode_t *)var->ptr) = (mode_t)n;
+         }
+       }
+       break;
+
     case CUPSD_VARTYPE_TIME :
        if (!value)
        {
@@ -2828,7 +2877,7 @@ parse_variable(
        else
          snprintf(temp, sizeof(temp), "%s/%s", ServerRoot, value);
 
-       if (access(temp, 0))
+       if (access(temp, 0) && _cups_strcasecmp(value, "internal") && _cups_strcasecmp(line, "ServerKeychain"))
        {
          cupsdLogMessage(CUPSD_LOG_ERROR,
                          "File or directory for \"%s %s\" on line %d of %s "
@@ -2927,15 +2976,60 @@ read_cupsd_conf(cups_file_t *fp)        /* I - File to read from */
       JobRetryInterval = atoi(value);
       cupsdLogMessage(CUPSD_LOG_WARN,
                      "FaxRetryInterval is deprecated; use "
-                     "JobRetryInterval on line %d.", linenum);
+                     "JobRetryInterval on line %d of %s.", linenum, ConfigurationFile);
     }
     else if (!_cups_strcasecmp(line, "FaxRetryLimit") && value)
     {
       JobRetryLimit = atoi(value);
       cupsdLogMessage(CUPSD_LOG_WARN,
                      "FaxRetryLimit is deprecated; use "
-                     "JobRetryLimit on line %d.", linenum);
+                     "JobRetryLimit on line %d of %s.", linenum, ConfigurationFile);
     }
+#ifdef HAVE_SSL
+    else if (!_cups_strcasecmp(line, "SSLOptions"))
+    {
+     /*
+      * SSLOptions [AllowRC4] [AllowSSL3] [None]
+      */
+
+      int      options = 0;            /* SSL/TLS options */
+
+      if (value)
+      {
+        char   *start,                 /* Start of option */
+               *end;                   /* End of option */
+
+       for (start = value; *start; start = end)
+       {
+        /*
+         * Find end of keyword...
+         */
+
+         end = start;
+         while (*end && !_cups_isspace(*end))
+           end ++;
+
+         if (*end)
+           *end++ = '\0';
+
+         /*
+         * Compare...
+         */
+
+          if (!_cups_strcasecmp(start, "AllowRC4"))
+           options |= _HTTP_TLS_ALLOW_RC4;
+          else if (!_cups_strcasecmp(start, "AllowSSL3"))
+           options |= _HTTP_TLS_ALLOW_SSL3;
+          else if (!_cups_strcasecmp(start, "None"))
+           options = 0;
+         else if (_cups_strcasecmp(start, "NoEmptyFragments"))
+           cupsdLogMessage(CUPSD_LOG_WARN, "Unknown SSL option %s at line %d.", start, linenum);
+        }
+      }
+
+      _httpTLSSetOptions(options);
+    }
+#endif /* HAVE_SSL */
     else if ((!_cups_strcasecmp(line, "Port") || !_cups_strcasecmp(line, "Listen")
 #ifdef HAVE_SSL
              || !_cups_strcasecmp(line, "SSLPort") || !_cups_strcasecmp(line, "SSLListen")
@@ -2981,9 +3075,15 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
 
         if (lis)
        {
-         httpAddrString(&lis->address, temp, sizeof(temp));
-         cupsdLogMessage(CUPSD_LOG_WARN,
-                         "Duplicate listen address \"%s\" ignored.", temp);
+#ifdef HAVE_ONDEMAND
+         if (!lis->on_demand)
+#endif /* HAVE_ONDEMAND */
+         {
+           httpAddrString(&lis->address, temp, sizeof(temp));
+           cupsdLogMessage(CUPSD_LOG_WARN,
+                           "Duplicate listen address \"%s\" ignored.", temp);
+         }
+
           continue;
        }
 
@@ -3033,7 +3133,7 @@ read_cupsd_conf(cups_file_t *fp)  /* I - File to read from */
 #endif /* AF_LOCAL */
        cupsdLogMessage(CUPSD_LOG_INFO, "Listening to %s:%d (IPv%d)", temp,
                         httpAddrPort(&(lis->address)),
-                       _httpAddrFamily(&(lis->address)) == AF_INET ? 4 : 6);
+                       httpAddrFamily(&(lis->address)) == AF_INET ? 4 : 6);
 
         if (!httpAddrLocalhost(&(lis->address)))
          RemotePort = httpAddrPort(&(lis->address));
@@ -3058,8 +3158,8 @@ read_cupsd_conf(cups_file_t *fp)  /* I - File to read from */
       if (protocols < 0)
       {
        cupsdLogMessage(CUPSD_LOG_ERROR,
-                       "Unknown browse protocol \"%s\" on line %d.",
-                       value, linenum);
+                       "Unknown browse protocol \"%s\" on line %d of %s.",
+                       value, linenum, ConfigurationFile);
         break;
       }
 
@@ -3075,10 +3175,6 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
        default_auth_type = CUPSD_AUTH_NONE;
       else if (!_cups_strcasecmp(value, "basic"))
        default_auth_type = CUPSD_AUTH_BASIC;
-      else if (!_cups_strcasecmp(value, "digest"))
-       default_auth_type = CUPSD_AUTH_DIGEST;
-      else if (!_cups_strcasecmp(value, "basicdigest"))
-       default_auth_type = CUPSD_AUTH_BASICDIGEST;
 #ifdef HAVE_GSSAPI
       else if (!_cups_strcasecmp(value, "negotiate"))
         default_auth_type = CUPSD_AUTH_NEGOTIATE;
@@ -3088,8 +3184,8 @@ read_cupsd_conf(cups_file_t *fp)  /* I - File to read from */
       else
       {
        cupsdLogMessage(CUPSD_LOG_WARN,
-                       "Unknown default authorization type %s on line %d.",
-                       value, linenum);
+                       "Unknown default authorization type %s on line %d of %s.",
+                       value, linenum, ConfigurationFile);
        if (FatalErrors & CUPSD_FATAL_CONFIG)
          return (0);
       }
@@ -3110,8 +3206,8 @@ read_cupsd_conf(cups_file_t *fp)  /* I - File to read from */
       else
       {
        cupsdLogMessage(CUPSD_LOG_WARN,
-                       "Unknown default encryption %s on line %d.",
-                       value, linenum);
+                       "Unknown default encryption %s on line %d of %s.",
+                       value, linenum, ConfigurationFile);
        if (FatalErrors & CUPSD_FATAL_CONFIG)
          return (0);
       }
@@ -3132,8 +3228,8 @@ read_cupsd_conf(cups_file_t *fp)  /* I - File to read from */
       else if (!_cups_strcasecmp(value, "double"))
         HostNameLookups = 2;
       else
-       cupsdLogMessage(CUPSD_LOG_WARN, "Unknown HostNameLookups %s on line %d.",
-                       value, linenum);
+       cupsdLogMessage(CUPSD_LOG_WARN, "Unknown HostNameLookups %s on line %d of %s.",
+                       value, linenum, ConfigurationFile);
     }
     else if (!_cups_strcasecmp(line, "AccessLogLevel") && value)
     {
@@ -3147,9 +3243,11 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
         AccessLogLevel = CUPSD_ACCESSLOG_ACTIONS;
       else if (!_cups_strcasecmp(value, "config"))
         AccessLogLevel = CUPSD_ACCESSLOG_CONFIG;
+      else if (!_cups_strcasecmp(value, "none"))
+        AccessLogLevel = CUPSD_ACCESSLOG_NONE;
       else
-        cupsdLogMessage(CUPSD_LOG_WARN, "Unknown AccessLogLevel %s on line %d.",
-                       value, linenum);
+        cupsdLogMessage(CUPSD_LOG_WARN, "Unknown AccessLogLevel %s on line %d of %s.",
+                       value, linenum, ConfigurationFile);
     }
     else if (!_cups_strcasecmp(line, "LogLevel") && value)
     {
@@ -3178,8 +3276,8 @@ read_cupsd_conf(cups_file_t *fp)  /* I - File to read from */
       else if (!_cups_strcasecmp(value, "none"))
         LogLevel = CUPSD_LOG_NONE;
       else
-        cupsdLogMessage(CUPSD_LOG_WARN, "Unknown LogLevel %s on line %d.",
-                       value, linenum);
+        cupsdLogMessage(CUPSD_LOG_WARN, "Unknown LogLevel %s on line %d of %s.",
+                       value, linenum, ConfigurationFile);
     }
     else if (!_cups_strcasecmp(line, "LogTimeFormat") && value)
     {
@@ -3192,8 +3290,8 @@ read_cupsd_conf(cups_file_t *fp)  /* I - File to read from */
       else if (!_cups_strcasecmp(value, "usecs"))
         LogTimeFormat = CUPSD_TIME_USECS;
       else
-        cupsdLogMessage(CUPSD_LOG_WARN, "Unknown LogTimeFormat %s on line %d.",
-                       value, linenum);
+        cupsdLogMessage(CUPSD_LOG_WARN, "Unknown LogTimeFormat %s on line %d of %s.",
+                       value, linenum, ConfigurationFile);
     }
     else if (!_cups_strcasecmp(line, "ServerTokens") && value)
     {
@@ -3224,8 +3322,8 @@ read_cupsd_conf(cups_file_t *fp)  /* I - File to read from */
       else if (!_cups_strcasecmp(value, "None"))
        cupsdClearString(&ServerHeader);
       else
-       cupsdLogMessage(CUPSD_LOG_WARN, "Unknown ServerTokens %s on line %d.",
-                        value, linenum);
+       cupsdLogMessage(CUPSD_LOG_WARN, "Unknown ServerTokens %s on line %d of %s.",
+                        value, linenum, ConfigurationFile);
     }
     else if (!_cups_strcasecmp(line, "PassEnv") && value)
     {
@@ -3301,26 +3399,9 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
       }
       else
         cupsdLogMessage(CUPSD_LOG_ERROR,
-                       "Missing value for SetEnv directive on line %d.",
-                       linenum);
+                       "Missing value for SetEnv directive on line %d of %s.",
+                       linenum, ConfigurationFile);
     }
-#ifdef HAVE_SSL
-    else if (!_cups_strcasecmp(line, "SSLOptions"))
-    {
-     /*
-      * SSLOptions options
-      */
-
-      if (!value || !_cups_strcasecmp(value, "none"))
-        SSLOptions = CUPSD_SSL_NONE;
-      else if (!_cups_strcasecmp(value, "noemptyfragments"))
-        SSLOptions = CUPSD_SSL_NOEMPTY;
-      else
-        cupsdLogMessage(CUPSD_LOG_ERROR,
-                       "Unknown value \"%s\" for SSLOptions directive on "
-                       "line %d.", value, linenum);
-    }
-#endif /* HAVE_SSL */
     else if (!_cups_strcasecmp(line, "AccessLog") ||
              !_cups_strcasecmp(line, "CacheDir") ||
              !_cups_strcasecmp(line, "ConfigFilePerm") ||
@@ -3341,6 +3422,7 @@ read_cupsd_conf(cups_file_t *fp)  /* I - File to read from */
              !_cups_strcasecmp(line, "ServerBin") ||
              !_cups_strcasecmp(line, "ServerCertificate") ||
              !_cups_strcasecmp(line, "ServerKey") ||
+             !_cups_strcasecmp(line, "ServerKeychain") ||
              !_cups_strcasecmp(line, "ServerRoot") ||
              !_cups_strcasecmp(line, "SMBConfigFile") ||
              !_cups_strcasecmp(line, "StateDir") ||
@@ -3394,7 +3476,7 @@ read_cups_files_conf(cups_file_t *fp)     /* I - File to read from */
       */
 
       if (isdigit(value[0]))
-        Group = atoi(value);
+        Group = (gid_t)atoi(value);
       else
       {
         endgrent();
@@ -3433,6 +3515,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") && getuid())
+      {
+        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)
     {
      /*
@@ -3469,7 +3575,7 @@ read_cups_files_conf(cups_file_t *fp)     /* I - File to read from */
             return (0);
         }
         else
-         User = atoi(value);
+         User = (uid_t)atoi(value);
       }
       else
       {
@@ -3503,6 +3609,15 @@ read_cups_files_conf(cups_file_t *fp)    /* I - File to read from */
         }
       }
     }
+    else if (!_cups_strcasecmp(line, "ServerCertificate") ||
+             !_cups_strcasecmp(line, "ServerKey"))
+    {
+      cupsdLogMessage(CUPSD_LOG_INFO,
+                     "The \"%s\" directive on line %d of %s is no longer "
+                     "supported; this will become an error in a future "
+                     "release.",
+                     line, linenum, CupsFilesFile);
+    }
     else if (!parse_variable(CupsFilesFile, linenum, line, value,
                             sizeof(cupsfiles_vars) / sizeof(cupsfiles_vars[0]),
                             cupsfiles_vars) &&
@@ -3532,8 +3647,8 @@ read_location(cups_file_t *fp,            /* I - Configuration file */
 
 
   if ((parent = cupsdFindLocation(location)) != NULL)
-    cupsdLogMessage(CUPSD_LOG_WARN, "Duplicate <Location %s> on line %d.",
-                    location, linenum);
+    cupsdLogMessage(CUPSD_LOG_WARN, "Duplicate <Location %s> on line %d of %s.",
+                    location, linenum, ConfigurationFile);
   else if ((parent = cupsdNewLocation(location)) == NULL)
     return (0);
   else
@@ -3558,7 +3673,7 @@ read_location(cups_file_t *fp,            /* I - Configuration file */
     {
       if (!value)
       {
-        cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d.", linenum);
+        cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of %s.", linenum, ConfigurationFile);
         if (FatalErrors & CUPSD_FATAL_CONFIG)
          return (0);
         else
@@ -3593,8 +3708,8 @@ read_location(cups_file_t *fp,            /* I - Configuration file */
        else if (!strcmp(value, "TRACE"))
          loc->limit |= CUPSD_AUTH_LIMIT_TRACE;
        else
-         cupsdLogMessage(CUPSD_LOG_WARN, "Unknown request type %s on line %d.",
-                         value, linenum);
+         cupsdLogMessage(CUPSD_LOG_WARN, "Unknown request type %s on line %d of %s.",
+                         value, linenum, ConfigurationFile);
 
         for (value = valptr; isspace(*value & 255); value ++);
       }
@@ -3609,15 +3724,15 @@ read_location(cups_file_t *fp,          /* I - Configuration file */
       loc = parent;
     else if (!value)
     {
-      cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value on line %d.", linenum);
+      cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value on line %d of %s.", linenum, ConfigurationFile);
       if (FatalErrors & CUPSD_FATAL_CONFIG)
        return (0);
     }
     else if (!parse_aaa(loc, line, value, linenum))
     {
       cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "Unknown Location directive %s on line %d.",
-                     line, linenum);
+                      "Unknown Location directive %s on line %d of %s.",
+                     line, linenum, ConfigurationFile);
       if (FatalErrors & CUPSD_FATAL_CONFIG)
        return (0);
     }
@@ -3656,8 +3771,8 @@ read_policy(cups_file_t *fp,              /* I - Configuration file */
   */
 
   if ((pol = cupsdFindPolicy(policy)) != NULL)
-    cupsdLogMessage(CUPSD_LOG_WARN, "Duplicate <Policy %s> on line %d.",
-                    policy, linenum);
+    cupsdLogMessage(CUPSD_LOG_WARN, "Duplicate <Policy %s> on line %d of %s.",
+                    policy, linenum, ConfigurationFile);
   else if ((pol = cupsdAddPolicy(policy)) == NULL)
     return (0);
 
@@ -3678,8 +3793,8 @@ read_policy(cups_file_t *fp,              /* I - Configuration file */
     {
       if (op)
         cupsdLogMessage(CUPSD_LOG_WARN,
-                       "Missing </Limit> before </Policy> on line %d.",
-                       linenum);
+                       "Missing </Limit> before </Policy> on line %d of %s.",
+                       linenum, ConfigurationFile);
 
       set_policy_defaults(pol);
 
@@ -3689,7 +3804,7 @@ read_policy(cups_file_t *fp,              /* I - Configuration file */
     {
       if (!value)
       {
-        cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d.", linenum);
+        cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of %s.", linenum, ConfigurationFile);
         if (FatalErrors & CUPSD_FATAL_CONFIG)
          return (0);
         else
@@ -3715,15 +3830,15 @@ read_policy(cups_file_t *fp,            /* I - Configuration file */
            ops[num_ops] = IPP_ANY_OPERATION;
          else if ((ops[num_ops] = ippOpValue(value)) == IPP_BAD_OPERATION)
            cupsdLogMessage(CUPSD_LOG_ERROR,
-                           "Bad IPP operation name \"%s\" on line %d.",
-                           value, linenum);
+                           "Bad IPP operation name \"%s\" on line %d of %s.",
+                           value, linenum, ConfigurationFile);
           else
            num_ops ++;
        }
        else
          cupsdLogMessage(CUPSD_LOG_ERROR,
-                         "Too many operations listed on line %d.",
-                         linenum);
+                         "Too many operations listed on line %d of %s.",
+                         linenum, ConfigurationFile);
 
         for (value = valptr; isspace(*value & 255); value ++);
       }
@@ -3764,7 +3879,7 @@ read_policy(cups_file_t *fp,              /* I - Configuration file */
     }
     else if (!value)
     {
-      cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value on line %d.", linenum);
+      cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value on line %d of %s.", linenum, ConfigurationFile);
       if (FatalErrors & CUPSD_FATAL_CONFIG)
        return (0);
     }
@@ -3777,7 +3892,7 @@ read_policy(cups_file_t *fp,              /* I - Configuration file */
       {
         cupsdLogMessage(CUPSD_LOG_ERROR,
                        "%s directive must appear outside <Limit>...</Limit> "
-                       "on line %d.", line, linenum);
+                       "on line %d of %s.", line, linenum, ConfigurationFile);
        if (FatalErrors & CUPSD_FATAL_CONFIG)
          return (0);
       }
@@ -3875,16 +3990,16 @@ read_policy(cups_file_t *fp,            /* I - Configuration file */
     else if (!op)
     {
       cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "Missing <Limit ops> directive before %s on line %d.",
-                      line, linenum);
+                      "Missing <Limit ops> directive before %s on line %d of %s.",
+                      line, linenum, ConfigurationFile);
       if (FatalErrors & CUPSD_FATAL_CONFIG)
        return (0);
     }
     else if (!parse_aaa(op, line, value, linenum))
     {
       cupsdLogMessage(CUPSD_LOG_ERROR,
-                     "Unknown Policy Limit directive %s on line %d.",
-                     line, linenum);
+                     "Unknown Policy Limit directive %s on line %d of %s.",
+                     line, linenum, ConfigurationFile);
 
       if (FatalErrors & CUPSD_FATAL_CONFIG)
        return (0);
@@ -3913,121 +4028,106 @@ set_policy_defaults(cupsd_policy_t *pol)/* I - Policy */
   * Verify that we have an explicit policy for Validate-Job, Cancel-Jobs,
   * Cancel-My-Jobs, Close-Job, and CUPS-Get-Document, which ensures that
   * upgrades do not introduce new security issues...
+  *
+  * CUPS STR #4659: Allow a lone <Limit All> policy.
   */
 
-  if ((op = cupsdFindPolicyOp(pol, IPP_VALIDATE_JOB)) == NULL ||
-      op->op == IPP_ANY_OPERATION)
+  if (cupsArrayCount(pol->ops) > 1)
   {
-    if ((op = cupsdFindPolicyOp(pol, IPP_PRINT_JOB)) != NULL &&
-       op->op != IPP_ANY_OPERATION)
+    if ((op = cupsdFindPolicyOp(pol, IPP_VALIDATE_JOB)) == NULL ||
+       op->op == IPP_ANY_OPERATION)
     {
-     /*
-      * Add a new limit for Validate-Job using the Print-Job limit as a
-      * template...
-      */
+      if ((op = cupsdFindPolicyOp(pol, IPP_PRINT_JOB)) != NULL &&
+         op->op != IPP_ANY_OPERATION)
+      {
+       /*
+       * Add a new limit for Validate-Job using the Print-Job limit as a
+       * template...
+       */
 
-      cupsdLogMessage(CUPSD_LOG_WARN,
-                     "No limit for Validate-Job defined in policy %s "
-                     "- using Print-Job's policy.", pol->name);
+       cupsdLogMessage(CUPSD_LOG_WARN, "No limit for Validate-Job defined in policy %s - using Print-Job's policy.", pol->name);
 
-      cupsdAddPolicyOp(pol, op, IPP_VALIDATE_JOB);
+       cupsdAddPolicyOp(pol, op, IPP_VALIDATE_JOB);
+      }
+      else
+       cupsdLogMessage(CUPSD_LOG_WARN, "No limit for Validate-Job defined in policy %s and no suitable template found.", pol->name);
     }
-    else
-      cupsdLogMessage(CUPSD_LOG_WARN,
-                     "No limit for Validate-Job defined in policy %s "
-                     "and no suitable template found.", pol->name);
-  }
 
-  if ((op = cupsdFindPolicyOp(pol, IPP_CANCEL_JOBS)) == NULL ||
-      op->op == IPP_ANY_OPERATION)
-  {
-    if ((op = cupsdFindPolicyOp(pol, IPP_PAUSE_PRINTER)) != NULL &&
-       op->op != IPP_ANY_OPERATION)
+    if ((op = cupsdFindPolicyOp(pol, IPP_CANCEL_JOBS)) == NULL ||
+       op->op == IPP_ANY_OPERATION)
     {
-     /*
-      * Add a new limit for Cancel-Jobs using the Pause-Printer limit as a
-      * template...
-      */
+      if ((op = cupsdFindPolicyOp(pol, IPP_PAUSE_PRINTER)) != NULL &&
+         op->op != IPP_ANY_OPERATION)
+      {
+       /*
+       * Add a new limit for Cancel-Jobs using the Pause-Printer limit as a
+       * template...
+       */
 
-      cupsdLogMessage(CUPSD_LOG_WARN,
-                     "No limit for Cancel-Jobs defined in policy %s "
-                     "- using Pause-Printer's policy.", pol->name);
+       cupsdLogMessage(CUPSD_LOG_WARN, "No limit for Cancel-Jobs defined in policy %s - using Pause-Printer's policy.", pol->name);
 
-      cupsdAddPolicyOp(pol, op, IPP_CANCEL_JOBS);
+       cupsdAddPolicyOp(pol, op, IPP_CANCEL_JOBS);
+      }
+      else
+       cupsdLogMessage(CUPSD_LOG_WARN, "No limit for Cancel-Jobs defined in policy %s and no suitable template found.", pol->name);
     }
-    else
-      cupsdLogMessage(CUPSD_LOG_WARN,
-                     "No limit for Cancel-Jobs defined in policy %s "
-                     "and no suitable template found.", pol->name);
-  }
 
-  if ((op = cupsdFindPolicyOp(pol, IPP_CANCEL_MY_JOBS)) == NULL ||
-      op->op == IPP_ANY_OPERATION)
-  {
-    if ((op = cupsdFindPolicyOp(pol, IPP_SEND_DOCUMENT)) != NULL &&
-       op->op != IPP_ANY_OPERATION)
+    if ((op = cupsdFindPolicyOp(pol, IPP_CANCEL_MY_JOBS)) == NULL ||
+       op->op == IPP_ANY_OPERATION)
     {
-     /*
-      * Add a new limit for Cancel-My-Jobs using the Send-Document limit as
-      * a template...
-      */
+      if ((op = cupsdFindPolicyOp(pol, IPP_SEND_DOCUMENT)) != NULL &&
+         op->op != IPP_ANY_OPERATION)
+      {
+       /*
+       * Add a new limit for Cancel-My-Jobs using the Send-Document limit as
+       * a template...
+       */
 
-      cupsdLogMessage(CUPSD_LOG_WARN,
-                     "No limit for Cancel-My-Jobs defined in policy %s "
-                     "- using Send-Document's policy.", pol->name);
+       cupsdLogMessage(CUPSD_LOG_WARN, "No limit for Cancel-My-Jobs defined in policy %s - using Send-Document's policy.", pol->name);
 
-      cupsdAddPolicyOp(pol, op, IPP_CANCEL_MY_JOBS);
+       cupsdAddPolicyOp(pol, op, IPP_CANCEL_MY_JOBS);
+      }
+      else
+       cupsdLogMessage(CUPSD_LOG_WARN, "No limit for Cancel-My-Jobs defined in policy %s and no suitable template found.", pol->name);
     }
-    else
-      cupsdLogMessage(CUPSD_LOG_WARN,
-                     "No limit for Cancel-My-Jobs defined in policy %s "
-                     "and no suitable template found.", pol->name);
-  }
 
-  if ((op = cupsdFindPolicyOp(pol, IPP_CLOSE_JOB)) == NULL ||
-      op->op == IPP_ANY_OPERATION)
-  {
-    if ((op = cupsdFindPolicyOp(pol, IPP_SEND_DOCUMENT)) != NULL &&
-       op->op != IPP_ANY_OPERATION)
+    if ((op = cupsdFindPolicyOp(pol, IPP_CLOSE_JOB)) == NULL ||
+       op->op == IPP_ANY_OPERATION)
     {
-     /*
-      * Add a new limit for Close-Job using the Send-Document limit as a
-      * template...
-      */
+      if ((op = cupsdFindPolicyOp(pol, IPP_SEND_DOCUMENT)) != NULL &&
+         op->op != IPP_ANY_OPERATION)
+      {
+       /*
+       * Add a new limit for Close-Job using the Send-Document limit as a
+       * template...
+       */
 
-      cupsdLogMessage(CUPSD_LOG_WARN,
-                     "No limit for Close-Job defined in policy %s "
-                     "- using Send-Document's policy.", pol->name);
+       cupsdLogMessage(CUPSD_LOG_WARN, "No limit for Close-Job defined in policy %s - using Send-Document's policy.", pol->name);
 
-      cupsdAddPolicyOp(pol, op, IPP_CLOSE_JOB);
+       cupsdAddPolicyOp(pol, op, IPP_CLOSE_JOB);
+      }
+      else
+       cupsdLogMessage(CUPSD_LOG_WARN, "No limit for Close-Job defined in policy %s and no suitable template found.", pol->name);
     }
-    else
-      cupsdLogMessage(CUPSD_LOG_WARN,
-                     "No limit for Close-Job defined in policy %s "
-                     "and no suitable template found.", pol->name);
-  }
 
-  if ((op = cupsdFindPolicyOp(pol, CUPS_GET_DOCUMENT)) == NULL ||
-      op->op == IPP_ANY_OPERATION)
-  {
-    if ((op = cupsdFindPolicyOp(pol, IPP_SEND_DOCUMENT)) != NULL &&
-       op->op != IPP_ANY_OPERATION)
+    if ((op = cupsdFindPolicyOp(pol, CUPS_GET_DOCUMENT)) == NULL ||
+       op->op == IPP_ANY_OPERATION)
     {
-     /*
-      * Add a new limit for CUPS-Get-Document using the Send-Document
-      * limit as a template...
-      */
+      if ((op = cupsdFindPolicyOp(pol, IPP_SEND_DOCUMENT)) != NULL &&
+         op->op != IPP_ANY_OPERATION)
+      {
+       /*
+       * Add a new limit for CUPS-Get-Document using the Send-Document
+       * limit as a template...
+       */
 
-      cupsdLogMessage(CUPSD_LOG_WARN,
-                     "No limit for CUPS-Get-Document defined in policy %s "
-                     "- using Send-Document's policy.", pol->name);
+       cupsdLogMessage(CUPSD_LOG_WARN, "No limit for CUPS-Get-Document defined in policy %s - using Send-Document's policy.", pol->name);
 
-      cupsdAddPolicyOp(pol, op, CUPS_GET_DOCUMENT);
+       cupsdAddPolicyOp(pol, op, CUPS_GET_DOCUMENT);
+      }
+      else
+       cupsdLogMessage(CUPSD_LOG_WARN, "No limit for CUPS-Get-Document defined in policy %s and no suitable template found.", pol->name);
     }
-    else
-      cupsdLogMessage(CUPSD_LOG_WARN,
-                     "No limit for CUPS-Get-Document defined in policy %s "
-                     "and no suitable template found.", pol->name);
   }
 
  /*
@@ -4037,18 +4137,14 @@ set_policy_defaults(cupsd_policy_t *pol)/* I - Policy */
 
   if (!pol->job_access)
   {
-    cupsdLogMessage(CUPSD_LOG_WARN,
-                   "No JobPrivateAccess defined in policy %s "
-                   "- using defaults.", pol->name);
+    cupsdLogMessage(CUPSD_LOG_WARN, "No JobPrivateAccess defined in policy %s - using defaults.", pol->name);
     cupsdAddString(&(pol->job_access), "@OWNER");
     cupsdAddString(&(pol->job_access), "@SYSTEM");
   }
 
   if (!pol->job_attrs)
   {
-    cupsdLogMessage(CUPSD_LOG_WARN,
-                   "No JobPrivateValues defined in policy %s "
-                   "- using defaults.", pol->name);
+    cupsdLogMessage(CUPSD_LOG_WARN, "No JobPrivateValues defined in policy %s - using defaults.", pol->name);
     cupsdAddString(&(pol->job_attrs), "job-name");
     cupsdAddString(&(pol->job_attrs), "job-originating-host-name");
     cupsdAddString(&(pol->job_attrs), "job-originating-user-name");
@@ -4057,18 +4153,14 @@ set_policy_defaults(cupsd_policy_t *pol)/* I - Policy */
 
   if (!pol->sub_access)
   {
-    cupsdLogMessage(CUPSD_LOG_WARN,
-                   "No SubscriptionPrivateAccess defined in policy %s "
-                   "- using defaults.", pol->name);
+    cupsdLogMessage(CUPSD_LOG_WARN, "No SubscriptionPrivateAccess defined in policy %s - using defaults.", pol->name);
     cupsdAddString(&(pol->sub_access), "@OWNER");
     cupsdAddString(&(pol->sub_access), "@SYSTEM");
   }
 
   if (!pol->sub_attrs)
   {
-    cupsdLogMessage(CUPSD_LOG_WARN,
-                   "No SubscriptionPrivateValues defined in policy %s "
-                   "- using defaults.", pol->name);
+    cupsdLogMessage(CUPSD_LOG_WARN, "No SubscriptionPrivateValues defined in policy %s - using defaults.", pol->name);
     cupsdAddString(&(pol->sub_attrs), "notify-events");
     cupsdAddString(&(pol->sub_attrs), "notify-pull-method");
     cupsdAddString(&(pol->sub_attrs), "notify-recipient-uri");
@@ -4076,8 +4168,3 @@ set_policy_defaults(cupsd_policy_t *pol)/* I - Policy */
     cupsdAddString(&(pol->sub_attrs), "notify-user-data");
   }
 }
-
-
-/*
- * End of "$Id: conf.c 9352 2010-11-06 04:55:26Z mike $".
- */