~ubuntu-branches/ubuntu/oneiric/cups/oneiric-proposed

« back to all changes in this revision

Viewing changes to .pc/default-ripcache-size-auto.patch/scheduler/conf.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt, Till Kamppeter, Martin Pitt
  • Date: 2011-08-07 12:53:12 UTC
  • mfrom: (1.2.13 upstream)
  • Revision ID: james.westby@ubuntu.com-20110807125312-s323cyb3oqaxaemo
Tags: 1.5.0-1
[ Till Kamppeter ]
* New upstream release
* debian/patches/usb-backend-no-segfault-on-bad-device-id.patch,
  debian/patches/usb-backend-accept-old-usblp-uris.patch,
  debian/patches/use-ps2write-ghostscript-device-for-pdftops-filter.patch:
  Removed, included upstream.
* debian/patches/poppler-based-pdftops-fixes.patch,
  debian/patches/do-not-emit-ps-level-3-with-poppler.patch: Replaced patch
  by a new one only containing the parts which remain after removing the
  parts included upstream.
* debian/patches/pidfile.patch,
  debian/patches/ppd-poll-with-client-conf.patch,
  debian/patches/cups-avahi.patch,
  debian/patches/drop_unnecessary_dependencies.patch,
  debian/patches/do-not-broadcast-with-hostnames.patch,
  debian/patches/ppdc-dynamic-linking.patch,
  debian/patches/pstops-based-workflow-only-for-printing-ps-on-a-ps-printer.patch:
  Manually regenerated to adapt to upstream changes.
* debian/patches/manpage-translations.patch,
  debian/patches/rootbackends-worldreadable.patch,
  debian/patches/no-conffile-timestamp.patch,
  debian/patches/read-embedded-options-from-incoming-postscript-and-add-to-ipp-attrs.patch,
  debian/patches/cups-snmp-oids-device-id-hp-ricoh.patch,
  debian/patches/configure-default-browse-protocols.patch,
  debian/patches/logfiles_adm_readable.patch,
  debian/patches/confdirperms.patch,
  debian/patches/printer-filtering.patch,
  debian/patches/show-compile-command-lines.patch,
  debian/patches/log-debug-history-nearly-unlimited.patch:
  Refreshed using quilt.
