]> 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 999e4719cfeec441a91a6aac82a52b3fff1bc34f..3cde8bd2989e527642003a32c41e85294f5a9040 100644 (file)
@@ -1,37 +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.
- *   read_configuration()     - Read a 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
@@ -68,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
@@ -83,51 +67,42 @@ typedef struct
  * Local globals...
  */
 
-static int                     default_auth_type       = CUPSD_AUTH_AUTO;
-                                       /* Default AuthType, if not specified */
-static const cupsd_var_t       variables[] =
+static const cupsd_var_t       cupsd_vars[] =
 {
-  { "AccessLog",               &AccessLog,             CUPSD_VARTYPE_STRING },
   { "AutoPurgeJobs",           &JobAutoPurge,          CUPSD_VARTYPE_BOOLEAN },
-#ifdef HAVE_DNSSD
-  { "BrowseDNSSDRegType",      &DNSSDRegType,          CUPSD_VARTYPE_STRING },
-#endif /* HAVE_DNSSD */
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+  { "BrowseDNSSDSubTypes",     &DNSSDSubTypes,         CUPSD_VARTYPE_STRING },
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
   { "BrowseWebIF",             &BrowseWebIF,           CUPSD_VARTYPE_BOOLEAN },
   { "Browsing",                        &Browsing,              CUPSD_VARTYPE_BOOLEAN },
-  { "CacheDir",                        &CacheDir,              CUPSD_VARTYPE_STRING },
   { "Classification",          &Classification,        CUPSD_VARTYPE_STRING },
   { "ClassifyOverride",                &ClassifyOverride,      CUPSD_VARTYPE_BOOLEAN },
-  { "ConfigFilePerm",          &ConfigFilePerm,        CUPSD_VARTYPE_INTEGER },
-  { "DataDir",                 &DataDir,               CUPSD_VARTYPE_STRING },
   { "DefaultLanguage",         &DefaultLanguage,       CUPSD_VARTYPE_STRING },
   { "DefaultLeaseDuration",    &DefaultLeaseDuration,  CUPSD_VARTYPE_TIME },
   { "DefaultPaperSize",                &DefaultPaperSize,      CUPSD_VARTYPE_STRING },
   { "DefaultPolicy",           &DefaultPolicy,         CUPSD_VARTYPE_STRING },
   { "DefaultShared",           &DefaultShared,         CUPSD_VARTYPE_BOOLEAN },
   { "DirtyCleanInterval",      &DirtyCleanInterval,    CUPSD_VARTYPE_TIME },
-  { "DocumentRoot",            &DocumentRoot,          CUPSD_VARTYPE_STRING },
-  { "ErrorLog",                        &ErrorLog,              CUPSD_VARTYPE_STRING },
   { "ErrorPolicy",             &ErrorPolicy,           CUPSD_VARTYPE_STRING },
-  { "FileDevice",              &FileDevice,            CUPSD_VARTYPE_BOOLEAN },
   { "FilterLimit",             &FilterLimit,           CUPSD_VARTYPE_INTEGER },
   { "FilterNice",              &FilterNice,            CUPSD_VARTYPE_INTEGER },
-  { "FontPath",                        &FontPath,              CUPSD_VARTYPE_STRING },
 #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 },
   { "LogDebugHistory",         &LogDebugHistory,       CUPSD_VARTYPE_INTEGER },
-  { "LogFilePerm",             &LogFilePerm,           CUPSD_VARTYPE_INTEGER },
-  { "LPDConfigFile",           &LPDConfigFile,         CUPSD_VARTYPE_STRING },
   { "MaxActiveJobs",           &MaxActiveJobs,         CUPSD_VARTYPE_INTEGER },
   { "MaxClients",              &MaxClients,            CUPSD_VARTYPE_INTEGER },
   { "MaxClientsPerHost",       &MaxClientsPerHost,     CUPSD_VARTYPE_INTEGER },
@@ -137,7 +112,7 @@ static const cupsd_var_t    variables[] =
   { "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 },
@@ -146,38 +121,53 @@ static const cupsd_var_t  variables[] =
   { "MaxSubscriptionsPerPrinter",&MaxSubscriptionsPerPrinter,  CUPSD_VARTYPE_INTEGER },
   { "MaxSubscriptionsPerUser", &MaxSubscriptionsPerUser,       CUPSD_VARTYPE_INTEGER },
   { "MultipleOperationTimeout",        &MultipleOperationTimeout,      CUPSD_VARTYPE_TIME },
-  { "PageLog",                 &PageLog,               CUPSD_VARTYPE_STRING },
   { "PageLogFormat",           &PageLogFormat,         CUPSD_VARTYPE_STRING },
   { "PreserveJobFiles",                &JobFiles,              CUPSD_VARTYPE_TIME },
   { "PreserveJobHistory",      &JobHistory,            CUPSD_VARTYPE_TIME },
-  { "Printcap",                        &Printcap,              CUPSD_VARTYPE_STRING },
-  { "PrintcapGUI",             &PrintcapGUI,           CUPSD_VARTYPE_STRING },
   { "ReloadTimeout",           &ReloadTimeout,         CUPSD_VARTYPE_TIME },
-  { "RemoteRoot",              &RemoteRoot,            CUPSD_VARTYPE_STRING },
-  { "RequestRoot",             &RequestRoot,           CUPSD_VARTYPE_STRING },
   { "RIPCache",                        &RIPCache,              CUPSD_VARTYPE_STRING },
   { "RootCertDuration",                &RootCertDuration,      CUPSD_VARTYPE_TIME },
   { "ServerAdmin",             &ServerAdmin,           CUPSD_VARTYPE_STRING },
+  { "ServerName",              &ServerName,            CUPSD_VARTYPE_STRING },
+  { "StrictConformance",       &StrictConformance,     CUPSD_VARTYPE_BOOLEAN },
+  { "Timeout",                 &Timeout,               CUPSD_VARTYPE_TIME },
+  { "WebInterface",            &WebInterface,          CUPSD_VARTYPE_BOOLEAN }
+};
+static const cupsd_var_t       cupsfiles_vars[] =
+{
+  { "AccessLog",               &AccessLog,             CUPSD_VARTYPE_STRING },
+  { "CacheDir",                        &CacheDir,              CUPSD_VARTYPE_STRING },
+  { "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_PERM },
+  { "LPDConfigFile",           &LPDConfigFile,         CUPSD_VARTYPE_STRING },
+  { "PageLog",                 &PageLog,               CUPSD_VARTYPE_STRING },
+  { "Printcap",                        &Printcap,              CUPSD_VARTYPE_STRING },
+  { "RemoteRoot",              &RemoteRoot,            CUPSD_VARTYPE_STRING },
+  { "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 */
-  { "ServerName",              &ServerName,            CUPSD_VARTYPE_STRING },
   { "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 */
-  { "TempDir",                 &TempDir,               CUPSD_VARTYPE_PATHNAME },
-  { "Timeout",                 &Timeout,               CUPSD_VARTYPE_TIME },
-  { "WebInterface",            &WebInterface,          CUPSD_VARTYPE_BOOLEAN }
+  { "TempDir",                 &TempDir,               CUPSD_VARTYPE_PATHNAME }
 };
-#define NUM_VARS       (sizeof(variables) / sizeof(variables[0]))
 
+static int             default_auth_type = CUPSD_AUTH_AUTO;
+                                       /* Default AuthType, if not specified */
 
 static const unsigned  ones[4] =
                        {
@@ -202,7 +192,12 @@ static int         parse_aaa(cupsd_location_t *loc, char *line,
 static int             parse_fatal_errors(const char *s);
 static int             parse_groups(const char *s);
 static int             parse_protocols(const char *s);
-static int             read_configuration(cups_file_t *fp);
+static int             parse_variable(const char *filename, int linenum,
+                                      const char *line, const char *value,
+                                      size_t num_vars,
+                                      const cupsd_var_t *vars);
+static int             read_cupsd_conf(cups_file_t *fp);
+static int             read_cups_files_conf(cups_file_t *fp);
 static int             read_location(cups_file_t *fp, char *name, int linenum);
 static int             read_policy(cups_file_t *fp, char *name, int linenum);
 static void            set_policy_defaults(cupsd_policy_t *pol);
@@ -226,7 +221,7 @@ cupsdAddAlias(cups_array_t *aliases,        /* I - Array of aliases */
     return;
 
   a->namelen = namelen;
-  strcpy(a->name, name);               /* OK since a->name is allocated */
+  memcpy(a->name, name, namelen + 1);  /* OK since a->name is allocated */
 
   cupsArrayAdd(aliases, a);
 }
@@ -240,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 */
 {
@@ -281,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);
       }
@@ -319,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);
   }
@@ -348,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);
     }
@@ -368,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);
     }
