2
* "$Id: conf.c 9470 2011-01-11 07:05:58Z mike $"
4
* Configuration routines for the Common UNIX Printing System (CUPS).
6
* Copyright 2007-2011 by Apple Inc.
7
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
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/".
17
* cupsdAddAlias() - Add a host alias.
18
* cupsdCheckPermissions() - Fix the mode and ownership of a file or
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
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.
35
* Include necessary headers...
41
#include <sys/utsname.h>
46
#endif /* HAVE_LIBPAPER */
50
* Possibly missing network definitions...
54
# define INADDR_NONE 0xffffffff
55
#endif /* !INADDR_NONE */
59
* Configuration variable structure...
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 */
72
char *name; /* Name of variable */
73
void *ptr; /* Pointer to variable */
74
cupsd_vartype_t type; /* Type (int, string, address) */
82
static const cupsd_var_t variables[] =
84
{ "AccessLog", &AccessLog, CUPSD_VARTYPE_STRING },
86
{ "AppleQuotas", &AppleQuotas, CUPSD_VARTYPE_BOOLEAN },
87
#endif /* __APPLE__ */
88
{ "AutoPurgeJobs", &JobAutoPurge, CUPSD_VARTYPE_BOOLEAN },
89
{ "BrowseInterval", &BrowseInterval, CUPSD_VARTYPE_INTEGER },
91
{ "BrowseLDAPBindDN", &BrowseLDAPBindDN, CUPSD_VARTYPE_STRING },
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 },
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 },
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 }
188
#define NUM_VARS (sizeof(variables) / sizeof(variables[0]))
191
static const unsigned ones[4] =
193
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
195
static const unsigned zeros[4] =
197
0x00000000, 0x00000000, 0x00000000, 0x00000000
205
static http_addrlist_t *get_address(const char *value, int defport);
206
static int get_addr_and_mask(const char *value, unsigned *ip,
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);
219
* 'cupsdAddAlias()' - Add a host alias.
223
cupsdAddAlias(cups_array_t *aliases, /* I - Array of aliases */
224
const char *name) /* I - Name to add */
226
cupsd_alias_t *a; /* New alias */
227
size_t namelen; /* Length of name */
230
namelen = strlen(name);
232
if ((a = (cupsd_alias_t *)malloc(sizeof(cupsd_alias_t) + namelen)) == NULL)
235
a->namelen = namelen;
236
strcpy(a->name, name); /* OK since a->name is allocated */
238
cupsArrayAdd(aliases, a);
243
* 'cupsdCheckPermissions()' - Fix the mode and ownership of a file or directory.
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 */
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? */
263
* Prepend the given root to the filename before testing it...
268
snprintf(pathname, sizeof(pathname), "%s/%s", filename, suffix);
273
* See if we can stat the file/directory...
276
if (lstat(filename, &fileinfo))
278
if (errno == ENOENT && create_dir)
281
cupsdLogMessage(CUPSD_LOG_DEBUG, "Creating missing directory \"%s\"",
284
if (mkdir(filename, mode))
287
cupsdLogMessage(CUPSD_LOG_ERROR,
288
"Unable to create directory \"%s\" - %s", filename,
291
syslog(LOG_ERR, "Unable to create directory \"%s\" - %s", filename,
298
fileinfo.st_mode = mode | S_IFDIR;
301
return (create_dir ? -1 : 1);
304
if ((is_symlink = S_ISLNK(fileinfo.st_mode)) != 0)
306
if (stat(filename, &fileinfo))
308
cupsdLogMessage(CUPSD_LOG_ERROR, "\"%s\" is a bad symlink - %s",
309
filename, strerror(errno));
315
* Make sure it's a regular file or a directory as needed...
318
if (!dir_created && !is_dir && !S_ISREG(fileinfo.st_mode))
320
cupsdLogMessage(CUPSD_LOG_ERROR, "\"%s\" is not a regular file!", filename);
324
if (!dir_created && is_dir && !S_ISDIR(fileinfo.st_mode))
327
cupsdLogMessage(CUPSD_LOG_ERROR, "\"%s\" is not a directory!", filename);
329
syslog(LOG_ERR, "\"%s\" is not a directory!", filename);
335
* If the filename is a symlink, do not change permissions (STR #2937)...
342
* Fix owner, group, and mode as needed...
345
if (dir_created || fileinfo.st_uid != user || fileinfo.st_gid != group)
348
cupsdLogMessage(CUPSD_LOG_DEBUG, "Repairing ownership of \"%s\"",
351
if (chown(filename, user, group) && !getuid())
354
cupsdLogMessage(CUPSD_LOG_ERROR,
355
"Unable to change ownership of \"%s\" - %s", filename,
358
syslog(LOG_ERR, "Unable to change ownership of \"%s\" - %s", filename,
365
if (dir_created || (fileinfo.st_mode & 07777) != mode)
368
cupsdLogMessage(CUPSD_LOG_DEBUG, "Repairing access permissions of \"%s\"",
371
if (chmod(filename, mode))
374
cupsdLogMessage(CUPSD_LOG_ERROR,
375
"Unable to change permissions of \"%s\" - %s", filename,
378
syslog(LOG_ERR, "Unable to change permissions of \"%s\" - %s", filename,
386
* Everything is OK...
394
* 'cupsdFreeAliases()' - Free all of the alias entries.
398
cupsdFreeAliases(cups_array_t *aliases) /* I - Array of aliases */
400
cupsd_alias_t *a; /* Current alias */
403
for (a = (cupsd_alias_t *)cupsArrayFirst(aliases);
405
a = (cupsd_alias_t *)cupsArrayNext(aliases))
408
cupsArrayDelete(aliases);
413
* 'cupsdReadConfiguration()' - Read the cupsd.conf file.
416
int /* O - 1 on success, 0 otherwise */
417
cupsdReadConfiguration(void)
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 */
437
* Save the old root paths...
440
old_serverroot = NULL;
441
cupsdSetString(&old_serverroot, ServerRoot);
442
old_requestroot = NULL;
443
cupsdSetString(&old_requestroot, RequestRoot);
446
* Reset the server configuration data...
449
cupsdDeleteAllLocations();
468
for (i = 0; i < NumRelays; i ++)
469
if (Relays[i].from.type == CUPSD_AUTH_NAME)
470
free(Relays[i].from.mask.name.name);
477
cupsdDeleteAllListeners();
479
old_remote_port = RemotePort;
486
cupsdFreeAliases(ServerAlias);
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");
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;
516
PrintcapFormat = PRINTCAP_BSD;
518
strlcpy(temp, ConfigurationFile, sizeof(temp));
519
if ((slash = strrchr(temp, '/')) != NULL)
522
cupsdSetString(&ServerRoot, temp);
524
cupsdClearString(&Classification);
525
ClassifyOverride = 0;
529
cupsdSetString(&ServerCertificate, "/Library/Keychains/System.keychain");
531
cupsdSetString(&ServerCertificate, "ssl/server.crt");
532
cupsdSetString(&ServerKey, "ssl/server.key");
533
# endif /* HAVE_CDSASSL */
534
#endif /* HAVE_SSL */
536
language = cupsLangDefault();
538
if (!strcmp(language->language, "C") || !strcmp(language->language, "POSIX"))
539
cupsdSetString(&DefaultLanguage, "en");
541
cupsdSetString(&DefaultLanguage, language->language);
543
cupsdClearString(&DefaultPaperSize);
545
cupsdSetString(&RIPCache, "8m");
547
cupsdSetString(&TempDir, NULL);
550
* Find the default user...
553
if ((user = getpwnam(CUPS_DEFAULT_USER)) != NULL)
558
* Use the (historical) NFS nobody user ID (-2 as a 16-bit twos-
559
* complement number...)
568
* Find the default group...
571
group = getgrnam(CUPS_DEFAULT_GROUP);
575
Group = group->gr_gid;
579
* Fallback to group "nobody"...
582
group = getgrnam("nobody");
586
Group = group->gr_gid;
590
* Use the (historical) NFS nobody group ID (-2 as a 16-bit twos-
591
* complement number...)
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;
607
DefaultEncryption = HTTP_ENCRYPT_REQUIRED;
608
SSLOptions = CUPSD_SSL_NONE;
609
#endif /* HAVE_SSL */
610
DirtyCleanInterval = DEFAULT_KEEPALIVE;
611
JobKillDelay = DEFAULT_TIMEOUT;
613
JobRetryInterval = 300;
618
HostNameLookups = FALSE;
619
ImplicitClasses = CUPS_DEFAULT_IMPLICIT_CLASSES;
620
ImplicitAnyClasses = FALSE;
621
HideImplicitMembers = 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;
630
MaxClientsPerHost = 0;
631
MaxLogSize = 1024 * 1024;
632
MaxPrinterHistory = 0;
634
MultipleOperationTimeout = DEFAULT_TIMEOUT;
635
ReloadTimeout = DEFAULT_KEEPALIVE;
636
RootCertDuration = 300;
637
Timeout = DEFAULT_TIMEOUT;
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;
647
Browsing = CUPS_DEFAULT_BROWSING;
648
DefaultShared = CUPS_DEFAULT_DEFAULT_SHARED;
650
cupsdSetString(&LPDConfigFile, CUPS_DEFAULT_LPD_CONFIG_FILE);
651
cupsdSetString(&SMBConfigFile, CUPS_DEFAULT_SMB_CONFIG_FILE);
653
cupsdClearString(&BrowseLocalOptions);
654
cupsdClearString(&BrowseRemoteOptions);
656
cupsdSetString(&ErrorPolicy, "stop-printer");
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 */
668
JobHistory = DEFAULT_HISTORY;
669
JobFiles = DEFAULT_FILES;
674
MaxJobsPerPrinter = 0;
675
MaxCopies = CUPS_DEFAULT_MAX_COPIES;
677
cupsdDeleteAllPolicies();
678
cupsdClearString(&DefaultPolicy);
680
#ifdef HAVE_AUTHORIZATION_H
681
cupsdClearString(&SystemGroupAuthKey);
682
#endif /* HAVE_AUTHORIZATION_H */
684
MaxSubscriptions = 100;
685
MaxSubscriptionsPerJob = 0;
686
MaxSubscriptionsPerPrinter = 0;
687
MaxSubscriptionsPerUser = 0;
688
DefaultLeaseDuration = 86400;
689
MaxLeaseDuration = 0;
692
LaunchdTimeout = DEFAULT_TIMEOUT + 10;
693
#endif /* HAVE_LAUNCHD */
697
#endif /* __APPLE__ */
700
* Setup environment variables...
706
* Read the configuration file...
709
if ((fp = cupsFileOpen(ConfigurationFile, "r")) == NULL)
712
status = read_configuration(fp);
721
cupsdLogMessage(CUPSD_LOG_INFO, "Remote access is %s.",
722
RemotePort ? "enabled" : "disabled");
725
BrowseLocalProtocols = 0; /* Disable sharing - no remote access */
728
* See if the ServerName is an IP address...
734
ServerAlias = cupsArrayNew(NULL, NULL);
736
cupsdLogMessage(CUPSD_LOG_DEBUG, "Added auto ServerAlias %s", ServerName);
740
if (gethostname(temp, sizeof(temp)))
742
cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get hostname: %s",
744
strlcpy(temp, "localhost", sizeof(temp));
747
cupsdSetString(&ServerName, temp);
750
ServerAlias = cupsArrayNew(NULL, NULL);
752
cupsdAddAlias(ServerAlias, temp);
753
cupsdLogMessage(CUPSD_LOG_DEBUG, "Added auto ServerAlias %s", temp);
757
struct hostent *host; /* Host entry to get FQDN */
759
if ((host = gethostbyname(temp)) != NULL)
761
if (strcasecmp(temp, host->h_name))
763
cupsdSetString(&ServerName, host->h_name);
764
cupsdAddAlias(ServerAlias, host->h_name);
765
cupsdLogMessage(CUPSD_LOG_DEBUG, "Added auto ServerAlias %s",
771
for (i = 0; host->h_aliases[i]; i ++)
772
if (strcasecmp(temp, host->h_aliases[i]))
774
cupsdAddAlias(ServerAlias, host->h_aliases[i]);
775
cupsdLogMessage(CUPSD_LOG_DEBUG, "Added auto ServerAlias %s",
783
* Make sure we have the base hostname added as an alias, too!
786
if ((slash = strchr(temp, '.')) != NULL)
789
cupsdAddAlias(ServerAlias, temp);
790
cupsdLogMessage(CUPSD_LOG_DEBUG, "Added auto ServerAlias %s", temp);
794
for (slash = ServerName; isdigit(*slash & 255) || *slash == '.'; slash ++);
796
ServerNameIsIP = !*slash;
799
* Make sure ServerAdmin is initialized...
803
cupsdSetStringf(&ServerAdmin, "root@%s", ServerName);
806
* Use the default system group if none was supplied in cupsd.conf...
809
if (NumSystemGroups == 0)
811
if (!parse_groups(CUPS_DEFAULT_SYSTEM_GROUPS))
814
* Find the group associated with GID 0...
821
cupsdSetString(&SystemGroups[0], group->gr_name);
823
cupsdSetString(&SystemGroups[0], "unknown");
825
SystemGroupIDs[0] = 0;
831
* Get the access control list for browsing...
834
BrowseACL = cupsdFindLocation("CUPS_INTERNAL_BROWSE_ACL");
837
* Open the system log for cupsd if necessary...
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 */
848
* Log the configuration file that was used...
851
cupsdLogMessage(CUPSD_LOG_INFO, "Loaded configuration file \"%s\"",
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
862
for (i = 0; i < NumSystemGroups; i ++)
863
if (Group == SystemGroupIDs[i])
866
if (i < NumSystemGroups)
869
* Log the error and reset the group to a safe value...
872
cupsdLogMessage(CUPSD_LOG_NOTICE,
873
"Group and SystemGroup cannot use the same groups!");
874
cupsdLogMessage(CUPSD_LOG_INFO, "Resetting Group to \"nobody\"...");
876
group = getgrnam("nobody");
880
Group = group->gr_gid;
884
* Use the (historical) NFS nobody group ID (-2 as a 16-bit twos-
885
* complement number...)
894
* Check that we have at least one listen/port line; if not, report this
895
* as an error and exit!
898
if (cupsArrayCount(Listeners) == 0)
904
cupsdLogMessage(CUPSD_LOG_EMERG,
905
"No valid Listen or Port lines were found in the "
906
"configuration file!");
912
cupsdEndProcess(getpid(), 0);
916
* Set the default locale using the language and charset...
919
cupsdSetStringf(&DefaultLocale, "%s.UTF-8", DefaultLanguage);
922
* Update all relative filenames to include the full path from ServerRoot...
925
if (DocumentRoot[0] != '/')
926
cupsdSetStringf(&DocumentRoot, "%s/%s", ServerRoot, DocumentRoot);
928
if (RequestRoot[0] != '/')
929
cupsdSetStringf(&RequestRoot, "%s/%s", ServerRoot, RequestRoot);
931
if (ServerBin[0] != '/')
932
cupsdSetStringf(&ServerBin, "%s/%s", ServerRoot, ServerBin);
934
if (StateDir[0] != '/')
935
cupsdSetStringf(&StateDir, "%s/%s", ServerRoot, StateDir);
937
if (CacheDir[0] != '/')
938
cupsdSetStringf(&CacheDir, "%s/%s", ServerRoot, CacheDir);
941
if (ServerCertificate[0] != '/')
942
cupsdSetStringf(&ServerCertificate, "%s/%s", ServerRoot, ServerCertificate);
944
if (!strncmp(ServerRoot, ServerCertificate, strlen(ServerRoot)) &&
945
cupsdCheckPermissions(ServerCertificate, NULL, 0600, RunUser, Group,
947
(FatalErrors & CUPSD_FATAL_PERMISSIONS))
950
# if defined(HAVE_LIBSSL) || defined(HAVE_GNUTLS)
951
if (ServerKey[0] != '/')
952
cupsdSetStringf(&ServerKey, "%s/%s", ServerRoot, ServerKey);
954
if (!strncmp(ServerRoot, ServerKey, strlen(ServerRoot)) &&
955
cupsdCheckPermissions(ServerKey, NULL, 0600, RunUser, Group, 0, 0) < 0 &&
956
(FatalErrors & CUPSD_FATAL_PERMISSIONS))
958
# endif /* HAVE_LIBSSL || HAVE_GNUTLS */
959
#endif /* HAVE_SSL */
962
* Make sure that directories and config files are owned and
963
* writable by the user and group in the cupsd.conf file...
966
snprintf(temp, sizeof(temp), "%s/rss", CacheDir);
968
if ((cupsdCheckPermissions(RequestRoot, NULL, 0710, RunUser,
970
cupsdCheckPermissions(CacheDir, NULL, 0775, RunUser,
972
cupsdCheckPermissions(temp, NULL, 0775, RunUser,
974
cupsdCheckPermissions(StateDir, NULL, 0755, RunUser,
976
cupsdCheckPermissions(StateDir, "certs", RunUser ? 0711 : 0511, User,
977
SystemGroupIDs[0], 1, 1) < 0 ||
978
cupsdCheckPermissions(ServerRoot, NULL, 0755, RunUser,
980
cupsdCheckPermissions(ServerRoot, "ppd", 0755, RunUser,
982
cupsdCheckPermissions(ServerRoot, "ssl", 0700, RunUser,
984
cupsdCheckPermissions(ServerRoot, "cupsd.conf", ConfigFilePerm, RunUser,
986
cupsdCheckPermissions(ServerRoot, "classes.conf", 0600, RunUser,
988
cupsdCheckPermissions(ServerRoot, "printers.conf", 0600, RunUser,
990
cupsdCheckPermissions(ServerRoot, "passwd.md5", 0600, User,
992
(FatalErrors & CUPSD_FATAL_PERMISSIONS))
996
* Update TempDir to the default if it hasn't been set already...
1001
if ((tmpdir = getenv("TMPDIR")) != NULL)
1004
* TMPDIR is defined, see if it is OK for us to use...
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!",
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);
1019
cupsdSetString(&TempDir, tmpdir);
1024
cupsdLogMessage(CUPSD_LOG_INFO, "Using default TempDir of %s/tmp...",
1026
cupsdSetStringf(&TempDir, "%s/tmp", RequestRoot);
1031
* Make sure the temporary directory has the right permissions...
1034
if (!strncmp(TempDir, RequestRoot, strlen(RequestRoot)) ||
1038
* Update ownership and permissions if the CUPS temp directory
1039
* is under the spool directory or does not exist...
1042
if (cupsdCheckPermissions(TempDir, NULL, 01770, RunUser, Group, 1, 1) < 0 &&
1043
(FatalErrors & CUPSD_FATAL_PERMISSIONS))
1048
* Update environment variables...
1054
* Update default paper size setting as needed...
1057
if (!DefaultPaperSize)
1059
#ifdef HAVE_LIBPAPER
1060
char *paper_result; /* Paper size name from libpaper */
1062
if ((paper_result = systempapername()) != NULL)
1063
cupsdSetString(&DefaultPaperSize, paper_result);
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))
1076
* These are the only locales that will default to "letter" size...
1079
cupsdSetString(&DefaultPaperSize, "Letter");
1082
cupsdSetString(&DefaultPaperSize, "A4");
1086
* Update classification setting as needed...
1089
if (Classification && !strcasecmp(Classification, "none"))
1090
cupsdClearString(&Classification);
1093
cupsdLogMessage(CUPSD_LOG_INFO, "Security set to \"%s\"", Classification);
1096
* Check the MaxClients setting, and then allocate memory for it...
1099
if (MaxClients > (MaxFDs / 3) || MaxClients <= 0)
1102
cupsdLogMessage(CUPSD_LOG_INFO,
1103
"MaxClients limited to 1/3 (%d) of the file descriptor "
1105
MaxFDs / 3, MaxFDs);
1107
MaxClients = MaxFDs / 3;
1110
cupsdLogMessage(CUPSD_LOG_INFO, "Configured for up to %d clients.",
1114
* Check the MaxActiveJobs setting; limit to 1/3 the available
1115
* file descriptors, since we need a pipe for each job...
1118
if (MaxActiveJobs > (MaxFDs / 3))
1119
MaxActiveJobs = MaxFDs / 3;
1122
* Update the MaxClientsPerHost value, as needed...
1125
if (MaxClientsPerHost <= 0)
1126
MaxClientsPerHost = MaxClients;
1128
if (MaxClientsPerHost > MaxClients)
1129
MaxClientsPerHost = MaxClients;
1131
cupsdLogMessage(CUPSD_LOG_INFO,
1132
"Allowing up to %d client connections per host.",
1136
* Make sure that BrowseTimeout is at least twice the interval...
1139
if (BrowseTimeout < (2 * BrowseInterval) || BrowseTimeout <= 0)
1141
cupsdLogMessage(CUPSD_LOG_ALERT, "Invalid BrowseTimeout value %d!",
1145
BrowseTimeout = BrowseInterval * 2;
1147
BrowseTimeout = DEFAULT_TIMEOUT;
1149
cupsdLogMessage(CUPSD_LOG_ALERT, "Reset BrowseTimeout to %d!",
1154
* Update the default policy, as needed...
1158
DefaultPolicyPtr = cupsdFindPolicy(DefaultPolicy);
1160
DefaultPolicyPtr = NULL;
1162
if (!DefaultPolicyPtr)
1164
cupsd_location_t *po; /* New policy operation */
1168
cupsdLogMessage(CUPSD_LOG_ERROR, "Default policy \"%s\" not found!",
1171
cupsdSetString(&DefaultPolicy, "default");
1173
if ((DefaultPolicyPtr = cupsdFindPolicy("default")) != NULL)
1174
cupsdLogMessage(CUPSD_LOG_INFO,
1175
"Using policy \"default\" as the default!");
1178
cupsdLogMessage(CUPSD_LOG_INFO,
1179
"Creating CUPS default administrative policy:");
1181
DefaultPolicyPtr = p = cupsdAddPolicy("default");
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");
1188
po = cupsdAddPolicyOp(p, NULL, IPP_CREATE_JOB);
1189
po->order_type = CUPSD_AUTH_ALLOW;
1191
cupsdAddPolicyOp(p, po, IPP_PRINT_JOB);
1192
cupsdAddPolicyOp(p, po, IPP_PRINT_URI);
1193
cupsdAddPolicyOp(p, po, IPP_VALIDATE_JOB);
1195
cupsdLogMessage(CUPSD_LOG_INFO, "</Limit>");
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");
1207
po = cupsdAddPolicyOp(p, NULL, IPP_SEND_DOCUMENT);
1208
po->order_type = CUPSD_AUTH_ALLOW;
1209
po->level = CUPSD_AUTH_USER;
1211
cupsdAddName(po, "@OWNER");
1212
cupsdAddName(po, "@SYSTEM");
1213
cupsdLogMessage(CUPSD_LOG_INFO, "Require user @OWNER @SYSTEM");
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);
1234
cupsdLogMessage(CUPSD_LOG_INFO, "</Limit>");
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");
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;
1254
cupsdAddName(po, "@SYSTEM");
1255
cupsdLogMessage(CUPSD_LOG_INFO, "Require user @SYSTEM");
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);
1279
cupsdLogMessage(CUPSD_LOG_INFO, "</Limit>");
1281
cupsdLogMessage(CUPSD_LOG_INFO, "<Limit All>");
1282
cupsdLogMessage(CUPSD_LOG_INFO, "Order Deny,Allow");
1284
po = cupsdAddPolicyOp(p, NULL, IPP_ANY_OPERATION);
1285
po->order_type = CUPSD_AUTH_ALLOW;
1287
cupsdLogMessage(CUPSD_LOG_INFO, "</Limit>");
1288
cupsdLogMessage(CUPSD_LOG_INFO, "</Policy>");
1292
cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdReadConfiguration: NumPolicies=%d",
1293
cupsArrayCount(Policies));
1294
for (i = 0, p = (cupsd_policy_t *)cupsArrayFirst(Policies);
1296
i ++, p = (cupsd_policy_t *)cupsArrayNext(Policies))
1297
cupsdLogMessage(CUPSD_LOG_DEBUG2,
1298
"cupsdReadConfiguration: Policies[%d]=\"%s\"", i, p->name);
1301
* If we are doing a full reload or the server root has changed, flush
1302
* the jobs, printers, etc. and start from scratch...
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))
1310
mime_type_t *type; /* Current type */
1311
char mimetype[MIME_MAX_SUPER + MIME_MAX_TYPE];
1312
/* MIME type name */
1315
cupsdLogMessage(CUPSD_LOG_INFO, "Full reload is required.");
1318
* Free all memory...
1321
cupsdDeleteAllSubscriptions();
1323
cupsdDeleteAllPrinters();
1325
DefaultPrinter = NULL;
1327
if (MimeDatabase != NULL)
1328
mimeDelete(MimeDatabase);
1332
for (i = 0; i < NumMimeTypes; i ++)
1333
_cupsStrFree(MimeTypes[i]);
1339
* Read the MIME type and conversion database...
1342
snprintf(temp, sizeof(temp), "%s/filter", ServerBin);
1343
snprintf(mimedir, sizeof(mimedir), "%s/mime", DataDir);
1345
MimeDatabase = mimeLoadTypes(NULL, mimedir);
1346
MimeDatabase = mimeLoadTypes(MimeDatabase, ServerRoot);
1347
MimeDatabase = mimeLoadFilters(MimeDatabase, mimedir, temp);
1348
MimeDatabase = mimeLoadFilters(MimeDatabase, ServerRoot, temp);
1352
cupsdLogMessage(CUPSD_LOG_EMERG,
1353
"Unable to load MIME database from \"%s\" or \"%s\"!",
1354
mimedir, ServerRoot);
1355
if (FatalErrors & CUPSD_FATAL_CONFIG)
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));
1365
* Create a list of MIME types for the document-format-supported
1369
NumMimeTypes = mimeNumTypes(MimeDatabase);
1370
if (!mimeType(MimeDatabase, "application", "octet-stream"))
1373
if ((MimeTypes = calloc(NumMimeTypes, sizeof(const char *))) == NULL)
1375
cupsdLogMessage(CUPSD_LOG_ERROR,
1376
"Unable to allocate memory for %d MIME types!",
1382
for (i = 0, type = mimeFirstType(MimeDatabase);
1384
i ++, type = mimeNextType(MimeDatabase))
1386
snprintf(mimetype, sizeof(mimetype), "%s/%s", type->super, type->type);
1388
MimeTypes[i] = _cupsStrAlloc(mimetype);
1391
if (i < NumMimeTypes)
1392
MimeTypes[i] = _cupsStrAlloc("application/octet-stream");
1395
if (LogLevel == CUPSD_LOG_DEBUG2)
1397
mime_filter_t *filter; /* Current filter */
1400
for (type = mimeFirstType(MimeDatabase);
1402
type = mimeNextType(MimeDatabase))
1403
cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdReadConfiguration: type %s/%s",
1404
type->super, type->type);
1406
for (filter = mimeFirstFilter(MimeDatabase);
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);
1420
snprintf(temp, sizeof(temp), "%s/banners", DataDir);
1421
cupsdLoadBanners(temp);
1424
* Load printers and classes...
1427
cupsdLoadAllPrinters();
1428
cupsdLoadAllClasses();
1429
cupsdLoadRemoteCache();
1431
cupsdCreateCommonData();
1434
* Update the printcap file as needed...
1437
if (Printcap && *Printcap && access(Printcap, 0))
1438
cupsdWritePrintcap();
1441
* Load queued jobs...
1447
* Load subscriptions...
1450
cupsdLoadAllSubscriptions();
1452
cupsdLogMessage(CUPSD_LOG_INFO, "Full reload complete.");
1457
* Not a full reload, so recreate the common printer attributes...
1460
cupsdCreateCommonData();
1463
* Update all printers as needed...
1466
cupsdUpdatePrinters();
1467
cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
1469
cupsdLogMessage(CUPSD_LOG_INFO, "Partial reload complete.");
1473
* Reset the reload state...
1476
NeedReload = RELOAD_NONE;
1478
cupsdClearString(&old_serverroot);
1479
cupsdClearString(&old_requestroot);
1486
* 'get_address()' - Get an address + port number from a line.
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 */
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 */
1501
* Check for an empty value...
1506
cupsdLogMessage(CUPSD_LOG_ERROR, "Bad (empty) address!");
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...
1515
strlcpy(buffer, value, sizeof(buffer));
1517
if ((portname = strrchr(buffer, ':')) != NULL && !strchr(portname, ']'))
1524
for (portname = buffer; isdigit(*portname & 255); portname ++);
1529
* Use the default port...
1532
sprintf(defpname, "%d", defport);
1533
portname = defpname;
1539
* The buffer contains just a port number...
1547
if (hostname && !strcmp(hostname, "*"))
1551
* Now lookup the address using httpAddrGetList()...
1554
if ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, portname)) == NULL)
1555
cupsdLogMessage(CUPSD_LOG_ERROR, "Hostname lookup for \"%s\" failed!",
1556
hostname ? hostname : "(nil)");
1563
* 'get_addr_and_mask()' - Get an IP address and netmask.
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 */
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 */
1581
* Get the address...
1584
ip[0] = ip[1] = ip[2] = ip[3] = 0x00000000;
1585
mask[0] = mask[1] = mask[2] = mask[3] = 0xffffffff;
1587
if ((maskval = strchr(value, '/')) != NULL)
1590
maskval = value + strlen(value);
1594
* Check for an IPv6 address...
1600
* Parse hexadecimal IPv6 address...
1605
for (i = 0, ptr = value + 1; *ptr && i < 8; i ++)
1609
else if (!strncmp(ptr, "::", 2))
1611
for (ptr2 = strchr(ptr + 2, ':'), j = 0;
1613
ptr2 = strchr(ptr2 + 1, ':'), j ++);
1618
else if (isxdigit(*ptr & 255))
1620
ipval = strtoul(ptr, (char **)&ptr, 16);
1628
ip[i / 2] |= ipval << 16;
1642
if (*ptr && *ptr != '/')
1646
#endif /* AF_INET6 */
1649
* Parse dotted-decimal IPv4 address...
1652
unsigned val[4]; /* IPv4 address values */
1656
ipcount = sscanf(value, "%u.%u.%u.%u", val + 0, val + 1, val + 2, val + 3);
1659
* Range check the IP numbers...
1662
for (i = 0; i < ipcount; i ++)
1667
* Make sure the trailing values are zeroed, as some C libraries like
1668
* glibc apparently like to fill the unused arguments with garbage...
1671
for (i = ipcount; i < 4; i ++)
1675
* Merge everything into a 32-bit IPv4 address in ip[3]...
1678
ip[3] = (((((val[0] << 8) | val[1]) << 8) | val[2]) << 8) | val[3];
1681
mask[3] = (0xffffffff << (32 - 8 * ipcount)) & 0xffffffff;
1687
* Get the netmask value(s)...
1690
memset(mask, 0, sizeof(unsigned) * 4);
1692
if (strchr(maskval, '.'))
1695
* Get dotted-decimal mask...
1698
if (family != AF_INET)
1701
if (sscanf(maskval, "%u.%u.%u.%u", mask + 0, mask + 1, mask + 2, mask + 3) != 4)
1704
mask[3] |= ((((mask[0] << 8) | mask[1]) << 8) | mask[2]) << 8;
1705
mask[0] = mask[1] = mask[2] = 0;
1710
* Get address/bits format...
1716
if (family == AF_INET6)
1724
mask[0] = 0xffffffff;
1726
mask[0] = (0xffffffff << (i - 96)) & 0xffffffff;
1729
mask[1] = 0xffffffff;
1733
mask[1] = (0xffffffff << (i - 64)) & 0xffffffff;
1736
mask[2] = 0xffffffff;
1740
mask[2] = (0xffffffff << (i - 32)) & 0xffffffff;
1743
mask[3] = 0xffffffff;
1747
mask[3] = (0xffffffff << i) & 0xffffffff;
1750
#endif /* AF_INET6 */
1755
mask[0] = 0xffffffff;
1756
mask[1] = 0xffffffff;
1757
mask[2] = 0xffffffff;
1760
mask[3] = (0xffffffff << (32 - i)) & 0xffffffff;
1762
mask[3] = 0xffffffff;
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],
1774
* Check for a valid netmask; no fallback like in CUPS 1.1.x!
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)
1788
* 'parse_aaa()' - Parse authentication, authorization, and access control lines.
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 */
1797
char *valptr; /* Pointer into value */
1798
unsigned ip[4], /* IP address components */
1799
mask[4]; /* IP netmask components */
1802
if (!strcasecmp(line, "Encryption"))
1805
* "Encryption xxx" - set required encryption level...
1808
if (!strcasecmp(value, "never"))
1809
loc->encryption = HTTP_ENCRYPT_NEVER;
1810
else if (!strcasecmp(value, "always"))
1812
cupsdLogMessage(CUPSD_LOG_ERROR,
1813
"Encryption value \"%s\" on line %d is invalid in this "
1814
"context. Using \"required\" instead.", value, linenum);
1816
loc->encryption = HTTP_ENCRYPT_REQUIRED;
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;
1824
cupsdLogMessage(CUPSD_LOG_ERROR,
1825
"Unknown Encryption value %s on line %d.", value, linenum);
1829
else if (!strcasecmp(line, "Order"))
1832
* "Order Deny,Allow" or "Order Allow,Deny"...
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;
1841
cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown Order value %s on line %d.",
1846
else if (!strcasecmp(line, "Allow") || !strcasecmp(line, "Deny"))
1849
* Allow [From] host/ip...
1850
* Deny [From] host/ip...
1855
if (!strncasecmp(value, "from", 4))
1858
* Strip leading "from"...
1863
while (isspace(*value & 255))
1871
* Find the end of the value...
1874
for (valptr = value; *valptr && !isspace(*valptr & 255); valptr ++);
1876
while (isspace(*valptr & 255))
1880
* Figure out what form the allow/deny address takes:
1891
* nnn.nnn.nnn.nnn/mm
1892
* nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
1895
if (!strcasecmp(value, "all"))
1901
if (!strcasecmp(line, "Allow"))
1902
cupsdAllowIP(loc, zeros, zeros);
1904
cupsdDenyIP(loc, zeros, zeros);
1906
else if (!strcasecmp(value, "none"))
1912
if (!strcasecmp(line, "Allow"))
1913
cupsdAllowIP(loc, ones, zeros);
1915
cupsdDenyIP(loc, ones, zeros);
1918
else if (value[0] == '*' || value[0] == '.' ||
1919
(!isdigit(value[0] & 255) && value[0] != '['))
1921
else if (value[0] == '*' || value[0] == '.' || !isdigit(value[0] & 255))
1922
#endif /* AF_INET6 */
1925
* Host or domain name...
1928
if (value[0] == '*')
1931
if (!strcasecmp(line, "Allow"))
1932
cupsdAllowHost(loc, value);
1934
cupsdDenyHost(loc, value);
1939
* One of many IP address forms...
1942
if (!get_addr_and_mask(value, ip, mask))
1944
cupsdLogMessage(CUPSD_LOG_ERROR, "Bad netmask value %s on line %d.",
1949
if (!strcasecmp(line, "Allow"))
1950
cupsdAllowIP(loc, ip, mask);
1952
cupsdDenyIP(loc, ip, mask);
1956
* Advance to next value...
1962
else if (!strcasecmp(line, "AuthType"))
1965
* AuthType {none,basic,digest,basicdigest,negotiate,default}
1968
if (!strcasecmp(value, "none"))
1970
loc->type = CUPSD_AUTH_NONE;
1971
loc->level = CUPSD_AUTH_ANON;
1973
else if (!strcasecmp(value, "basic"))
1975
loc->type = CUPSD_AUTH_BASIC;
1977
if (loc->level == CUPSD_AUTH_ANON)
1978
loc->level = CUPSD_AUTH_USER;
1980
else if (!strcasecmp(value, "digest"))
1982
loc->type = CUPSD_AUTH_DIGEST;
1984
if (loc->level == CUPSD_AUTH_ANON)
1985
loc->level = CUPSD_AUTH_USER;
1987
else if (!strcasecmp(value, "basicdigest"))
1989
loc->type = CUPSD_AUTH_BASICDIGEST;
1991
if (loc->level == CUPSD_AUTH_ANON)
1992
loc->level = CUPSD_AUTH_USER;
1994
else if (!strcasecmp(value, "default"))
1996
loc->type = CUPSD_AUTH_DEFAULT;
1998
if (loc->level == CUPSD_AUTH_ANON)
1999
loc->level = CUPSD_AUTH_USER;
2002
else if (!strcasecmp(value, "negotiate"))
2004
loc->type = CUPSD_AUTH_NEGOTIATE;
2006
if (loc->level == CUPSD_AUTH_ANON)
2007
loc->level = CUPSD_AUTH_USER;
2009
#endif /* HAVE_GSSAPI */
2012
cupsdLogMessage(CUPSD_LOG_WARN,
2013
"Unknown authorization type %s on line %d.",
2018
else if (!strcasecmp(line, "AuthClass"))
2021
* AuthClass anonymous, user, system, group
2024
if (!strcasecmp(value, "anonymous"))
2026
loc->type = CUPSD_AUTH_NONE;
2027
loc->level = CUPSD_AUTH_ANON;
2029
cupsdLogMessage(CUPSD_LOG_WARN,
2030
"\"AuthClass %s\" is deprecated; consider removing "
2034
else if (!strcasecmp(value, "user"))
2036
loc->level = CUPSD_AUTH_USER;
2038
cupsdLogMessage(CUPSD_LOG_WARN,
2039
"\"AuthClass %s\" is deprecated; consider using "
2040
"\"Require valid-user\" on line %d.",
2043
else if (!strcasecmp(value, "group"))
2045
loc->level = CUPSD_AUTH_GROUP;
2047
cupsdLogMessage(CUPSD_LOG_WARN,
2048
"\"AuthClass %s\" is deprecated; consider using "
2049
"\"Require user @groupname\" on line %d.",
2052
else if (!strcasecmp(value, "system"))
2054
loc->level = CUPSD_AUTH_GROUP;
2056
cupsdAddName(loc, "@SYSTEM");
2058
cupsdLogMessage(CUPSD_LOG_WARN,
2059
"\"AuthClass %s\" is deprecated; consider using "
2060
"\"Require user @SYSTEM\" on line %d.",
2065
cupsdLogMessage(CUPSD_LOG_WARN,
2066
"Unknown authorization class %s on line %d.",
2071
else if (!strcasecmp(line, "AuthGroupName"))
2073
cupsdAddName(loc, value);
2075
cupsdLogMessage(CUPSD_LOG_WARN,
2076
"\"AuthGroupName %s\" directive is deprecated; consider "
2077
"using \"Require user @%s\" on line %d.",
2078
value, value, linenum);
2080
else if (!strcasecmp(line, "Require"))
2083
* Apache synonym for AuthClass and AuthGroupName...
2087
* Require valid-user
2088
* Require group names
2089
* Require user names
2092
for (valptr = value; !isspace(*valptr & 255) && *valptr; valptr ++);
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;
2104
cupsdLogMessage(CUPSD_LOG_WARN, "Unknown Require type %s on line %d.",
2110
* Get the list of names from the line...
2113
for (value = valptr; *value;)
2115
while (isspace(*value & 255))
2118
#ifdef HAVE_AUTHORIZATION_H
2119
if (!strncmp(value, "@AUTHKEY(", 9))
2122
* Grab "@AUTHKEY(name)" value...
2125
for (valptr = value + 9; *valptr != ')' && *valptr; valptr ++);
2131
#endif /* HAVE_AUTHORIZATION_H */
2132
if (*value == '\"' || *value == '\'')
2135
* Grab quoted name...
2138
for (valptr = value + 1; *valptr != *value && *valptr; valptr ++);
2145
* Grab literal name.
2148
for (valptr = value; !isspace(*valptr & 255) && *valptr; valptr ++);
2154
cupsdAddName(loc, value);
2156
for (value = valptr; isspace(*value & 255); value ++);
2159
else if (!strcasecmp(line, "Satisfy"))
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;
2167
cupsdLogMessage(CUPSD_LOG_WARN, "Unknown Satisfy value %s on line %d.",
2180
* 'parse_fatal_errors()' - Parse FatalErrors values in a string.
2183
static int /* O - FatalErrors bits */
2184
parse_fatal_errors(const char *s) /* I - FatalErrors string */
2186
int fatal; /* FatalErrors bits */
2187
char value[1024], /* Value string */
2188
*valstart, /* Pointer into value */
2189
*valend; /* End of value */
2193
* Empty FatalErrors line yields NULL pointer...
2197
return (CUPSD_FATAL_NONE);
2200
* Loop through the value string,...
2203
strlcpy(value, s, sizeof(value));
2205
fatal = CUPSD_FATAL_NONE;
2207
for (valstart = value; *valstart;)
2210
* Get the current space/comma-delimited kind name...
2213
for (valend = valstart; *valend; valend ++)
2214
if (isspace(*valend & 255) || *valend == ',')
2221
* Add the error to the bitmask...
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);
2250
for (valstart = valend; *valstart; valstart ++)
2251
if (!isspace(*valstart & 255) || *valstart != ',')
2260
* 'parse_groups()' - Parse system group names in a string.
2263
static int /* O - 1 on success, 0 on failure */
2264
parse_groups(const char *s) /* I - Space-delimited groups */
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 */
2275
* Make a copy of the string and parse out the groups...
2278
strlcpy(value, s, sizeof(value));
2283
while (*valstart && NumSystemGroups < MAX_SYSTEM_GROUPS)
2285
if (*valstart == '\'' || *valstart == '\"')
2288
* Scan quoted name...
2291
quote = *valstart++;
2293
for (valend = valstart; *valend; valend ++)
2294
if (*valend == quote)
2300
* Scan space or comma-delimited name...
2303
for (valend = valstart; *valend; valend ++)
2304
if (isspace(*valend) || *valend == ',')
2311
group = getgrnam(valstart);
2314
cupsdSetString(SystemGroups + NumSystemGroups, valstart);
2315
SystemGroupIDs[NumSystemGroups] = group->gr_gid;
2326
while (*valstart == ',' || isspace(*valstart))
2335
* 'parse_protocols()' - Parse browse protocols in a string.
2338
static int /* O - Browse protocol bits */
2339
parse_protocols(const char *s) /* I - Space-delimited protocols */
2341
int protocols; /* Browse protocol bits */
2342
char value[1024], /* Value string */
2343
*valstart, /* Pointer into value */
2344
*valend; /* End of value */
2348
* Empty protocol line yields NULL pointer...
2355
* Loop through the value string,...
2358
strlcpy(value, s, sizeof(value));
2362
for (valstart = value; *valstart;)
2365
* Get the current space/comma-delimited protocol name...
2368
for (valend = valstart; *valend; valend ++)
2369
if (isspace(*valend & 255) || *valend == ',')
2376
* Add the protocol to the bitmask...
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);
2399
for (valstart = valend; *valstart; valstart ++)
2400
if (!isspace(*valstart & 255) || *valstart != ',')
2409
* 'read_configuration()' - Read a configuration file.
2412
static int /* O - 1 on success, 0 on failure */
2413
read_configuration(cups_file_t *fp) /* I - File to read from */
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 */
2441
* Loop through each line in the file...
2446
while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
2449
* Decode the directive...
2452
if (!strcasecmp(line, "Include") && value)
2458
if (value[0] == '/')
2459
strlcpy(incname, value, sizeof(incname));
2461
snprintf(incname, sizeof(incname), "%s/%s", ServerRoot, value);
2463
if ((incfile = cupsFileOpen(incname, "rb")) == NULL)
2464
cupsdLogMessage(CUPSD_LOG_ERROR,
2465
"Unable to include config file \"%s\" - %s",
2466
incname, strerror(errno));
2469
read_configuration(incfile);
2470
cupsFileClose(incfile);
2473
else if (!strcasecmp(line, "<Location") && value)
2479
linenum = read_location(fp, value, linenum);
2483
else if (!strcasecmp(line, "<Policy") && value)
2489
linenum = read_policy(fp, value, linenum);
2493
else if (!strcasecmp(line, "FatalErrors"))
2494
FatalErrors = parse_fatal_errors(value);
2495
else if (!strcasecmp(line, "FaxRetryInterval") && value)
2497
JobRetryInterval = atoi(value);
2498
cupsdLogMessage(CUPSD_LOG_WARN,
2499
"FaxRetryInterval is deprecated; use "
2500
"JobRetryInterval on line %d.", linenum);
2502
else if (!strcasecmp(line, "FaxRetryLimit") && value)
2504
JobRetryLimit = atoi(value);
2505
cupsdLogMessage(CUPSD_LOG_WARN,
2506
"FaxRetryLimit is deprecated; use "
2507
"JobRetryLimit on line %d.", linenum);
2509
else if (!strcasecmp(line, "Port") || !strcasecmp(line, "Listen")
2511
|| !strcasecmp(line, "SSLPort") || !strcasecmp(line, "SSLListen")
2512
#endif /* HAVE_SSL */
2516
* Add listening address(es) to the list...
2519
cupsd_listener_t *lis; /* New listeners array */
2523
* Get the address list...
2526
addrlist = get_address(value, IPP_PORT);
2530
cupsdLogMessage(CUPSD_LOG_ERROR, "Bad %s address %s at line %d.", line,
2536
* Add each address...
2539
for (addr = addrlist; addr; addr = addr->next)
2542
* See if this address is already present...
2545
for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
2547
lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
2548
if (httpAddrEqual(&(addr->addr), &(lis->address)) &&
2549
_httpAddrPort(&(addr->addr)) == _httpAddrPort(&(lis->address)))
2554
httpAddrString(&lis->address, temp, sizeof(temp));
2555
cupsdLogMessage(CUPSD_LOG_WARN,
2556
"Duplicate listen address \"%s\" ignored!", temp);
2561
* Allocate another listener...
2565
Listeners = cupsArrayNew(NULL, NULL);
2569
cupsdLogMessage(CUPSD_LOG_ERROR,
2570
"Unable to allocate %s at line %d - %s.",
2571
line, linenum, strerror(errno));
2575
if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL)
2577
cupsdLogMessage(CUPSD_LOG_ERROR,
2578
"Unable to allocate %s at line %d - %s.",
2579
line, linenum, strerror(errno));
2583
cupsArrayAdd(Listeners, lis);
2586
* Copy the current address and log it...
2589
memcpy(&(lis->address), &(addr->addr), sizeof(lis->address));
2593
if (!strcasecmp(line, "SSLPort") || !strcasecmp(line, "SSLListen"))
2594
lis->encryption = HTTP_ENCRYPT_ALWAYS;
2595
#endif /* HAVE_SSL */
2597
httpAddrString(&lis->address, temp, sizeof(temp));
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));
2604
#endif /* AF_INET6 */
2606
if (lis->address.addr.sa_family == AF_LOCAL)
2607
cupsdLogMessage(CUPSD_LOG_INFO, "Listening to %s (Domain)", temp);
2609
#endif /* AF_LOCAL */
2610
cupsdLogMessage(CUPSD_LOG_INFO, "Listening to %s:%d (IPv4)", temp,
2611
ntohs(lis->address.ipv4.sin_port));
2613
if (!httpAddrLocalhost(&(lis->address)))
2616
if (lis->address.addr.sa_family == AF_INET6)
2617
RemotePort = ntohs(lis->address.ipv6.sin6_port);
2619
#endif /* AF_INET6 */
2620
RemotePort = ntohs(lis->address.ipv4.sin_port);
2628
httpAddrFreeList(addrlist);
2630
else if (!strcasecmp(line, "BrowseAddress") && value)
2633
* Add a browse address to the list...
2636
cupsd_dirsvc_addr_t *dira; /* New browse address array */
2639
if (NumBrowsers == 0)
2640
dira = malloc(sizeof(cupsd_dirsvc_addr_t));
2642
dira = realloc(Browsers, (NumBrowsers + 1) * sizeof(cupsd_dirsvc_addr_t));
2646
cupsdLogMessage(CUPSD_LOG_ERROR,
2647
"Unable to allocate BrowseAddress at line %d - %s.",
2648
linenum, strerror(errno));
2653
dira += NumBrowsers;
2655
memset(dira, 0, sizeof(cupsd_dirsvc_addr_t));
2657
if (!strcasecmp(value, "@LOCAL"))
2660
* Send browse data to all local interfaces...
2663
strcpy(dira->iface, "*");
2666
else if (!strncasecmp(value, "@IF(", 4))
2669
* Send browse data to the named interface...
2672
strlcpy(dira->iface, value + 4, sizeof(Browsers[0].iface));
2674
ptr = dira->iface + strlen(dira->iface) - 1;
2680
else if ((addrlist = get_address(value, BrowsePort)) != NULL)
2683
* Only IPv4 addresses are supported...
2686
for (addr = addrlist; addr; addr = addr->next)
2687
if (addr->addr.addr.sa_family == AF_INET)
2692
memcpy(&(dira->to), &(addrlist->addr), sizeof(dira->to));
2693
httpAddrString(&(dira->to), temp, sizeof(temp));
2695
cupsdLogMessage(CUPSD_LOG_INFO,
2696
"Sending browsing info to %s:%d (IPv4)",
2697
temp, ntohs(dira->to.ipv4.sin_port));
2702
cupsdLogMessage(CUPSD_LOG_ERROR, "Bad BrowseAddress %s at line %d.",
2705
httpAddrFreeList(addrlist);
2708
cupsdLogMessage(CUPSD_LOG_ERROR, "Bad BrowseAddress %s at line %d.",
2711
else if (!strcasecmp(line, "BrowseOrder") && value)
2714
* "BrowseOrder Deny,Allow" or "BrowseOrder Allow,Deny"...
2717
if ((location = cupsdFindLocation("CUPS_INTERNAL_BROWSE_ACL")) == NULL)
2718
location = cupsdAddLocation("CUPS_INTERNAL_BROWSE_ACL");
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;
2728
cupsdLogMessage(CUPSD_LOG_ERROR,
2729
"Unknown BrowseOrder value %s on line %d.",
2732
else if (!strcasecmp(line, "BrowseProtocols") ||
2733
!strcasecmp(line, "BrowseLocalProtocols") ||
2734
!strcasecmp(line, "BrowseRemoteProtocols"))
2737
* "BrowseProtocols name [... name]"
2738
* "BrowseLocalProtocols name [... name]"
2739
* "BrowseRemoteProtocols name [... name]"
2742
int protocols = parse_protocols(value);
2746
cupsdLogMessage(CUPSD_LOG_ERROR,
2747
"Unknown browse protocol \"%s\" on line %d.",
2752
if (strcasecmp(line, "BrowseLocalProtocols"))
2753
BrowseRemoteProtocols = protocols;
2754
if (strcasecmp(line, "BrowseRemoteProtocols"))
2755
BrowseLocalProtocols = protocols;
2757
else if ((!strcasecmp(line, "BrowseAllow") ||
2758
!strcasecmp(line, "BrowseDeny")) && value)
2761
* BrowseAllow [From] host/ip...
2762
* BrowseDeny [From] host/ip...
2765
if ((location = cupsdFindLocation("CUPS_INTERNAL_BROWSE_ACL")) == NULL)
2766
location = cupsdAddLocation("CUPS_INTERNAL_BROWSE_ACL");
2768
if (location == NULL)
2769
cupsdLogMessage(CUPSD_LOG_ERROR,
2770
"Unable to initialize browse access control list!");
2775
if (!strncasecmp(value, "from", 4))
2778
* Strip leading "from"...
2783
while (isspace(*value & 255))
2791
* Find the end of the value...
2794
for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++);
2796
while (isspace(*valueptr & 255))
2800
* Figure out what form the allow/deny address takes:
2811
* nnn.nnn.nnn.nnn/mm
2812
* nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
2815
if (!strcasecmp(value, "all"))
2821
if (!strcasecmp(line, "BrowseAllow"))
2822
cupsdAllowIP(location, zeros, zeros);
2824
cupsdDenyIP(location, zeros, zeros);
2826
else if (!strcasecmp(value, "none"))
2832
if (!strcasecmp(line, "BrowseAllow"))
2833
cupsdAllowIP(location, ones, zeros);
2835
cupsdDenyIP(location, ones, zeros);
2838
else if (value[0] == '*' || value[0] == '.' ||
2839
(!isdigit(value[0] & 255) && value[0] != '['))
2841
else if (value[0] == '*' || value[0] == '.' || !isdigit(value[0] & 255))
2842
#endif /* AF_INET6 */
2845
* Host or domain name...
2848
if (value[0] == '*')
2851
if (!strcasecmp(line, "BrowseAllow"))
2852
cupsdAllowHost(location, value);
2854
cupsdDenyHost(location, value);
2859
* One of many IP address forms...
2862
if (!get_addr_and_mask(value, ip, mask))
2864
cupsdLogMessage(CUPSD_LOG_ERROR, "Bad netmask value %s on line %d.",
2869
if (!strcasecmp(line, "BrowseAllow"))
2870
cupsdAllowIP(location, ip, mask);
2872
cupsdDenyIP(location, ip, mask);
2876
* Advance to next value...
2883
else if (!strcasecmp(line, "BrowseRelay") && value)
2886
* BrowseRelay [from] source [to] destination
2890
relay = malloc(sizeof(cupsd_dirsvc_relay_t));
2892
relay = realloc(Relays, (NumRelays + 1) * sizeof(cupsd_dirsvc_relay_t));
2896
cupsdLogMessage(CUPSD_LOG_ERROR,
2897
"Unable to allocate BrowseRelay at line %d - %s.",
2898
linenum, strerror(errno));
2905
memset(relay, 0, sizeof(cupsd_dirsvc_relay_t));
2907
if (!strncasecmp(value, "from ", 5))
2910
* Strip leading "from"...
2915
while (isspace(*value))
2920
* Figure out what form the from address takes:
2929
* nnn.nnn.nnn.nnn/mm
2930
* nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
2934
if (value[0] == '*' || value[0] == '.' ||
2935
(!isdigit(value[0] & 255) && value[0] != '['))
2937
if (value[0] == '*' || value[0] == '.' || !isdigit(value[0] & 255))
2938
#endif /* AF_INET6 */
2941
* Host or domain name...
2944
if (value[0] == '*')
2947
strlcpy(temp, value, sizeof(temp));
2948
if ((ptr = strchr(temp, ' ')) != NULL)
2951
relay->from.type = CUPSD_AUTH_NAME;
2953
if ((relay->from.mask.name.name = strdup(temp)) == NULL)
2955
cupsdLogMessage(CUPSD_LOG_ERROR,
2956
"Unable to allocate BrowseRelay name at line %d - %s.",
2957
linenum, strerror(errno));
2961
relay->from.mask.name.length = strlen(temp);
2966
* One of many IP address forms...
2969
if (!get_addr_and_mask(value, ip, mask))
2971
cupsdLogMessage(CUPSD_LOG_ERROR, "Bad netmask value %s on line %d.",
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));
2984
* Skip value and trailing whitespace...
2987
for (; *value; value ++)
2988
if (isspace(*value))
2991
while (isspace(*value))
2994
if (!strncasecmp(value, "to ", 3))
2997
* Strip leading "to"...
3002
while (isspace(*value))
3007
* Get "to" address and port...
3010
if ((addrlist = get_address(value, BrowsePort)) != NULL)
3013
* Only IPv4 addresses are supported...
3016
for (addr = addrlist; addr; addr = addr->next)
3017
if (addr->addr.addr.sa_family == AF_INET)
3022
memcpy(&(relay->to), &(addrlist->addr), sizeof(relay->to));
3024
httpAddrString(&(relay->to), temp, sizeof(temp));
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);
3037
strlcpy(temp2, relay->from.mask.name.name, sizeof(temp2));
3039
cupsdLogMessage(CUPSD_LOG_INFO, "Relaying from %s to %s:%d (IPv4)",
3040
temp2, temp, ntohs(relay->to.ipv4.sin_port));
3045
cupsdLogMessage(CUPSD_LOG_ERROR, "Bad relay address %s at line %d.",
3048
httpAddrFreeList(addrlist);
3052
if (relay->from.type == CUPSD_AUTH_NAME)
3053
free(relay->from.mask.name.name);
3055
cupsdLogMessage(CUPSD_LOG_ERROR, "Bad relay address %s at line %d.",
3059
else if (!strcasecmp(line, "BrowsePoll") && value)
3062
* BrowsePoll address[:port]
3065
char *portname; /* Port name */
3066
int portnum; /* Port number */
3067
struct servent *service; /* Service */
3071
* Extract the port name from the address...
3074
if ((portname = strrchr(value, ':')) != NULL && !strchr(portname, ']'))
3078
if (isdigit(*portname & 255))
3079
portnum = atoi(portname);
3080
else if ((service = getservbyname(portname, NULL)) != NULL)
3081
portnum = ntohs(service->s_port);
3084
cupsdLogMessage(CUPSD_LOG_ERROR, "Lookup of service \"%s\" failed!",
3090
portnum = ippPort();
3093
* Add the poll entry...
3097
pollp = malloc(sizeof(cupsd_dirsvc_poll_t));
3099
pollp = realloc(Polled, (NumPolled + 1) * sizeof(cupsd_dirsvc_poll_t));
3103
cupsdLogMessage(CUPSD_LOG_ERROR,
3104
"Unable to allocate BrowsePoll at line %d - %s.",
3105
linenum, strerror(errno));
3113
memset(pollp, 0, sizeof(cupsd_dirsvc_poll_t));
3115
strlcpy(pollp->hostname, value, sizeof(pollp->hostname));
3116
pollp->port = portnum;
3118
cupsdLogMessage(CUPSD_LOG_INFO, "Polling %s:%d", pollp->hostname,
3121
else if (!strcasecmp(line, "DefaultAuthType") && value)
3124
* DefaultAuthType {basic,digest,basicdigest,negotiate}
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;
3136
else if (!strcasecmp(value, "negotiate"))
3137
DefaultAuthType = CUPSD_AUTH_NEGOTIATE;
3138
#endif /* HAVE_GSSAPI */
3141
cupsdLogMessage(CUPSD_LOG_WARN,
3142
"Unknown default authorization type %s on line %d.",
3144
if (FatalErrors & CUPSD_FATAL_CONFIG)
3149
else if (!strcasecmp(line, "DefaultEncryption"))
3152
* DefaultEncryption {Never,IfRequested,Required}
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;
3163
cupsdLogMessage(CUPSD_LOG_WARN,
3164
"Unknown default encryption %s on line %d.",
3166
if (FatalErrors & CUPSD_FATAL_CONFIG)
3170
#endif /* HAVE_SSL */
3171
else if (!strcasecmp(line, "User") && value)
3174
* User ID to run as...
3177
if (isdigit(value[0] & 255))
3179
int uid = atoi(value);
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.",
3192
struct passwd *p; /* Password information */
3195
p = getpwnam(value);
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.",
3209
cupsdLogMessage(CUPSD_LOG_ERROR,
3210
"Unknown User \"%s\" on line %d, ignoring!",
3214
else if (!strcasecmp(line, "Group") && value)
3217
* Group ID to run as...
3220
if (isdigit(value[0]))
3221
Group = atoi(value);
3225
group = getgrnam(value);
3228
Group = group->gr_gid;
3230
cupsdLogMessage(CUPSD_LOG_ERROR,
3231
"Unknown Group \"%s\" on line %d, ignoring!",
3235
else if (!strcasecmp(line, "SystemGroup") && value)
3238
* SystemGroup (admin) group(s)...
3241
if (!parse_groups(value))
3242
cupsdLogMessage(CUPSD_LOG_ERROR,
3243
"Unknown SystemGroup \"%s\" on line %d, ignoring!",
3246
else if (!strcasecmp(line, "HostNameLookups") && value)
3249
* Do hostname lookups?
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;
3261
cupsdLogMessage(CUPSD_LOG_WARN, "Unknown HostNameLookups %s on line %d.",
3264
else if (!strcasecmp(line, "AccessLogLevel") && value)
3267
* Amount of logging to do to access log...
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;
3277
cupsdLogMessage(CUPSD_LOG_WARN, "Unknown AccessLogLevel %s on line %d.",
3280
else if (!strcasecmp(line, "LogLevel") && value)
3283
* Amount of logging to do to error log...
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;
3307
cupsdLogMessage(CUPSD_LOG_WARN, "Unknown LogLevel %s on line %d.",
3310
else if (!strcasecmp(line, "LogTimeFormat") && value)
3313
* Amount of logging to do to error log...
3316
if (!strcasecmp(value, "standard"))
3317
LogTimeFormat = CUPSD_TIME_STANDARD;
3318
else if (!strcasecmp(value, "usecs"))
3319
LogTimeFormat = CUPSD_TIME_USECS;
3321
cupsdLogMessage(CUPSD_LOG_WARN, "Unknown LogTimeFormat %s on line %d.",
3324
else if (!strcasecmp(line, "PrintcapFormat") && value)
3327
* Format of printcap file?
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;
3337
cupsdLogMessage(CUPSD_LOG_WARN, "Unknown PrintcapFormat %s on line %d.",
3340
else if (!strcasecmp(line, "ServerTokens") && value)
3343
* Set the string used for the Server header...
3346
struct utsname plat; /* Platform info */
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",
3364
else if (!strcasecmp(value, "None"))
3365
cupsdClearString(&ServerHeader);
3367
cupsdLogMessage(CUPSD_LOG_WARN, "Unknown ServerTokens %s on line %d.",
3370
else if (!strcasecmp(line, "PassEnv") && value)
3373
* PassEnv variable [... variable]
3378
for (valuelen = 0; value[valuelen]; valuelen ++)
3379
if (isspace(value[valuelen]) || value[valuelen] == ',')
3382
if (value[valuelen])
3384
value[valuelen] = '\0';
3388
cupsdSetEnv(value, NULL);
3390
for (value += valuelen; *value; value ++)
3391
if (!isspace(*value) || *value != ',')
3395
else if (!strcasecmp(line, "ServerAlias") && value)
3398
ServerAlias = cupsArrayNew(NULL, NULL);
3400
cupsdAddAlias(ServerAlias, value);
3402
else if (!strcasecmp(line, "SetEnv") && value)
3405
* SetEnv variable value
3408
for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++);
3416
while (isspace(*valueptr & 255))
3419
cupsdSetEnv(value, valueptr);
3422
cupsdLogMessage(CUPSD_LOG_ERROR,
3423
"Missing value for SetEnv directive on line %d.",
3427
else if (!strcasecmp(line, "SSLOptions"))
3430
* SSLOptions options
3433
if (!value || !strcasecmp(value, "none"))
3434
SSLOptions = CUPSD_SSL_NONE;
3435
else if (!strcasecmp(value, "noemptyfragments"))
3436
SSLOptions = CUPSD_SSL_NOEMPTY;
3438
cupsdLogMessage(CUPSD_LOG_ERROR,
3439
"Unknown value \"%s\" for SSLOptions directive on "
3440
"line %d.", value, linenum);
3442
#endif /* HAVE_SSL */
3446
* Find a simple variable in the list...
3449
for (i = NUM_VARS, var = variables; i > 0; i --, var ++)
3450
if (!strcasecmp(line, var->name))
3456
* Unknown directive! Output an error message and continue...
3460
cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value for %s on line %d.",
3463
cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown directive %s on line %d.",
3470
case CUPSD_VARTYPE_INTEGER :
3472
cupsdLogMessage(CUPSD_LOG_ERROR,
3473
"Missing integer value for %s on line %d!",
3478
char *units; /* Units */
3481
n = strtol(value, &units, 0);
3483
if (units && *units)
3485
if (tolower(units[0] & 255) == 'g')
3486
n *= 1024 * 1024 * 1024;
3487
else if (tolower(units[0] & 255) == 'm')
3489
else if (tolower(units[0] & 255) == 'k')
3491
else if (tolower(units[0] & 255) == 't')
3496
cupsdLogMessage(CUPSD_LOG_ERROR,
3497
"Bad negative integer value for %s on line %d!",
3500
*((int *)var->ptr) = n;
3504
case CUPSD_VARTYPE_BOOLEAN :
3506
cupsdLogMessage(CUPSD_LOG_ERROR,
3507
"Missing boolean value for %s on line %d!",
3509
else if (!strcasecmp(value, "true") ||
3510
!strcasecmp(value, "on") ||
3511
!strcasecmp(value, "enabled") ||
3512
!strcasecmp(value, "yes") ||
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;
3522
cupsdLogMessage(CUPSD_LOG_ERROR,
3523
"Unknown boolean value %s on line %d.",
3527
case CUPSD_VARTYPE_PATHNAME :
3530
cupsdLogMessage(CUPSD_LOG_ERROR,
3531
"Missing pathname value for %s on line %d!",
3536
if (value[0] == '/')
3537
strlcpy(temp, value, sizeof(temp));
3539
snprintf(temp, sizeof(temp), "%s/%s", ServerRoot, value);
3541
if (access(temp, 0))
3543
cupsdLogMessage(CUPSD_LOG_ERROR,
3544
"File or directory for \"%s %s\" on line %d "
3545
"does not exist!", line, value, linenum);
3549
case CUPSD_VARTYPE_STRING :
3550
cupsdSetString((char **)var->ptr, value);
3561
* 'read_location()' - Read a <Location path> definition.
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 */
3569
cupsd_location_t *loc, /* New location */
3570
*parent; /* Parent location */
3571
char line[HTTP_MAX_BUFFER],
3573
*value, /* Value for directive */
3574
*valptr; /* Pointer into value */
3577
if ((parent = cupsdAddLocation(location)) == NULL)
3580
parent->limit = CUPSD_AUTH_LIMIT_ALL;
3583
while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
3586
* Decode the directive...
3589
if (!strcasecmp(line, "</Location>"))
3591
else if (!strcasecmp(line, "<Limit") ||
3592
!strcasecmp(line, "<LimitExcept"))
3596
cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d.", linenum);
3597
if (FatalErrors & CUPSD_FATAL_CONFIG)
3603
if ((loc = cupsdCopyLocation(&parent)) == NULL)
3609
for (valptr = value; !isspace(*valptr & 255) && *valptr; valptr ++);
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;
3629
cupsdLogMessage(CUPSD_LOG_WARN, "Unknown request type %s on line %d!",
3632
for (value = valptr; isspace(*value & 255); value ++);
3635
if (!strcasecmp(line, "<LimitExcept"))
3636
loc->limit = CUPSD_AUTH_LIMIT_ALL ^ loc->limit;
3638
parent->limit &= ~loc->limit;
3640
else if (!strcasecmp(line, "</Limit>") ||
3641
!strcasecmp(line, "</LimitExcept>"))
3643
else if (!parse_aaa(loc, line, value, linenum))
3645
cupsdLogMessage(CUPSD_LOG_ERROR,
3646
"Unknown Location directive %s on line %d.",
3648
if (FatalErrors & CUPSD_FATAL_CONFIG)
3653
cupsdLogMessage(CUPSD_LOG_ERROR,
3654
"Unexpected end-of-file at line %d while reading location!",
3657
return ((FatalErrors & CUPSD_FATAL_CONFIG) ? 0 : linenum);
3662
* 'read_policy()' - Read a <Policy name> definition.
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 */
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],
3677
*value, /* Value for directive */
3678
*valptr; /* Pointer into value */
3682
* Create the policy...
3685
if ((pol = cupsdAddPolicy(policy)) == NULL)
3689
* Read from the file...
3695
while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
3698
* Decode the directive...
3701
if (!strcasecmp(line, "</Policy>"))
3704
cupsdLogMessage(CUPSD_LOG_WARN,
3705
"Missing </Limit> before </Policy> on line %d!",
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...
3714
if ((op = cupsdFindPolicyOp(pol, IPP_VALIDATE_JOB)) == NULL ||
3715
op->op == IPP_ANY_OPERATION)
3717
if ((op = cupsdFindPolicyOp(pol, IPP_PRINT_JOB)) != NULL &&
3718
op->op != IPP_ANY_OPERATION)
3721
* Add a new limit for Validate-Job using the Print-Job limit as a
3725
cupsdLogMessage(CUPSD_LOG_WARN,
3726
"No limit for Validate-Job defined in policy %s "
3727
"- using Print-Job's policy", pol->name);
3729
cupsdAddPolicyOp(pol, op, IPP_VALIDATE_JOB);
3733
if ((op = cupsdFindPolicyOp(pol, CUPS_GET_DOCUMENT)) == NULL ||
3734
op->op == IPP_ANY_OPERATION)
3736
if ((op = cupsdFindPolicyOp(pol, IPP_SEND_DOCUMENT)) != NULL &&
3737
op->op != IPP_ANY_OPERATION)
3740
* Add a new limit for CUPS-Get-Document using the Send-Document
3741
* limit as a template...
3744
cupsdLogMessage(CUPSD_LOG_WARN,
3745
"No limit for CUPS-Get-Document defined in policy %s "
3746
"- using Send-Document's policy", pol->name);
3748
cupsdAddPolicyOp(pol, op, CUPS_GET_DOCUMENT);
3754
else if (!strcasecmp(line, "<Limit") && !op)
3758
cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d.", linenum);
3759
if (FatalErrors & CUPSD_FATAL_CONFIG)
3766
* Scan for IPP operation names...
3773
for (valptr = value; !isspace(*valptr & 255) && *valptr; valptr ++);
3778
if (num_ops < (int)(sizeof(ops) / sizeof(ops[0])))
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!",
3790
cupsdLogMessage(CUPSD_LOG_ERROR,
3791
"Too many operations listed on line %d!",
3794
for (value = valptr; isspace(*value & 255); value ++);
3798
* If none are specified, apply the policy to all operations...
3803
ops[0] = IPP_ANY_OPERATION;
3808
* Add a new policy for the first operation...
3811
op = cupsdAddPolicyOp(pol, NULL, ops[0]);
3813
else if (!strcasecmp(line, "</Limit>") && op)
3816
* Finish the current operation limit...
3822
* Copy the policy to the other operations...
3825
for (i = 1; i < num_ops; i ++)
3826
cupsdAddPolicyOp(pol, op, ops[i]);
3833
cupsdLogMessage(CUPSD_LOG_ERROR,
3834
"Missing <Limit ops> directive before %s on line %d.",
3836
if (FatalErrors & CUPSD_FATAL_CONFIG)
3839
else if (!parse_aaa(op, line, value, linenum))
3842
cupsdLogMessage(CUPSD_LOG_ERROR,
3843
"Unknown Policy Limit directive %s on line %d.",
3846
cupsdLogMessage(CUPSD_LOG_ERROR,
3847
"Unknown Policy directive %s on line %d.",
3850
if (FatalErrors & CUPSD_FATAL_CONFIG)
3855
cupsdLogMessage(CUPSD_LOG_ERROR,
3856
"Unexpected end-of-file at line %d while reading policy \"%s\"!",
3859
return ((FatalErrors & CUPSD_FATAL_CONFIG) ? 0 : linenum);
3864
* End of "$Id: conf.c 9470 2011-01-11 07:05:58Z mike $".