* debian/patches/default-ripcache-size-auto.patch: Dropped, as once,
  Ghostscript 9.04 is ignoring the cache size value as it crashes easily
  otherwise (Ghostscript upstream bug #691586) and second, CUPS defaults to
  more reasonable 128 MB (now only used for imagetops).
* debian/patches/support-gzipped-charmaps.patch: Dropped, as the SBCS and
  VBCS character maps are not used any more by CUPS.
* debian/rules: Enable threads in the ./configure command line, as otherwise
  CUPS 1.5.0 does not build at all.
* debian/local/filters/pdf-filters/filter/pdftoijs.cxx,
  debian/local/filters/pdf-filters/filter/pdftoraster.cxx,
  debian/local/filters/pdf-filters/pdftoopvp/pdftoopvp.cxx,
  debian/local/filters/pdf-filters/pdftopdf/pdftopdf.cxx: Under CUPS 1.5.x.
  all programs using the PPD API of CUPS need to explicitly include
  "<cups/ppd.h>". Updated the PDF filter add-on package.
* debian/local/filters/pdf-filters/addtocups: Make the addition of the
  pdftopdf and pdftoopvp directories also work with CUPS 1.5.x.
* debian/local/filters/pdf-filters/addtocups,
  debian/local/filters/pdf-filters/removefromcups: Added a symbolic link
  cups/i18n.h, so that texttopdf builds.
* debian/cups-client.install: Install the new ipptool and its sample
  files and manpages.
* debian/cups-client.install: Commented out lines for dropped man page
  translations: ipptool, lppasswd, client.conf, ipptoolfile, cupsenable,
  lpadmin, lpinfo, cupsreject, cupsdisable, cupsaccept
* debian/cups-common.install, debian/rules: The /usr/share/cups/charmaps
  directory got removed from CUPS.
* debian/libcups2-dev.install: cups/i18n.h got renamed to
  cups/language-private.h. Install this as /usr/include/cups/i18n.h.
* debian/libcups2.symbols, debian/libcupsmime1.symbols: Updated.
* debian/cups.lintian-overrides, debian/cups.postinst, debian/cups.prerm,
  debian/cups.templates, debian/local/apparmor-profile: The "scsi"
  CUPS backend got dropped upstream, removed its treatment from these files.

[ Martin Pitt ]
* Add Serbian (Cyrillic) debconf translations, thanks Zlatan Todoric.
  (Closes: #635105)
* Add Serbian (Latin) debconf translations, thanks Zlatan Todoric.
  (Closes: #635108)
* debian/local/apparmor-profile: Allow access to serial printers on USB
  adapters. (LP: #677432)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * "$Id: conf.c 9470 2011-01-11 07:05:58Z mike $"
3
 
 *
4
 
 *   Configuration routines for the Common UNIX Printing System (CUPS).
5
 
 *
6
 
 *   Copyright 2007-2011 by Apple Inc.
7
 
 *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
8
 
 *
9
 
 *   These coded instructions, statements, and computer programs are the
10
 
 *   property of Apple Inc. and are protected by Federal copyright
11
 
 *   law.  Distribution and use rights are outlined in the file "LICENSE.txt"
12
 
 *   which should have been included with this file.  If this file is
13
 
 *   file is missing or damaged, see the license at "http://www.cups.org/".
14
 
 *
15
 
 * Contents:
16
 
 *
17
 
 *   cupsdAddAlias()          - Add a host alias.
18
 
 *   cupsdCheckPermissions()  - Fix the mode and ownership of a file or
19
 
 *                              directory.
20
 
 *   cupsdFreeAliases()       - Free all of the alias entries.
21
 
 *   cupsdReadConfiguration() - Read the cupsd.conf file.
22
 
 *   get_address()            - Get an address + port number from a line.
23
 
 *   get_addr_and_mask()      - Get an IP address and netmask.
24
 
 *   parse_aaa()              - Parse authentication, authorization, and access
25
 
 *                              control lines.
26
 
 *   parse_fatal_errors()     - Parse FatalErrors values in a string.
27
 
 *   parse_groups()           - Parse system group names in a string.
28
 
 *   parse_protocols()        - Parse browse protocols in a string.
29
 
 *   read_configuration()     - Read a configuration file.
30
 
 *   read_location()          - Read a <Location path> definition.
31
 
 *   read_policy()            - Read a <Policy name> definition.
32
 
 */
33
 
 
34
 
/*
35
 
 * Include necessary headers...
36
 
 */
37
 
 
38
 
#include "cupsd.h"
39
 
#include <stdarg.h>
40
 
#include <grp.h>
41
 
#include <sys/utsname.h>
42
 
#include <syslog.h>
43
 
 
44
 
#ifdef HAVE_LIBPAPER
45
 
#  include <paper.h>
46
 
#endif /* HAVE_LIBPAPER */
47
 
 
48
 
 
49
 
/*
50
 
 * Possibly missing network definitions...
51
 
 */
52
 
 
53
 
#ifndef INADDR_NONE
54
 
#  define INADDR_NONE   0xffffffff
55
 
#endif /* !INADDR_NONE */
56
 
 
57
 
 
58
 
/*
59
 
 * Configuration variable structure...
60
 
 */
61
 
 
62
 
typedef enum
63
 
{
64
 
  CUPSD_VARTYPE_INTEGER,                /* Integer option */
65
 
  CUPSD_VARTYPE_STRING,                 /* String option */
66
 
  CUPSD_VARTYPE_BOOLEAN,                /* Boolean option */
67
 
  CUPSD_VARTYPE_PATHNAME                /* File/directory name option */
68
 
} cupsd_vartype_t;
69
 
 
70
 
typedef struct
71
 
{
72
 
  char                  *name;          /* Name of variable */
73
 
  void                  *ptr;           /* Pointer to variable */
74
 
  cupsd_vartype_t       type;           /* Type (int, string, address) */
75
 
} cupsd_var_t;
76
 
 
77
 
 
78
 
/*
79
 
 * Local globals...
80
 
 */
81
 
 
82
 
static const cupsd_var_t        variables[] =
83
 
{
84
 
  { "AccessLog",                &AccessLog,             CUPSD_VARTYPE_STRING },
85
 
#ifdef __APPLE__
86
 
  { "AppleQuotas",              &AppleQuotas,           CUPSD_VARTYPE_BOOLEAN },
87
 
#endif  /* __APPLE__ */
88
 
  { "AutoPurgeJobs",            &JobAutoPurge,          CUPSD_VARTYPE_BOOLEAN },
89
 
  { "BrowseInterval",           &BrowseInterval,        CUPSD_VARTYPE_INTEGER },
90
 
#ifdef HAVE_LDAP
91
 
  { "BrowseLDAPBindDN",         &BrowseLDAPBindDN,      CUPSD_VARTYPE_STRING },
92
 
#  ifdef HAVE_LDAP_SSL
93
 
  { "BrowseLDAPCACertFile",     &BrowseLDAPCACertFile,  CUPSD_VARTYPE_PATHNAME },
94
 
#  endif /* HAVE_LDAP_SSL */
95
 
  { "BrowseLDAPDN",             &BrowseLDAPDN,          CUPSD_VARTYPE_STRING },
96
 
  { "BrowseLDAPPassword",       &BrowseLDAPPassword,    CUPSD_VARTYPE_STRING },
97
 
  { "BrowseLDAPServer",         &BrowseLDAPServer,      CUPSD_VARTYPE_STRING },
98
 
#endif /* HAVE_LDAP */
99
 
  { "BrowseLocalOptions",       &BrowseLocalOptions,    CUPSD_VARTYPE_STRING },
100
 
  { "BrowsePort",               &BrowsePort,            CUPSD_VARTYPE_INTEGER },
101
 
  { "BrowseRemoteOptions",      &BrowseRemoteOptions,   CUPSD_VARTYPE_STRING },
102
 
  { "BrowseShortNames",         &BrowseShortNames,      CUPSD_VARTYPE_BOOLEAN },
103
 
  { "BrowseTimeout",            &BrowseTimeout,         CUPSD_VARTYPE_INTEGER },
104
 
  { "BrowseWebIF",              &BrowseWebIF,           CUPSD_VARTYPE_BOOLEAN },
105
 
  { "Browsing",                 &Browsing,              CUPSD_VARTYPE_BOOLEAN },
106
 
  { "CacheDir",                 &CacheDir,              CUPSD_VARTYPE_STRING },
107
 
  { "Classification",           &Classification,        CUPSD_VARTYPE_STRING },
108
 
  { "ClassifyOverride",         &ClassifyOverride,      CUPSD_VARTYPE_BOOLEAN },
109
 
  { "ConfigFilePerm",           &ConfigFilePerm,        CUPSD_VARTYPE_INTEGER },
110
 
  { "DataDir",                  &DataDir,               CUPSD_VARTYPE_STRING },
111
 
  { "DefaultLanguage",          &DefaultLanguage,       CUPSD_VARTYPE_STRING },
112
 
  { "DefaultLeaseDuration",     &DefaultLeaseDuration,  CUPSD_VARTYPE_INTEGER },
113
 
  { "DefaultPaperSize",         &DefaultPaperSize,      CUPSD_VARTYPE_STRING },
114
 
  { "DefaultPolicy",            &DefaultPolicy,         CUPSD_VARTYPE_STRING },
115
 
  { "DefaultShared",            &DefaultShared,         CUPSD_VARTYPE_BOOLEAN },
116
 
  { "DirtyCleanInterval",       &DirtyCleanInterval,    CUPSD_VARTYPE_INTEGER },
117
 
  { "DocumentRoot",             &DocumentRoot,          CUPSD_VARTYPE_STRING },
118
 
  { "ErrorLog",                 &ErrorLog,              CUPSD_VARTYPE_STRING },
119
 
  { "ErrorPolicy",              &ErrorPolicy,           CUPSD_VARTYPE_STRING },
120
 
  { "FileDevice",               &FileDevice,            CUPSD_VARTYPE_BOOLEAN },
121
 
  { "FilterLimit",              &FilterLimit,           CUPSD_VARTYPE_INTEGER },
122
 
  { "FilterNice",               &FilterNice,            CUPSD_VARTYPE_INTEGER },
123
 
  { "FontPath",                 &FontPath,              CUPSD_VARTYPE_STRING },
124
 
  { "HideImplicitMembers",      &HideImplicitMembers,   CUPSD_VARTYPE_BOOLEAN },
125
 
  { "ImplicitClasses",          &ImplicitClasses,       CUPSD_VARTYPE_BOOLEAN },
126
 
  { "ImplicitAnyClasses",       &ImplicitAnyClasses,    CUPSD_VARTYPE_BOOLEAN },
127
 
  { "JobKillDelay",             &JobKillDelay,          CUPSD_VARTYPE_INTEGER },
128
 
  { "JobRetryLimit",            &JobRetryLimit,         CUPSD_VARTYPE_INTEGER },
129
 
  { "JobRetryInterval",         &JobRetryInterval,      CUPSD_VARTYPE_INTEGER },
130
 
  { "KeepAliveTimeout",         &KeepAliveTimeout,      CUPSD_VARTYPE_INTEGER },
131
 
  { "KeepAlive",                &KeepAlive,             CUPSD_VARTYPE_BOOLEAN },
132
 
#ifdef HAVE_LAUNCHD
133
 
  { "LaunchdTimeout",           &LaunchdTimeout,        CUPSD_VARTYPE_INTEGER },
134
 
#endif /* HAVE_LAUNCHD */
135
 
  { "LimitRequestBody",         &MaxRequestSize,        CUPSD_VARTYPE_INTEGER },
136
 
  { "ListenBackLog",            &ListenBackLog,         CUPSD_VARTYPE_INTEGER },
137
 
  { "LogDebugHistory",          &LogDebugHistory,       CUPSD_VARTYPE_INTEGER },
138
 
  { "LogFilePerm",              &LogFilePerm,           CUPSD_VARTYPE_INTEGER },
139
 
  { "LPDConfigFile",            &LPDConfigFile,         CUPSD_VARTYPE_STRING },
140
 
  { "MaxActiveJobs",            &MaxActiveJobs,         CUPSD_VARTYPE_INTEGER },
141
 
  { "MaxClients",               &MaxClients,            CUPSD_VARTYPE_INTEGER },
142
 
  { "MaxClientsPerHost",        &MaxClientsPerHost,     CUPSD_VARTYPE_INTEGER },
143
 
  { "MaxCopies",                &MaxCopies,             CUPSD_VARTYPE_INTEGER },
144
 
  { "MaxEvents",                &MaxEvents,             CUPSD_VARTYPE_INTEGER },
145
 
  { "MaxJobs",                  &MaxJobs,               CUPSD_VARTYPE_INTEGER },
146
 
  { "MaxJobsPerPrinter",        &MaxJobsPerPrinter,     CUPSD_VARTYPE_INTEGER },
147
 
  { "MaxJobsPerUser",           &MaxJobsPerUser,        CUPSD_VARTYPE_INTEGER },
148
 
  { "MaxLeaseDuration",         &MaxLeaseDuration,      CUPSD_VARTYPE_INTEGER },
149
 
  { "MaxLogSize",               &MaxLogSize,            CUPSD_VARTYPE_INTEGER },
150
 
  { "MaxPrinterHistory",        &MaxPrinterHistory,     CUPSD_VARTYPE_INTEGER },
151
 
  { "MaxRequestSize",           &MaxRequestSize,        CUPSD_VARTYPE_INTEGER },
152
 
  { "MaxSubscriptions",         &MaxSubscriptions,      CUPSD_VARTYPE_INTEGER },
153
 
  { "MaxSubscriptionsPerJob",   &MaxSubscriptionsPerJob,        CUPSD_VARTYPE_INTEGER },
154
 
  { "MaxSubscriptionsPerPrinter",&MaxSubscriptionsPerPrinter,   CUPSD_VARTYPE_INTEGER },
155
 
  { "MaxSubscriptionsPerUser",  &MaxSubscriptionsPerUser,       CUPSD_VARTYPE_INTEGER },
156
 
  { "MultipleOperationTimeout", &MultipleOperationTimeout,      CUPSD_VARTYPE_INTEGER },
157
 
  { "PageLog",                  &PageLog,               CUPSD_VARTYPE_STRING },
158
 
  { "PageLogFormat",            &PageLogFormat,         CUPSD_VARTYPE_STRING },
159
 
  { "PreserveJobFiles",         &JobFiles,              CUPSD_VARTYPE_BOOLEAN },
160
 
  { "PreserveJobHistory",       &JobHistory,            CUPSD_VARTYPE_BOOLEAN },
161
 
  { "Printcap",                 &Printcap,              CUPSD_VARTYPE_STRING },
162
 
  { "PrintcapGUI",              &PrintcapGUI,           CUPSD_VARTYPE_STRING },
163
 
  { "ReloadTimeout",            &ReloadTimeout,         CUPSD_VARTYPE_INTEGER },
164
 
  { "RemoteRoot",               &RemoteRoot,            CUPSD_VARTYPE_STRING },
165
 
  { "RequestRoot",              &RequestRoot,           CUPSD_VARTYPE_STRING },
166
 
  { "RIPCache",                 &RIPCache,              CUPSD_VARTYPE_STRING },
167
 
  { "RootCertDuration",         &RootCertDuration,      CUPSD_VARTYPE_INTEGER },
168
 
  { "ServerAdmin",              &ServerAdmin,           CUPSD_VARTYPE_STRING },
169
 
  { "ServerBin",                &ServerBin,             CUPSD_VARTYPE_PATHNAME },
170
 
#ifdef HAVE_SSL
171
 
  { "ServerCertificate",        &ServerCertificate,     CUPSD_VARTYPE_PATHNAME },
172
 
#  if defined(HAVE_LIBSSL) || defined(HAVE_GNUTLS)
173
 
  { "ServerKey",                &ServerKey,             CUPSD_VARTYPE_PATHNAME },
174
 
#  endif /* HAVE_LIBSSL || HAVE_GNUTLS */
175
 
#endif /* HAVE_SSL */
176
 
  { "ServerName",               &ServerName,            CUPSD_VARTYPE_STRING },
177
 
  { "ServerRoot",               &ServerRoot,            CUPSD_VARTYPE_PATHNAME },
178
 
  { "SMBConfigFile",            &SMBConfigFile,         CUPSD_VARTYPE_STRING },
179
 
  { "StateDir",                 &StateDir,              CUPSD_VARTYPE_STRING },
180
 
#ifdef HAVE_AUTHORIZATION_H
181
 
  { "SystemGroupAuthKey",       &SystemGroupAuthKey,    CUPSD_VARTYPE_STRING },
182
 
#endif /* HAVE_AUTHORIZATION_H */
183
 
  { "TempDir",                  &TempDir,               CUPSD_VARTYPE_PATHNAME },
184
 
  { "Timeout",                  &Timeout,               CUPSD_VARTYPE_INTEGER },
185
 
  { "UseNetworkDefault",        &UseNetworkDefault,     CUPSD_VARTYPE_BOOLEAN },
186
 
  { "PidFile",                  &PidFile,               CUPSD_VARTYPE_STRING }
187
 
};
188
 
#define NUM_VARS        (sizeof(variables) / sizeof(variables[0]))
189
 
 
190
 
 
191
 
static const unsigned   ones[4] =
192
 
                        {
193
 
                          0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
194
 
                        };
195
 
static const unsigned   zeros[4] =
196
 
                        {
197
 
                          0x00000000, 0x00000000, 0x00000000, 0x00000000
198
 
                        };
199
 
 
200
 
 
201
 
/*
202
 
 * Local functions...
203
 
 */
204
 
 
205
 
static http_addrlist_t  *get_address(const char *value, int defport);
206
 
static int              get_addr_and_mask(const char *value, unsigned *ip,
207
 
                                          unsigned *mask);
208
 
static int              parse_aaa(cupsd_location_t *loc, char *line,
209
 
                                  char *value, int linenum);
210
 
static int              parse_fatal_errors(const char *s);
211
 
static int              parse_groups(const char *s);
212
 
static int              parse_protocols(const char *s);
213
 
static int              read_configuration(cups_file_t *fp);
214
 
static int              read_location(cups_file_t *fp, char *name, int linenum);
215
 
static int              read_policy(cups_file_t *fp, char *name, int linenum);
216
 
 
217
 
 
218
 
/*
219
 
 * 'cupsdAddAlias()' - Add a host alias.
220
 
 */
221
 
 
222
 
void
223
 
cupsdAddAlias(cups_array_t *aliases,    /* I - Array of aliases */
224
 
              const char   *name)       /* I - Name to add */
225
 
{
226
 
  cupsd_alias_t *a;                     /*  New alias */
227
 
  size_t        namelen;                /* Length of name */
228
 
 
229
 
 
230
 
  namelen = strlen(name);
231
 
 
232
 
  if ((a = (cupsd_alias_t *)malloc(sizeof(cupsd_alias_t) + namelen)) == NULL)
233
 
    return;
234
 
 
235
 
  a->namelen = namelen;
236
 
  strcpy(a->name, name);                /* OK since a->name is allocated */
237
 
 
238
 
  cupsArrayAdd(aliases, a);
239
 
}
240
 
 
241
 
 
242
 
/*
243
 
 * 'cupsdCheckPermissions()' - Fix the mode and ownership of a file or directory.
244
 
 */
245
 
 
246
 
int                                     /* O - 0 on success, -1 on error, 1 on warning */
247
 
cupsdCheckPermissions(
248
 
    const char *filename,               /* I - File/directory name */
249
 
    const char *suffix,                 /* I - Additional file/directory name */
250
 
    int        mode,                    /* I - Permissions */
251
 
    int        user,                    /* I - Owner */
252
 
    int        group,                   /* I - Group */
253
 
    int        is_dir,                  /* I - 1 = directory, 0 = file */
254
 
    int        create_dir)              /* I - 1 = create directory, -1 = create w/o logging, 0 = not */
255
 
{
256
 
  int           dir_created = 0;        /* Did we create a directory? */
257
 
  char          pathname[1024];         /* File name with prefix */
258
 
  struct stat   fileinfo;               /* Stat buffer */
259
 
  int           is_symlink;             /* Is "filename" a symlink? */
260
 
 
261
 
 
262
 
 /*
263
 
  * Prepend the given root to the filename before testing it...
264
 
  */
265
 
 
266
 
  if (suffix)
267
 
  {
268
 
    snprintf(pathname, sizeof(pathname), "%s/%s", filename, suffix);
269
 
    filename = pathname;
270
 
  }
271
 
 
272
 
 /*
273
 
  * See if we can stat the file/directory...
274
 
  */
275
 
 
276
 
  if (lstat(filename, &fileinfo))
277
 
  {
278
 
    if (errno == ENOENT && create_dir)
279
 
    {
280
 
      if (create_dir > 0)
281
 
        cupsdLogMessage(CUPSD_LOG_DEBUG, "Creating missing directory \"%s\"",
282
 
                        filename);
283
 
 
284
 
      if (mkdir(filename, mode))
285
 
      {
286
 
        if (create_dir > 0)
287
 
          cupsdLogMessage(CUPSD_LOG_ERROR,
288
 
                          "Unable to create directory \"%s\" - %s", filename,
289
 
                          strerror(errno));
290
 
        else
291
 
          syslog(LOG_ERR, "Unable to create directory \"%s\" - %s", filename,
292
 
                 strerror(errno));
293
 
 
294
 
        return (-1);
295
 
      }
296
 
 
297
 
      dir_created      = 1;
298
 
      fileinfo.st_mode = mode | S_IFDIR;
299
 
    }
300
 
    else
301
 
      return (create_dir ? -1 : 1);
302
 
  }
303
 
 
304
 
  if ((is_symlink = S_ISLNK(fileinfo.st_mode)) != 0)
305
 
  {
306
 
    if (stat(filename, &fileinfo))
307
 
    {
308
 
      cupsdLogMessage(CUPSD_LOG_ERROR, "\"%s\" is a bad symlink - %s",
309
 
                      filename, strerror(errno));
310
 
      return (-1);
311
 
    }
312
 
  }
313
 
 
314
 
 /*
315
 
  * Make sure it's a regular file or a directory as needed...
316
 
  */
317
 
 
318
 
  if (!dir_created && !is_dir && !S_ISREG(fileinfo.st_mode))
319
 
  {
320
 
    cupsdLogMessage(CUPSD_LOG_ERROR, "\"%s\" is not a regular file!", filename);
321
 
    return (-1);
322
 
  }
323
 
 
324
 
  if (!dir_created && is_dir && !S_ISDIR(fileinfo.st_mode))
325
 
  {
326
 
    if (create_dir >= 0)
327
 
      cupsdLogMessage(CUPSD_LOG_ERROR, "\"%s\" is not a directory!", filename);
328
 
    else
329
 
      syslog(LOG_ERR, "\"%s\" is not a directory!", filename);
330
 
 
331
 
    return (-1);
332
 
  }
333
 
 
334
 
 /*
335
 
  * If the filename is a symlink, do not change permissions (STR #2937)...
336
 
  */
337
 
 
338
 
  if (is_symlink)
339
 
    return (0);
340
 
 
341
 
 /*
342
 
  * Fix owner, group, and mode as needed...
343
 
  */
344
 
 
345
 
  if (dir_created || fileinfo.st_uid != user || fileinfo.st_gid != group)
346
 
  {
347
 
    if (create_dir >= 0)
348
 
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Repairing ownership of \"%s\"",
349
 
                      filename);
350
 
 
351
 
    if (chown(filename, user, group) && !getuid())
352
 
    {
353
 
      if (create_dir >= 0)
354
 
        cupsdLogMessage(CUPSD_LOG_ERROR,
355
 
                        "Unable to change ownership of \"%s\" - %s", filename,
356
 
                        strerror(errno));
357
 
      else
358
 
        syslog(LOG_ERR, "Unable to change ownership of \"%s\" - %s", filename,
359
 
               strerror(errno));
360
 
 
361
 
      return (1);
362
 
    }
363
 
  }
364
 
 
365
 
  if (dir_created || (fileinfo.st_mode & 07777) != mode)
366
 
  {
367
 
    if (create_dir >= 0)
368
 
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Repairing access permissions of \"%s\"",
369
 
                      filename);
370
 
 
371
 
    if (chmod(filename, mode))
372
 
    {
373
 
      if (create_dir >= 0)
374
 
        cupsdLogMessage(CUPSD_LOG_ERROR,
375
 
                        "Unable to change permissions of \"%s\" - %s", filename,
376
 
                        strerror(errno));
377
 
      else
378
 
        syslog(LOG_ERR, "Unable to change permissions of \"%s\" - %s", filename,
379
 
               strerror(errno));
380
 
 
381
 
      return (1);
382
 
    }
383
 
  }
384
 
 
385
 
 /*
386
 
  * Everything is OK...
387
 
  */
388
 
 
389
 
  return (0);
390
 
}
391
 
 
392
 
 
393
 
/*
394
 
 * 'cupsdFreeAliases()' - Free all of the alias entries.
395
 
 */
396
 
 
397
 
void
398
 
cupsdFreeAliases(cups_array_t *aliases) /* I - Array of aliases */
399
 
{
400
 
  cupsd_alias_t *a;                     /* Current alias */
401
 
 
402
 
 
403
 
  for (a = (cupsd_alias_t *)cupsArrayFirst(aliases);
404
 
       a;
405
 
       a = (cupsd_alias_t *)cupsArrayNext(aliases))
406
 
    free(a);
407
 
 
408
 
  cupsArrayDelete(aliases);
409
 
}
410
 
 
411
 
 
412
 
/*
413
 
 * 'cupsdReadConfiguration()' - Read the cupsd.conf file.
414
 
 */
415
 
 
416
 
int                                     /* O - 1 on success, 0 otherwise */
417
 
cupsdReadConfiguration(void)
418
 
{
419
 
  int           i;                      /* Looping var */
420
 
  cups_file_t   *fp;                    /* Configuration file */
421
 
  int           status;                 /* Return status */
422
 
  char          temp[1024],             /* Temporary buffer */
423
 
                mimedir[1024],          /* MIME directory */
424
 
                *slash;                 /* Directory separator */
425
 
  cups_lang_t   *language;              /* Language */
426
 
  struct passwd *user;                  /* Default user */
427
 
  struct group  *group;                 /* Default group */
428
 
  char          *old_serverroot,        /* Old ServerRoot */
429
 
                *old_requestroot;       /* Old RequestRoot */
430
 
  int           old_remote_port;        /* Old RemotePort */
431
 
  const char    *tmpdir;                /* TMPDIR environment variable */
432
 
  struct stat   tmpinfo;                /* Temporary directory info */
433
 
  cupsd_policy_t *p;                    /* Policy */
434
 
 
435
 
 
436
 
 /*
437
 
  * Save the old root paths...
438
 
  */
439
 
 
440
 
  old_serverroot = NULL;
441
 
  cupsdSetString(&old_serverroot, ServerRoot);
442
 
  old_requestroot = NULL;
443
 
  cupsdSetString(&old_requestroot, RequestRoot);
444
 
 
445
 
 /*
446
 
  * Reset the server configuration data...
447
 
  */
448
 
 
449
 
  cupsdDeleteAllLocations();
450
 
 
451
 
  if (NumBrowsers > 0)
452
 
  {
453
 
    free(Browsers);
454
 
    Browsers = NULL;
455
 
 
456
 
    NumBrowsers = 0;
457
 
  }
458
 
 
459
 
  if (NumPolled > 0)
460
 
  {
461
 
    free(Polled);
462
 
 
463
 
    NumPolled = 0;
464
 
  }
465
 
 
466
 
  if (NumRelays > 0)
467
 
  {
468
 
    for (i = 0; i < NumRelays; i ++)
469
 
      if (Relays[i].from.type == CUPSD_AUTH_NAME)
470
 
        free(Relays[i].from.mask.name.name);
471
 
 
472
 
    free(Relays);
473
 
 
474
 
    NumRelays = 0;
475
 
  }
476
 
 
477
 
  cupsdDeleteAllListeners();
478
 
 
479
 
  old_remote_port = RemotePort;
480
 
  RemotePort      = 0;
481
 
 
482
 
 /*
483
 
  * String options...
484
 
  */
485
 
 
486
 
  cupsdFreeAliases(ServerAlias);
487
 
  ServerAlias = NULL;
488
 
 
489
 
  cupsdClearString(&ServerName);
490
 
  cupsdClearString(&ServerAdmin);
491
 
  cupsdSetString(&ServerBin, CUPS_SERVERBIN);
492
 
  cupsdSetString(&RequestRoot, CUPS_REQUESTS);
493
 
  cupsdSetString(&CacheDir, CUPS_CACHEDIR);
494
 
  cupsdSetString(&DataDir, CUPS_DATADIR);
495
 
  cupsdSetString(&DocumentRoot, CUPS_DOCROOT);
496
 
  cupsdSetString(&AccessLog, CUPS_LOGDIR "/access_log");
497
 
  cupsdSetString(&ErrorLog, CUPS_LOGDIR "/error_log");
498
 
  cupsdSetString(&PageLog, CUPS_LOGDIR "/page_log");
499
 
  cupsdSetString(&PageLogFormat,
500
 
                 "%p %u %j %T %P %C %{job-billing} "
501
 
                 "%{job-originating-host-name} %{job-name} %{media} %{sides}");
502
 
  cupsdSetString(&Printcap, CUPS_DEFAULT_PRINTCAP);
503
 
  cupsdSetString(&PrintcapGUI, "/usr/bin/glpoptions");
504
 
  cupsdSetString(&FontPath, CUPS_FONTPATH);
505
 
  cupsdSetString(&RemoteRoot, "remroot");
506
 
  cupsdSetString(&ServerHeader, "CUPS/1.4");
507
 
  cupsdSetString(&StateDir, CUPS_STATEDIR);
508
 
  cupsdSetString(&PidFile, "/var/run/cups/cupsd.pid");
509
 
 
510
 
  if (!strcmp(CUPS_DEFAULT_PRINTCAP, "/etc/printers.conf"))
511
 
    PrintcapFormat = PRINTCAP_SOLARIS;
512
 
  else if (!strcmp(CUPS_DEFAULT_PRINTCAP,
513
 
                   "/Library/Preferences/org.cups.printers.plist"))
514
 
    PrintcapFormat = PRINTCAP_PLIST;
515
 
  else
516
 
    PrintcapFormat = PRINTCAP_BSD;
517
 
 
518
 
  strlcpy(temp, ConfigurationFile, sizeof(temp));
519
 
  if ((slash = strrchr(temp, '/')) != NULL)
520
 
    *slash = '\0';
521
 
 
522
 
  cupsdSetString(&ServerRoot, temp);
523
 
 
524
 
  cupsdClearString(&Classification);
525
 
  ClassifyOverride  = 0;
526
 
 
527
 
#ifdef HAVE_SSL
528
 
#  ifdef HAVE_CDSASSL
529
 
  cupsdSetString(&ServerCertificate, "/Library/Keychains/System.keychain");
530
 
#  else
531
 
  cupsdSetString(&ServerCertificate, "ssl/server.crt");
532
 
  cupsdSetString(&ServerKey, "ssl/server.key");
533
 
#  endif /* HAVE_CDSASSL */
534
 
#endif /* HAVE_SSL */
535
 
 
536
 
  language = cupsLangDefault();
537
 
 
538
 
  if (!strcmp(language->language, "C") || !strcmp(language->language, "POSIX"))
539
 
    cupsdSetString(&DefaultLanguage, "en");
540
 
  else
541
 
    cupsdSetString(&DefaultLanguage, language->language);
542
 
 
543
 
  cupsdClearString(&DefaultPaperSize);
544
 
 
545
 
  cupsdSetString(&RIPCache, "8m");
546
 
 
547
 
  cupsdSetString(&TempDir, NULL);
548
 
 
549
 
 /*
550
 
  * Find the default user...
551
 
  */
552
 
 
553
 
  if ((user = getpwnam(CUPS_DEFAULT_USER)) != NULL)
554
 
    User = user->pw_uid;
555
 
  else
556
 
  {
557
 
   /*
558
 
    * Use the (historical) NFS nobody user ID (-2 as a 16-bit twos-
559
 
    * complement number...)
560
 
    */
561
 
 
562
 
    User = 65534;
563
 
  }
564
 
 
565
 
  endpwent();
566
 
 
567
 
 /*
568
 
  * Find the default group...
569
 
  */
570
 
 
571
 
  group = getgrnam(CUPS_DEFAULT_GROUP);
572
 
  endgrent();
573
 
 
574
 
  if (group)
575
 
    Group = group->gr_gid;
576
 
  else
577
 
  {
578
 
   /*
579
 
    * Fallback to group "nobody"...
580
 
    */
581
 
 
582
 
    group = getgrnam("nobody");
583
 
    endgrent();
584
 
 
585
 
    if (group)
586
 
      Group = group->gr_gid;
587
 
    else
588
 
    {
589
 
     /*
590
 
      * Use the (historical) NFS nobody group ID (-2 as a 16-bit twos-
591
 
      * complement number...)
592
 
      */
593
 
 
594
 
      Group = 65534;
595
 
    }
596
 
  }
597
 
 
598
 
 /*
599
 
  * Numeric options...
600
 
  */
601
 
 
602
 
  AccessLogLevel           = CUPSD_ACCESSLOG_ACTIONS;
603
 
  ConfigFilePerm           = CUPS_DEFAULT_CONFIG_FILE_PERM;
604
 
  FatalErrors              = parse_fatal_errors(CUPS_DEFAULT_FATAL_ERRORS);
605
 
  DefaultAuthType          = CUPSD_AUTH_BASIC;
606
 
#ifdef HAVE_SSL
607
 
  DefaultEncryption        = HTTP_ENCRYPT_REQUIRED;
608
 
  SSLOptions               = CUPSD_SSL_NONE;
609
 
#endif /* HAVE_SSL */
610
 
  DirtyCleanInterval       = DEFAULT_KEEPALIVE;
611
 
  JobKillDelay             = DEFAULT_TIMEOUT;
612
 
  JobRetryLimit            = 5;
613
 
  JobRetryInterval         = 300;
614
 
  FileDevice               = FALSE;
615
 
  FilterLevel              = 0;
616
 
  FilterLimit              = 0;
617
 
  FilterNice               = 0;
618
 
  HostNameLookups          = FALSE;
619
 
  ImplicitClasses          = CUPS_DEFAULT_IMPLICIT_CLASSES;
620
 
  ImplicitAnyClasses       = FALSE;
621
 
  HideImplicitMembers      = TRUE;
622
 
  KeepAlive                = TRUE;
623
 
  KeepAliveTimeout         = DEFAULT_KEEPALIVE;
624
 
  ListenBackLog            = SOMAXCONN;
625
 
  LogDebugHistory          = 200;
626
 
  LogFilePerm              = CUPS_DEFAULT_LOG_FILE_PERM;
627
 
  LogLevel                 = CUPSD_LOG_WARN;
628
 
  LogTimeFormat            = CUPSD_TIME_STANDARD;
629
 
  MaxClients               = 100;
630
 
  MaxClientsPerHost        = 0;
631
 
  MaxLogSize               = 1024 * 1024;
632
 
  MaxPrinterHistory        = 0;
633
 
  MaxRequestSize           = 0;
634
 
  MultipleOperationTimeout = DEFAULT_TIMEOUT;
635
 
  ReloadTimeout            = DEFAULT_KEEPALIVE;
636
 
  RootCertDuration         = 300;
637
 
  Timeout                  = DEFAULT_TIMEOUT;
638
 
  NumSystemGroups          = 0;
639
 
 
640
 
  BrowseInterval           = DEFAULT_INTERVAL;
641
 
  BrowsePort               = ippPort();
642
 
  BrowseLocalProtocols     = parse_protocols(CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS);
643
 
  BrowseRemoteProtocols    = parse_protocols(CUPS_DEFAULT_BROWSE_REMOTE_PROTOCOLS);
644
 
  BrowseShortNames         = CUPS_DEFAULT_BROWSE_SHORT_NAMES;
645
 
  BrowseTimeout            = DEFAULT_TIMEOUT;
646
 
  BrowseWebIF              = FALSE;
647
 
  Browsing                 = CUPS_DEFAULT_BROWSING;
648
 
  DefaultShared            = CUPS_DEFAULT_DEFAULT_SHARED;
649
 
 
650
 
  cupsdSetString(&LPDConfigFile, CUPS_DEFAULT_LPD_CONFIG_FILE);
651
 
  cupsdSetString(&SMBConfigFile, CUPS_DEFAULT_SMB_CONFIG_FILE);
652
 
 
653
 
  cupsdClearString(&BrowseLocalOptions);
654
 
  cupsdClearString(&BrowseRemoteOptions);
655
 
 
656
 
  cupsdSetString(&ErrorPolicy, "stop-printer");
657
 
 
658
 
#ifdef HAVE_LDAP
659
 
  cupsdClearString(&BrowseLDAPBindDN);
660
 
  cupsdClearString(&BrowseLDAPDN);
661
 
  cupsdClearString(&BrowseLDAPPassword);
662
 
  cupsdClearString(&BrowseLDAPServer);
663
 
#  ifdef HAVE_LDAP_SSL
664
 
  cupsdClearString(&BrowseLDAPCACertFile);
665
 
#  endif /* HAVE_LDAP_SSL */
666
 
#endif /* HAVE_LDAP */
667
 
 
668
 
  JobHistory          = DEFAULT_HISTORY;
669
 
  JobFiles            = DEFAULT_FILES;
670
 
  JobAutoPurge        = 0;
671
 
  MaxJobs             = 500;
672
 
  MaxActiveJobs       = 0;
673
 
  MaxJobsPerUser      = 0;
674
 
  MaxJobsPerPrinter   = 0;
675
 
  MaxCopies           = CUPS_DEFAULT_MAX_COPIES;
676
 
 
677
 
  cupsdDeleteAllPolicies();
678
 
  cupsdClearString(&DefaultPolicy);
679
 
 
680
 
#ifdef HAVE_AUTHORIZATION_H
681
 
  cupsdClearString(&SystemGroupAuthKey);
682
 
#endif /* HAVE_AUTHORIZATION_H */
683
 
 
684
 
  MaxSubscriptions           = 100;
685
 
  MaxSubscriptionsPerJob     = 0;
686
 
  MaxSubscriptionsPerPrinter = 0;
687
 
  MaxSubscriptionsPerUser    = 0;
688
 
  DefaultLeaseDuration       = 86400;
689
 
  MaxLeaseDuration           = 0;
690
 
 
691
 
#ifdef HAVE_LAUNCHD
692
 
  LaunchdTimeout = DEFAULT_TIMEOUT + 10;
693
 
#endif /* HAVE_LAUNCHD */
694
 
 
695
 
#ifdef __APPLE__
696
 
  AppleQuotas = TRUE;
697
 
#endif  /* __APPLE__ */
698
 
 
699
 
 /*
700
 
  * Setup environment variables...
701
 
  */
702
 
 
703
 
  cupsdInitEnv();
704
 
 
705
 
 /*
706
 
  * Read the configuration file...
707
 
  */
708
 
 
709
 
  if ((fp = cupsFileOpen(ConfigurationFile, "r")) == NULL)
710
 
    return (0);
711
 
 
712
 
  status = read_configuration(fp);
713
 
 
714
 
  cupsFileClose(fp);
715
 
 
716
 
  if (!status)
717
 
    return (0);
718
 
 
719
 
  RunUser = getuid();
720
 
 
721
 
  cupsdLogMessage(CUPSD_LOG_INFO, "Remote access is %s.",
722
 
                  RemotePort ? "enabled" : "disabled");
723
 
 
724
 
  if (!RemotePort)
725
 
    BrowseLocalProtocols = 0;           /* Disable sharing - no remote access */
726
 
 
727
 
 /*
728
 
  * See if the ServerName is an IP address...
729
 
  */
730
 
 
731
 
  if (ServerName)
732
 
  {
733
 
    if (!ServerAlias)
734
 
      ServerAlias = cupsArrayNew(NULL, NULL);
735
 
 
736
 
    cupsdLogMessage(CUPSD_LOG_DEBUG, "Added auto ServerAlias %s", ServerName);
737
 
  }
738
 
  else
739
 
  {
740
 
    if (gethostname(temp, sizeof(temp)))
741
 
    {
742
 
      cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get hostname: %s",
743
 
                      strerror(errno));
744
 
      strlcpy(temp, "localhost", sizeof(temp));
745
 
    }
746
 
 
747
 
    cupsdSetString(&ServerName, temp);
748
 
 
749
 
    if (!ServerAlias)
750
 
      ServerAlias = cupsArrayNew(NULL, NULL);
751
 
 
752
 
    cupsdAddAlias(ServerAlias, temp);
753
 
    cupsdLogMessage(CUPSD_LOG_DEBUG, "Added auto ServerAlias %s", temp);
754
 
 
755
 
    if (HostNameLookups)
756
 
    {
757
 
      struct hostent    *host;          /* Host entry to get FQDN */
758
 
 
759
 
      if ((host = gethostbyname(temp)) != NULL)
760
 
      {
761
 
        if (strcasecmp(temp, host->h_name))
762
 
        {
763
 
          cupsdSetString(&ServerName, host->h_name);
764
 
          cupsdAddAlias(ServerAlias, host->h_name);
765
 
          cupsdLogMessage(CUPSD_LOG_DEBUG, "Added auto ServerAlias %s",
766
 
                          host->h_name);
767
 
        }
768
 
 
769
 
        if (host->h_aliases)
770
 
        {
771
 
          for (i = 0; host->h_aliases[i]; i ++)
772
 
            if (strcasecmp(temp, host->h_aliases[i]))
773
 
            {
774
 
              cupsdAddAlias(ServerAlias, host->h_aliases[i]);
775
 
              cupsdLogMessage(CUPSD_LOG_DEBUG, "Added auto ServerAlias %s",
776
 
                              host->h_aliases[i]);
777
 
            }
778
 
        }
779
 
      }
780
 
    }
781
 
 
782
 
   /*
783
 
    * Make sure we have the base hostname added as an alias, too!
784
 
    */
785
 
 
786
 
    if ((slash = strchr(temp, '.')) != NULL)
787
 
    {
788
 
      *slash = '\0';
789
 
      cupsdAddAlias(ServerAlias, temp);
790
 
      cupsdLogMessage(CUPSD_LOG_DEBUG, "Added auto ServerAlias %s", temp);
791
 
    }
792
 
  }
793
 
 
794
 
  for (slash = ServerName; isdigit(*slash & 255) || *slash == '.'; slash ++);
795
 
 
796
 
  ServerNameIsIP = !*slash;
797
 
 
798
 
 /*
799
 
  * Make sure ServerAdmin is initialized...
800
 
  */
801
 
 
802
 
  if (!ServerAdmin)
803
 
    cupsdSetStringf(&ServerAdmin, "root@%s", ServerName);
804
 
 
805
 
 /*
806
 
  * Use the default system group if none was supplied in cupsd.conf...
807
 
  */
808
 
 
809
 
  if (NumSystemGroups == 0)
810
 
  {
811
 
    if (!parse_groups(CUPS_DEFAULT_SYSTEM_GROUPS))
812
 
    {
813
 
     /*
814
 
      * Find the group associated with GID 0...
815
 
      */
816
 
 
817
 
      group = getgrgid(0);
818
 
      endgrent();
819
 
 
820
 
      if (group != NULL)
821
 
        cupsdSetString(&SystemGroups[0], group->gr_name);
822
 
      else
823
 
        cupsdSetString(&SystemGroups[0], "unknown");
824
 
 
825
 
      SystemGroupIDs[0] = 0;
826
 
      NumSystemGroups   = 1;
827
 
    }
828
 
  }
829
 
 
830
 
 /*
831
 
  * Get the access control list for browsing...
832
 
  */
833
 
 
834
 
  BrowseACL = cupsdFindLocation("CUPS_INTERNAL_BROWSE_ACL");
835
 
 
836
 
 /*
837
 
  * Open the system log for cupsd if necessary...
838
 
  */
839
 
 
840
 
#ifdef HAVE_VSYSLOG
841
 
  if (!strcmp(AccessLog, "syslog") ||
842
 
      !strcmp(ErrorLog, "syslog") ||
843
 
      !strcmp(PageLog, "syslog"))
844
 
    openlog("cupsd", LOG_PID | LOG_NOWAIT | LOG_NDELAY, LOG_LPR);
845
 
#endif /* HAVE_VSYSLOG */
846
 
 
847
 
 /*
848
 
  * Log the configuration file that was used...
849
 
  */
850
 
 
851
 
  cupsdLogMessage(CUPSD_LOG_INFO, "Loaded configuration file \"%s\"",
852
 
                  ConfigurationFile);
853
 
 
854
 
 /*
855
 
  * Validate the Group and SystemGroup settings - they cannot be the same,
856
 
  * otherwise the CGI programs will be able to authenticate as root without
857
 
  * a password!
858
 
  */
859
 
 
860
 
  if (!RunUser)
861
 
  {
862
 
    for (i = 0; i < NumSystemGroups; i ++)
863
 
      if (Group == SystemGroupIDs[i])
864
 
        break;
865
 
 
866
 
    if (i < NumSystemGroups)
867
 
    {
868
 
     /*
869
 
      * Log the error and reset the group to a safe value...
870
 
      */
871
 
 
872
 
      cupsdLogMessage(CUPSD_LOG_NOTICE,
873
 
                      "Group and SystemGroup cannot use the same groups!");
874
 
      cupsdLogMessage(CUPSD_LOG_INFO, "Resetting Group to \"nobody\"...");
875
 
 
876
 
      group = getgrnam("nobody");
877
 
      endgrent();
878
 
 
879
 
      if (group != NULL)
880
 
        Group = group->gr_gid;
881
 
      else
882
 
      {
883
 
       /*
884
 
        * Use the (historical) NFS nobody group ID (-2 as a 16-bit twos-
885
 
        * complement number...)
886
 
        */
887
 
 
888
 
        Group = 65534;
889
 
      }
890
 
    }
891
 
  }
892
 
 
893
 
 /*
894
 
  * Check that we have at least one listen/port line; if not, report this
895
 
  * as an error and exit!
896
 
  */
897
 
 
898
 
  if (cupsArrayCount(Listeners) == 0)
899
 
  {
900
 
   /*
901
 
    * No listeners!
902
 
    */
903
 
 
904
 
    cupsdLogMessage(CUPSD_LOG_EMERG,
905
 
                    "No valid Listen or Port lines were found in the "
906
 
                    "configuration file!");
907
 
 
908
 
   /*
909
 
    * Commit suicide...
910
 
    */
911
 
 
912
 
    cupsdEndProcess(getpid(), 0);
913
 
  }
914
 
 
915
 
 /*
916
 
  * Set the default locale using the language and charset...
917
 
  */
918
 
 
919
 
  cupsdSetStringf(&DefaultLocale, "%s.UTF-8", DefaultLanguage);
920
 
 
921
 
 /*
922
 
  * Update all relative filenames to include the full path from ServerRoot...
923
 
  */
924
 
 
925
 
  if (DocumentRoot[0] != '/')
926
 
    cupsdSetStringf(&DocumentRoot, "%s/%s", ServerRoot, DocumentRoot);
927
 
 
928
 
  if (RequestRoot[0] != '/')
929
 
    cupsdSetStringf(&RequestRoot, "%s/%s", ServerRoot, RequestRoot);
930
 
 
931
 
  if (ServerBin[0] != '/')
932
 
    cupsdSetStringf(&ServerBin, "%s/%s", ServerRoot, ServerBin);
933
 
 
934
 
  if (StateDir[0] != '/')
935
 
    cupsdSetStringf(&StateDir, "%s/%s", ServerRoot, StateDir);
936
 
 
937
 
  if (CacheDir[0] != '/')
938
 
    cupsdSetStringf(&CacheDir, "%s/%s", ServerRoot, CacheDir);
939
 
 
940
 
#ifdef HAVE_SSL
941
 
  if (ServerCertificate[0] != '/')
942
 
    cupsdSetStringf(&ServerCertificate, "%s/%s", ServerRoot, ServerCertificate);
943
 
 
944
 
  if (!strncmp(ServerRoot, ServerCertificate, strlen(ServerRoot)) &&
945
 
      cupsdCheckPermissions(ServerCertificate, NULL, 0600, RunUser, Group,
946
 
                            0, 0) < 0 &&
947
 
      (FatalErrors & CUPSD_FATAL_PERMISSIONS))
948
 
    return (0);
949
 
 
950
 
#  if defined(HAVE_LIBSSL) || defined(HAVE_GNUTLS)
951
 
  if (ServerKey[0] != '/')
952
 
    cupsdSetStringf(&ServerKey, "%s/%s", ServerRoot, ServerKey);
953
 
 
954
 
  if (!strncmp(ServerRoot, ServerKey, strlen(ServerRoot)) &&
955
 
      cupsdCheckPermissions(ServerKey, NULL, 0600, RunUser, Group, 0, 0) < 0 &&
956
 
      (FatalErrors & CUPSD_FATAL_PERMISSIONS))
957
 
    return (0);
958
 
#  endif /* HAVE_LIBSSL || HAVE_GNUTLS */
959
 
#endif /* HAVE_SSL */
960
 
 
961
 
 /*
962
 
  * Make sure that directories and config files are owned and
963
 
  * writable by the user and group in the cupsd.conf file...
964
 
  */
965
 
 
966
 
  snprintf(temp, sizeof(temp), "%s/rss", CacheDir);
967
 
 
968
 
  if ((cupsdCheckPermissions(RequestRoot, NULL, 0710, RunUser,
969
 
                             Group, 1, 1) < 0 ||
970
 
       cupsdCheckPermissions(CacheDir, NULL, 0775, RunUser,
971
 
                             Group, 1, 1) < 0 ||
972
 
       cupsdCheckPermissions(temp, NULL, 0775, RunUser,
973
 
                             Group, 1, 1) < 0 ||
974
 
       cupsdCheckPermissions(StateDir, NULL, 0755, RunUser,
975
 
                             Group, 1, 1) < 0 ||
976
 
       cupsdCheckPermissions(StateDir, "certs", RunUser ? 0711 : 0511, User,
977
 
                             SystemGroupIDs[0], 1, 1) < 0 ||
978
 
       cupsdCheckPermissions(ServerRoot, NULL, 0755, RunUser,
979
 
                             Group, 1, 0) < 0 ||
980
 
       cupsdCheckPermissions(ServerRoot, "ppd", 0755, RunUser,
981
 
                             Group, 1, 1) < 0 ||
982
 
       cupsdCheckPermissions(ServerRoot, "ssl", 0700, RunUser,
983
 
                             Group, 1, 0) < 0 ||
984
 
       cupsdCheckPermissions(ServerRoot, "cupsd.conf", ConfigFilePerm, RunUser,
985
 
                             Group, 0, 0) < 0 ||
986
 
       cupsdCheckPermissions(ServerRoot, "classes.conf", 0600, RunUser,
987
 
                             Group, 0, 0) < 0 ||
988
 
       cupsdCheckPermissions(ServerRoot, "printers.conf", 0600, RunUser,
989
 
                             Group, 0, 0) < 0 ||
990
 
       cupsdCheckPermissions(ServerRoot, "passwd.md5", 0600, User,
991
 
                             Group, 0, 0) < 0) &&
992
 
      (FatalErrors & CUPSD_FATAL_PERMISSIONS))
993
 
    return (0);
994
 
 
995
 
 /*
996
 
  * Update TempDir to the default if it hasn't been set already...
997
 
  */
998
 
 
999
 
  if (!TempDir)
1000
 
  {
1001
 
    if ((tmpdir = getenv("TMPDIR")) != NULL)
1002
 
    {
1003
 
     /*
1004
 
      * TMPDIR is defined, see if it is OK for us to use...
1005
 
      */
1006
 
 
1007
 
      if (stat(tmpdir, &tmpinfo))
1008
 
        cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to access TMPDIR (%s): %s",
1009
 
                        tmpdir, strerror(errno));
1010
 
      else if (!S_ISDIR(tmpinfo.st_mode))
1011
 
        cupsdLogMessage(CUPSD_LOG_ERROR, "TMPDIR (%s) is not a directory!",
1012
 
                        tmpdir);
1013
 
      else if ((tmpinfo.st_uid != User || !(tmpinfo.st_mode & S_IWUSR)) &&
1014
 
               (tmpinfo.st_gid != Group || !(tmpinfo.st_mode & S_IWGRP)) &&
1015
 
               !(tmpinfo.st_mode & S_IWOTH))
1016
 
        cupsdLogMessage(CUPSD_LOG_ERROR,
1017
 
                        "TMPDIR (%s) has the wrong permissions!", tmpdir);
1018
 
      else
1019
 
        cupsdSetString(&TempDir, tmpdir);
1020
 
    }
1021
 
 
1022
 
    if (!TempDir)
1023
 
    {
1024
 
      cupsdLogMessage(CUPSD_LOG_INFO, "Using default TempDir of %s/tmp...",
1025
 
                      RequestRoot);
1026
 
      cupsdSetStringf(&TempDir, "%s/tmp", RequestRoot);
1027
 
    }
1028
 
  }
1029
 
 
1030
 
 /*
1031
 
  * Make sure the temporary directory has the right permissions...
1032
 
  */
1033
 
 
1034
 
  if (!strncmp(TempDir, RequestRoot, strlen(RequestRoot)) ||
1035
 
      access(TempDir, 0))
1036
 
  {
1037
 
   /*
1038
 
    * Update ownership and permissions if the CUPS temp directory
1039
 
    * is under the spool directory or does not exist...
1040
 
    */
1041
 
 
1042
 
    if (cupsdCheckPermissions(TempDir, NULL, 01770, RunUser, Group, 1, 1) < 0 &&
1043
 
        (FatalErrors & CUPSD_FATAL_PERMISSIONS))
1044
 
      return (0);
1045
 
  }
1046
 
 
1047
 
 /*
1048
 
  * Update environment variables...
1049
 
  */
1050
 
 
1051
 
  cupsdUpdateEnv();
1052
 
 
1053
 
 /*
1054
 
  * Update default paper size setting as needed...
1055
 
  */
1056
 
 
1057
 
  if (!DefaultPaperSize)
1058
 
  {
1059
 
#ifdef HAVE_LIBPAPER
1060
 
    char        *paper_result;          /* Paper size name from libpaper */
1061
 
 
1062
 
    if ((paper_result = systempapername()) != NULL)
1063
 
      cupsdSetString(&DefaultPaperSize, paper_result);
1064
 
    else
1065
 
#endif /* HAVE_LIBPAPER */
1066
 
    if (!DefaultLanguage ||
1067
 
        !strcasecmp(DefaultLanguage, "C") ||
1068
 
        !strcasecmp(DefaultLanguage, "POSIX") ||
1069
 
        !strcasecmp(DefaultLanguage, "en") ||
1070
 
        !strncasecmp(DefaultLanguage, "en.", 3) ||
1071
 
        !strncasecmp(DefaultLanguage, "en_US", 5) ||
1072
 
        !strncasecmp(DefaultLanguage, "en_CA", 5) ||
1073
 
        !strncasecmp(DefaultLanguage, "fr_CA", 5))
1074
 
    {
1075
 
     /*
1076
 
      * These are the only locales that will default to "letter" size...
1077
 
      */
1078
 
 
1079
 
      cupsdSetString(&DefaultPaperSize, "Letter");
1080
 
    }
1081
 
    else
1082
 
      cupsdSetString(&DefaultPaperSize, "A4");
1083
 
  }
1084
 
 
1085
 
 /*
1086
 
  * Update classification setting as needed...
1087
 
  */
1088
 
 
1089
 
  if (Classification && !strcasecmp(Classification, "none"))
1090
 
    cupsdClearString(&Classification);
1091
 
 
1092
 
  if (Classification)
1093
 
    cupsdLogMessage(CUPSD_LOG_INFO, "Security set to \"%s\"", Classification);
1094
 
 
1095
 
 /*
1096
 
  * Check the MaxClients setting, and then allocate memory for it...
1097
 
  */
1098
 
 
1099
 
  if (MaxClients > (MaxFDs / 3) || MaxClients <= 0)
1100
 
  {
1101
 
    if (MaxClients > 0)
1102
 
      cupsdLogMessage(CUPSD_LOG_INFO,
1103
 
                      "MaxClients limited to 1/3 (%d) of the file descriptor "
1104
 
                      "limit (%d)...",
1105
 
                      MaxFDs / 3, MaxFDs);
1106
 
 
1107
 
    MaxClients = MaxFDs / 3;
1108
 
  }
1109
 
 
1110
 
  cupsdLogMessage(CUPSD_LOG_INFO, "Configured for up to %d clients.",
1111
 
                  MaxClients);
1112
 
 
1113
 
 /*
1114
 
  * Check the MaxActiveJobs setting; limit to 1/3 the available
1115
 
  * file descriptors, since we need a pipe for each job...
1116
 
  */
1117
 
 
1118
 
  if (MaxActiveJobs > (MaxFDs / 3))
1119
 
    MaxActiveJobs = MaxFDs / 3;
1120
 
 
1121
 
 /*
1122
 
  * Update the MaxClientsPerHost value, as needed...
1123
 
  */
1124
 
 
1125
 
  if (MaxClientsPerHost <= 0)
1126
 
    MaxClientsPerHost = MaxClients;
1127
 
 
1128
 
  if (MaxClientsPerHost > MaxClients)
1129
 
    MaxClientsPerHost = MaxClients;
1130
 
 
1131
 
  cupsdLogMessage(CUPSD_LOG_INFO,
1132
 
                  "Allowing up to %d client connections per host.",
1133
 
                  MaxClientsPerHost);
1134
 
 
1135
 
 /*
1136
 
  * Make sure that BrowseTimeout is at least twice the interval...
1137
 
  */
1138
 
 
1139
 
  if (BrowseTimeout < (2 * BrowseInterval) || BrowseTimeout <= 0)
1140
 
  {
1141
 
    cupsdLogMessage(CUPSD_LOG_ALERT, "Invalid BrowseTimeout value %d!",
1142
 
                    BrowseTimeout);
1143
 
 
1144
 
    if (BrowseInterval)
1145
 
      BrowseTimeout = BrowseInterval * 2;
1146
 
    else
1147
 
      BrowseTimeout = DEFAULT_TIMEOUT;
1148
 
 
1149
 
    cupsdLogMessage(CUPSD_LOG_ALERT, "Reset BrowseTimeout to %d!",
1150
 
                    BrowseTimeout);
1151
 
  }
1152
 
 
1153
 
 /*
1154
 
  * Update the default policy, as needed...
1155
 
  */
1156
 
 
1157
 
  if (DefaultPolicy)
1158
 
    DefaultPolicyPtr = cupsdFindPolicy(DefaultPolicy);
1159
 
  else
1160
 
    DefaultPolicyPtr = NULL;
1161
 
 
1162
 
  if (!DefaultPolicyPtr)
1163
 
  {
1164
 
    cupsd_location_t    *po;            /* New policy operation */
1165
 
 
1166
 
 
1167
 
    if (DefaultPolicy)
1168
 
      cupsdLogMessage(CUPSD_LOG_ERROR, "Default policy \"%s\" not found!",
1169
 
                      DefaultPolicy);
1170
 
 
1171
 
    cupsdSetString(&DefaultPolicy, "default");
1172
 
 
1173
 
    if ((DefaultPolicyPtr = cupsdFindPolicy("default")) != NULL)
1174
 
      cupsdLogMessage(CUPSD_LOG_INFO,
1175
 
                      "Using policy \"default\" as the default!");
1176
 
    else
1177
 
    {
1178
 
      cupsdLogMessage(CUPSD_LOG_INFO,
1179
 
                      "Creating CUPS default administrative policy:");
1180
 
 
1181
 
      DefaultPolicyPtr = p = cupsdAddPolicy("default");
1182
 
 
1183
 
      cupsdLogMessage(CUPSD_LOG_INFO, "<Policy default>");
1184
 
      cupsdLogMessage(CUPSD_LOG_INFO,
1185
 
                      "<Limit Create-Job Print-Job Print-URI Validate-Job>");
1186
 
      cupsdLogMessage(CUPSD_LOG_INFO, "Order Deny,Allow");
1187
 
 
1188
 
      po = cupsdAddPolicyOp(p, NULL, IPP_CREATE_JOB);
1189
 
      po->order_type = CUPSD_AUTH_ALLOW;
1190
 
 
1191
 
      cupsdAddPolicyOp(p, po, IPP_PRINT_JOB);
1192
 
      cupsdAddPolicyOp(p, po, IPP_PRINT_URI);
1193
 
      cupsdAddPolicyOp(p, po, IPP_VALIDATE_JOB);
1194
 
 
1195
 
      cupsdLogMessage(CUPSD_LOG_INFO, "</Limit>");
1196
 
 
1197
 
      cupsdLogMessage(CUPSD_LOG_INFO,
1198
 
                      "<Limit Send-Document Send-URI Cancel-Job Hold-Job "
1199
 
                      "Release-Job Restart-Job Purge-Jobs "
1200
 
                      "Set-Job-Attributes Create-Job-Subscription "
1201
 
                      "Renew-Subscription Cancel-Subscription "
1202
 
                      "Get-Notifications Reprocess-Job Cancel-Current-Job "
1203
 
                      "Suspend-Current-Job Resume-Job CUPS-Move-Job "
1204
 
                      "CUPS-Authenticate-Job CUPS-Get-Document>");
1205
 
      cupsdLogMessage(CUPSD_LOG_INFO, "Order Deny,Allow");
1206
 
 
1207
 
      po = cupsdAddPolicyOp(p, NULL, IPP_SEND_DOCUMENT);
1208
 
      po->order_type = CUPSD_AUTH_ALLOW;
1209
 
      po->level      = CUPSD_AUTH_USER;
1210
 
 
1211
 
      cupsdAddName(po, "@OWNER");
1212
 
      cupsdAddName(po, "@SYSTEM");
1213
 
      cupsdLogMessage(CUPSD_LOG_INFO, "Require user @OWNER @SYSTEM");
1214
 
 
1215
 
      cupsdAddPolicyOp(p, po, IPP_SEND_URI);
1216
 
      cupsdAddPolicyOp(p, po, IPP_CANCEL_JOB);
1217
 
      cupsdAddPolicyOp(p, po, IPP_HOLD_JOB);
1218
 
      cupsdAddPolicyOp(p, po, IPP_RELEASE_JOB);
1219
 
      cupsdAddPolicyOp(p, po, IPP_RESTART_JOB);
1220
 
      cupsdAddPolicyOp(p, po, IPP_PURGE_JOBS);
1221
 
      cupsdAddPolicyOp(p, po, IPP_SET_JOB_ATTRIBUTES);
1222
 
      cupsdAddPolicyOp(p, po, IPP_CREATE_JOB_SUBSCRIPTION);
1223
 
      cupsdAddPolicyOp(p, po, IPP_RENEW_SUBSCRIPTION);
1224
 
      cupsdAddPolicyOp(p, po, IPP_CANCEL_SUBSCRIPTION);
1225
 
      cupsdAddPolicyOp(p, po, IPP_GET_NOTIFICATIONS);
1226
 
      cupsdAddPolicyOp(p, po, IPP_REPROCESS_JOB);
1227
 
      cupsdAddPolicyOp(p, po, IPP_CANCEL_CURRENT_JOB);
1228
 
      cupsdAddPolicyOp(p, po, IPP_SUSPEND_CURRENT_JOB);
1229
 
      cupsdAddPolicyOp(p, po, IPP_RESUME_JOB);
1230
 
      cupsdAddPolicyOp(p, po, CUPS_MOVE_JOB);
1231
 
      cupsdAddPolicyOp(p, po, CUPS_AUTHENTICATE_JOB);
1232
 
      cupsdAddPolicyOp(p, po, CUPS_GET_DOCUMENT);
1233
 
 
1234
 
      cupsdLogMessage(CUPSD_LOG_INFO, "</Limit>");
1235
 
 
1236
 
      cupsdLogMessage(CUPSD_LOG_INFO,
1237
 
                      "<Limit Pause-Printer Resume-Printer "
1238
 
                      "Set-Printer-Attributes Enable-Printer "
1239
 
                      "Disable-Printer Pause-Printer-After-Current-Job "
1240
 
                      "Hold-New-Jobs Release-Held-New-Jobs "
1241
 
                      "Deactivate-Printer Activate-Printer Restart-Printer "
1242
 
                      "Shutdown-Printer Startup-Printer Promote-Job "
1243
 
                      "Schedule-Job-After CUPS-Add-Printer "
1244
 
                      "CUPS-Delete-Printer CUPS-Add-Class CUPS-Delete-Class "
1245
 
                      "CUPS-Accept-Jobs CUPS-Reject-Jobs CUPS-Set-Default>");
1246
 
      cupsdLogMessage(CUPSD_LOG_INFO, "Order Deny,Allow");
1247
 
      cupsdLogMessage(CUPSD_LOG_INFO, "AuthType Default");
1248
 
 
1249
 
      po = cupsdAddPolicyOp(p, NULL, IPP_PAUSE_PRINTER);
1250
 
      po->order_type = CUPSD_AUTH_ALLOW;
1251
 
      po->type       = CUPSD_AUTH_DEFAULT;
1252
 
      po->level      = CUPSD_AUTH_USER;
1253
 
 
1254
 
      cupsdAddName(po, "@SYSTEM");
1255
 
      cupsdLogMessage(CUPSD_LOG_INFO, "Require user @SYSTEM");
1256
 
 
1257
 
      cupsdAddPolicyOp(p, po, IPP_RESUME_PRINTER);
1258
 
      cupsdAddPolicyOp(p, po, IPP_SET_PRINTER_ATTRIBUTES);
1259
 
      cupsdAddPolicyOp(p, po, IPP_ENABLE_PRINTER);
1260
 
      cupsdAddPolicyOp(p, po, IPP_DISABLE_PRINTER);
1261
 
      cupsdAddPolicyOp(p, po, IPP_PAUSE_PRINTER_AFTER_CURRENT_JOB);
1262
 
      cupsdAddPolicyOp(p, po, IPP_HOLD_NEW_JOBS);
1263
 
      cupsdAddPolicyOp(p, po, IPP_RELEASE_HELD_NEW_JOBS);
1264
 
      cupsdAddPolicyOp(p, po, IPP_DEACTIVATE_PRINTER);
1265
 
      cupsdAddPolicyOp(p, po, IPP_ACTIVATE_PRINTER);
1266
 
      cupsdAddPolicyOp(p, po, IPP_RESTART_PRINTER);
1267
 
      cupsdAddPolicyOp(p, po, IPP_SHUTDOWN_PRINTER);
1268
 
      cupsdAddPolicyOp(p, po, IPP_STARTUP_PRINTER);
1269
 
      cupsdAddPolicyOp(p, po, IPP_PROMOTE_JOB);
1270
 
      cupsdAddPolicyOp(p, po, IPP_SCHEDULE_JOB_AFTER);
1271
 
      cupsdAddPolicyOp(p, po, CUPS_ADD_PRINTER);
1272
 
      cupsdAddPolicyOp(p, po, CUPS_DELETE_PRINTER);
1273
 
      cupsdAddPolicyOp(p, po, CUPS_ADD_CLASS);
1274
 
      cupsdAddPolicyOp(p, po, CUPS_DELETE_CLASS);
1275
 
      cupsdAddPolicyOp(p, po, CUPS_ACCEPT_JOBS);
1276
 
      cupsdAddPolicyOp(p, po, CUPS_REJECT_JOBS);
1277
 
      cupsdAddPolicyOp(p, po, CUPS_SET_DEFAULT);
1278
 
 
1279
 
      cupsdLogMessage(CUPSD_LOG_INFO, "</Limit>");
1280
 
 
1281
 
      cupsdLogMessage(CUPSD_LOG_INFO, "<Limit All>");
1282
 
      cupsdLogMessage(CUPSD_LOG_INFO, "Order Deny,Allow");
1283
 
 
1284
 
      po = cupsdAddPolicyOp(p, NULL, IPP_ANY_OPERATION);
1285
 
      po->order_type = CUPSD_AUTH_ALLOW;
1286
 
 
1287
 
      cupsdLogMessage(CUPSD_LOG_INFO, "</Limit>");
1288
 
      cupsdLogMessage(CUPSD_LOG_INFO, "</Policy>");
1289
 
    }
1290
 
  }
1291
 
 
1292
 
  cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdReadConfiguration: NumPolicies=%d",
1293
 
                  cupsArrayCount(Policies));