@@ -419,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__ */
 
@@ -579,10 +587,9 @@ cupsdReadConfiguration(void)
                  "%p %u %j %T %P %C %{job-billing} "
                 "%{job-originating-host-name} %{job-name} %{media} %{sides}");
   cupsdSetString(&Printcap, CUPS_DEFAULT_PRINTCAP);
-  cupsdSetString(&PrintcapGUI, "/usr/bin/glpoptions");
   cupsdSetString(&FontPath, CUPS_FONTPATH);
   cupsdSetString(&RemoteRoot, "remroot");
-  cupsdSetStringf(&ServerHeader, "CUPS/%d.%d", CUPS_VERSION_MAJOR,
+  cupsdSetStringf(&ServerHeader, "CUPS/%d.%d IPP/2.1", CUPS_VERSION_MAJOR,
                   CUPS_VERSION_MINOR);
   cupsdSetString(&StateDir, CUPS_STATEDIR);
 
@@ -604,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();
@@ -696,10 +704,10 @@ cupsdReadConfiguration(void)
   AccessLogLevel           = CUPSD_ACCESSLOG_ACTIONS;
   ConfigFilePerm           = CUPS_DEFAULT_CONFIG_FILE_PERM;
   FatalErrors              = parse_fatal_errors(CUPS_DEFAULT_FATAL_ERRORS);
-  default_auth_type          = CUPSD_AUTH_BASIC;
+  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;
@@ -722,10 +730,13 @@ cupsdReadConfiguration(void)
   MaxLogSize               = 1024 * 1024;
   MaxRequestSize           = 0;
   MultipleOperationTimeout = DEFAULT_TIMEOUT;
+  NumSystemGroups          = 0;
   ReloadTimeout                   = DEFAULT_KEEPALIVE;
   RootCertDuration         = 300;
+  Sandboxing               = CUPSD_SANDBOXING_STRICT;
+  StrictConformance        = FALSE;
+  SyncOnClose              = FALSE;
   Timeout                  = DEFAULT_TIMEOUT;
-  NumSystemGroups          = 0;
   WebInterface             = CUPS_DEFAULT_WEBIF;
 
   BrowseLocalProtocols     = parse_protocols(CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS);
@@ -733,9 +744,9 @@ cupsdReadConfiguration(void)
   Browsing                 = CUPS_DEFAULT_BROWSING;
   DefaultShared            = CUPS_DEFAULT_DEFAULT_SHARED;
 
-#ifdef HAVE_DNSSD
-  cupsdSetString(&DNSSDRegType, "_ipp._tcp,_cups");
-#endif /* HAVE_DNSSD */
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+  cupsdSetString(&DNSSDSubTypes, "_cups,_print");
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
 
   cupsdSetString(&LPDConfigFile, CUPS_DEFAULT_LPD_CONFIG_FILE);
   cupsdSetString(&SMBConfigFile, CUPS_DEFAULT_SMB_CONFIG_FILE);
@@ -757,7 +768,7 @@ cupsdReadConfiguration(void)
   cupsdClearString(&DefaultPolicy);
 
 #ifdef HAVE_AUTHORIZATION_H
-  cupsdClearString(&SystemGroupAuthKey);
+  cupsdSetString(&SystemGroupAuthKey, CUPS_DEFAULT_SYSTEM_AUTHKEY);
 #endif /* HAVE_AUTHORIZATION_H */
 
   MaxSubscriptions           = 100;
@@ -767,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...
@@ -778,21 +789,77 @@ cupsdReadConfiguration(void)
   cupsdInitEnv();
 
  /*
-  * Read the configuration file...
+  * Read the cups-files.conf file...
+  */
+
+  if ((fp = cupsFileOpen(CupsFilesFile, "r")) != NULL)
+  {
+    status = read_cups_files_conf(fp);
+
+    cupsFileClose(fp);
+
+    if (!status)
+    {
+      if (TestConfigFile)
+        printf("\"%s\" contains errors.\n", CupsFilesFile);
+      else
+#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);
+    }
+  }
+  else if (errno == ENOENT)
+    cupsdLogMessage(CUPSD_LOG_INFO, "No %s, using defaults.", CupsFilesFile);
+  else
+  {
+#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);
+  }
+
+  if (!ErrorLog)
+    cupsdSetString(&ErrorLog, CUPS_LOGDIR "/error_log");
+
+ /*
+  * Read the cupsd.conf file...
   */
 
   if ((fp = cupsFileOpen(ConfigurationFile, "r")) == NULL)
+  {
+#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);
+  }
 
-  status = read_configuration(fp);
+  status = read_cupsd_conf(fp);
 
   cupsFileClose(fp);
 
   if (!status)
-    return (0);
+  {
+    if (TestConfigFile)
+      printf("\"%s\" contains errors.\n", ConfigurationFile);
+    else
+#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 */
 
-  if (!ErrorLog)
-    cupsdSetString(&ErrorLog, CUPS_LOGDIR "/error_log");
+    return (0);
+  }
 
   RunUser = getuid();
 
@@ -906,28 +973,34 @@ cupsdReadConfiguration(void)
   }
 
  /*
-  * Open the system log for cupsd if necessary...
+  * Make sure ConfigFilePerm and LogFilePerm have sane values...
   */
 