1294
 
  for (i = 0, p = (cupsd_policy_t *)cupsArrayFirst(Policies);
1295
 
       p;
1296
 
       i ++, p = (cupsd_policy_t *)cupsArrayNext(Policies))
1297
 
    cupsdLogMessage(CUPSD_LOG_DEBUG2,
1298
 
                    "cupsdReadConfiguration: Policies[%d]=\"%s\"", i, p->name);
1299
 
 
1300
 
 /*
1301
 
  * If we are doing a full reload or the server root has changed, flush
1302
 
  * the jobs, printers, etc. and start from scratch...
1303
 
  */
1304
 
 
1305
 
  if (NeedReload == RELOAD_ALL ||
1306
 
      old_remote_port != RemotePort ||
1307
 
      !old_serverroot || !ServerRoot || strcmp(old_serverroot, ServerRoot) ||
1308
 
      !old_requestroot || !RequestRoot || strcmp(old_requestroot, RequestRoot))
1309
 
  {
1310
 
    mime_type_t *type;                  /* Current type */
1311
 
    char        mimetype[MIME_MAX_SUPER + MIME_MAX_TYPE];
1312
 
                                        /* MIME type name */
1313
 
 
1314
 
 
1315
 
    cupsdLogMessage(CUPSD_LOG_INFO, "Full reload is required.");
1316
 
 
1317
 
   /*
1318
 
    * Free all memory...
1319
 
    */
1320
 
 
1321
 
    cupsdDeleteAllSubscriptions();
1322
 
    cupsdFreeAllJobs();
1323
 
    cupsdDeleteAllPrinters();
1324
 
 
1325
 
    DefaultPrinter = NULL;
1326
 
 
1327
 
    if (MimeDatabase != NULL)
1328
 
      mimeDelete(MimeDatabase);
1329
 
 
1330
 
    if (NumMimeTypes)
1331
 
    {
1332
 
      for (i = 0; i < NumMimeTypes; i ++)
1333
 
        _cupsStrFree(MimeTypes[i]);
1334
 
 
1335
 
      free(MimeTypes);
1336
 
    }
1337
 
 
1338
 
   /*
1339
 
    * Read the MIME type and conversion database...
1340
 
    */
1341
 
 
1342
 
    snprintf(temp, sizeof(temp), "%s/filter", ServerBin);
1343
 
    snprintf(mimedir, sizeof(mimedir), "%s/mime", DataDir);
1344
 
 
1345
 
    MimeDatabase = mimeLoadTypes(NULL, mimedir);
1346
 
    MimeDatabase = mimeLoadTypes(MimeDatabase, ServerRoot);
1347
 
    MimeDatabase = mimeLoadFilters(MimeDatabase, mimedir, temp);
1348
 
    MimeDatabase = mimeLoadFilters(MimeDatabase, ServerRoot, temp);
1349
 
 
1350
 
    if (!MimeDatabase)
1351
 
    {
1352
 
      cupsdLogMessage(CUPSD_LOG_EMERG,
1353
 
                      "Unable to load MIME database from \"%s\" or \"%s\"!",
1354
 
                      mimedir, ServerRoot);
1355
 
      if (FatalErrors & CUPSD_FATAL_CONFIG)
1356
 
        return (0);
1357
 
    }
1358
 
 
1359
 
    cupsdLogMessage(CUPSD_LOG_INFO,
1360
 
                    "Loaded MIME database from \"%s\" and \"%s\": %d types, "
1361
 
                    "%d filters...", mimedir, ServerRoot,
1362
 
                    mimeNumTypes(MimeDatabase), mimeNumFilters(MimeDatabase));
1363
 
 
1364
 
   /*
1365
 
    * Create a list of MIME types for the document-format-supported
1366
 
    * attribute...
1367
 
    */
1368
 
 
1369
 
    NumMimeTypes = mimeNumTypes(MimeDatabase);
1370
 
    if (!mimeType(MimeDatabase, "application", "octet-stream"))
1371
 
      NumMimeTypes ++;
1372
 
 
1373
 
    if ((MimeTypes = calloc(NumMimeTypes, sizeof(const char *))) == NULL)
1374
 
    {
1375
 
      cupsdLogMessage(CUPSD_LOG_ERROR,
1376
 
                      "Unable to allocate memory for %d MIME types!",
1377
 
                      NumMimeTypes);
1378
 
      NumMimeTypes = 0;
1379
 
    }
1380
 
    else
1381
 
    {
1382
 
      for (i = 0, type = mimeFirstType(MimeDatabase);
1383
 
           type;
1384
 
           i ++, type = mimeNextType(MimeDatabase))
1385
 
      {
1386
 
        snprintf(mimetype, sizeof(mimetype), "%s/%s", type->super, type->type);
1387
 
 
1388
 
        MimeTypes[i] = _cupsStrAlloc(mimetype);
1389
 
      }
1390
 
 
1391
 
      if (i < NumMimeTypes)
1392
 
        MimeTypes[i] = _cupsStrAlloc("application/octet-stream");
1393
 
    }
1394
 
 
1395
 
    if (LogLevel == CUPSD_LOG_DEBUG2)
1396
 
    {
1397
 
      mime_filter_t     *filter;        /* Current filter */
1398
 
 
1399
 
 
1400
 
      for (type = mimeFirstType(MimeDatabase);
1401
 
           type;
1402
 
           type = mimeNextType(MimeDatabase))
1403
 
        cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdReadConfiguration: type %s/%s",
1404
 
                        type->super, type->type);
1405
 
 
1406
 
      for (filter = mimeFirstFilter(MimeDatabase);
1407
 
           filter;
1408
 
           filter = mimeNextFilter(MimeDatabase))
1409
 
        cupsdLogMessage(CUPSD_LOG_DEBUG2,
1410
 
                        "cupsdReadConfiguration: filter %s/%s to %s/%s %d %s",
1411
 
                        filter->src->super, filter->src->type,
1412
 
                        filter->dst->super, filter->dst->type,
1413
 
                        filter->cost, filter->filter);
1414
 
    }