-#ifdef HAVE_VSYSLOG
-  if (!strcmp(AccessLog, "syslog") ||
-      !strcmp(ErrorLog, "syslog") ||
-      !strcmp(PageLog, "syslog"))
-    openlog("cupsd", LOG_PID | LOG_NOWAIT | LOG_NDELAY, LOG_LPR);
-#endif /* HAVE_VSYSLOG */
+  ConfigFilePerm &= 0664;
+  LogFilePerm    &= 0664;
 
  /*
-  * Make sure each of the log files exists and gets rotated as necessary...
+  * Open the system log for cupsd if necessary...
   */
 
-  if (strcmp(AccessLog, "syslog"))
-    cupsdCheckLogFile(&AccessFile, AccessLog);
+  if (!LogStderr)
+  {
+    if (!strcmp(AccessLog, "stderr"))
+      cupsdSetString(&AccessLog, "syslog");
+
+    if (!strcmp(ErrorLog, "stderr"))
+      cupsdSetString(&ErrorLog, "syslog");
 
-  if (strcmp(ErrorLog, "syslog"))
-    cupsdCheckLogFile(&ErrorFile, ErrorLog);
+    if (!strcmp(PageLog, "stderr"))
+      cupsdSetString(&PageLog, "syslog");
+  }
 
-  if (strcmp(PageLog, "syslog"))
-    cupsdCheckLogFile(&PageFile, PageLog);
+#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 && !HAVE_ASL_H && !HAVE_SYSTEMD_SD_JOURNAL_H */
 
  /*
   * Log the configuration file that was used...
@@ -954,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");
@@ -1023,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 */
 
  /*
@@ -1052,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 ||
@@ -1066,7 +1133,9 @@ cupsdReadConfiguration(void)
                             Group, 1, 1) < 0 ||
        cupsdCheckPermissions(ServerRoot, "ssl", 0700, RunUser,
                             Group, 1, 0) < 0 ||
-       cupsdCheckPermissions(ServerRoot, "cupsd.conf", ConfigFilePerm, RunUser,
+       cupsdCheckPermissions(ConfigurationFile, NULL, ConfigFilePerm, RunUser,
+                            Group, 0, 0) < 0 ||
+       cupsdCheckPermissions(CupsFilesFile, NULL, ConfigFilePerm, RunUser,
                             Group, 0, 0) < 0 ||
        cupsdCheckPermissions(ServerRoot, "classes.conf", 0600, RunUser,
                             Group, 0, 0) < 0 ||
@@ -1081,11 +1150,20 @@ cupsdReadConfiguration(void)
   * Update TempDir to the default if it hasn't been set already...
   */
 
+#ifdef __APPLE__
+  if (TempDir && !RunUser &&
+      (!strncmp(TempDir, "/private/tmp", 12) || !strncmp(TempDir, "/tmp", 4)))
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot use %s for TempDir.", TempDir);
+    cupsdClearString(&TempDir);
+  }
+#endif /* __APPLE__ */
+
   if (!TempDir)
   {
 #ifdef __APPLE__
     if ((tmpdir = getenv("TMPDIR")) != NULL &&
-        strncmp(tmpdir, "/private/tmp", 12))
+        strncmp(tmpdir, "/private/tmp", 12) && strncmp(tmpdir, "/tmp", 4))
 #else
     if ((tmpdir = getenv("TMPDIR")) != NULL)
 #endif /* __APPLE__ */
@@ -1108,15 +1186,17 @@ cupsdReadConfiguration(void)
       else
         cupsdSetString(&TempDir, tmpdir);
     }
+  }
 
-    if (!TempDir)
-    {
-      cupsdLogMessage(CUPSD_LOG_INFO, "Using default TempDir of %s/tmp...",
-                     RequestRoot);
-      cupsdSetStringf(&TempDir, "%s/tmp", RequestRoot);
-    }
+  if (!TempDir)
+  {
+    cupsdLogMessage(CUPSD_LOG_INFO, "Using default TempDir of %s/tmp...",
+                   RequestRoot);
+    cupsdSetStringf(&TempDir, "%s/tmp", RequestRoot);
   }
 
+  setenv("TMPDIR", TempDir, 1);
+
  /*
   * Make sure the temporary directory has the right permissions...
   */
@@ -1140,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...
   */
@@ -1262,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");
@@ -1470,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.",
@@ -1744,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;
@@ -1812,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;
@@ -1839,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
@@ -1962,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;
     }
@@ -1974,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);
     }
   }
@@ -1990,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);
     }
   }
@@ -2093,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);
        }
 
@@ -2129,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;
@@ -2162,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);
     }
   }
@@ -2189,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"))
     {
@@ -2198,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"))
     {
@@ -2209,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);
     }
   }
@@ -2226,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"))
   {
@@ -2253,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);
     }
 
@@ -2316,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);
     }
   }
@@ -2548,114 +2631,421 @@ parse_protocols(const char *s)                /* I - Space-delimited protocols */
 
 
 /*
- * 'read_configuration()' - Read a configuration file.
+ * 'parse_variable()' - Parse a variable line.
  */
 
 static int                             /* O - 1 on success, 0 on failure */
-read_configuration(cups_file_t *fp)    /* I - File to read from */
+parse_variable(
+    const char        *filename,       /* I - Name of configuration file */
+    int               linenum,         /* I - Line in configuration file */
+    const char        *line,           /* I - Line from configuration file */
+    const char        *value,          /* I - Value from configuration file */
+    size_t            num_vars,                /* I - Number of variables */
+    const cupsd_var_t *vars)           /* I - Variables */
 {
-  int                  i;              /* Looping var */
-  int                  linenum;        /* Current line number */
-  char                 line[HTTP_MAX_BUFFER],
-                                       /* Line from file */
-                       temp[HTTP_MAX_BUFFER],
-                                       /* Temporary buffer for value */
-                       *value,         /* Pointer to value */
-                       *valueptr;      /* Pointer into value */
-  int                  valuelen;       /* Length of value */
-  cupsd_var_t const    *var;           /* Current variable */
-  http_addrlist_t      *addrlist,      /* Address list */
-                       *addr;          /* Current address */
-  cups_file_t          *incfile;       /* Include file */
-  char                 incname[1024];  /* Include filename */
-  struct group         *group;         /* Group */
+  size_t               i;              /* Looping var */
+  const cupsd_var_t    *var;           /* Variables */
+  char                 temp[1024];     /* Temporary string */
 
 
- /*
-  * Loop through each line in the file...
-  */
-
-  linenum = 0;
+  for (i = num_vars, var = vars; i > 0; i --, var ++)
+    if (!_cups_strcasecmp(line, var->name))
+      break;
 
-  while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
+  if (i == 0)
   {
    /*
-    * Decode the directive...
+    * Unknown directive!  Output an error message and continue...
     */
 
-    if (!_cups_strcasecmp(line, "Include") && value)
-    {
-     /*
-      * Include filename
-      */
+    if (!value)
+      cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value for %s on line %d of %s.",
+                     line, linenum, filename);
+    else
+      cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown directive %s on line %d of %s.",
+                     line, linenum, filename);
 
-      if (value[0] == '/')
-        strlcpy(incname, value, sizeof(incname));
-      else
-        snprintf(incname, sizeof(incname), "%s/%s", ServerRoot, value);
+    return (0);
+  }
 