1415
 
 
1416
 
   /*
1417
 
    * Load banners...
1418
 
    */
1419
 
 
1420
 
    snprintf(temp, sizeof(temp), "%s/banners", DataDir);
1421
 
    cupsdLoadBanners(temp);
1422
 
 
1423
 
   /*
1424
 
    * Load printers and classes...
1425
 
    */
1426
 
 
1427
 
    cupsdLoadAllPrinters();
1428
 
    cupsdLoadAllClasses();
1429
 
    cupsdLoadRemoteCache();
1430
 
 
1431
 
    cupsdCreateCommonData();
1432
 
 
1433
 
   /*
1434
 
    * Update the printcap file as needed...
1435
 
    */
1436
 
 
1437
 
    if (Printcap && *Printcap && access(Printcap, 0))
1438
 
      cupsdWritePrintcap();
1439
 
 
1440
 
   /*
1441
 
    * Load queued jobs...
1442
 
    */
1443
 
 
1444
 
    cupsdLoadAllJobs();
1445
 
 
1446
 
   /*
1447
 
    * Load subscriptions...
1448
 
    */
1449
 
 
1450
 
    cupsdLoadAllSubscriptions();
1451
 
 
1452
 
    cupsdLogMessage(CUPSD_LOG_INFO, "Full reload complete.");
1453
 
  }
1454
 
  else
1455
 
  {
1456
 
   /*
1457
 
    * Not a full reload, so recreate the common printer attributes...
1458
 
    */
1459
 
 
1460
 
    cupsdCreateCommonData();
1461
 
 
1462
 
   /*
1463
 
    * Update all printers as needed...
1464
 
    */
1465
 
 
1466
 
    cupsdUpdatePrinters();
1467
 
    cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
1468
 
 
1469
 
    cupsdLogMessage(CUPSD_LOG_INFO, "Partial reload complete.");
1470
 
  }
1471
 
 
1472
 
 /*
1473
 
  * Reset the reload state...
1474
 
  */
1475
 
 
1476
 
  NeedReload = RELOAD_NONE;
1477
 
 
1478
 
  cupsdClearString(&old_serverroot);
1479
 
  cupsdClearString(&old_requestroot);
1480
 
 
1481
 
  return (1);
1482
 
}
1483
 
 
1484
 
 
1485
 
/*
1486
 
 * 'get_address()' - Get an address + port number from a line.
1487
 
 */
1488
 
 
1489
 
static http_addrlist_t *                /* O - Pointer to list if address good, NULL if bad */
1490
 
get_address(const char  *value,         /* I - Value string */
1491
 
            int         defport)        /* I - Default port */
1492
 
{
1493
 
  char                  buffer[1024],   /* Hostname + port number buffer */
1494
 
                        defpname[255],  /* Default port name */
1495
 
                        *hostname,      /* Hostname or IP */
1496
 
                        *portname;      /* Port number or name */
1497
 
  http_addrlist_t       *addrlist;      /* Address list */
1498
 
 
1499
 
 
1500
 
 /*
1501
 
  * Check for an empty value...
1502
 
  */
1503
 
 
1504
 
  if (!*value)
1505
 
  {
1506
 
    cupsdLogMessage(CUPSD_LOG_ERROR, "Bad (empty) address!");
1507
 
    return (NULL);
1508
 
  }
1509
 
 
1510
 
 /*
1511
 
  * Grab a hostname and port number; if there is no colon and the port name
1512
 
  * is only digits, then we have a port number by itself...
1513
 
  */
1514
 
 
1515
 
  strlcpy(buffer, value, sizeof(buffer));
1516
 
 
1517
 
  if ((portname = strrchr(buffer, ':')) != NULL && !strchr(portname, ']'))
1518
 
  {
1519
 
    *portname++ = '\0';
1520
 
    hostname = buffer;
1521
 
  }
1522
 
  else
1523
 
  {
1524
 
    for (portname = buffer; isdigit(*portname & 255); portname ++);
1525
 
 
1526
 
    if (*portname)
1527
 
    {
1528
 
     /*
1529
 
      * Use the default port...
1530
 
      */
1531
 
 
1532
 
      sprintf(defpname, "%d", defport);
1533
 
      portname = defpname;
1534
 
      hostname = buffer;
1535
 
    }
1536
 
    else
1537
 
    {
1538
 
     /*
1539
 
      * The buffer contains just a port number...
1540
 
      */
1541
 
 
1542
 
      portname = buffer;
1543
 
      hostname = NULL;
1544
 
    }
1545
 
  }
1546
 
 
1547
 
  if (hostname && !strcmp(hostname, "*"))
1548
 
    hostname = NULL;
1549
 
 
1550
 
 /*
1551
 
  * Now lookup the address using httpAddrGetList()...
1552
 
  */
1553
 
 
1554
 
  if ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, portname)) == NULL)
1555
 
    cupsdLogMessage(CUPSD_LOG_ERROR, "Hostname lookup for \"%s\" failed!",
1556
 
                    hostname ? hostname : "(nil)");
1557
 
 
1558
 
  return (addrlist);
1559
 
}
1560
 
 
1561
 
 
1562
 
/*
1563
 
 * 'get_addr_and_mask()' - Get an IP address and netmask.
1564
 
 */
1565
 
 
1566
 
static int                              /* O - 1 on success, 0 on failure */
1567
 
get_addr_and_mask(const char *value,    /* I - String from config file */
1568
 
                  unsigned   *ip,       /* O - Address value */
1569
 
                  unsigned   *mask)     /* O - Mask value */
1570
 
{
1571
 
  int           i, j,                   /* Looping vars */
1572
 
                family,                 /* Address family */
1573
 
                ipcount;                /* Count of fields in address */
1574
 
  unsigned      ipval;                  /* Value */
1575
 
  const char    *maskval,               /* Pointer to start of mask value */
1576
 
                *ptr,                   /* Pointer into value */
1577
 
                *ptr2;                  /* ... */
1578
 
 
1579
 
 
1580
 
 /*
1581
 
  * Get the address...
1582
 
  */
1583
 
 
1584
 
  ip[0]   = ip[1]   = ip[2]   = ip[3]   = 0x00000000;
1585
 
  mask[0] = mask[1] = mask[2] = mask[3] = 0xffffffff;
1586
 
 
1587
 
  if ((maskval = strchr(value, '/')) != NULL)
1588
 
    maskval ++;
1589
 
  else
1590
 
    maskval = value + strlen(value);
1591
 
 
1592
 
#ifdef AF_INET6
1593
 
 /*
1594
 
  * Check for an IPv6 address...
1595
 
  */
1596
 
 
1597
 
  if (*value == '[')
1598
 
  {
1599
 
   /*
1600
 
    * Parse hexadecimal IPv6 address...
1601
 
    */
1602
 
 
1603
 
    family  = AF_INET6;
1604
 
 
1605
 
    for (i = 0, ptr = value + 1; *ptr && i < 8; i ++)
1606
 
    {
1607
 
      if (*ptr == ']')
1608
 
        break;
1609
 
      else if (!strncmp(ptr, "::", 2))
1610
 
      {
1611
 
        for (ptr2 = strchr(ptr + 2, ':'), j = 0;
1612
 
             ptr2;
1613
 
             ptr2 = strchr(ptr2 + 1, ':'), j ++);
1614
 
 
1615
 
        i = 7 - j;
1616
 
        ptr ++;
1617
 
      }
1618
 
      else if (isxdigit(*ptr & 255))
1619
 
      {
1620
 
        ipval = strtoul(ptr, (char **)&ptr, 16);
1621
 
 
1622
 
        if (ipval > 0xffff)
1623
 
          return (0);
1624
 
 
1625
 
        if (i & 1)
1626
 
          ip[i / 2] |= ipval;
1627
 
        else
1628
 
          ip[i / 2] |= ipval << 16;
1629
 
      }
1630
 
      else
1631
 
        return (0);
1632
 
 
1633
 
      while (*ptr == ':')
1634
 
        ptr ++;
1635
 
    }
1636
 
 
1637
 
    if (*ptr != ']')
1638
 
      return (0);
1639
 
 
1640
 
    ptr ++;
1641
 
 
1642
 
    if (*ptr && *ptr != '/')
1643
 
      return (0);
1644
 
  }
1645
 
  else
1646
 
#endif /* AF_INET6 */
1647
 
  {
1648
 
   /*
1649
 
    * Parse dotted-decimal IPv4 address...
1650
 
    */
1651
 
 
1652
 
    unsigned val[4];                    /* IPv4 address values */
1653
 
 
1654
 
 
1655
 
    family  = AF_INET;
1656
 
    ipcount = sscanf(value, "%u.%u.%u.%u", val + 0, val + 1, val + 2, val + 3);
1657
 
 
1658
 
   /*
1659
 
    * Range check the IP numbers...
1660
 
    */
1661
 
 
1662
 
    for (i = 0; i < ipcount; i ++)
1663
 
      if (val[i] > 255)
1664
 
        return (0);
1665
 
 
1666
 
   /*
1667
 
    * Make sure the trailing values are zeroed, as some C libraries like
1668
 
    * glibc apparently like to fill the unused arguments with garbage...
1669
 
    */
1670
 
 
1671
 
    for (i = ipcount; i < 4; i ++)
1672
 
      val[i] = 0;
1673
 
 
1674
 
   /*
1675
 
    * Merge everything into a 32-bit IPv4 address in ip[3]...
1676
 
    */
1677
 
 
1678
 
    ip[3] = (((((val[0] << 8) | val[1]) << 8) | val[2]) << 8) | val[3];
1679
 
 
1680
 
    if (ipcount < 4)
1681
 
      mask[3] = (0xffffffff << (32 - 8 * ipcount)) & 0xffffffff;
1682
 
  }
1683
 
 
1684
 
  if (*maskval)
1685
 
  {
1686
 
   /*
1687
 
    * Get the netmask value(s)...
1688
 
    */
1689
 
 
1690
 
    memset(mask, 0, sizeof(unsigned) * 4);
1691
 
 
1692
 
    if (strchr(maskval, '.'))
1693
 
    {
1694
 
     /*
1695
 
      * Get dotted-decimal mask...
1696
 
      */
1697
 
 
1698
 
      if (family != AF_INET)
1699
 
        return (0);
1700
 
 
1701
 
      if (sscanf(maskval, "%u.%u.%u.%u", mask + 0, mask + 1, mask + 2, mask + 3) != 4)
1702
 
        return (0);
1703
 
 
1704
 
      mask[3] |= ((((mask[0] << 8) | mask[1]) << 8) | mask[2]) << 8;
1705
 
      mask[0] = mask[1] = mask[2] = 0;
1706
 
    }
1707
 
    else
1708
 
    {
1709
 
     /*
1710
 
      * Get address/bits format...
1711
 
      */
1712
 
 
1713
 
      i = atoi(maskval);
1714
 
 
1715
 
#ifdef AF_INET6
1716
 
      if (family == AF_INET6)
1717
 
      {
1718
 
        if (i > 128)
1719
 
          return (0);
1720
 
 
1721
 
        i = 128 - i;
1722
 
 
1723
 
        if (i <= 96)
1724
 
          mask[0] = 0xffffffff;
1725
 
        else
1726
 
          mask[0] = (0xffffffff << (i - 96)) & 0xffffffff;
1727
 
 
1728
 
        if (i <= 64)
1729
 
          mask[1] = 0xffffffff;
1730
 
        else if (i >= 96)
1731
 
          mask[1] = 0;
1732
 
        else
1733
 
          mask[1] = (0xffffffff << (i - 64)) & 0xffffffff;
1734
 
 
1735
 
        if (i <= 32)
1736
 
          mask[2] = 0xffffffff;
1737
 
        else if (i >= 64)
1738
 
          mask[2] = 0;
1739
 
        else
1740
 
          mask[2] = (0xffffffff << (i - 32)) & 0xffffffff;
1741
 
 
1742
 
        if (i == 0)
1743
 
          mask[3] = 0xffffffff;
1744
 
        else if (i >= 32)
1745
 
          mask[3] = 0;
1746
 
        else
1747
 
          mask[3] = (0xffffffff << i) & 0xffffffff;
1748
 
      }
1749
 
      else
1750
 
#endif /* AF_INET6 */
1751
 
      {
1752
 
        if (i > 32)
1753
 
          return (0);
1754
 
 
1755
 
        mask[0] = 0xffffffff;
1756
 
        mask[1] = 0xffffffff;
1757
 
        mask[2] = 0xffffffff;
1758
 
 
1759
 
        if (i < 32)
1760
 
          mask[3] = (0xffffffff << (32 - i)) & 0xffffffff;
1761
 
        else
1762
 
          mask[3] = 0xffffffff;
1763
 
      }
1764
 
    }
1765
 
  }
1766
 
 
1767
 
  cupsdLogMessage(CUPSD_LOG_DEBUG2,
1768
 
                  "get_addr_and_mask(value=\"%s\", "
1769
 
                  "ip=[%08x:%08x:%08x:%08x], mask=[%08x:%08x:%08x:%08x])",
1770
 
             value, ip[0], ip[1], ip[2], ip[3], mask[0], mask[1], mask[2],
1771
 
             mask[3]);
1772
 
 
1773
 
 /*
1774
 
  * Check for a valid netmask; no fallback like in CUPS 1.1.x!
1775
 
  */
1776
 
 
1777
 
  if ((ip[0] & ~mask[0]) != 0 ||
1778
 
      (ip[1] & ~mask[1]) != 0 ||
1779
 
      (ip[2] & ~mask[2]) != 0 ||
1780
 
      (ip[3] & ~mask[3]) != 0)
1781
 
    return (0);
1782
 
 
1783
 
  return (1);
1784
 
}
1785
 
 
1786
 
 
1787
 
/*
1788
 
 * 'parse_aaa()' - Parse authentication, authorization, and access control lines.
1789
 
 */
1790
 
 
1791
 
static int                              /* O - 1 on success, 0 on failure */
1792
 
parse_aaa(cupsd_location_t *loc,        /* I - Location */
1793
 
          char             *line,       /* I - Line from file */
1794
 
          char             *value,      /* I - Start of value data */
1795
 
          int              linenum)     /* I - Current line number */
1796
 
{
1797
 
  char          *valptr;                /* Pointer into value */
1798
 
  unsigned      ip[4],                  /* IP address components */
1799
 
                mask[4];                /* IP netmask components */
1800
 
 
1801
 
 
1802
 
  if (!strcasecmp(line, "Encryption"))
1803
 
  {
1804
 
   /*
1805
 
    * "Encryption xxx" - set required encryption level...
1806
 
    */
1807
 
 
1808
 
    if (!strcasecmp(value, "never"))
1809
 
      loc->encryption = HTTP_ENCRYPT_NEVER;
1810
 
    else if (!strcasecmp(value, "always"))
1811
 
    {
1812
 
      cupsdLogMessage(CUPSD_LOG_ERROR,
1813
 
                      "Encryption value \"%s\" on line %d is invalid in this "
1814
 
                      "context. Using \"required\" instead.", value, linenum);
1815
 
 
1816
 
      loc->encryption = HTTP_ENCRYPT_REQUIRED;
1817
 
    }
1818
 
    else if (!strcasecmp(value, "required"))
1819
 
      loc->encryption = HTTP_ENCRYPT_REQUIRED;
1820
 
    else if (!strcasecmp(value, "ifrequested"))
1821
 
      loc->encryption = HTTP_ENCRYPT_IF_REQUESTED;
1822
 
    else
1823
 
    {
1824
 
      cupsdLogMessage(CUPSD_LOG_ERROR,
1825
 
                      "Unknown Encryption value %s on line %d.", value, linenum);
1826
 
      return (0);
1827
 
    }
1828
 
  }
1829
 
  else if (!strcasecmp(line, "Order"))
1830
 
  {
1831
 
   /*
1832
 
    * "Order Deny,Allow" or "Order Allow,Deny"...
1833
 
    */
1834
 
 
1835
 
    if (!strncasecmp(value, "deny", 4))
1836
 
      loc->order_type = CUPSD_AUTH_ALLOW;
1837
 
    else if (!strncasecmp(value, "allow", 5))
1838
 
      loc->order_type = CUPSD_AUTH_DENY;
1839
 
    else
1840
 
    {
1841
 
      cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown Order value %s on line %d.",
1842
 
                      value, linenum);
1843
 
      return (0);
1844
 
    }
1845
 
  }
1846
 
  else if (!strcasecmp(line, "Allow") || !strcasecmp(line, "Deny"))
1847
 
  {
1848
 
   /*
1849
 
    * Allow [From] host/ip...
1850
 
    * Deny [From] host/ip...
1851
 
    */
1852
 
 
1853
 
    while (*value)
1854
 
    {
1855
 
      if (!strncasecmp(value, "from", 4))
1856
 
      {
1857
 
       /*
1858
 
        * Strip leading "from"...
1859
 
        */
1860
 
 
1861
 
        value += 4;
1862
 
 
1863
 
        while (isspace(*value & 255))
1864
 
          value ++;
1865
 
 
1866
 
        if (!*value)
1867
 
          break;
1868
 
      }
1869
 
 
1870
 
     /*
1871
 
      * Find the end of the value...
1872
 
      */
1873
 
 
1874
 
      for (valptr = value; *valptr && !isspace(*valptr & 255); valptr ++);
1875
 
 
1876
 
      while (isspace(*valptr & 255))
1877
 
        *valptr++ = '\0';
1878
 
 
1879
 
     /*
1880
 
      * Figure out what form the allow/deny address takes:
1881
 
      *
1882
 
      *    All
1883
 
      *    None
1884
 
      *    *.domain.com
1885
 
      *    .domain.com
1886
 
      *    host.domain.com
1887
 
      *    nnn.*
1888
 
      *    nnn.nnn.*
1889
 
      *    nnn.nnn.nnn.*
1890
 
      *    nnn.nnn.nnn.nnn
1891
 
      *    nnn.nnn.nnn.nnn/mm
1892
 
      *    nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
1893
 
      */
1894
 
 
1895
 
      if (!strcasecmp(value, "all"))
1896
 
      {
1897
 
       /*
1898
 
        * All hosts...
1899
 
        */
1900
 
 
1901
 
        if (!strcasecmp(line, "Allow"))
1902
 
          cupsdAllowIP(loc, zeros, zeros);
1903
 
        else
1904
 
          cupsdDenyIP(loc, zeros, zeros);
1905
 
      }
1906
 
      else if (!strcasecmp(value, "none"))
1907
 
      {
1908
 
       /*
1909
 
        * No hosts...
1910
 
        */
1911
 
 
1912
 
        if (!strcasecmp(line, "Allow"))
1913
 
          cupsdAllowIP(loc, ones, zeros);
1914
 
        else
1915
 
          cupsdDenyIP(loc, ones, zeros);
1916
 
      }
1917
 
#ifdef AF_INET6
1918
 
      else if (value[0] == '*' || value[0] == '.' ||
1919
 
               (!isdigit(value[0] & 255) && value[0] != '['))
1920
 
#else
1921
 
      else if (value[0] == '*' || value[0] == '.' || !isdigit(value[0] & 255))
1922
 
#endif /* AF_INET6 */
1923
 
      {
1924
 
       /*
1925
 
        * Host or domain name...
1926
 
        */
1927
 
 
1928
 
        if (value[0] == '*')
1929
 
          value ++;
1930
 
 
1931
 
        if (!strcasecmp(line, "Allow"))
1932
 
          cupsdAllowHost(loc, value);
1933
 
        else
1934
 
          cupsdDenyHost(loc, value);
1935
 
      }
1936
 
      else
1937
 
      {
1938
 
       /*
1939
 
        * One of many IP address forms...
1940
 
        */
1941
 
 
1942
 
        if (!get_addr_and_mask(value, ip, mask))
1943
 
        {
1944
 
          cupsdLogMessage(CUPSD_LOG_ERROR, "Bad netmask value %s on line %d.",
1945
 
                          value, linenum);
1946
 
          return (0);
1947
 
        }
1948
 
 
1949
 
        if (!strcasecmp(line, "Allow"))
1950
 
          cupsdAllowIP(loc, ip, mask);
1951
 
        else
1952
 
          cupsdDenyIP(loc, ip, mask);
1953
 
      }
1954
 
 
1955
 
     /*
1956
 
      * Advance to next value...
1957
 
      */
1958
 
 
1959
 
      value = valptr;
1960
 
    }
1961
 
  }
1962
 
  else if (!strcasecmp(line, "AuthType"))
1963
 
  {
1964
 
   /*
1965
 
    * AuthType {none,basic,digest,basicdigest,negotiate,default}
1966
 
    */
1967
 
 
1968
 
    if (!strcasecmp(value, "none"))
1969
 
    {
1970
 
      loc->type  = CUPSD_AUTH_NONE;
1971
 
      loc->level = CUPSD_AUTH_ANON;
1972
 
    }
1973
 
    else if (!strcasecmp(value, "basic"))
1974
 
    {
1975
 
      loc->type = CUPSD_AUTH_BASIC;
1976
 
 
1977
 
      if (loc->level == CUPSD_AUTH_ANON)
1978
 
        loc->level = CUPSD_AUTH_USER;
1979
 
    }
1980
 
    else if (!strcasecmp(value, "digest"))
1981
 
    {
1982
 
      loc->type = CUPSD_AUTH_DIGEST;
1983
 
 
1984
 
      if (loc->level == CUPSD_AUTH_ANON)
1985
 
        loc->level = CUPSD_AUTH_USER;
1986
 
    }
1987
 
    else if (!strcasecmp(value, "basicdigest"))
1988
 
    {
1989
 
      loc->type = CUPSD_AUTH_BASICDIGEST;
1990
 
 
1991
 
      if (loc->level == CUPSD_AUTH_ANON)
1992
 
        loc->level = CUPSD_AUTH_USER;
1993
 
    }
1994
 
    else if (!strcasecmp(value, "default"))
1995
 
    {
1996
 
      loc->type = CUPSD_AUTH_DEFAULT;
1997
 
 
1998
 
      if (loc->level == CUPSD_AUTH_ANON)
1999
 
        loc->level = CUPSD_AUTH_USER;
2000
 
    }
2001
 
#ifdef HAVE_GSSAPI
2002
 
    else if (!strcasecmp(value, "negotiate"))
2003
 
    {
2004
 
      loc->type = CUPSD_AUTH_NEGOTIATE;
2005
 
 
2006
 
      if (loc->level == CUPSD_AUTH_ANON)
2007
 
        loc->level = CUPSD_AUTH_USER;
2008
 
    }
2009
 
#endif /* HAVE_GSSAPI */
2010
 
    else
2011
 
    {
2012
 
      cupsdLogMessage(CUPSD_LOG_WARN,
2013
 
                      "Unknown authorization type %s on line %d.",
2014
 
                      value, linenum);
2015
 
      return (0);
2016
 
    }
2017
 
  }
2018
 
  else if (!strcasecmp(line, "AuthClass"))
2019
 
  {
2020
 
   /*
2021
 
    * AuthClass anonymous, user, system, group
2022
 
    */
2023
 
 
2024
 
    if (!strcasecmp(value, "anonymous"))
2025
 
    {
2026
 
      loc->type  = CUPSD_AUTH_NONE;
2027
 
      loc->level = CUPSD_AUTH_ANON;
2028
 
 
2029
 
      cupsdLogMessage(CUPSD_LOG_WARN,
2030
 
                      "\"AuthClass %s\" is deprecated; consider removing "
2031
 
                      "it from line %d.",
2032
 
                      value, linenum);
2033
 
    }
2034
 
    else if (!strcasecmp(value, "user"))
2035
 
    {
2036
 
      loc->level = CUPSD_AUTH_USER;
2037
 
 
2038
 
      cupsdLogMessage(CUPSD_LOG_WARN,
2039
 
                      "\"AuthClass %s\" is deprecated; consider using "
2040
 
                      "\"Require valid-user\" on line %d.",
2041
 
                      value, linenum);
2042
 
    }
2043
 
    else if (!strcasecmp(value, "group"))
2044
 
    {
2045
 
      loc->level = CUPSD_AUTH_GROUP;
2046
 
 
2047
 
      cupsdLogMessage(CUPSD_LOG_WARN,
2048
 
                      "\"AuthClass %s\" is deprecated; consider using "
2049
 
                      "\"Require user @groupname\" on line %d.",
2050
 
                      value, linenum);
2051
 
    }
2052
 
    else if (!strcasecmp(value, "system"))
2053
 
    {
2054
 
      loc->level = CUPSD_AUTH_GROUP;
2055
 
 
2056
 
      cupsdAddName(loc, "@SYSTEM");
2057
 
 
2058
 
      cupsdLogMessage(CUPSD_LOG_WARN,
2059
 
                      "\"AuthClass %s\" is deprecated; consider using "
2060
 
                      "\"Require user @SYSTEM\" on line %d.",
2061
 
                      value, linenum);
2062
 
    }
2063
 
    else
2064
 
    {
2065
 
      cupsdLogMessage(CUPSD_LOG_WARN,
2066
 
                      "Unknown authorization class %s on line %d.",
2067
 
                      value, linenum);
2068
 
      return (0);
2069
 
    }
2070
 
  }
2071
 
  else if (!strcasecmp(line, "AuthGroupName"))
2072
 
  {
2073
 
    cupsdAddName(loc, value);
2074
 
 
2075
 
    cupsdLogMessage(CUPSD_LOG_WARN,
2076
 
                    "\"AuthGroupName %s\" directive is deprecated; consider "
2077
 
                    "using \"Require user @%s\" on line %d.",
2078
 
                    value, value, linenum);
2079
 
  }
2080
 
  else if (!strcasecmp(line, "Require"))
2081
 
  {
2082
 
   /*
2083
 
    * Apache synonym for AuthClass and AuthGroupName...
2084
 
    *
2085
 
    * Get initial word:
2086
 
    *
2087
 
    *     Require valid-user
2088
 
    *     Require group names
2089
 
    *     Require user names
2090
 
    */
2091
 
 
2092
 
    for (valptr = value; !isspace(*valptr & 255) && *valptr; valptr ++);
2093
 
 
2094
 
    if (*valptr)
2095
 
      *valptr++ = '\0';
2096
 
 
2097
 
    if (!strcasecmp(value, "valid-user") ||
2098
 
        !strcasecmp(value, "user"))
2099
 
      loc->level = CUPSD_AUTH_USER;
2100
 
    else if (!strcasecmp(value, "group"))
2101
 
      loc->level = CUPSD_AUTH_GROUP;
2102
 
    else
2103
 
    {
2104
 
      cupsdLogMessage(CUPSD_LOG_WARN, "Unknown Require type %s on line %d.",
2105
 
                      value, linenum);
2106
 
      return (0);
2107
 
    }
2108
 
 
2109
 
   /*
2110
 
    * Get the list of names from the line...
2111
 
    */
2112
 
 
2113
 
    for (value = valptr; *value;)
2114
 
    {
2115
 
      while (isspace(*value & 255))
2116
 
        value ++;
2117
 
 
2118
 
#ifdef HAVE_AUTHORIZATION_H
2119
 
      if (!strncmp(value, "@AUTHKEY(", 9))
2120
 
      {
2121
 
       /*
2122
 
        * Grab "@AUTHKEY(name)" value...
2123
 
        */
2124
 
 
2125
 
        for (valptr = value + 9; *valptr != ')' && *valptr; valptr ++);
2126
 
 
2127
 
        if (*valptr)
2128
 
          *valptr++ = '\0';
2129
 
      }
2130
 
      else
2131
 
#endif /* HAVE_AUTHORIZATION_H */
2132
 
      if (*value == '\"' || *value == '\'')
2133
 
      {
2134
 
       /*
2135
 
        * Grab quoted name...
2136
 
        */
2137
 
 
2138
 
        for (valptr = value + 1; *valptr != *value && *valptr; valptr ++);
2139
 
 
2140
 
        value ++;
2141
 
      }
2142
 
      else
2143
 
      {
2144
 
       /*
2145
 
        * Grab literal name.
2146
 
        */
2147
 
 
2148
 
        for (valptr = value; !isspace(*valptr & 255) && *valptr; valptr ++);
2149
 
      }
2150
 
 
2151
 
      if (*valptr)
2152
 
        *valptr++ = '\0';
2153
 
 
2154
 
      cupsdAddName(loc, value);
2155
 
 
2156
 
      for (value = valptr; isspace(*value & 255); value ++);
2157
 
    }
2158
 
  }
2159
 
  else if (!strcasecmp(line, "Satisfy"))
2160
 
  {
2161
 
    if (!strcasecmp(value, "all"))
2162
 
      loc->satisfy = CUPSD_AUTH_SATISFY_ALL;
2163
 
    else if (!strcasecmp(value, "any"))
2164
 
      loc->satisfy = CUPSD_AUTH_SATISFY_ANY;
2165
 
    else
2166
 
    {
2167
 
      cupsdLogMessage(CUPSD_LOG_WARN, "Unknown Satisfy value %s on line %d.",
2168
 
                      value, linenum);
2169
 
      return (0);
2170
 
    }
2171
 
  }
2172
 
  else
2173
 
    return (0);
2174
 
 
2175
 
  return (1);
2176
 
}
2177
 
 
2178
 
 
2179
 
/*
2180
 
 * 'parse_fatal_errors()' - Parse FatalErrors values in a string.
2181
 
 */
2182
 
 
2183
 
static int                              /* O - FatalErrors bits */
2184
 
parse_fatal_errors(const char *s)       /* I - FatalErrors string */
2185
 
{
2186
 
  int   fatal;                          /* FatalErrors bits */
2187
 
  char  value[1024],                    /* Value string */
2188
 
        *valstart,                      /* Pointer into value */
2189
 
        *valend;                        /* End of value */
2190
 
 
2191
 
 
2192
 
 /*
2193
 
  * Empty FatalErrors line yields NULL pointer...
2194
 
  */
2195
 
 
2196
 
  if (!s)
2197
 
    return (CUPSD_FATAL_NONE);
2198
 
 
2199
 
 /*
2200
 
  * Loop through the value string,...
2201
 
  */
2202
 
 
2203
 
  strlcpy(value, s, sizeof(value));
2204
 
 
2205
 
  fatal = CUPSD_FATAL_NONE;
2206
 
 
2207
 
  for (valstart = value; *valstart;)
2208
 
  {
2209
 
   /*
2210
 
    * Get the current space/comma-delimited kind name...
2211
 
    */
2212
 
 
2213
 
    for (valend = valstart; *valend; valend ++)
2214
 
      if (isspace(*valend & 255) || *valend == ',')
2215
 
        break;
2216
 
 
2217
 
    if (*valend)
2218
 
      *valend++ = '\0';
2219
 
 
2220
 
   /*
2221
 
    * Add the error to the bitmask...
2222
 
    */
2223
 
 
2224
 
    if (!strcasecmp(valstart, "all"))
2225
 
      fatal = CUPSD_FATAL_ALL;
2226
 
    else if (!strcasecmp(valstart, "browse"))
2227
 
      fatal |= CUPSD_FATAL_BROWSE;
2228
 
    else if (!strcasecmp(valstart, "-browse"))
2229
 
      fatal &= ~CUPSD_FATAL_BROWSE;
2230
 
    else if (!strcasecmp(valstart, "config"))
2231
 
      fatal |= CUPSD_FATAL_CONFIG;
2232
 
    else if (!strcasecmp(valstart, "-config"))
2233
 
      fatal &= ~CUPSD_FATAL_CONFIG;
2234
 
    else if (!strcasecmp(valstart, "listen"))
2235
 
      fatal |= CUPSD_FATAL_LISTEN;
2236
 
    else if (!strcasecmp(valstart, "-listen"))
2237
 
      fatal &= ~CUPSD_FATAL_LISTEN;
2238
 
    else if (!strcasecmp(valstart, "log"))
2239
 
      fatal |= CUPSD_FATAL_LOG;
2240
 
    else if (!strcasecmp(valstart, "-log"))
2241
 
      fatal &= ~CUPSD_FATAL_LOG;
2242
 
    else if (!strcasecmp(valstart, "permissions"))
2243
 
      fatal |= CUPSD_FATAL_PERMISSIONS;
2244
 
    else if (!strcasecmp(valstart, "-permissions"))
2245
 
      fatal &= ~CUPSD_FATAL_PERMISSIONS;
2246
 
    else if (strcasecmp(valstart, "none"))
2247
 
      cupsdLogMessage(CUPSD_LOG_ERROR,
2248
 
                      "Unknown FatalErrors kind \"%s\" ignored!", valstart);
2249
 
 
2250
 
    for (valstart = valend; *valstart; valstart ++)
2251
 
      if (!isspace(*valstart & 255) || *valstart != ',')
2252
 
        break;
2253
 
  }
2254
 
 
2255
 
  return (fatal);
2256
 
}
2257
 
 
2258
 
 
2259
 
/*
2260
 
 * 'parse_groups()' - Parse system group names in a string.
2261
 
 */
2262
 
 
2263
 
static int                              /* O - 1 on success, 0 on failure */
2264
 
parse_groups(const char *s)             /* I - Space-delimited groups */
2265
 