-      if ((incfile = cupsFileOpen(incname, "rb")) == NULL)
-        cupsdLogMessage(CUPSD_LOG_ERROR,
-                       "Unable to include config file \"%s\" - %s",
-                       incname, strerror(errno));
-      else
-      {
-        read_configuration(incfile);
-       cupsFileClose(incfile);
-      }
-    }
-    else if (!_cups_strcasecmp(line, "<Location") && value)
-    {
-     /*
-      * <Location path>
-      */
+  switch (var->type)
+  {
+    case CUPSD_VARTYPE_INTEGER :
+       if (!value)
+       {
+         cupsdLogMessage(CUPSD_LOG_ERROR,
+                         "Missing integer value for %s on line %d of %s.",
+                         line, linenum, filename);
+          return (0);
+       }
+       else if (!isdigit(*value & 255))
+       {
+         cupsdLogMessage(CUPSD_LOG_ERROR,
+                         "Bad integer value for %s on line %d of %s.",
+                         line, linenum, filename);
+          return (0);
+       }
+       else
+       {
+         int   n;              /* Number */
+         char  *units;         /* Units */
 
-      linenum = read_location(fp, value, linenum);
-      if (linenum == 0)
-       return (0);
-    }
-    else if (!_cups_strcasecmp(line, "<Policy") && value)
-    {
-     /*
-      * <Policy name>
-      */
+         n = strtol(value, &units, 0);
 
-      linenum = read_policy(fp, value, linenum);
-      if (linenum == 0)
-       return (0);
-    }
-    else if (!_cups_strcasecmp(line, "FatalErrors"))
-      FatalErrors = parse_fatal_errors(value);
-    else if (!_cups_strcasecmp(line, "FaxRetryInterval") && value)
-    {
-      JobRetryInterval = atoi(value);
-      cupsdLogMessage(CUPSD_LOG_WARN,
-                     "FaxRetryInterval is deprecated; use "
-                     "JobRetryInterval on line %d.", linenum);
-    }
-    else if (!_cups_strcasecmp(line, "FaxRetryLimit") && value)
-    {
-      JobRetryLimit = atoi(value);
-      cupsdLogMessage(CUPSD_LOG_WARN,
-                     "FaxRetryLimit is deprecated; use "
-                     "JobRetryLimit on line %d.", linenum);
-    }
-    else if ((!_cups_strcasecmp(line, "Port") || !_cups_strcasecmp(line, "Listen")
-#ifdef HAVE_SSL
-             || !_cups_strcasecmp(line, "SSLPort") || !_cups_strcasecmp(line, "SSLListen")
-#endif /* HAVE_SSL */
-            ) && value)
-    {
-     /*
-      * Add listening address(es) to the list...
-      */
+         if (units && *units)
+         {
+           if (tolower(units[0] & 255) == 'g')
+             n *= 1024 * 1024 * 1024;
+           else if (tolower(units[0] & 255) == 'm')
+             n *= 1024 * 1024;
+           else if (tolower(units[0] & 255) == 'k')
+             n *= 1024;
+           else if (tolower(units[0] & 255) == 't')
+             n *= 262144;
+           else
+           {
+             cupsdLogMessage(CUPSD_LOG_ERROR,
+                             "Unknown integer value for %s on line %d of %s.",
+                             line, linenum, filename);
+             return (0);
+           }
+         }
 
-      cupsd_listener_t *lis;           /* New listeners array */
+         if (n < 0)
+         {
+           cupsdLogMessage(CUPSD_LOG_ERROR,
+                           "Bad negative integer value for %s on line %d of "
+                           "%s.", line, linenum, filename);
+           return (0);
+         }
+         else
+         {
+           *((int *)var->ptr) = n;
+         }
+       }
+       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 */
 
-     /*
-      * Get the address list...
-      */
+         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)
+       {
+         cupsdLogMessage(CUPSD_LOG_ERROR,
+                         "Missing time interval value for %s on line %d of "
+                         "%s.", line, linenum, filename);
+         return (0);
+       }
+       else if (!_cups_strncasecmp(line, "PreserveJob", 11) &&
+                (!_cups_strcasecmp(value, "true") ||
+                 !_cups_strcasecmp(value, "on") ||
+                 !_cups_strcasecmp(value, "enabled") ||
+                 !_cups_strcasecmp(value, "yes")))
+       {
+         *((int *)var->ptr) = INT_MAX;
+       }
+       else if (!_cups_strcasecmp(value, "false") ||
+                !_cups_strcasecmp(value, "off") ||
+                !_cups_strcasecmp(value, "disabled") ||
+                !_cups_strcasecmp(value, "no"))
+       {
+         *((int *)var->ptr) = 0;
+       }
+       else if (!isdigit(*value & 255))
+       {
+         cupsdLogMessage(CUPSD_LOG_ERROR,
+                         "Unknown time interval value for %s on line %d of "
+                         "%s.", line, linenum, filename);
+          return (0);
+       }
+       else
+       {
+         double        n;              /* Number */
+         char          *units;         /* Units */
+
+         n = strtod(value, &units);
+
+         if (units && *units)
+         {
+           if (tolower(units[0] & 255) == 'w')
+             n *= 7 * 24 * 60 * 60;
+           else if (tolower(units[0] & 255) == 'd')
+             n *= 24 * 60 * 60;
+           else if (tolower(units[0] & 255) == 'h')
+             n *= 60 * 60;
+           else if (tolower(units[0] & 255) == 'm')
+             n *= 60;
+           else
+           {
+             cupsdLogMessage(CUPSD_LOG_ERROR,
+                             "Unknown time interval value for %s on line "
+                             "%d of %s.", line, linenum, filename);
+             return (0);
+           }
+         }
+
+         if (n < 0.0 || n > INT_MAX)
+         {
+           cupsdLogMessage(CUPSD_LOG_ERROR,
+                           "Bad time value for %s on line %d of %s.",
+                           line, linenum, filename);
+           return (0);
+         }
+         else
+         {
+           *((int *)var->ptr) = (int)n;
+         }
+       }
+       break;
+
+    case CUPSD_VARTYPE_BOOLEAN :
+       if (!value)
+       {
+         cupsdLogMessage(CUPSD_LOG_ERROR,
+                         "Missing boolean value for %s on line %d of %s.",
+                         line, linenum, filename);
+         return (0);
+       }
+       else if (!_cups_strcasecmp(value, "true") ||
+                !_cups_strcasecmp(value, "on") ||
+                !_cups_strcasecmp(value, "enabled") ||
+                !_cups_strcasecmp(value, "yes") ||
+                atoi(value) != 0)
+       {
+         *((int *)var->ptr) = TRUE;
+       }
+       else if (!_cups_strcasecmp(value, "false") ||
+                !_cups_strcasecmp(value, "off") ||
+                !_cups_strcasecmp(value, "disabled") ||
+                !_cups_strcasecmp(value, "no") ||
+                !_cups_strcasecmp(value, "0"))
+       {
+         *((int *)var->ptr) = FALSE;
+       }
+       else
+       {
+         cupsdLogMessage(CUPSD_LOG_ERROR,
+                         "Unknown boolean value %s on line %d of %s.",
+                         value, linenum, filename);
+         return (0);
+       }
+       break;
+
+    case CUPSD_VARTYPE_PATHNAME :
+       if (!value)
+       {
+         cupsdLogMessage(CUPSD_LOG_ERROR,
+                         "Missing pathname value for %s on line %d of %s.",
+                         line, linenum, filename);
+         return (0);
+       }
+
+       if (value[0] == '/')
+         strlcpy(temp, value, sizeof(temp));
+       else
+         snprintf(temp, sizeof(temp), "%s/%s", ServerRoot, value);
+
+       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 "
+                         "does not exist.", line, value, linenum, filename);
+         return (0);
+       }
+
+       cupsdSetString((char **)var->ptr, temp);
+       break;
+
+    case CUPSD_VARTYPE_STRING :
+       cupsdSetString((char **)var->ptr, value);
+       break;
+  }
+
+  return (1);
+}
+
+
+/*
+ * 'read_cupsd_conf()' - Read the cupsd.conf configuration file.
+ */
+
+static int                             /* O - 1 on success, 0 on failure */
+read_cupsd_conf(cups_file_t *fp)       /* I - File to read from */
+{
+  int                  linenum;        /* Current line number */
+  char                 line[HTTP_MAX_BUFFER],
+                                       /* Line from file */
+                       temp[HTTP_MAX_BUFFER],
+                                       /* Temporary buffer for value */
+                       *value,         /* Pointer to value */
+                       *valueptr;      /* Pointer into value */
+  int                  valuelen;       /* Length of value */
+  http_addrlist_t      *addrlist,      /* Address list */
+                       *addr;          /* Current address */
+  cups_file_t          *incfile;       /* Include file */
+  char                 incname[1024];  /* Include filename */
+
+
+ /*
+  * Loop through each line in the file...
+  */
+
+  linenum = 0;
+
+  while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
+  {
+   /*
+    * Decode the directive...
+    */
+
+    if (!_cups_strcasecmp(line, "Include") && value)
+    {
+     /*
+      * Include filename
+      */
+
+      if (value[0] == '/')
+        strlcpy(incname, value, sizeof(incname));
+      else
+        snprintf(incname, sizeof(incname), "%s/%s", ServerRoot, value);
+
+      if ((incfile = cupsFileOpen(incname, "rb")) == NULL)
+        cupsdLogMessage(CUPSD_LOG_ERROR,
+                       "Unable to include config file \"%s\" - %s",
+                       incname, strerror(errno));
+      else
+      {
+        read_cupsd_conf(incfile);
+       cupsFileClose(incfile);
+      }
+    }
+    else if (!_cups_strcasecmp(line, "<Location") && value)
+    {
+     /*
+      * <Location path>
+      */
+
+      linenum = read_location(fp, value, linenum);
+      if (linenum == 0)
+       return (0);
+    }
+    else if (!_cups_strcasecmp(line, "<Policy") && value)
+    {
+     /*
+      * <Policy name>
+      */
+
+      linenum = read_policy(fp, value, linenum);
+      if (linenum == 0)
+       return (0);
+    }
+    else if (!_cups_strcasecmp(line, "FaxRetryInterval") && value)
+    {
+      JobRetryInterval = atoi(value);
+      cupsdLogMessage(CUPSD_LOG_WARN,
+                     "FaxRetryInterval is deprecated; use "
+                     "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 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")
+#endif /* HAVE_SSL */
+            ) && value)
+    {
+     /*
+      * Add listening address(es) to the list...
+      */
+
+      cupsd_listener_t *lis;           /* New listeners array */
+
+
+     /*
+      * Get the address list...
+      */
 
       addrlist = get_address(value, IPP_PORT);
 
@@ -2680,14 +3070,20 @@ read_configuration(cups_file_t *fp)     /* I - File to read from */
             lis;
             lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
           if (httpAddrEqual(&(addr->addr), &(lis->address)) &&
-             _httpAddrPort(&(addr->addr)) == _httpAddrPort(&(lis->address)))
+             httpAddrPort(&(addr->addr)) == httpAddrPort(&(lis->address)))
            break;
 
         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;
        }
 