{
2266
 
  int           status;                 /* Return status */
2267
 
  char          value[1024],            /* Value string */
2268
 
                *valstart,              /* Pointer into value */
2269
 
                *valend,                /* End of value */
2270
 
                quote;                  /* Quote character */
2271
 
  struct group  *group;                 /* Group */
2272
 
 
2273
 
 
2274
 
 /*
2275
 
  * Make a copy of the string and parse out the groups...
2276
 
  */
2277
 
 
2278
 
  strlcpy(value, s, sizeof(value));
2279
 
 
2280
 
  status   = 1;
2281
 
  valstart = value;
2282
 
 
2283
 
  while (*valstart && NumSystemGroups < MAX_SYSTEM_GROUPS)
2284
 
  {
2285
 
    if (*valstart == '\'' || *valstart == '\"')
2286
 
    {
2287
 
     /*
2288
 
      * Scan quoted name...
2289
 
      */
2290
 
 
2291
 
      quote = *valstart++;
2292
 
 
2293
 
      for (valend = valstart; *valend; valend ++)
2294
 
        if (*valend == quote)
2295
 
          break;
2296
 
    }
2297
 
    else
2298
 
    {
2299
 
     /*
2300
 
      * Scan space or comma-delimited name...
2301
 
      */
2302
 
 
2303
 
      for (valend = valstart; *valend; valend ++)
2304
 
        if (isspace(*valend) || *valend == ',')
2305
 
          break;
2306
 
    }
2307
 
 
2308
 
    if (*valend)
2309
 
      *valend++ = '\0';
2310
 
 
2311
 
    group = getgrnam(valstart);
2312
 
    if (group)
2313
 
    {
2314
 
      cupsdSetString(SystemGroups + NumSystemGroups, valstart);
2315
 
      SystemGroupIDs[NumSystemGroups] = group->gr_gid;
2316
 
 
2317
 
      NumSystemGroups ++;
2318
 
    }
2319
 
    else
2320
 
      status = 0;
2321
 
 
2322
 
    endgrent();
2323
 
 
2324
 
    valstart = valend;
2325
 
 
2326
 
    while (*valstart == ',' || isspace(*valstart))
2327
 
      valstart ++;
2328
 
  }
2329
 
 
2330
 
  return (status);
2331
 
}
2332
 
 
2333
 
 
2334
 
/*
2335
 
 * 'parse_protocols()' - Parse browse protocols in a string.
2336
 
 */
2337
 
 
2338
 
static int                              /* O - Browse protocol bits */
2339
 
parse_protocols(const char *s)          /* I - Space-delimited protocols */
2340
 
{
2341
 
  int   protocols;                      /* Browse protocol bits */
2342
 
  char  value[1024],                    /* Value string */
2343
 
        *valstart,                      /* Pointer into value */
2344
 
        *valend;                        /* End of value */
2345
 
 
2346
 
 
2347
 
 /*
2348
 
  * Empty protocol line yields NULL pointer...
2349
 
  */
2350
 
 
2351
 
  if (!s)
2352
 
    return (0);
2353
 
 
2354
 
 /*
2355
 
  * Loop through the value string,...
2356
 
  */
2357
 
 
2358
 
  strlcpy(value, s, sizeof(value));
2359
 
 
2360
 
  protocols = 0;
2361
 
 
2362
 
  for (valstart = value; *valstart;)
2363
 
  {
2364
 
   /*
2365
 
    * Get the current space/comma-delimited protocol name...
2366
 
    */
2367
 
 
2368
 
    for (valend = valstart; *valend; valend ++)
2369
 
      if (isspace(*valend & 255) || *valend == ',')
2370
 
        break;
2371
 
 
2372
 
    if (*valend)
2373
 
      *valend++ = '\0';
2374
 
 
2375
 
   /*
2376
 
    * Add the protocol to the bitmask...
2377
 
    */
2378
 
 
2379
 
    if (!strcasecmp(valstart, "cups"))
2380
 
      protocols |= BROWSE_CUPS;
2381
 
    else if (!strcasecmp(valstart, "slp"))
2382
 
      protocols |= BROWSE_SLP;
2383
 
    else if (!strcasecmp(valstart, "ldap"))
2384
 
      protocols |= BROWSE_LDAP;
2385
 
    else if (!strcasecmp(valstart, "dnssd") ||
2386
 
             !strcasecmp(valstart, "dns-sd") ||
2387
 
             !strcasecmp(valstart, "bonjour"))
2388
 
      protocols |= BROWSE_DNSSD;
2389
 
    else if (!strcasecmp(valstart, "lpd"))
2390
 
      protocols |= BROWSE_LPD;
2391
 
    else if (!strcasecmp(valstart, "smb"))
2392
 
      protocols |= BROWSE_SMB;
2393
 
    else if (!strcasecmp(valstart, "all"))
2394
 
      protocols |= BROWSE_ALL;
2395
 
    else if (strcasecmp(valstart, "none"))
2396
 
      cupsdLogMessage(CUPSD_LOG_ERROR,
2397
 
                      "Unknown browse protocol \"%s\" ignored!", valstart);
2398
 
 
2399
 
    for (valstart = valend; *valstart; valstart ++)
2400
 
      if (!isspace(*valstart & 255) || *valstart != ',')
2401
 
        break;
2402
 
  }
2403
 
 
2404
 
  return (protocols);
2405
 
}
2406
 
 
2407
 
 
2408
 
/*
2409
 
 * 'read_configuration()' - Read a configuration file.
2410
 
 */
2411
 
 
2412
 
static int                              /* O - 1 on success, 0 on failure */
2413
 
read_configuration(cups_file_t *fp)     /* I - File to read from */
2414
 
{
2415
 
  int                   i;              /* Looping var */
2416
 
  int                   linenum;        /* Current line number */
2417
 
  char                  line[HTTP_MAX_BUFFER],
2418
 
                                        /* Line from file */
2419
 
                        temp[HTTP_MAX_BUFFER],
2420
 
                                        /* Temporary buffer for value */
2421
 
                        temp2[HTTP_MAX_BUFFER],
2422
 
                                        /* Temporary buffer 2 for value */
2423
 
                        *ptr,           /* Pointer into line/temp */
2424
 
                        *value,         /* Pointer to value */
2425
 
                        *valueptr;      /* Pointer into value */
2426
 
  int                   valuelen;       /* Length of value */
2427
 
  cupsd_var_t const     *var;           /* Current variable */
2428
 
  http_addrlist_t       *addrlist,      /* Address list */
2429
 
                        *addr;          /* Current address */
2430
 
  unsigned              ip[4],          /* Address value */
2431
 
                        mask[4];        /* Netmask value */
2432
 
  cupsd_dirsvc_relay_t  *relay;         /* Relay data */
2433
 
  cupsd_dirsvc_poll_t   *pollp;         /* Polling data */
2434
 
  cupsd_location_t      *location;      /* Browse location */
2435
 
  cups_file_t           *incfile;       /* Include file */
2436
 
  char                  incname[1024];  /* Include filename */
2437
 
  struct group          *group;         /* Group */
2438
 
 
2439
 
 
2440
 
 /*
2441
 
  * Loop through each line in the file...
2442
 
  */
2443
 
 
2444
 
  linenum = 0;
2445
 
 
2446
 
  while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
2447
 
  {
2448
 
   /*
2449
 
    * Decode the directive...
2450
 
    */
2451
 
 
2452
 
    if (!strcasecmp(line, "Include") && value)
2453
 
    {
2454
 
     /*
2455
 
      * Include filename
2456
 
      */
2457
 
 
2458
 
      if (value[0] == '/')
2459
 
        strlcpy(incname, value, sizeof(incname));
2460
 
      else
2461
 
        snprintf(incname, sizeof(incname), "%s/%s", ServerRoot, value);
2462
 
 
2463
 
      if ((incfile = cupsFileOpen(incname, "rb")) == NULL)
2464
 
        cupsdLogMessage(CUPSD_LOG_ERROR,
2465
 
                        "Unable to include config file \"%s\" - %s",
2466
 
                        incname, strerror(errno));
2467
 
      else
2468
 
      {
2469
 
        read_configuration(incfile);
2470
 
        cupsFileClose(incfile);
2471
 
      }
2472
 
    }
2473
 
    else if (!strcasecmp(line, "<Location") && value)
2474
 
    {
2475
 
     /*
2476
 
      * <Location path>
2477
 
      */
2478
 
 
2479
 
      linenum = read_location(fp, value, linenum);
2480
 
      if (linenum == 0)
2481
 
        return (0);
2482
 
    }
2483
 
    else if (!strcasecmp(line, "<Policy") && value)
2484
 
    {
2485
 
     /*
2486
 
      * <Policy name>
2487
 
      */
2488
 
 
2489
 
      linenum = read_policy(fp, value, linenum);
2490
 
      if (linenum == 0)
2491
 
        return (0);
2492
 
    }
2493
 
    else if (!strcasecmp(line, "FatalErrors"))
2494
 
      FatalErrors = parse_fatal_errors(value);
2495
 
    else if (!strcasecmp(line, "FaxRetryInterval") && value)
2496
 
    {
2497
 
      JobRetryInterval = atoi(value);
2498
 
      cupsdLogMessage(CUPSD_LOG_WARN,
2499
 
                      "FaxRetryInterval is deprecated; use "
2500
 
                      "JobRetryInterval on line %d.", linenum);
2501
 
    }
2502
 
    else if (!strcasecmp(line, "FaxRetryLimit") && value)
2503
 
    {
2504
 
      JobRetryLimit = atoi(value);
2505
 
      cupsdLogMessage(CUPSD_LOG_WARN,
2506
 
                      "FaxRetryLimit is deprecated; use "
2507
 
                      "JobRetryLimit on line %d.", linenum);
2508
 
    }
2509
 
    else if (!strcasecmp(line, "Port") || !strcasecmp(line, "Listen")
2510
 
#ifdef HAVE_SSL
2511
 
             || !strcasecmp(line, "SSLPort") || !strcasecmp(line, "SSLListen")
2512
 
#endif /* HAVE_SSL */
2513
 
             )
2514
 
    {
2515
 
     /*
2516
 
      * Add listening address(es) to the list...
2517
 
      */
2518
 
 
2519
 
      cupsd_listener_t  *lis;           /* New listeners array */
2520
 
 
2521
 
 
2522
 
     /*
2523
 
      * Get the address list...
2524
 
      */
2525
 
 
2526
 
      addrlist = get_address(value, IPP_PORT);
2527
 
 
2528
 
      if (!addrlist)
2529
 
      {
2530
 
        cupsdLogMessage(CUPSD_LOG_ERROR, "Bad %s address %s at line %d.", line,
2531
 
                        value, linenum);
2532
 
        continue;
2533
 
      }
2534
 
 
2535
 
     /*
2536
 
      * Add each address...
2537
 
      */
2538
 
 
2539
 
      for (addr = addrlist; addr; addr = addr->next)
2540
 
      {
2541
 
       /*
2542
 
        * See if this address is already present...
2543
 
        */
2544
 
 
2545
 
        for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
2546
 
             lis;
2547
 
             lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
2548
 
          if (httpAddrEqual(&(addr->addr), &(lis->address)) &&
2549
 
              _httpAddrPort(&(addr->addr)) == _httpAddrPort(&(lis->address)))
2550
 
            break;
2551
 
 
2552
 
        if (lis)
2553
 
        {
2554
 
          httpAddrString(&lis->address, temp, sizeof(temp));
2555
 
          cupsdLogMessage(CUPSD_LOG_WARN,
2556
 
                          "Duplicate listen address \"%s\" ignored!", temp);
2557
 
          continue;
2558
 
        }
2559
 
 
2560
 
       /*
2561
 
        * Allocate another listener...
2562
 
        */
2563
 
 
2564
 
        if (!Listeners)
2565
 
          Listeners = cupsArrayNew(NULL, NULL);
2566
 
 
2567
 
        if (!Listeners)
2568
 
        {
2569
 
          cupsdLogMessage(CUPSD_LOG_ERROR,
2570
 
                          "Unable to allocate %s at line %d - %s.",
2571
 
                          line, linenum, strerror(errno));
2572
 
          break;
2573
 
        }
2574
 
 
2575
 
        if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL)
2576
 
        {
2577
 
          cupsdLogMessage(CUPSD_LOG_ERROR,
2578
 
                          "Unable to allocate %s at line %d - %s.",
2579
 
                          line, linenum, strerror(errno));
2580
 
          break;
2581
 
        }
2582
 
 
2583
 
        cupsArrayAdd(Listeners, lis);
2584
 
 
2585
 
       /*
2586
 
        * Copy the current address and log it...
2587
 
        */
2588
 
 
2589
 
        memcpy(&(lis->address), &(addr->addr), sizeof(lis->address));
2590
 
        lis->fd = -1;
2591
 
 
2592
 
#ifdef HAVE_SSL
2593
 
        if (!strcasecmp(line, "SSLPort") || !strcasecmp(line, "SSLListen"))
2594
 
          lis->encryption = HTTP_ENCRYPT_ALWAYS;
2595
 
#endif /* HAVE_SSL */
2596
 
 
2597
 
        httpAddrString(&lis->address, temp, sizeof(temp));
2598
 
 
2599
 
#ifdef AF_INET6
2600
 
        if (lis->address.addr.sa_family == AF_INET6)
2601
 
          cupsdLogMessage(CUPSD_LOG_INFO, "Listening to %s:%d (IPv6)", temp,
2602
 
                          ntohs(lis->address.ipv6.sin6_port));
2603
 
        else
2604
 
#endif /* AF_INET6 */
2605
 
#ifdef AF_LOCAL
2606
 
        if (lis->address.addr.sa_family == AF_LOCAL)
2607
 
          cupsdLogMessage(CUPSD_LOG_INFO, "Listening to %s (Domain)", temp);
2608
 
        else
2609
 
#endif /* AF_LOCAL */
2610
 
        cupsdLogMessage(CUPSD_LOG_INFO, "Listening to %s:%d (IPv4)", temp,
2611
 
                        ntohs(lis->address.ipv4.sin_port));
2612
 
 
2613
 
        if (!httpAddrLocalhost(&(lis->address)))
2614
 
        {
2615
 
#ifdef AF_INET6
2616
 
          if (lis->address.addr.sa_family == AF_INET6)
2617
 
            RemotePort = ntohs(lis->address.ipv6.sin6_port);
2618
 
          else
2619
 
#endif /* AF_INET6 */
2620
 
          RemotePort = ntohs(lis->address.ipv4.sin_port);
2621
 
        }
2622
 
      }
2623
 
 
2624
 
     /*
2625
 
      * Free the list...
2626
 
      */
2627
 
 
2628
 
      httpAddrFreeList(addrlist);
2629
 
    }
2630
 
    else if (!strcasecmp(line, "BrowseAddress") && value)
2631
 
    {
2632
 
     /*
2633
 
      * Add a browse address to the list...
2634
 
      */
2635
 
 
2636
 
      cupsd_dirsvc_addr_t       *dira;  /* New browse address array */
2637
 
 
2638
 
 
2639
 
      if (NumBrowsers == 0)
2640
 
        dira = malloc(sizeof(cupsd_dirsvc_addr_t));
2641
 
      else
2642
 
        dira = realloc(Browsers, (NumBrowsers + 1) * sizeof(cupsd_dirsvc_addr_t));
2643
 
 
2644
 
      if (!dira)
2645
 
      {
2646
 
        cupsdLogMessage(CUPSD_LOG_ERROR,
2647
 
                        "Unable to allocate BrowseAddress at line %d - %s.",
2648
 
                        linenum, strerror(errno));
2649
 
        continue;
2650
 
      }
2651
 
 
2652
 
      Browsers = dira;
2653
 
      dira     += NumBrowsers;
2654
 
 
2655
 
      memset(dira, 0, sizeof(cupsd_dirsvc_addr_t));
2656
 
 
2657
 
      if (!strcasecmp(value, "@LOCAL"))
2658
 
      {
2659
 
       /*
2660
 
        * Send browse data to all local interfaces...
2661
 
        */
2662
 
 
2663
 
        strcpy(dira->iface, "*");
2664
 
        NumBrowsers ++;
2665
 
      }
2666
 
      else if (!strncasecmp(value, "@IF(", 4))
2667
 
      {
2668
 
       /*
2669
 
        * Send browse data to the named interface...
2670
 
        */
2671
 
 
2672
 
        strlcpy(dira->iface, value + 4, sizeof(Browsers[0].iface));
2673
 
 
2674
 
        ptr = dira->iface + strlen(dira->iface) - 1;
2675
 
        if (*ptr == ')')
2676
 
          *ptr = '\0';
2677
 
 
2678
 
        NumBrowsers ++;
2679
 
      }
2680
 
      else if ((addrlist = get_address(value, BrowsePort)) != NULL)
2681
 
      {
2682
 
       /*
2683
 
        * Only IPv4 addresses are supported...
2684
 
        */
2685
 
 
2686
 
        for (addr = addrlist; addr; addr = addr->next)
2687
 
          if (addr->addr.addr.sa_family == AF_INET)
2688
 
            break;
2689
 
 
2690
 
        if (addr)
2691
 
        {
2692
 
          memcpy(&(dira->to), &(addrlist->addr), sizeof(dira->to));
2693
 
          httpAddrString(&(dira->to), temp, sizeof(temp));
2694
 
 
2695
 
          cupsdLogMessage(CUPSD_LOG_INFO,
2696
 
                          "Sending browsing info to %s:%d (IPv4)",
2697
 
                          temp, ntohs(dira->to.ipv4.sin_port));
2698
 
 
2699
 
          NumBrowsers ++;
2700
 
        }
2701
 
        else
2702
 
          cupsdLogMessage(CUPSD_LOG_ERROR, "Bad BrowseAddress %s at line %d.",
2703
 
                          value, linenum);
2704
 
 
2705
 
        httpAddrFreeList(addrlist);
2706
 
      }
2707
 
      else
2708
 
        cupsdLogMessage(CUPSD_LOG_ERROR, "Bad BrowseAddress %s at line %d.",
2709
 
                        value, linenum);
2710
 
    }
2711
 
    else if (!strcasecmp(line, "BrowseOrder") && value)
2712
 
    {
2713
 
     /*
2714
 
      * "BrowseOrder Deny,Allow" or "BrowseOrder Allow,Deny"...
2715
 
      */
2716
 
 
2717
 
      if ((location = cupsdFindLocation("CUPS_INTERNAL_BROWSE_ACL")) == NULL)
2718
 
        location = cupsdAddLocation("CUPS_INTERNAL_BROWSE_ACL");
2719
 
 
2720
 
      if (location == NULL)
2721
 
        cupsdLogMessage(CUPSD_LOG_ERROR,
2722
 
                        "Unable to initialize browse access control list!");
2723
 
      else if (!strncasecmp(value, "deny", 4))
2724
 
        location->order_type = CUPSD_AUTH_ALLOW;
2725
 
      else if (!strncasecmp(value, "allow", 5))
2726
 
        location->order_type = CUPSD_AUTH_DENY;
2727
 
      else
2728
 
        cupsdLogMessage(CUPSD_LOG_ERROR,
2729
 
                        "Unknown BrowseOrder value %s on line %d.",
2730
 
                        value, linenum);
2731
 
    }
2732
 
    else if (!strcasecmp(line, "BrowseProtocols") ||
2733
 
             !strcasecmp(line, "BrowseLocalProtocols") ||
2734
 
             !strcasecmp(line, "BrowseRemoteProtocols"))
2735
 
    {
2736
 
     /*
2737
 
      * "BrowseProtocols name [... name]"
2738
 
      * "BrowseLocalProtocols name [... name]"
2739
 
      * "BrowseRemoteProtocols name [... name]"
2740
 
      */
2741
 
 
2742
 
      int protocols = parse_protocols(value);
2743
 
 
2744
 
      if (protocols < 0)
2745
 
      {
2746
 
        cupsdLogMessage(CUPSD_LOG_ERROR,
2747
 
                        "Unknown browse protocol \"%s\" on line %d.",
2748
 
                        value, linenum);
2749
 
        break;
2750
 
      }
2751
 
 
2752
 
      if (strcasecmp(line, "BrowseLocalProtocols"))
2753
 
        BrowseRemoteProtocols = protocols;
2754
 
      if (strcasecmp(line, "BrowseRemoteProtocols"))
2755
 
        BrowseLocalProtocols = protocols;
2756
 
    }
2757
 
    else if ((!strcasecmp(line, "BrowseAllow") ||
2758
 
              !strcasecmp(line, "BrowseDeny")) && value)
2759
 
    {
2760
 
     /*
2761
 
      * BrowseAllow [From] host/ip...
2762
 
      * BrowseDeny [From] host/ip...
2763
 
      */
2764
 
 
2765
 
      if ((location = cupsdFindLocation("CUPS_INTERNAL_BROWSE_ACL")) == NULL)
2766
 
        location = cupsdAddLocation("CUPS_INTERNAL_BROWSE_ACL");
2767
 
 
2768
 
      if (location == NULL)
2769
 
        cupsdLogMessage(CUPSD_LOG_ERROR,
2770
 
                        "Unable to initialize browse access control list!");
2771
 
      else
2772
 
      {
2773
 
        while (*value)
2774
 
        {
2775
 
          if (!strncasecmp(value, "from", 4))
2776
 
          {
2777
 
           /*
2778
 
            * Strip leading "from"...
2779
 
            */
2780
 
 
2781
 
            value += 4;
2782
 
 
2783
 
            while (isspace(*value & 255))
2784
 
              value ++;
2785
 
 
2786
 
            if (!*value)
2787
 
              break;
2788
 
          }
2789
 
 
2790
 
         /*
2791
 
          * Find the end of the value...
2792
 
          */
2793
 
 
2794
 
          for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++);
2795
 
 
2796
 
          while (isspace(*valueptr & 255))
2797
 
            *valueptr++ = '\0';
2798
 
 
2799
 
         /*
2800
 
          * Figure out what form the allow/deny address takes:
2801
 
          *
2802
 
          *    All
2803
 
          *    None
2804
 
          *    *.domain.com
2805
 
          *    .domain.com
2806
 
          *    host.domain.com
2807
 
          *    nnn.*
2808
 
          *    nnn.nnn.*
2809
 
          *    nnn.nnn.nnn.*
2810
 
          *    nnn.nnn.nnn.nnn
2811
 
          *    nnn.nnn.nnn.nnn/mm
2812
 
          *    nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
2813
 
          */
2814
 
 
2815
 
          if (!strcasecmp(value, "all"))
2816
 
          {
2817
 
           /*
2818
 
            * All hosts...
2819
 
            */
2820
 
 
2821
 
            if (!strcasecmp(line, "BrowseAllow"))
2822
 
              cupsdAllowIP(location, zeros, zeros);
2823
 
            else
2824
 
              cupsdDenyIP(location, zeros, zeros);
2825
 
          }
2826
 
          else if (!strcasecmp(value, "none"))
2827
 
          {
2828
 
           /*
2829
 
            * No hosts...
2830
 
            */
2831
 
 
2832
 
            if (!strcasecmp(line, "BrowseAllow"))
2833
 
              cupsdAllowIP(location, ones, zeros);
2834
 
            else
2835
 
              cupsdDenyIP(location, ones, zeros);
2836
 
          }
2837
 
#ifdef AF_INET6
2838
 
          else if (value[0] == '*' || value[0] == '.' ||
2839
 
                   (!isdigit(value[0] & 255) && value[0] != '['))
2840
 
#else
2841
 
          else if (value[0] == '*' || value[0] == '.' || !isdigit(value[0] & 255))
2842
 
#endif /* AF_INET6 */
2843
 
          {
2844
 
           /*
2845
 
            * Host or domain name...
2846
 
            */
2847
 
 
2848
 
            if (value[0] == '*')
2849
 
              value ++;
2850
 
 
2851
 
            if (!strcasecmp(line, "BrowseAllow"))
2852
 
              cupsdAllowHost(location, value);
2853
 
            else
2854
 
              cupsdDenyHost(location, value);
2855
 
          }
2856
 
          else
2857
 
          {
2858
 
           /*
2859
 
            * One of many IP address forms...
2860
 
            */
2861
 
 
2862
 
            if (!get_addr_and_mask(value, ip, mask))
2863
 
            {
2864
 
              cupsdLogMessage(CUPSD_LOG_ERROR, "Bad netmask value %s on line %d.",
2865
 
                              value, linenum);
2866
 
              break;
2867
 
            }
2868
 
 
2869
 
            if (!strcasecmp(line, "BrowseAllow"))
2870
 
              cupsdAllowIP(location, ip, mask);
2871
 
            else
2872
 
              cupsdDenyIP(location, ip, mask);
2873
 
          }
2874
 
 
2875
 
         /*
2876
 
          * Advance to next value...
2877
 
          */
2878
 
 
2879
 
          value = valueptr;
2880
 
        }
2881
 
      }
2882
 
    }