@@ -2736,11 +3132,11 @@ read_configuration(cups_file_t *fp)     /* I - File to read from */
        else
 #endif /* AF_LOCAL */
        cupsdLogMessage(CUPSD_LOG_INFO, "Listening to %s:%d (IPv%d)", temp,
-                        _httpAddrPort(&(lis->address)),
-                       _httpAddrFamily(&(lis->address)) == AF_INET ? 4 : 6);
+                        httpAddrPort(&(lis->address)),
+                       httpAddrFamily(&(lis->address)) == AF_INET ? 4 : 6);
 
         if (!httpAddrLocalhost(&(lis->address)))
-         RemotePort = _httpAddrPort(&(lis->address));
+         RemotePort = httpAddrPort(&(lis->address));
       }
 
      /*
@@ -2762,27 +3158,23 @@ read_configuration(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;
       }
 
       BrowseLocalProtocols = protocols;
     }
-    else if (!_cups_strcasecmp(line, "default_auth_type") && value)
+    else if (!_cups_strcasecmp(line, "DefaultAuthType") && value)
     {
      /*
-      * default_auth_type {basic,digest,basicdigest,negotiate}
+      * DefaultAuthType {basic,digest,basicdigest,negotiate}
       */
 
       if (!_cups_strcasecmp(value, "none"))
        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;
@@ -2792,8 +3184,8 @@ read_configuration(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);
       }
@@ -2814,88 +3206,13 @@ read_configuration(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);
       }
     }
 #endif /* HAVE_SSL */