2883
 
    else if (!strcasecmp(line, "BrowseRelay") && value)
2884
 
    {
2885
 
     /*
2886
 
      * BrowseRelay [from] source [to] destination
2887
 
      */
2888
 
 
2889
 
      if (NumRelays == 0)
2890
 
        relay = malloc(sizeof(cupsd_dirsvc_relay_t));
2891
 
      else
2892
 
        relay = realloc(Relays, (NumRelays + 1) * sizeof(cupsd_dirsvc_relay_t));
2893
 
 
2894
 
      if (!relay)
2895
 
      {
2896
 
        cupsdLogMessage(CUPSD_LOG_ERROR,
2897
 
                        "Unable to allocate BrowseRelay at line %d - %s.",
2898
 
                        linenum, strerror(errno));
2899
 
        continue;
2900
 
      }
2901
 
 
2902
 
      Relays = relay;
2903
 
      relay  += NumRelays;
2904
 
 
2905
 
      memset(relay, 0, sizeof(cupsd_dirsvc_relay_t));
2906
 
 
2907
 
      if (!strncasecmp(value, "from ", 5))
2908
 
      {
2909
 
       /*
2910
 
        * Strip leading "from"...
2911
 
        */
2912
 
 
2913
 
        value += 5;
2914
 
 
2915
 
        while (isspace(*value))
2916
 
          value ++;
2917
 
      }
2918
 
 
2919
 
     /*
2920
 
      * Figure out what form the from address takes:
2921
 
      *
2922
 
      *    *.domain.com
2923
 
      *    .domain.com
2924
 
      *    host.domain.com
2925
 
      *    nnn.*
2926
 
      *    nnn.nnn.*
2927
 
      *    nnn.nnn.nnn.*
2928
 
      *    nnn.nnn.nnn.nnn
2929
 
      *    nnn.nnn.nnn.nnn/mm
2930
 
      *    nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
2931
 
      */
2932
 
 
2933
 
#ifdef AF_INET6
2934
 
      if (value[0] == '*' || value[0] == '.' ||
2935
 
          (!isdigit(value[0] & 255) && value[0] != '['))
2936
 
#else
2937
 
      if (value[0] == '*' || value[0] == '.' || !isdigit(value[0] & 255))
2938
 
#endif /* AF_INET6 */
2939
 
      {
2940
 
       /*
2941
 
        * Host or domain name...
2942
 
        */
2943
 
 
2944
 
        if (value[0] == '*')
2945
 
          value ++;
2946
 
 
2947
 
        strlcpy(temp, value, sizeof(temp));
2948
 
        if ((ptr = strchr(temp, ' ')) != NULL)
2949
 
          *ptr = '\0';
2950
 
 
2951
 
        relay->from.type = CUPSD_AUTH_NAME;
2952
 
 
2953
 
        if ((relay->from.mask.name.name = strdup(temp)) == NULL)
2954
 
        {
2955
 
          cupsdLogMessage(CUPSD_LOG_ERROR,
2956
 
                          "Unable to allocate BrowseRelay name at line %d - %s.",
2957
 
                          linenum, strerror(errno));
2958
 
          continue;
2959
 
        }
2960
 
 
2961
 
        relay->from.mask.name.length = strlen(temp);
2962
 
      }
2963
 
      else
2964
 
      {
2965
 
       /*
2966
 
        * One of many IP address forms...
2967
 
        */
2968
 
 
2969
 
        if (!get_addr_and_mask(value, ip, mask))
2970
 
        {
2971
 
          cupsdLogMessage(CUPSD_LOG_ERROR, "Bad netmask value %s on line %d.",
2972
 
                          value, linenum);
2973
 
          break;
2974
 
        }
2975
 
 
2976
 
        relay->from.type = CUPSD_AUTH_IP;
2977
 
        memcpy(relay->from.mask.ip.address, ip,
2978
 
               sizeof(relay->from.mask.ip.address));
2979
 
        memcpy(relay->from.mask.ip.netmask, mask,
2980
 
               sizeof(relay->from.mask.ip.netmask));
2981
 
      }
2982
 
 
2983
 
     /*
2984
 
      * Skip value and trailing whitespace...
2985
 
      */
2986
 
 
2987
 
      for (; *value; value ++)
2988
 
        if (isspace(*value))
2989
 
          break;
2990
 
 
2991
 
      while (isspace(*value))
2992
 
        value ++;
2993
 
 
2994
 
      if (!strncasecmp(value, "to ", 3))
2995
 
      {
2996
 
       /*
2997
 
        * Strip leading "to"...
2998
 
        */
2999
 
 
3000
 
        value += 3;
3001
 
 
3002
 
        while (isspace(*value))
3003
 
          value ++;
3004
 
      }
3005
 
 
3006
 
     /*
3007
 
      * Get "to" address and port...
3008
 
      */
3009
 
 
3010
 
      if ((addrlist = get_address(value, BrowsePort)) != NULL)
3011
 
      {
3012
 
       /*
3013
 
        * Only IPv4 addresses are supported...
3014
 
        */
3015
 
 
3016
 
        for (addr = addrlist; addr; addr = addr->next)
3017
 
          if (addr->addr.addr.sa_family == AF_INET)
3018
 
            break;
3019
 
 
3020
 
        if (addr)
3021
 
        {
3022
 
          memcpy(&(relay->to), &(addrlist->addr), sizeof(relay->to));
3023
 
 
3024
 
          httpAddrString(&(relay->to), temp, sizeof(temp));
3025
 
 
3026
 
          if (relay->from.type == CUPSD_AUTH_IP)
3027
 
            snprintf(temp2, sizeof(temp2), "%u.%u.%u.%u/%u.%u.%u.%u",
3028
 
                     relay->from.mask.ip.address[0] >> 24,
3029
 
                     (relay->from.mask.ip.address[0] >> 16) & 255,
3030
 
                     (relay->from.mask.ip.address[0] >> 8) & 255,
3031
 
                     relay->from.mask.ip.address[0] & 255,
3032
 
                     relay->from.mask.ip.netmask[0] >> 24,
3033
 
                     (relay->from.mask.ip.netmask[0] >> 16) & 255,
3034
 
                     (relay->from.mask.ip.netmask[0] >> 8) & 255,
3035
 
                     relay->from.mask.ip.netmask[0] & 255);
3036
 
          else
3037
 
            strlcpy(temp2, relay->from.mask.name.name, sizeof(temp2));
3038
 
 
3039
 
          cupsdLogMessage(CUPSD_LOG_INFO, "Relaying from %s to %s:%d (IPv4)",
3040
 
                          temp2, temp, ntohs(relay->to.ipv4.sin_port));
3041
 
 
3042
 
          NumRelays ++;
3043
 
        }
3044
 
        else
3045
 
          cupsdLogMessage(CUPSD_LOG_ERROR, "Bad relay address %s at line %d.",
3046
 
                          value, linenum);
3047
 
 
3048
 
        httpAddrFreeList(addrlist);
3049
 
      }
3050
 
      else
3051
 
      {
3052
 
        if (relay->from.type == CUPSD_AUTH_NAME)
3053
 
          free(relay->from.mask.name.name);
3054
 
 
3055
 
        cupsdLogMessage(CUPSD_LOG_ERROR, "Bad relay address %s at line %d.",
3056
 
                        value, linenum);
3057
 
      }
3058
 
    }
3059
 
    else if (!strcasecmp(line, "BrowsePoll") && value)
3060
 
    {
3061
 
     /*
3062
 
      * BrowsePoll address[:port]
3063
 
      */
3064
 
 
3065
 
      char              *portname;      /* Port name */
3066
 
      int               portnum;        /* Port number */
3067
 
      struct servent    *service;       /* Service */
3068
 
 
3069
 
 
3070
 
     /*
3071
 
      * Extract the port name from the address...
3072
 
      */
3073
 
 
3074
 
      if ((portname = strrchr(value, ':')) != NULL && !strchr(portname, ']'))
3075
 
      {
3076
 
        *portname++ = '\0';
3077
 
 
3078
 
        if (isdigit(*portname & 255))
3079
 
          portnum = atoi(portname);
3080
 
        else if ((service = getservbyname(portname, NULL)) != NULL)
3081
 
          portnum = ntohs(service->s_port);
3082
 
        else
3083
 
        {
3084
 
          cupsdLogMessage(CUPSD_LOG_ERROR, "Lookup of service \"%s\" failed!",
3085
 
                          portname);
3086
 
          continue;
3087
 
        }
3088
 
      }
3089
 
      else
3090
 
        portnum = ippPort();
3091
 
 
3092
 
     /*
3093
 
      * Add the poll entry...
3094
 
      */
3095
 
 
3096
 
      if (NumPolled == 0)
3097
 
        pollp = malloc(sizeof(cupsd_dirsvc_poll_t));
3098
 
      else
3099
 
        pollp = realloc(Polled, (NumPolled + 1) * sizeof(cupsd_dirsvc_poll_t));
3100
 
 
3101
 
      if (!pollp)
3102
 
      {
3103
 
        cupsdLogMessage(CUPSD_LOG_ERROR,
3104
 
                        "Unable to allocate BrowsePoll at line %d - %s.",
3105
 
                        linenum, strerror(errno));
3106
 
        continue;
3107
 
      }
3108
 
 
3109
 
      Polled = pollp;
3110
 
      pollp   += NumPolled;
3111
 
 
3112
 
      NumPolled ++;
3113
 
      memset(pollp, 0, sizeof(cupsd_dirsvc_poll_t));
3114
 
 
3115
 
      strlcpy(pollp->hostname, value, sizeof(pollp->hostname));
3116
 
      pollp->port = portnum;
3117
 
 
3118
 
      cupsdLogMessage(CUPSD_LOG_INFO, "Polling %s:%d", pollp->hostname,
3119
 
                      pollp->port);
3120
 
    }
3121
 
    else if (!strcasecmp(line, "DefaultAuthType") && value)
3122
 
    {
3123
 
     /*
3124
 
      * DefaultAuthType {basic,digest,basicdigest,negotiate}
3125
 
      */
3126
 
 
3127
 
      if (!strcasecmp(value, "none"))
3128
 
        DefaultAuthType = CUPSD_AUTH_NONE;
3129
 
      else if (!strcasecmp(value, "basic"))
3130
 
        DefaultAuthType = CUPSD_AUTH_BASIC;
3131
 
      else if (!strcasecmp(value, "digest"))
3132
 
        DefaultAuthType = CUPSD_AUTH_DIGEST;
3133
 
      else if (!strcasecmp(value, "basicdigest"))
3134
 
        DefaultAuthType = CUPSD_AUTH_BASICDIGEST;
3135
 
#ifdef HAVE_GSSAPI
3136
 
      else if (!strcasecmp(value, "negotiate"))
3137
 
        DefaultAuthType = CUPSD_AUTH_NEGOTIATE;
3138
 
#endif /* HAVE_GSSAPI */
3139
 
      else
3140
 
      {
3141
 
        cupsdLogMessage(CUPSD_LOG_WARN,
3142
 
                        "Unknown default authorization type %s on line %d.",
3143
 
                        value, linenum);
3144
 
        if (FatalErrors & CUPSD_FATAL_CONFIG)
3145
 
          return (0);
3146
 
      }
3147
 
    }
3148
 
#ifdef HAVE_SSL
3149
 
    else if (!strcasecmp(line, "DefaultEncryption"))
3150
 
    {
3151
 
     /*
3152
 
      * DefaultEncryption {Never,IfRequested,Required}
3153
 
      */
3154
 
 
3155
 
      if (!value || !strcasecmp(value, "never"))
3156
 
        DefaultEncryption = HTTP_ENCRYPT_NEVER;
3157
 
      else if (!strcasecmp(value, "required"))
3158
 
        DefaultEncryption = HTTP_ENCRYPT_REQUIRED;
3159
 
      else if (!strcasecmp(value, "ifrequested"))
3160
 
        DefaultEncryption = HTTP_ENCRYPT_IF_REQUESTED;
3161
 
      else
3162
 
      {
3163
 
        cupsdLogMessage(CUPSD_LOG_WARN,
3164
 
                        "Unknown default encryption %s on line %d.",
3165
 
                        value, linenum);
3166
 
        if (FatalErrors & CUPSD_FATAL_CONFIG)
3167
 
          return (0);
3168
 
      }
3169
 
    }
3170
 
#endif /* HAVE_SSL */
3171
 
    else if (!strcasecmp(line, "User") && value)
3172
 
    {
3173
 
     /*
3174
 
      * User ID to run as...
3175
 
      */
3176
 
 
3177
 
      if (isdigit(value[0] & 255))
3178
 
      {
3179
 
        int uid = atoi(value);
3180
 
 
3181
 
        if (!uid)
3182
 
          cupsdLogMessage(CUPSD_LOG_ERROR,
3183
 
                          "Will not use User 0 as specified on line %d "
3184
 
                          "for security reasons.  You must use a non-"
3185
 
                          "privileged account instead.",
3186
 
                          linenum);
3187
 
        else
3188
 
          User = atoi(value);
3189
 
      }
3190
 
      else
3191
 
      {
3192
 
        struct passwd *p;       /* Password information */
3193
 
 
3194
 
        endpwent();
3195
 
        p = getpwnam(value);
3196
 
 
3197
 
        if (p)
3198
 
        {
3199
 
          if (!p->pw_uid)
3200
 
            cupsdLogMessage(CUPSD_LOG_ERROR,
3201
 
                            "Will not use User %s (UID=0) as specified on line "
3202
 
                            "%d for security reasons.  You must use a non-"
3203
 
                            "privileged account instead.",
3204
 
                            value, linenum);
3205
 
          else
3206
 
            User = p->pw_uid;
3207
 
        }
3208
 
        else
3209
 
          cupsdLogMessage(CUPSD_LOG_ERROR,
3210
 
                          "Unknown User \"%s\" on line %d, ignoring!",
3211
 
                          value, linenum);
3212
 
      }
3213
 
    }
3214
 
    else if (!strcasecmp(line, "Group") && value)
3215
 
    {
3216
 
     /*
3217
 
      * Group ID to run as...
3218
 
      */
3219
 
 
3220
 
      if (isdigit(value[0]))
3221
 
        Group = atoi(value);
3222
 
      else
3223
 
      {
3224
 
        endgrent();
3225
 
        group = getgrnam(value);
3226
 
 
3227
 
        if (group != NULL)
3228
 
          Group = group->gr_gid;
3229
 
        else
3230
 
          cupsdLogMessage(CUPSD_LOG_ERROR,
3231
 
                          "Unknown Group \"%s\" on line %d, ignoring!",
3232
 
                          value, linenum);
3233
 
      }
3234
 
    }
3235
 
    else if (!strcasecmp(line, "SystemGroup") && value)
3236
 
    {
3237
 
     /*
3238
 
      * SystemGroup (admin) group(s)...
3239
 
      */
3240
 
 
3241
 
      if (!parse_groups(value))
3242
 
        cupsdLogMessage(CUPSD_LOG_ERROR,
3243
 
                        "Unknown SystemGroup \"%s\" on line %d, ignoring!",
3244
 
                        value, linenum);
3245
 
    }
3246
 
    else if (!strcasecmp(line, "HostNameLookups") && value)
3247
 
    {
3248
 
     /*
3249
 
      * Do hostname lookups?
3250
 
      */
3251
 
 
3252
 
      if (!strcasecmp(value, "off") || !strcasecmp(value, "no") ||
3253
 
          !strcasecmp(value, "false"))
3254
 
        HostNameLookups = 0;
3255
 
      else if (!strcasecmp(value, "on") || !strcasecmp(value, "yes") ||
3256
 
          !strcasecmp(value, "true"))
3257
 
        HostNameLookups = 1;
3258
 
      else if (!strcasecmp(value, "double"))
3259
 
        HostNameLookups = 2;
3260
 
      else
3261
 
        cupsdLogMessage(CUPSD_LOG_WARN, "Unknown HostNameLookups %s on line %d.",
3262
 
                        value, linenum);
3263
 
    }
3264
 
    else if (!strcasecmp(line, "AccessLogLevel") && value)
3265
 
    {
3266
 
     /*
3267
 
      * Amount of logging to do to access log...
3268
 
      */
3269
 
 
3270
 
      if (!strcasecmp(value, "all"))
3271
 
        AccessLogLevel = CUPSD_ACCESSLOG_ALL;
3272
 
      else if (!strcasecmp(value, "actions"))
3273
 
        AccessLogLevel = CUPSD_ACCESSLOG_ACTIONS;
3274
 
      else if (!strcasecmp(value, "config"))
3275
 
        AccessLogLevel = CUPSD_ACCESSLOG_CONFIG;
3276
 
      else
3277
 
        cupsdLogMessage(CUPSD_LOG_WARN, "Unknown AccessLogLevel %s on line %d.",
3278
 
                        value, linenum);
3279
 
    }
3280
 
    else if (!strcasecmp(line, "LogLevel") && value)
3281
 
    {
3282
 
     /*
3283
 
      * Amount of logging to do to error log...
3284
 
      */
3285
 
 
3286
 
      if (!strcasecmp(value, "debug2"))
3287
 
        LogLevel = CUPSD_LOG_DEBUG2;
3288
 
      else if (!strcasecmp(value, "debug"))
3289
 
        LogLevel = CUPSD_LOG_DEBUG;
3290
 
      else if (!strcasecmp(value, "info"))
3291
 
        LogLevel = CUPSD_LOG_INFO;
3292
 
      else if (!strcasecmp(value, "notice"))
3293
 
        LogLevel = CUPSD_LOG_NOTICE;
3294
 
      else if (!strcasecmp(value, "warn"))
3295
 
        LogLevel = CUPSD_LOG_WARN;
3296
 
      else if (!strcasecmp(value, "error"))
3297
 
        LogLevel = CUPSD_LOG_ERROR;
3298
 
      else if (!strcasecmp(value, "crit"))
3299
 
        LogLevel = CUPSD_LOG_CRIT;
3300
 
      else if (!strcasecmp(value, "alert"))
3301
 
        LogLevel = CUPSD_LOG_ALERT;
3302
 
      else if (!strcasecmp(value, "emerg"))
3303
 
        LogLevel = CUPSD_LOG_EMERG;
3304
 
      else if (!strcasecmp(value, "none"))
3305
 
        LogLevel = CUPSD_LOG_NONE;
3306
 
      else
3307
 
        cupsdLogMessage(CUPSD_LOG_WARN, "Unknown LogLevel %s on line %d.",
3308
 
                        value, linenum);
3309
 
    }
3310
 
    else if (!strcasecmp(line, "LogTimeFormat") && value)
3311
 
    {
3312
 
     /*
3313
 
      * Amount of logging to do to error log...
3314
 
      */
3315
 
 
3316
 
      if (!strcasecmp(value, "standard"))
3317
 
        LogTimeFormat = CUPSD_TIME_STANDARD;
3318
 
      else if (!strcasecmp(value, "usecs"))
3319
 
        LogTimeFormat = CUPSD_TIME_USECS;
3320
 
      else
3321
 
        cupsdLogMessage(CUPSD_LOG_WARN, "Unknown LogTimeFormat %s on line %d.",
3322
 
                        value, linenum);
3323
 
    }
3324
 
    else if (!strcasecmp(line, "PrintcapFormat") && value)
3325
 
    {
3326
 
     /*
3327
 
      * Format of printcap file?
3328
 
      */
3329
 
 
3330
 
      if (!strcasecmp(value, "bsd"))
3331
 
        PrintcapFormat = PRINTCAP_BSD;
3332
 
      else if (!strcasecmp(value, "plist"))
3333
 
        PrintcapFormat = PRINTCAP_PLIST;
3334
 
      else if (!strcasecmp(value, "solaris"))
3335
 
        PrintcapFormat = PRINTCAP_SOLARIS;
3336
 
      else
3337
 
        cupsdLogMessage(CUPSD_LOG_WARN, "Unknown PrintcapFormat %s on line %d.",
3338
 
                        value, linenum);
3339
 
    }