-    else if (!_cups_strcasecmp(line, "User") && value)
-    {
-     /*
-      * User ID to run as...
-      */
-
-      if (isdigit(value[0] & 255))
-      {
-        int uid = atoi(value);
-
-       if (!uid)
-         cupsdLogMessage(CUPSD_LOG_ERROR,
-                         "Will not use User 0 as specified on line %d "
-                         "for security reasons.  You must use a non-"
-                         "privileged account instead.",
-                         linenum);
-        else
-         User = atoi(value);
-      }
-      else
-      {
-        struct passwd *p;      /* Password information */
-
-        endpwent();
-       p = getpwnam(value);
-
-       if (p)
-       {
-         if (!p->pw_uid)
-           cupsdLogMessage(CUPSD_LOG_ERROR,
-                           "Will not use User %s (UID=0) as specified on line "
-                           "%d for security reasons.  You must use a non-"
-                           "privileged account instead.",
-                           value, linenum);
-         else
-           User = p->pw_uid;
-       }
-       else
-         cupsdLogMessage(CUPSD_LOG_ERROR,
-                         "Unknown User \"%s\" on line %d, ignoring.",
-                         value, linenum);
-      }
-    }
-    else if (!_cups_strcasecmp(line, "Group") && value)
-    {
-     /*
-      * Group ID to run as...
-      */
-
-      if (isdigit(value[0]))
-        Group = atoi(value);
-      else
-      {
-        endgrent();
-       group = getgrnam(value);
-
-       if (group != NULL)
-         Group = group->gr_gid;
-       else
-         cupsdLogMessage(CUPSD_LOG_ERROR,
-                         "Unknown Group \"%s\" on line %d, ignoring.",
-                         value, linenum);
-      }
-    }
-    else if (!_cups_strcasecmp(line, "SystemGroup") && value)
-    {
-     /*
-      * SystemGroup (admin) group(s)...
-      */
-
-      if (!parse_groups(value))
-       cupsdLogMessage(CUPSD_LOG_ERROR,
-                       "Unknown SystemGroup \"%s\" on line %d, ignoring.",
-                       value, linenum);
-    }
     else if (!_cups_strcasecmp(line, "HostNameLookups") && value)
     {
      /*
@@ -2911,8 +3228,8 @@ read_configuration(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)
     {
@@ -2926,9 +3243,11 @@ read_configuration(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)
     {
@@ -2957,8 +3276,8 @@ read_configuration(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)
     {
@@ -2971,24 +3290,8 @@ read_configuration(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);
-    }
-    else if (!_cups_strcasecmp(line, "PrintcapFormat") && value)
-    {
-     /*
-      * Format of printcap file?
-      */
-
-      if (!_cups_strcasecmp(value, "bsd"))
-        PrintcapFormat = PRINTCAP_BSD;
-      else if (!_cups_strcasecmp(value, "plist"))
-        PrintcapFormat = PRINTCAP_PLIST;
-      else if (!_cups_strcasecmp(value, "solaris"))
-        PrintcapFormat = PRINTCAP_SOLARIS;
-      else
-       cupsdLogMessage(CUPSD_LOG_WARN, "Unknown PrintcapFormat %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)
     {
@@ -3002,24 +3305,25 @@ read_configuration(cups_file_t *fp)     /* I - File to read from */
       uname(&plat);
 
       if (!_cups_strcasecmp(value, "ProductOnly"))
-       cupsdSetString(&ServerHeader, "CUPS");
+       cupsdSetString(&ServerHeader, "CUPS IPP");
       else if (!_cups_strcasecmp(value, "Major"))
-       cupsdSetStringf(&ServerHeader, "CUPS/%d", CUPS_VERSION_MAJOR);
+       cupsdSetStringf(&ServerHeader, "CUPS/%d IPP/2", CUPS_VERSION_MAJOR);
       else if (!_cups_strcasecmp(value, "Minor"))
-       cupsdSetStringf(&ServerHeader, "CUPS/%d.%d", CUPS_VERSION_MAJOR,
+       cupsdSetStringf(&ServerHeader, "CUPS/%d.%d IPP/2.1", CUPS_VERSION_MAJOR,
                        CUPS_VERSION_MINOR);
       else if (!_cups_strcasecmp(value, "Minimal"))
-       cupsdSetString(&ServerHeader, CUPS_MINIMAL);
+       cupsdSetString(&ServerHeader, CUPS_MINIMAL " IPP/2.1");
       else if (!_cups_strcasecmp(value, "OS"))
-       cupsdSetStringf(&ServerHeader, CUPS_MINIMAL " (%s)", plat.sysname);
+       cupsdSetStringf(&ServerHeader, CUPS_MINIMAL " (%s %s) IPP/2.1",
+                       plat.sysname, plat.release);
       else if (!_cups_strcasecmp(value, "Full"))
-       cupsdSetStringf(&ServerHeader, CUPS_MINIMAL " (%s) IPP/2.1",
-                       plat.sysname);
+       cupsdSetStringf(&ServerHeader, CUPS_MINIMAL " (%s %s; %s) IPP/2.1",
+                       plat.sysname, plat.release, plat.machine);
       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)
     {
@@ -3095,202 +3399,230 @@ read_configuration(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"))
+    else if (!_cups_strcasecmp(line, "AccessLog") ||
+             !_cups_strcasecmp(line, "CacheDir") ||
+             !_cups_strcasecmp(line, "ConfigFilePerm") ||
+             !_cups_strcasecmp(line, "DataDir") ||
+             !_cups_strcasecmp(line, "DocumentRoot") ||
+             !_cups_strcasecmp(line, "ErrorLog") ||
+             !_cups_strcasecmp(line, "FatalErrors") ||
+             !_cups_strcasecmp(line, "FileDevice") ||
+             !_cups_strcasecmp(line, "FontPath") ||
+             !_cups_strcasecmp(line, "Group") ||
+             !_cups_strcasecmp(line, "LogFilePerm") ||
+             !_cups_strcasecmp(line, "LPDConfigFile") ||
+             !_cups_strcasecmp(line, "PageLog") ||
+             !_cups_strcasecmp(line, "Printcap") ||
+             !_cups_strcasecmp(line, "PrintcapFormat") ||
+             !_cups_strcasecmp(line, "RemoteRoot") ||
+             !_cups_strcasecmp(line, "RequestRoot") ||
+             !_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") ||
+             !_cups_strcasecmp(line, "SystemGroup") ||
+             !_cups_strcasecmp(line, "SystemGroupAuthKey") ||
+             !_cups_strcasecmp(line, "TempDir") ||
+            !_cups_strcasecmp(line, "User"))
     {
-     /*
-      * 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);
+      cupsdLogMessage(CUPSD_LOG_INFO,
+                     "Please move \"%s%s%s\" on line %d of %s to the %s file; "
+                     "this will become an error in a future release.",
+                     line, value ? " " : "", value ? value : "", linenum,
+                     ConfigurationFile, CupsFilesFile);
     }
-#endif /* HAVE_SSL */
     else
+      parse_variable(ConfigurationFile, linenum, line, value,
+                     sizeof(cupsd_vars) / sizeof(cupsd_vars[0]), cupsd_vars);
+  }
+
+  return (1);
+}
+
+
+/*
+ * 'read_cups_files_conf()' - Read the cups-files.conf configuration file.
+ */
+
+static int                             /* O - 1 on success, 0 on failure */
+read_cups_files_conf(cups_file_t *fp)  /* I - File to read from */
+{
+  int          linenum;                /* Current line number */
+  char         line[HTTP_MAX_BUFFER],  /* Line from file */
+               *value;                 /* Value from line */
+  struct group *group;                 /* Group */
+
+
+ /*
+  * Loop through each line in the file...
+  */
+
+  linenum = 0;
+
+  while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
+  {
+    if (!_cups_strcasecmp(line, "FatalErrors"))
+      FatalErrors = parse_fatal_errors(value);
+    else if (!_cups_strcasecmp(line, "Group") && value)
     {
      /*
-      * Find a simple variable in the list...
+      * Group ID to run as...
       */
 
-      for (i = NUM_VARS, var = variables; i > 0; i --, var ++)
-        if (!_cups_strcasecmp(line, var->name))
-         break;
-
-      if (i == 0)
+      if (isdigit(value[0]))
+        Group = (gid_t)atoi(value);
+      else
       {
-       /*
-        * Unknown directive!  Output an error message and continue...
-       */
+        endgrent();
+       group = getgrnam(value);
 
-        if (!value)
-         cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value for %s on line %d.",
-                         line, linenum);
+       if (group != NULL)
+         Group = group->gr_gid;
        else
-         cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown directive %s on line %d.",
-                         line, linenum);
-        continue;
+       {
+         cupsdLogMessage(CUPSD_LOG_ERROR,
+                         "Unknown Group \"%s\" on line %d of %s.", value,
+                         linenum, CupsFilesFile);
+         if (FatalErrors & CUPSD_FATAL_CONFIG)
+           return (0);
+       }
       }
+    }
+    else if (!_cups_strcasecmp(line, "PrintcapFormat") && value)
+    {
+     /*
+      * Format of printcap file?
+      */
 
-      switch (var->type)
+      if (!_cups_strcasecmp(value, "bsd"))
+        PrintcapFormat = PRINTCAP_BSD;
+      else if (!_cups_strcasecmp(value, "plist"))
+        PrintcapFormat = PRINTCAP_PLIST;
+      else if (!_cups_strcasecmp(value, "solaris"))
+        PrintcapFormat = PRINTCAP_SOLARIS;
+      else
       {
-        case CUPSD_VARTYPE_INTEGER :
-           if (!value)
-             cupsdLogMessage(CUPSD_LOG_ERROR,
-                             "Missing integer value for %s on line %d.",
-                             line, linenum);
-           else if (!isdigit(*value & 255))
-             cupsdLogMessage(CUPSD_LOG_ERROR,
-                             "Bad integer value for %s on line %d.",
-                             line, linenum);
-           else
-           {
-             int       n;              /* Number */
-             char      *units;         /* Units */
-
-              n = strtol(value, &units, 0);
-
-             if (units && *units)
-             {
-               if (tolower(units[0] & 255) == 'g')
-                 n *= 1024 * 1024 * 1024;
-               else if (tolower(units[0] & 255) == 'm')
-                 n *= 1024 * 1024;
-               else if (tolower(units[0] & 255) == 'k')
-                 n *= 1024;
-               else if (tolower(units[0] & 255) == 't')
-                 n *= 262144;
-               else
-               {
-                 cupsdLogMessage(CUPSD_LOG_ERROR,
-                                 "Unknown integer value for %s on line %d.",
-                                 line, linenum);
-                 break;
-               }
-             }
-
-              if (n < 0)
-               cupsdLogMessage(CUPSD_LOG_ERROR,
-                               "Bad negative integer value for %s on line %d.",
-                               line, linenum);
-             else
-               *((int *)var->ptr) = n;
-           }
-           break;
+       cupsdLogMessage(CUPSD_LOG_ERROR,
+                       "Unknown PrintcapFormat \"%s\" on line %d of %s.",
+                       value, linenum, CupsFilesFile);
+        if (FatalErrors & CUPSD_FATAL_CONFIG)
+          return (0);
+      }
+    }
+    else if (!_cups_strcasecmp(line, "Sandboxing") && value)
+    {
+     /*
+      * Level of sandboxing?
+      */
 
-        case CUPSD_VARTYPE_TIME :
-           if (!value)
-             cupsdLogMessage(CUPSD_LOG_ERROR,
-                             "Missing time interval value for %s on line %d.",
-                             line, linenum);
-           else if (!_cups_strncasecmp(line, "PreserveJob", 11) &&
-                    (!_cups_strcasecmp(value, "true") ||
-                     !_cups_strcasecmp(value, "on") ||
-                     !_cups_strcasecmp(value, "enabled") ||
-                     !_cups_strcasecmp(value, "yes")))
-             *((int *)var->ptr) = INT_MAX;
-           else if (!_cups_strcasecmp(value, "false") ||
-                    !_cups_strcasecmp(value, "off") ||
-                    !_cups_strcasecmp(value, "disabled") ||
-                    !_cups_strcasecmp(value, "no"))
-             *((int *)var->ptr) = 0;
-           else if (!isdigit(*value & 255))
-             cupsdLogMessage(CUPSD_LOG_ERROR,
-                             "Unknown time interval value for %s on line %d.",
-                             line, linenum);
-           else
-           {
-             double    n;              /* Number */
-             char      *units;         /* Units */
-
-              n = strtod(value, &units);
-
-             if (units && *units)
-             {
-               if (tolower(units[0] & 255) == 'w')
-                 n *= 7 * 24 * 60 * 60;
-               else if (tolower(units[0] & 255) == 'd')
-                 n *= 24 * 60 * 60;
-               else if (tolower(units[0] & 255) == 'h')
-                 n *= 60 * 60;
-               else if (tolower(units[0] & 255) == 'm')
-                 n *= 60;
-               else
-               {
-                 cupsdLogMessage(CUPSD_LOG_ERROR,
-                                 "Unknown time interval value for %s on line "
-                                 "%d.", line, linenum);
-                 break;
-               }
-             }
-
-              if (n < 0.0 || n > INT_MAX)
-               cupsdLogMessage(CUPSD_LOG_ERROR,
-                               "Bad time value for %s on line %d.",
-                               line, linenum);
-             else
-               *((int *)var->ptr) = (int)n;
-           }
-           break;
+      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)
+    {
+     /*
+      * SystemGroup (admin) group(s)...
+      */
 
-       case CUPSD_VARTYPE_BOOLEAN :
-           if (!value)
-             cupsdLogMessage(CUPSD_LOG_ERROR,
-                             "Missing boolean value for %s on line %d.",
-                             line, linenum);
-            else if (!_cups_strcasecmp(value, "true") ||
-                    !_cups_strcasecmp(value, "on") ||
-                    !_cups_strcasecmp(value, "enabled") ||
-                    !_cups_strcasecmp(value, "yes") ||
-                    atoi(value) != 0)
-              *((int *)var->ptr) = TRUE;
-           else if (!_cups_strcasecmp(value, "false") ||
-                    !_cups_strcasecmp(value, "off") ||
-                    !_cups_strcasecmp(value, "disabled") ||
-                    !_cups_strcasecmp(value, "no") ||
-                    !_cups_strcasecmp(value, "0"))
-              *((int *)var->ptr) = FALSE;
-           else
-              cupsdLogMessage(CUPSD_LOG_ERROR,
-                             "Unknown boolean value %s on line %d.",
-                             value, linenum);
-           break;
+      if (!parse_groups(value))
+      {
+       cupsdLogMessage(CUPSD_LOG_ERROR,
+                       "Unknown SystemGroup \"%s\" on line %d of %s.", value,
+                       linenum, CupsFilesFile);
+        if (FatalErrors & CUPSD_FATAL_CONFIG)
+          return (0);
+      }
+    }
+    else if (!_cups_strcasecmp(line, "User") && value)
+    {
+     /*
+      * User ID to run as...
+      */
 
-       case CUPSD_VARTYPE_PATHNAME :
-            if (!value)
-           {
-             cupsdLogMessage(CUPSD_LOG_ERROR,
-                             "Missing pathname value for %s on line %d.",
-                             line, linenum);
-              break;
-           }
+      if (isdigit(value[0] & 255))
+      {
+        int uid = atoi(value);
 
-           if (value[0] == '/')
-             strlcpy(temp, value, sizeof(temp));
-           else
-             snprintf(temp, sizeof(temp), "%s/%s", ServerRoot, value);
+       if (!uid)
+       {
+         cupsdLogMessage(CUPSD_LOG_ERROR,
+                         "Will not use User 0 as specified on line %d of %s "
+                         "for security reasons.  You must use a non-"
+                         "privileged account instead.",
+                         linenum, CupsFilesFile);
+          if (FatalErrors & CUPSD_FATAL_CONFIG)
+            return (0);
+        }
+        else
+         User = (uid_t)atoi(value);
+      }
+      else
+      {
+        struct passwd *p;      /* Password information */
 
-            if (access(temp, 0))
-           {
-             cupsdLogMessage(CUPSD_LOG_ERROR,
-                             "File or directory for \"%s %s\" on line %d "
-                             "does not exist.", line, value, linenum);
-              break;
-           }
+        endpwent();
+       p = getpwnam(value);
 
-       case CUPSD_VARTYPE_STRING :
-           cupsdSetString((char **)var->ptr, value);
-           break;
+       if (p)
+       {
+         if (!p->pw_uid)
+         {
+           cupsdLogMessage(CUPSD_LOG_ERROR,
+                           "Will not use User %s (UID=0) as specified on line "
+                           "%d of %s for security reasons.  You must use a "
+                           "non-privileged account instead.",
+                           value, linenum, CupsFilesFile);
+           if (FatalErrors & CUPSD_FATAL_CONFIG)
+             return (0);
+         }
+         else
+           User = p->pw_uid;
+       }
+       else
+       {
+         cupsdLogMessage(CUPSD_LOG_ERROR,
+                         "Unknown User \"%s\" on line %d of %s.",
+                         value, linenum, CupsFilesFile);
+          if (FatalErrors & CUPSD_FATAL_CONFIG)
+            return (0);
+        }
       }
     }
+    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) &&
+            (FatalErrors & CUPSD_FATAL_CONFIG))
+      return (0);
   }
 
   return (1);
@@ -3315,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
@@ -3341,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
@@ -3376,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 ++);
       }
@@ -3392,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);
     }
@@ -3439,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);
 
@@ -3461,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);
 
@@ -3472,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
@@ -3498,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 ++);
       }
@@ -3547,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);
     }
@@ -3560,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);
       }
@@ -3658,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);
@@ -3696,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);
   }
 
  /*
@@ -3820,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");
@@ -3840,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");
@@ -3859,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 $".
- */