3340
 
    else if (!strcasecmp(line, "ServerTokens") && value)
3341
 
    {
3342
 
     /*
3343
 
      * Set the string used for the Server header...
3344
 
      */
3345
 
 
3346
 
      struct utsname plat;              /* Platform info */
3347
 
 
3348
 
 
3349
 
      uname(&plat);
3350
 
 
3351
 
      if (!strcasecmp(value, "ProductOnly"))
3352
 
        cupsdSetString(&ServerHeader, "CUPS");
3353
 
      else if (!strcasecmp(value, "Major"))
3354
 
        cupsdSetString(&ServerHeader, "CUPS/1");
3355
 
      else if (!strcasecmp(value, "Minor"))
3356
 
        cupsdSetString(&ServerHeader, "CUPS/1.4");
3357
 
      else if (!strcasecmp(value, "Minimal"))
3358
 
        cupsdSetString(&ServerHeader, CUPS_MINIMAL);
3359
 
      else if (!strcasecmp(value, "OS"))
3360
 
        cupsdSetStringf(&ServerHeader, CUPS_MINIMAL " (%s)", plat.sysname);
3361
 
      else if (!strcasecmp(value, "Full"))
3362
 
        cupsdSetStringf(&ServerHeader, CUPS_MINIMAL " (%s) IPP/1.1",
3363
 
                        plat.sysname);
3364
 
      else if (!strcasecmp(value, "None"))
3365
 
        cupsdClearString(&ServerHeader);
3366
 
      else
3367
 
        cupsdLogMessage(CUPSD_LOG_WARN, "Unknown ServerTokens %s on line %d.",
3368
 
                        value, linenum);
3369
 
    }
3370
 
    else if (!strcasecmp(line, "PassEnv") && value)
3371
 
    {
3372
 
     /*
3373
 
      * PassEnv variable [... variable]
3374
 
      */
3375
 
 
3376
 
      for (; *value;)
3377
 
      {
3378
 
        for (valuelen = 0; value[valuelen]; valuelen ++)
3379
 
          if (isspace(value[valuelen]) || value[valuelen] == ',')
3380
 
            break;
3381
 
 
3382
 
        if (value[valuelen])
3383
 
        {
3384
 
          value[valuelen] = '\0';
3385
 
          valuelen ++;
3386
 
        }
3387
 
 
3388
 
        cupsdSetEnv(value, NULL);
3389
 
 
3390
 
        for (value += valuelen; *value; value ++)
3391
 
          if (!isspace(*value) || *value != ',')
3392
 
            break;
3393
 
      }
3394
 
    }
3395
 
    else if (!strcasecmp(line, "ServerAlias") && value)
3396
 
    {
3397
 
      if (!ServerAlias)
3398
 
        ServerAlias = cupsArrayNew(NULL, NULL);
3399
 
 
3400
 
      cupsdAddAlias(ServerAlias, value);
3401
 
    }
3402
 
    else if (!strcasecmp(line, "SetEnv") && value)
3403
 
    {
3404
 
     /*
3405
 
      * SetEnv variable value
3406
 
      */
3407
 
 
3408
 
      for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++);
3409
 
 
3410
 
      if (*valueptr)
3411
 
      {
3412
 
       /*
3413
 
        * Found a value...
3414
 
        */
3415
 
 
3416
 
        while (isspace(*valueptr & 255))
3417
 
          *valueptr++ = '\0';
3418
 
 
3419
 
        cupsdSetEnv(value, valueptr);
3420
 
      }
3421
 
      else
3422
 
        cupsdLogMessage(CUPSD_LOG_ERROR,
3423
 
                        "Missing value for SetEnv directive on line %d.",
3424
 
                        linenum);
3425
 
    }
3426
 
#ifdef HAVE_SSL
3427
 
    else if (!strcasecmp(line, "SSLOptions"))
3428
 
    {
3429
 
     /*
3430
 
      * SSLOptions options
3431
 
      */
3432
 
 
3433
 
      if (!value || !strcasecmp(value, "none"))
3434
 
        SSLOptions = CUPSD_SSL_NONE;
3435
 
      else if (!strcasecmp(value, "noemptyfragments"))
3436
 
        SSLOptions = CUPSD_SSL_NOEMPTY;
3437
 
      else
3438
 
        cupsdLogMessage(CUPSD_LOG_ERROR,
3439
 
                        "Unknown value \"%s\" for SSLOptions directive on "
3440
 
                        "line %d.", value, linenum);
3441
 
    }
3442
 
#endif /* HAVE_SSL */
3443
 
    else
3444
 
    {
3445
 
     /*
3446
 
      * Find a simple variable in the list...
3447
 
      */
3448
 
 
3449
 
      for (i = NUM_VARS, var = variables; i > 0; i --, var ++)
3450
 
        if (!strcasecmp(line, var->name))
3451
 
          break;
3452
 
 
3453
 
      if (i == 0)
3454
 
      {
3455
 
       /*
3456
 
        * Unknown directive!  Output an error message and continue...
3457
 
        */
3458
 
 
3459
 
        if (!value)
3460
 
          cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value for %s on line %d.",
3461
 
                          line, linenum);
3462
 
        else
3463
 
          cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown directive %s on line %d.",
3464
 
                          line, linenum);
3465
 
        continue;
3466
 
      }
3467
 
 
3468
 
      switch (var->type)
3469
 
      {
3470
 
        case CUPSD_VARTYPE_INTEGER :
3471
 
            if (!value)
3472
 
              cupsdLogMessage(CUPSD_LOG_ERROR,
3473
 
                              "Missing integer value for %s on line %d!",
3474
 
                              line, linenum);
3475
 
            else
3476
 
            {
3477
 
              int       n;              /* Number */
3478
 
              char      *units;         /* Units */
3479
 
 
3480
 
 
3481
 
              n = strtol(value, &units, 0);
3482
 
 
3483
 
              if (units && *units)
3484
 
              {
3485
 
                if (tolower(units[0] & 255) == 'g')
3486
 
                  n *= 1024 * 1024 * 1024;
3487
 
                else if (tolower(units[0] & 255) == 'm')
3488
 
                  n *= 1024 * 1024;
3489
 
                else if (tolower(units[0] & 255) == 'k')
3490
 
                  n *= 1024;
3491
 
                else if (tolower(units[0] & 255) == 't')
3492
 
                  n *= 262144;
3493
 
              }
3494
 
 
3495
 
              if (n < 0)
3496
 
                cupsdLogMessage(CUPSD_LOG_ERROR,
3497
 
                                "Bad negative integer value for %s on line %d!",
3498
 
                                line, linenum);
3499
 
              else
3500
 
                *((int *)var->ptr) = n;
3501
 
            }
3502
 
            break;
3503
 
 
3504
 
        case CUPSD_VARTYPE_BOOLEAN :
3505
 
            if (!value)
3506
 
              cupsdLogMessage(CUPSD_LOG_ERROR,
3507
 
                              "Missing boolean value for %s on line %d!",
3508
 
                              line, linenum);
3509
 
            else if (!strcasecmp(value, "true") ||
3510
 
                     !strcasecmp(value, "on") ||
3511
 
                     !strcasecmp(value, "enabled") ||
3512
 
                     !strcasecmp(value, "yes") ||
3513
 
                     atoi(value) != 0)
3514
 
              *((int *)var->ptr) = TRUE;
3515
 
            else if (!strcasecmp(value, "false") ||
3516
 
                     !strcasecmp(value, "off") ||
3517
 
                     !strcasecmp(value, "disabled") ||
3518
 
                     !strcasecmp(value, "no") ||
3519
 
                     !strcasecmp(value, "0"))
3520
 
              *((int *)var->ptr) = FALSE;
3521
 
            else
3522
 
              cupsdLogMessage(CUPSD_LOG_ERROR,
3523
 
                              "Unknown boolean value %s on line %d.",
3524
 
                              value, linenum);
3525
 
            break;
3526
 
 
3527
 
        case CUPSD_VARTYPE_PATHNAME :
3528
 
            if (!value)
3529
 
            {
3530
 
              cupsdLogMessage(CUPSD_LOG_ERROR,
3531
 
                              "Missing pathname value for %s on line %d!",
3532
 
                              line, linenum);
3533
 
              break;
3534
 
            }
3535
 
 
3536
 
            if (value[0] == '/')
3537
 
              strlcpy(temp, value, sizeof(temp));
3538
 
            else
3539
 
              snprintf(temp, sizeof(temp), "%s/%s", ServerRoot, value);
3540
 
 
3541
 
            if (access(temp, 0))
3542
 
            {
3543
 
              cupsdLogMessage(CUPSD_LOG_ERROR,
3544
 
                              "File or directory for \"%s %s\" on line %d "
3545
 
                              "does not exist!", line, value, linenum);
3546
 
              break;
3547
 
            }
3548
 
 
3549
 
        case CUPSD_VARTYPE_STRING :
3550
 
            cupsdSetString((char **)var->ptr, value);
3551
 
            break;
3552
 
      }
3553
 
    }
3554
 
  }
3555
 
 
3556
 
  return (1);
3557
 
}
3558
 
 
3559
 
 
3560
 
/*
3561
 
 * 'read_location()' - Read a <Location path> definition.
3562
 
 */
3563
 
 
3564
 
static int                              /* O - New line number or 0 on error */
3565
 
read_location(cups_file_t *fp,          /* I - Configuration file */
3566
 
              char        *location,    /* I - Location name/path */
3567
 
              int         linenum)      /* I - Current line number */
3568
 
{
3569
 
  cupsd_location_t      *loc,           /* New location */
3570
 
                        *parent;        /* Parent location */
3571
 
  char                  line[HTTP_MAX_BUFFER],
3572
 
                                        /* Line buffer */
3573
 
                        *value,         /* Value for directive */
3574
 
                        *valptr;        /* Pointer into value */
3575
 
 
3576
 
 
3577
 
  if ((parent = cupsdAddLocation(location)) == NULL)
3578
 
    return (0);
3579
 
 
3580
 
  parent->limit = CUPSD_AUTH_LIMIT_ALL;
3581
 
  loc           = parent;
3582
 
 
3583
 
  while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
3584
 
  {
3585
 
   /*
3586
 
    * Decode the directive...
3587
 
    */
3588
 
 
3589
 
    if (!strcasecmp(line, "</Location>"))
3590
 
      return (linenum);
3591
 
    else if (!strcasecmp(line, "<Limit") ||
3592
 
             !strcasecmp(line, "<LimitExcept"))
3593
 
    {
3594
 
      if (!value)
3595
 
      {
3596
 
        cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d.", linenum);
3597
 
        if (FatalErrors & CUPSD_FATAL_CONFIG)
3598
 
          return (0);
3599
 
        else
3600
 
          continue;
3601
 
      }
3602
 
 
3603
 
      if ((loc = cupsdCopyLocation(&parent)) == NULL)
3604
 
        return (0);
3605
 
 
3606
 
      loc->limit = 0;
3607
 
      while (*value)
3608
 
      {
3609
 
        for (valptr = value; !isspace(*valptr & 255) && *valptr; valptr ++);
3610
 
 
3611
 
        if (*valptr)
3612
 
          *valptr++ = '\0';
3613
 
 
3614
 
        if (!strcmp(value, "ALL"))
3615
 
          loc->limit = CUPSD_AUTH_LIMIT_ALL;
3616
 
        else if (!strcmp(value, "GET"))
3617
 
          loc->limit |= CUPSD_AUTH_LIMIT_GET;
3618
 
        else if (!strcmp(value, "HEAD"))
3619
 
          loc->limit |= CUPSD_AUTH_LIMIT_HEAD;
3620
 
        else if (!strcmp(value, "OPTIONS"))
3621
 
          loc->limit |= CUPSD_AUTH_LIMIT_OPTIONS;
3622
 
        else if (!strcmp(value, "POST"))
3623
 
          loc->limit |= CUPSD_AUTH_LIMIT_POST;
3624
 
        else if (!strcmp(value, "PUT"))
3625
 
          loc->limit |= CUPSD_AUTH_LIMIT_PUT;
3626
 
        else if (!strcmp(value, "TRACE"))
3627
 
          loc->limit |= CUPSD_AUTH_LIMIT_TRACE;
3628
 
        else
3629
 
          cupsdLogMessage(CUPSD_LOG_WARN, "Unknown request type %s on line %d!",
3630
 
                          value, linenum);
3631
 
 
3632
 
        for (value = valptr; isspace(*value & 255); value ++);
3633
 
      }
3634
 
 
3635
 
      if (!strcasecmp(line, "<LimitExcept"))
3636
 
        loc->limit = CUPSD_AUTH_LIMIT_ALL ^ loc->limit;
3637
 
 
3638
 
      parent->limit &= ~loc->limit;
3639
 
    }
3640
 
    else if (!strcasecmp(line, "</Limit>") ||
3641
 
             !strcasecmp(line, "</LimitExcept>"))
3642
 
      loc = parent;
3643
 
    else if (!parse_aaa(loc, line, value, linenum))
3644
 
    {
3645
 
      cupsdLogMessage(CUPSD_LOG_ERROR,
3646
 
                      "Unknown Location directive %s on line %d.",
3647
 
                      line, linenum);
3648
 
      if (FatalErrors & CUPSD_FATAL_CONFIG)
3649
 
        return (0);
3650
 
    }
3651
 
  }
3652
 
 
3653
 
  cupsdLogMessage(CUPSD_LOG_ERROR,
3654
 
                  "Unexpected end-of-file at line %d while reading location!",
3655
 
                  linenum);
3656
 
 
3657
 
  return ((FatalErrors & CUPSD_FATAL_CONFIG) ? 0 : linenum);
3658
 
}
3659
 
 
3660
 
 
3661
 
/*
3662
 
 * 'read_policy()' - Read a <Policy name> definition.
3663
 
 */
3664
 
 
3665
 
static int                              /* O - New line number or 0 on error */
3666
 
read_policy(cups_file_t *fp,            /* I - Configuration file */
3667
 
            char        *policy,        /* I - Location name/path */
3668
 
            int         linenum)        /* I - Current line number */
3669
 
{
3670
 
  int                   i;              /* Looping var */
3671
 
  cupsd_policy_t        *pol;           /* Policy */
3672
 
  cupsd_location_t      *op;            /* Policy operation */
3673
 
  int                   num_ops;        /* Number of IPP operations */
3674
 
  ipp_op_t              ops[100];       /* Operations */
3675
 
  char                  line[HTTP_MAX_BUFFER],
3676
 
                                        /* Line buffer */
3677
 
                        *value,         /* Value for directive */
3678
 
                        *valptr;        /* Pointer into value */
3679
 
 
3680
 
 
3681
 
 /*
3682
 
  * Create the policy...
3683
 
  */
3684
 
 
3685
 
  if ((pol = cupsdAddPolicy(policy)) == NULL)
3686
 
    return (0);
3687
 
 
3688
 
 /*
3689
 
  * Read from the file...
3690
 
  */
3691
 
 
3692
 
  op      = NULL;
3693
 
  num_ops = 0;
3694
 
 
3695
 
  while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
3696
 
  {
3697
 
   /*
3698
 
    * Decode the directive...
3699
 
    */
3700
 
 
3701
 
    if (!strcasecmp(line, "</Policy>"))
3702
 
    {
3703
 
      if (op)
3704
 
        cupsdLogMessage(CUPSD_LOG_WARN,
3705
 
                        "Missing </Limit> before </Policy> on line %d!",
3706
 
                        linenum);
3707
 
 
3708
 
     /*
3709
 
      * Verify that we have an explicit policy for Validate-Job and
3710
 
      * CUPS-Get-Document, which ensures that upgrades do not introduce new
3711
 
      * security issues...
3712
 
      */
3713
 
 
3714
 
      if ((op = cupsdFindPolicyOp(pol, IPP_VALIDATE_JOB)) == NULL ||
3715
 
          op->op == IPP_ANY_OPERATION)
3716
 
      {
3717
 
        if ((op = cupsdFindPolicyOp(pol, IPP_PRINT_JOB)) != NULL &&
3718
 
            op->op != IPP_ANY_OPERATION)
3719
 
        {
3720
 
         /*
3721
 
          * Add a new limit for Validate-Job using the Print-Job limit as a
3722
 
          * template...
3723
 
          */
3724
 
 
3725
 
          cupsdLogMessage(CUPSD_LOG_WARN,
3726
 
                          "No limit for Validate-Job defined in policy %s "
3727
 
                          "- using Print-Job's policy", pol->name);
3728
 
 
3729
 
          cupsdAddPolicyOp(pol, op, IPP_VALIDATE_JOB);
3730
 
        }
3731
 
      }
3732
 
 
3733
 
      if ((op = cupsdFindPolicyOp(pol, CUPS_GET_DOCUMENT)) == NULL ||
3734
 
          op->op == IPP_ANY_OPERATION)
3735
 
      {
3736
 
        if ((op = cupsdFindPolicyOp(pol, IPP_SEND_DOCUMENT)) != NULL &&
3737
 
            op->op != IPP_ANY_OPERATION)
3738
 
        {
3739
 
         /*
3740
 
          * Add a new limit for CUPS-Get-Document using the Send-Document
3741
 
          * limit as a template...
3742
 
          */
3743
 
 
3744
 
          cupsdLogMessage(CUPSD_LOG_WARN,
3745
 
                          "No limit for CUPS-Get-Document defined in policy %s "
3746
 
                          "- using Send-Document's policy", pol->name);
3747
 
 
3748
 
          cupsdAddPolicyOp(pol, op, CUPS_GET_DOCUMENT);
3749
 
        }
3750
 
      }
3751
 
 
3752
 
      return (linenum);
3753
 
    }
3754
 
    else if (!strcasecmp(line, "<Limit") && !op)
3755
 
    {
3756
 
      if (!value)
3757
 
      {
3758
 
        cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d.", linenum);
3759
 
        if (FatalErrors & CUPSD_FATAL_CONFIG)
3760
 
          return (0);
3761
 
        else
3762
 
          continue;
3763
 
      }
3764
 
 
3765
 
     /*
3766
 
      * Scan for IPP operation names...
3767
 
      */
3768
 
 
3769
 
      num_ops = 0;
3770
 
 
3771
 
      while (*value)
3772
 
      {
3773
 
        for (valptr = value; !isspace(*valptr & 255) && *valptr; valptr ++);
3774
 
 
3775
 
        if (*valptr)
3776
 
          *valptr++ = '\0';
3777
 
 
3778
 
        if (num_ops < (int)(sizeof(ops) / sizeof(ops[0])))
3779
 
        {
3780
 
          if (!strcasecmp(value, "All"))
3781
 
            ops[num_ops] = IPP_ANY_OPERATION;
3782
 
          else if ((ops[num_ops] = ippOpValue(value)) == IPP_BAD_OPERATION)
3783
 
            cupsdLogMessage(CUPSD_LOG_ERROR,
3784
 
                            "Bad IPP operation name \"%s\" on line %d!",
3785
 
                            value, linenum);
3786
 
          else
3787
 
            num_ops ++;
3788
 
        }
3789
 
        else
3790
 
          cupsdLogMessage(CUPSD_LOG_ERROR,
3791
 
                          "Too many operations listed on line %d!",
3792
 
                          linenum);
3793
 
 
3794
 
        for (value = valptr; isspace(*value & 255); value ++);
3795
 
      }
3796
 
 
3797
 
     /*
3798
 
      * If none are specified, apply the policy to all operations...
3799
 
      */
3800
 
 
3801
 
      if (num_ops == 0)
3802
 
      {
3803
 
        ops[0]  = IPP_ANY_OPERATION;
3804
 
        num_ops = 1;
3805
 
      }
3806
 
 
3807
 
     /*
3808
 
      * Add a new policy for the first operation...
3809
 
      */
3810
 
 
3811
 
      op = cupsdAddPolicyOp(pol, NULL, ops[0]);
3812
 
    }
3813
 
    else if (!strcasecmp(line, "</Limit>") && op)
3814
 
    {
3815
 
     /*
3816
 
      * Finish the current operation limit...
3817
 
      */
3818
 
 
3819
 
      if (num_ops > 1)
3820
 
      {
3821
 
       /*
3822
 
        * Copy the policy to the other operations...
3823
 
        */
3824
 
 
3825
 
        for (i = 1; i < num_ops; i ++)
3826
 
          cupsdAddPolicyOp(pol, op, ops[i]);
3827
 
      }
3828
 
 
3829
 
      op = NULL;
3830
 
    }
3831
 
    else if (!op)
3832
 
    {
3833
 
      cupsdLogMessage(CUPSD_LOG_ERROR,
3834
 
                      "Missing <Limit ops> directive before %s on line %d.",
3835
 
                      line, linenum);
3836
 
      if (FatalErrors & CUPSD_FATAL_CONFIG)
3837
 
        return (0);
3838
 
    }
3839
 
    else if (!parse_aaa(op, line, value, linenum))
3840
 
    {
3841
 
      if (op)
3842
 
        cupsdLogMessage(CUPSD_LOG_ERROR,
3843
 
                        "Unknown Policy Limit directive %s on line %d.",
3844
 
                        line, linenum);
3845
 
      else
3846
 
        cupsdLogMessage(CUPSD_LOG_ERROR,
3847
 
                        "Unknown Policy directive %s on line %d.",
3848
 
                        line, linenum);
3849
 
 
3850
 
      if (FatalErrors & CUPSD_FATAL_CONFIG)
3851
 
        return (0);
3852
 
    }
3853
 
  }
3854
 
 
3855
 
  cupsdLogMessage(CUPSD_LOG_ERROR,
3856
 
                  "Unexpected end-of-file at line %d while reading policy \"%s\"!",
3857
 
                  linenum, policy);
3858
 
 
3859
 
  return ((FatalErrors & CUPSD_FATAL_CONFIG) ? 0 : linenum);
3860
 
}
3861
 
 
3862
 
 
3863
 
/*
3864
 
 * End of "$Id: conf.c 9470 2011-01-11 07:05:58Z mike $".
3865
 
 */