]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/adminutil.c
Update usage info.
[thirdparty/cups.git] / cups / adminutil.c
CommitLineData
757d2cad 1/*
7e86f2f6 2 * Administration utility API definitions for CUPS.
757d2cad 3 *
f1def5b8
MS
4 * Copyright © 2007-2018 by Apple Inc.
5 * Copyright © 2001-2007 by Easy Software Products.
757d2cad 6 *
f1def5b8
MS
7 * Licensed under Apache License v2.0. See the file "LICENSE" for more
8 * information.
757d2cad 9 */
10
11/*
12 * Include necessary headers...
13 */
14
71e16022 15#include "cups-private.h"
fb863569 16#include "debug-internal.h"
f787e1e3 17#include "ppd.h"
757d2cad 18#include "adminutil.h"
757d2cad 19#include <fcntl.h>
757d2cad 20#include <sys/stat.h>
19dc16f7 21#ifndef _WIN32
b86bc4cf 22# include <unistd.h>
23# include <sys/wait.h>
19dc16f7 24#endif /* !_WIN32 */
757d2cad 25
26
27/*
28 * Local functions...
29 */
30
757d2cad 31static http_status_t get_cupsd_conf(http_t *http, _cups_globals_t *cg,
32 time_t last_update, char *name,
07623986 33 size_t namelen, int *remote);
757d2cad 34static void invalidate_cupsd_cache(_cups_globals_t *cg);
757d2cad 35
36
37/*
38 * 'cupsAdminCreateWindowsPPD()' - Create the Windows PPD file for a printer.
426c6a59 39 *
5a9febac 40 * @deprecated@
757d2cad 41 */
42
43char * /* O - PPD file or NULL */
44cupsAdminCreateWindowsPPD(
01ce6322 45 http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
757d2cad 46 const char *dest, /* I - Printer or class */
47 char *buffer, /* I - Filename buffer */
48 int bufsize) /* I - Size of filename buffer */
49{
757d2cad 50 if (buffer)
51 *buffer = '\0';
52
f1def5b8 53 return (NULL);
757d2cad 54}
55
56
57/*
58 * 'cupsAdminExportSamba()' - Export a printer to Samba.
426c6a59 59 *
5a9febac 60 * @deprecated@
757d2cad 61 */
62
63int /* O - 1 on success, 0 on failure */
64cupsAdminExportSamba(
65 const char *dest, /* I - Destination to export */
66 const char *ppd, /* I - PPD file */
67 const char *samba_server, /* I - Samba server */
68 const char *samba_user, /* I - Samba username */
69 const char *samba_password, /* I - Samba password */
70 FILE *logfile) /* I - Log file, if any */
71{
f1def5b8 72 return (0);
757d2cad 73}
74
75
7594b224 76/*
77 * 'cupsAdminGetServerSettings()' - Get settings from the server.
78 *
79 * The returned settings should be freed with cupsFreeOptions() when
80 * you are done with them.
81 *
8072030b 82 * @since CUPS 1.3/macOS 10.5@
7594b224 83 */
84
85int /* O - 1 on success, 0 on failure */
86cupsAdminGetServerSettings(
01ce6322 87 http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
7594b224 88 int *num_settings, /* O - Number of settings */
89 cups_option_t **settings) /* O - Settings */
757d2cad 90{
91 int i; /* Looping var */
92 cups_file_t *cupsd; /* cupsd.conf file */
93 char cupsdconf[1024]; /* cupsd.conf filename */
94 int remote; /* Remote cupsd.conf file? */
95 http_status_t status; /* Status of getting cupsd.conf */
96 char line[1024], /* Line from cupsd.conf file */
97 *value; /* Value on line */
98 cups_option_t *setting; /* Current setting */
99 _cups_globals_t *cg = _cupsGlobals(); /* Global data */
100
101
102 /*
103 * Range check input...
104 */
105
01ce6322 106 if (!http)
1ff0402e
MS
107 {
108 /*
109 * See if we are connected to the same server...
110 */
111
112 if (cg->http)
113 {
114 /*
115 * Compare the connection hostname, port, and encryption settings to
116 * the cached defaults; these were initialized the first time we
117 * connected...
118 */
119
120 if (strcmp(cg->http->hostname, cg->server) ||
a469f8a5 121 cg->ipp_port != httpAddrPort(cg->http->hostaddr) ||
1ff0402e 122 (cg->http->encryption != cg->encryption &&
cb7f98ee 123 cg->http->encryption == HTTP_ENCRYPTION_NEVER))
1ff0402e
MS
124 {
125 /*
126 * Need to close the current connection because something has changed...
127 */
128
129 httpClose(cg->http);
130 cg->http = NULL;
131 }
132 }
133
134 /*
135 * (Re)connect as needed...
136 */
137
138 if (!cg->http)
139 {
db8b865d
MS
140 if ((cg->http = httpConnect2(cupsServer(), ippPort(), NULL, AF_UNSPEC,
141 cupsEncryption(), 1, 0, NULL)) == NULL)
1ff0402e
MS
142 {
143 if (errno)
cb7f98ee 144 _cupsSetError(IPP_STATUS_ERROR_SERVICE_UNAVAILABLE, NULL, 0);
1ff0402e 145 else
cb7f98ee 146 _cupsSetError(IPP_STATUS_ERROR_SERVICE_UNAVAILABLE,
1ff0402e
MS
147 _("Unable to connect to host."), 1);
148
149 if (num_settings)
150 *num_settings = 0;
151
152 if (settings)
153 *settings = NULL;
154
155 return (0);
156 }
157 }
f11a948a
MS
158
159 http = cg->http;
1ff0402e 160 }
01ce6322 161
757d2cad 162 if (!http || !num_settings || !settings)
163 {
cb7f98ee 164 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
757d2cad 165
166 if (num_settings)
167 *num_settings = 0;
168
169 if (settings)
170 *settings = NULL;
171
172 return (0);
173 }
174
175 *num_settings = 0;
176 *settings = NULL;
177
178 /*
179 * Get the cupsd.conf file...
180 */
181
182 if ((status = get_cupsd_conf(http, cg, cg->cupsd_update, cupsdconf,
cb7f98ee 183 sizeof(cupsdconf), &remote)) == HTTP_STATUS_OK)
757d2cad 184 {
185 if ((cupsd = cupsFileOpen(cupsdconf, "r")) == NULL)
480ef0fe 186 {
187 char message[1024]; /* Message string */
188
189
190 snprintf(message, sizeof(message),
749b1e90 191 _cupsLangString(cupsLangDefault(), _("Open of %s failed: %s")),
480ef0fe 192 cupsdconf, strerror(errno));
cb7f98ee 193 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, message, 0);
480ef0fe 194 }
757d2cad 195 }
196 else
197 cupsd = NULL;
198
199 if (cupsd)
200 {
201 /*
202 * Read the file, keeping track of what settings are enabled...
203 */
204
205 int remote_access = 0, /* Remote access allowed? */
206 remote_admin = 0, /* Remote administration allowed? */
f7deaa1a 207 remote_any = 0, /* Remote access from anywhere allowed? */
757d2cad 208 browsing = 1, /* Browsing enabled? */
757d2cad 209 cancel_policy = 1, /* Cancel-job policy set? */
210 debug_logging = 0; /* LogLevel debug set? */
211 int linenum = 0, /* Line number in file */
212 in_location = 0, /* In a location section? */
213 in_policy = 0, /* In a policy section? */
214 in_cancel_job = 0, /* In a cancel-job section? */
215 in_admin_location = 0; /* In the /admin location? */
216
217
218 invalidate_cupsd_cache(cg);
219
220 cg->cupsd_update = time(NULL);
221 httpGetHostname(http, cg->cupsd_hostname, sizeof(cg->cupsd_hostname));
222
223 while (cupsFileGetConf(cupsd, line, sizeof(line), &value, &linenum))
224 {
c24d2134 225 if (!value && strncmp(line, "</", 2))
0a682745 226 value = line + strlen(line);
757d2cad 227
88f9aafc 228 if ((!_cups_strcasecmp(line, "Port") || !_cups_strcasecmp(line, "Listen")) && value)
757d2cad 229 {
230 char *port; /* Pointer to port number, if any */
231
232
233 if ((port = strrchr(value, ':')) != NULL)
234 *port = '\0';
d09495fa 235 else if (isdigit(*value & 255))
236 {
237 /*
238 * Listen on a port number implies remote access...
239 */
240
241 remote_access = 1;
242 continue;
243 }
757d2cad 244
88f9aafc 245 if (_cups_strcasecmp(value, "localhost") && strcmp(value, "127.0.0.1")
d09495fa 246#ifdef AF_LOCAL
247 && *value != '/'
248#endif /* AF_LOCAL */
249#ifdef AF_INET6
1106b00e 250 && strcmp(value, "[::1]")
d09495fa 251#endif /* AF_INET6 */
252 )
757d2cad 253 remote_access = 1;
254 }
88f9aafc 255 else if (!_cups_strcasecmp(line, "Browsing"))
757d2cad 256 {
a2326b5b
MS
257 browsing = !_cups_strcasecmp(value, "yes") ||
258 !_cups_strcasecmp(value, "on") ||
88f9aafc 259 !_cups_strcasecmp(value, "true");
757d2cad 260 }
88f9aafc 261 else if (!_cups_strcasecmp(line, "LogLevel"))
757d2cad 262 {
88f9aafc 263 debug_logging = !_cups_strncasecmp(value, "debug", 5);
757d2cad 264 }
a2326b5b
MS
265 else if (!_cups_strcasecmp(line, "<Policy") &&
266 !_cups_strcasecmp(value, "default"))
757d2cad 267 {
268 in_policy = 1;
269 }
88f9aafc 270 else if (!_cups_strcasecmp(line, "</Policy>"))
757d2cad 271 {
272 in_policy = 0;
273 }
88f9aafc 274 else if (!_cups_strcasecmp(line, "<Limit") && in_policy && value)
757d2cad 275 {
276 /*
277 * See if the policy limit is for the Cancel-Job operation...
278 */
279
280 char *valptr; /* Pointer into value */
281
282
283 while (*value)
284 {
7cf5915e 285 for (valptr = value; *valptr && !_cups_isspace(*valptr); valptr ++);
757d2cad 286
287 if (*valptr)
288 *valptr++ = '\0';
289
a2326b5b
MS
290 if (!_cups_strcasecmp(value, "cancel-job") ||
291 !_cups_strcasecmp(value, "all"))
757d2cad 292 {
293 in_cancel_job = 1;
294 break;
295 }
296
7cf5915e 297 for (value = valptr; _cups_isspace(*value); value ++);
757d2cad 298 }
299 }
88f9aafc 300 else if (!_cups_strcasecmp(line, "</Limit>"))
757d2cad 301 {
302 in_cancel_job = 0;
303 }
88f9aafc 304 else if (!_cups_strcasecmp(line, "Require") && in_cancel_job)
757d2cad 305 {
306 cancel_policy = 0;
307 }
88f9aafc 308 else if (!_cups_strcasecmp(line, "<Location") && value)
757d2cad 309 {
88f9aafc 310 in_admin_location = !_cups_strcasecmp(value, "/admin");
757d2cad 311 in_location = 1;
312 }
88f9aafc 313 else if (!_cups_strcasecmp(line, "</Location>"))
757d2cad 314 {
315 in_admin_location = 0;
316 in_location = 0;
317 }
88f9aafc 318 else if (!_cups_strcasecmp(line, "Allow") && value &&
a2326b5b
MS
319 _cups_strcasecmp(value, "localhost") &&
320 _cups_strcasecmp(value, "127.0.0.1")
d09495fa 321#ifdef AF_LOCAL
322 && *value != '/'
323#endif /* AF_LOCAL */
324#ifdef AF_INET6
325 && strcmp(value, "::1")
326#endif /* AF_INET6 */
327 )
757d2cad 328 {
080811b1
MS
329 if (in_admin_location)
330 remote_admin = 1;
88f9aafc 331 else if (!_cups_strcasecmp(value, "all"))
f7deaa1a 332 remote_any = 1;
757d2cad 333 }
b9faaae1 334 else if (line[0] != '<' && !in_location && !in_policy &&
88f9aafc
MS
335 _cups_strcasecmp(line, "Allow") &&
336 _cups_strcasecmp(line, "AuthType") &&
337 _cups_strcasecmp(line, "Deny") &&
338 _cups_strcasecmp(line, "Order") &&
339 _cups_strcasecmp(line, "Require") &&
340 _cups_strcasecmp(line, "Satisfy"))
757d2cad 341 cg->cupsd_num_settings = cupsAddOption(line, value,
342 cg->cupsd_num_settings,
343 &(cg->cupsd_settings));
344 }
345
346 cupsFileClose(cupsd);
347
348 cg->cupsd_num_settings = cupsAddOption(CUPS_SERVER_DEBUG_LOGGING,
349 debug_logging ? "1" : "0",
350 cg->cupsd_num_settings,
351 &(cg->cupsd_settings));
352
353 cg->cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ADMIN,
354 (remote_access && remote_admin) ?
355 "1" : "0",
356 cg->cupsd_num_settings,
357 &(cg->cupsd_settings));
358
f7deaa1a 359 cg->cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ANY,
360 remote_any ? "1" : "0",
361 cg->cupsd_num_settings,
362 &(cg->cupsd_settings));
363
757d2cad 364 cg->cupsd_num_settings = cupsAddOption(CUPS_SERVER_SHARE_PRINTERS,
a2326b5b
MS
365 (remote_access && browsing) ? "1" :
366 "0",
757d2cad 367 cg->cupsd_num_settings,
368 &(cg->cupsd_settings));
369
370 cg->cupsd_num_settings = cupsAddOption(CUPS_SERVER_USER_CANCEL_ANY,
371 cancel_policy ? "1" : "0",
372 cg->cupsd_num_settings,
373 &(cg->cupsd_settings));
374 }
cb7f98ee 375 else if (status != HTTP_STATUS_NOT_MODIFIED)
757d2cad 376 invalidate_cupsd_cache(cg);
377
378 /*
379 * Remove any temporary files and copy the settings array...
380 */
381
382 if (remote)
383 unlink(cupsdconf);
384
385 for (i = cg->cupsd_num_settings, setting = cg->cupsd_settings;
386 i > 0;
387 i --, setting ++)
388 *num_settings = cupsAddOption(setting->name, setting->value,
389 *num_settings, settings);
390
391 return (cg->cupsd_num_settings > 0);
392}
393
394
7594b224 395/*
396 * 'cupsAdminSetServerSettings()' - Set settings on the server.
397 *
8072030b 398 * @since CUPS 1.3/macOS 10.5@
7594b224 399 */
400
401int /* O - 1 on success, 0 on failure */
402cupsAdminSetServerSettings(
01ce6322 403 http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
7594b224 404 int num_settings, /* I - Number of settings */
405 cups_option_t *settings) /* I - Settings */
757d2cad 406{
407 int i; /* Looping var */
408 http_status_t status; /* GET/PUT status */
07725fee 409 const char *server_port_env; /* SERVER_PORT env var */
410 int server_port; /* IPP port for server */
757d2cad 411 cups_file_t *cupsd; /* cupsd.conf file */
412 char cupsdconf[1024]; /* cupsd.conf filename */
413 int remote; /* Remote cupsd.conf file? */
414 char tempfile[1024]; /* Temporary new cupsd.conf */
415 cups_file_t *temp; /* Temporary file */
416 char line[1024], /* Line from cupsd.conf file */
417 *value; /* Value on line */
418 int linenum, /* Line number in file */
419 in_location, /* In a location section? */
420 in_policy, /* In a policy section? */
421 in_default_policy, /* In the default policy section? */
422 in_cancel_job, /* In a cancel-job section? */
423 in_admin_location, /* In the /admin location? */
424 in_conf_location, /* In the /admin/conf location? */
fcad6032 425 in_log_location, /* In the /admin/log location? */
757d2cad 426 in_root_location; /* In the / location? */
427 const char *val; /* Setting value */
a2326b5b 428 int share_printers, /* Share local printers */
757d2cad 429 remote_admin, /* Remote administration allowed? */
f7deaa1a 430 remote_any, /* Remote access from anywhere? */
757d2cad 431 user_cancel_any, /* Cancel-job policy set? */
432 debug_logging; /* LogLevel debug set? */
433 int wrote_port_listen, /* Wrote the port/listen lines? */
434 wrote_browsing, /* Wrote the browsing lines? */
435 wrote_policy, /* Wrote the policy? */
436 wrote_loglevel, /* Wrote the LogLevel line? */
437 wrote_admin_location, /* Wrote the /admin location? */
438 wrote_conf_location, /* Wrote the /admin/conf location? */
fcad6032 439 wrote_log_location, /* Wrote the /admin/log location? */
757d2cad 440 wrote_root_location; /* Wrote the / location? */
441 int indent; /* Indentation */
442 int cupsd_num_settings; /* New number of settings */
a2326b5b 443 int old_share_printers, /* Share local printers */
b86bc4cf 444 old_remote_admin, /* Remote administration allowed? */
6720d4f4 445 old_remote_any, /* Remote access from anywhere? */
b86bc4cf 446 old_user_cancel_any, /* Cancel-job policy set? */
447 old_debug_logging; /* LogLevel debug set? */
757d2cad 448 cups_option_t *cupsd_settings, /* New settings */
449 *setting; /* Current setting */
450 _cups_globals_t *cg = _cupsGlobals(); /* Global data */
451
452
453 /*
454 * Range check input...
455 */
456
01ce6322
MS
457 if (!http)
458 http = _cupsConnect();
459
757d2cad 460 if (!http || !num_settings || !settings)
461 {
cb7f98ee 462 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
757d2cad 463
464 return (0);
465 }
466
467 /*
468 * Get the cupsd.conf file...
469 */
470
1f0275e3 471 if (get_cupsd_conf(http, cg, 0, cupsdconf, sizeof(cupsdconf),
cb7f98ee 472 &remote) == HTTP_STATUS_OK)
757d2cad 473 {
474 if ((cupsd = cupsFileOpen(cupsdconf, "r")) == NULL)
475 {
cb7f98ee 476 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, NULL, 0);
757d2cad 477 return (0);
478 }
479 }
480 else
481 return (0);
482
b86bc4cf 483 /*
484 * Get current settings...
485 */
486
ba55dc12
MS
487 if (!cupsAdminGetServerSettings(http, &cupsd_num_settings,
488 &cupsd_settings))
b86bc4cf 489 return (0);
490
491 if ((val = cupsGetOption(CUPS_SERVER_DEBUG_LOGGING, cupsd_num_settings,
492 cupsd_settings)) != NULL)
493 old_debug_logging = atoi(val);
494 else
495 old_debug_logging = 0;
496
1106b00e
MS
497 DEBUG_printf(("1cupsAdminSetServerSettings: old debug_logging=%d",
498 old_debug_logging));
499
b86bc4cf 500 if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ADMIN, cupsd_num_settings,
501 cupsd_settings)) != NULL)
502 old_remote_admin = atoi(val);
503 else
504 old_remote_admin = 0;
505
1106b00e
MS
506 DEBUG_printf(("1cupsAdminSetServerSettings: old remote_admin=%d",
507 old_remote_admin));
508
f7deaa1a 509 if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ANY, cupsd_num_settings,
510 cupsd_settings)) != NULL)
6720d4f4 511 old_remote_any = atoi(val);
f7deaa1a 512 else
6720d4f4 513 old_remote_any = 0;
f7deaa1a 514
ba55dc12 515 DEBUG_printf(("1cupsAdminSetServerSettings: old remote_any=%d",
6720d4f4 516 old_remote_any));
ba55dc12 517
b86bc4cf 518 if ((val = cupsGetOption(CUPS_SERVER_SHARE_PRINTERS, cupsd_num_settings,
519 cupsd_settings)) != NULL)
520 old_share_printers = atoi(val);
521 else
522 old_share_printers = 0;
523
1106b00e
MS
524 DEBUG_printf(("1cupsAdminSetServerSettings: old share_printers=%d",
525 old_share_printers));
526
b86bc4cf 527 if ((val = cupsGetOption(CUPS_SERVER_USER_CANCEL_ANY, cupsd_num_settings,
528 cupsd_settings)) != NULL)
529 old_user_cancel_any = atoi(val);
530 else
531 old_user_cancel_any = 0;
532
1106b00e
MS
533 DEBUG_printf(("1cupsAdminSetServerSettings: old user_cancel_any=%d",
534 old_user_cancel_any));
535
b86bc4cf 536 cupsFreeOptions(cupsd_num_settings, cupsd_settings);
537
757d2cad 538 /*
539 * Get basic settings...
540 */
541
542 if ((val = cupsGetOption(CUPS_SERVER_DEBUG_LOGGING, num_settings,
543 settings)) != NULL)
b86bc4cf 544 {
757d2cad 545 debug_logging = atoi(val);
b86bc4cf 546
547 if (debug_logging == old_debug_logging)
548 {
549 /*
550 * No change to this setting...
551 */
552
553 debug_logging = -1;
554 }
555 }
757d2cad 556 else
b86bc4cf 557 debug_logging = -1;
757d2cad 558
1106b00e
MS
559 DEBUG_printf(("1cupsAdminSetServerSettings: debug_logging=%d",
560 debug_logging));
561
6720d4f4
MS
562 if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ANY, num_settings, settings)) != NULL)
563 {
f7deaa1a 564 remote_any = atoi(val);
565
6720d4f4
MS
566 if (remote_any == old_remote_any)
567 {
568 /*
569 * No change to this setting...
570 */
571
572 remote_any = -1;
573 }
574 }
575 else
576 remote_any = -1;
577
578 DEBUG_printf(("1cupsAdminSetServerSettings: remote_any=%d", remote_any));
1106b00e 579
757d2cad 580 if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ADMIN, num_settings,
581 settings)) != NULL)
b86bc4cf 582 {
757d2cad 583 remote_admin = atoi(val);
b86bc4cf 584
1106b00e 585 if (remote_admin == old_remote_admin)
b86bc4cf 586 {
587 /*
588 * No change to this setting...
589 */
590
591 remote_admin = -1;
592 }
593 }
757d2cad 594 else
b86bc4cf 595 remote_admin = -1;
757d2cad 596
1106b00e
MS
597 DEBUG_printf(("1cupsAdminSetServerSettings: remote_admin=%d",
598 remote_admin));
599
757d2cad 600 if ((val = cupsGetOption(CUPS_SERVER_SHARE_PRINTERS, num_settings,
601 settings)) != NULL)
b86bc4cf 602 {
757d2cad 603 share_printers = atoi(val);
b86bc4cf 604
1106b00e 605 if (share_printers == old_share_printers)
b86bc4cf 606 {
607 /*
608 * No change to this setting...
609 */
610
611 share_printers = -1;
612 }
613 }
757d2cad 614 else
b86bc4cf 615 share_printers = -1;
757d2cad 616
1106b00e
MS
617 DEBUG_printf(("1cupsAdminSetServerSettings: share_printers=%d",
618 share_printers));
619
757d2cad 620 if ((val = cupsGetOption(CUPS_SERVER_USER_CANCEL_ANY, num_settings,
621 settings)) != NULL)
b86bc4cf 622 {
757d2cad 623 user_cancel_any = atoi(val);
b86bc4cf 624
625 if (user_cancel_any == old_user_cancel_any)
626 {
627 /*
628 * No change to this setting...
629 */
630
631 user_cancel_any = -1;
632 }
633 }
757d2cad 634 else
b86bc4cf 635 user_cancel_any = -1;
757d2cad 636
1106b00e
MS
637 DEBUG_printf(("1cupsAdminSetServerSettings: user_cancel_any=%d",
638 user_cancel_any));
639
757d2cad 640 /*
641 * Create a temporary file for the new cupsd.conf file...
642 */
643
644 if ((temp = cupsTempFile2(tempfile, sizeof(tempfile))) == NULL)
645 {
646 cupsFileClose(cupsd);
647
648 if (remote)
649 unlink(cupsdconf);
650
cb7f98ee 651 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, NULL, 0);
757d2cad 652 return (0);
653 }
654
655 /*
656 * Copy the old file to the new, making changes along the way...
657 */
658
659 cupsd_num_settings = 0;
660 in_admin_location = 0;
661 in_cancel_job = 0;
662 in_conf_location = 0;
663 in_default_policy = 0;
664 in_location = 0;
fcad6032 665 in_log_location = 0;
757d2cad 666 in_policy = 0;
667 in_root_location = 0;
668 linenum = 0;
669 wrote_admin_location = 0;
670 wrote_browsing = 0;
671 wrote_conf_location = 0;
fcad6032 672 wrote_log_location = 0;
757d2cad 673 wrote_loglevel = 0;
674 wrote_policy = 0;
675 wrote_port_listen = 0;
676 wrote_root_location = 0;
677 indent = 0;
678
07725fee 679 if ((server_port_env = getenv("SERVER_PORT")) != NULL)
680 {
681 if ((server_port = atoi(server_port_env)) <= 0)
682 server_port = ippPort();
683 }
684 else
685 server_port = ippPort();
686
687 if (server_port <= 0)
688 server_port = IPP_PORT;
689
757d2cad 690 while (cupsFileGetConf(cupsd, line, sizeof(line), &value, &linenum))
691 {
88f9aafc 692 if ((!_cups_strcasecmp(line, "Port") || !_cups_strcasecmp(line, "Listen")) &&
6720d4f4 693 (remote_admin >= 0 || remote_any >= 0 || share_printers >= 0))
757d2cad 694 {
695 if (!wrote_port_listen)
696 {
697 wrote_port_listen = 1;
698
ba55dc12 699 if (remote_admin > 0 || remote_any > 0 || share_printers > 0)
757d2cad 700 {
701 cupsFilePuts(temp, "# Allow remote access\n");
07725fee 702 cupsFilePrintf(temp, "Port %d\n", server_port);
757d2cad 703 }
704 else
705 {
480ef0fe 706 cupsFilePuts(temp, "# Only listen for connections from the local "
707 "machine.\n");
07725fee 708 cupsFilePrintf(temp, "Listen localhost:%d\n", server_port);
757d2cad 709 }
710
711#ifdef CUPS_DEFAULT_DOMAINSOCKET
07725fee 712 if ((!value || strcmp(CUPS_DEFAULT_DOMAINSOCKET, value)) &&
713 !access(CUPS_DEFAULT_DOMAINSOCKET, 0))
757d2cad 714 cupsFilePuts(temp, "Listen " CUPS_DEFAULT_DOMAINSOCKET "\n");
715#endif /* CUPS_DEFAULT_DOMAINSOCKET */
716 }
b86bc4cf 717 else if (value && value[0] == '/'
718#ifdef CUPS_DEFAULT_DOMAINSOCKET
719 && strcmp(CUPS_DEFAULT_DOMAINSOCKET, value)
720#endif /* CUPS_DEFAULT_DOMAINSOCKET */
721 )
07725fee 722 cupsFilePrintf(temp, "Listen %s\n", value);
757d2cad 723 }
88f9aafc 724 else if ((!_cups_strcasecmp(line, "Browsing") ||
a2326b5b
MS
725 !_cups_strcasecmp(line, "BrowseLocalProtocols")) &&
726 share_printers >= 0)
757d2cad 727 {
728 if (!wrote_browsing)
729 {
09a101d6 730 int new_share_printers = (share_printers > 0 ||
731 (share_printers == -1 &&
732 old_share_printers > 0));
733
757d2cad 734 wrote_browsing = 1;
735
a2326b5b 736 if (new_share_printers)
757d2cad 737 {
2e4ff8af
MS
738 const char *localp = cupsGetOption("BrowseLocalProtocols",
739 num_settings, settings);
2e4ff8af 740
7a0cbd5e 741 if (!localp || !localp[0])
0a682745
MS
742 localp = cupsGetOption("BrowseLocalProtocols", cupsd_num_settings,
743 cupsd_settings);
744
a2326b5b 745 cupsFilePuts(temp, "# Share local printers on the local network.\n");
757d2cad 746 cupsFilePuts(temp, "Browsing On\n");
2e4ff8af 747
a2326b5b
MS
748 if (!localp)
749 localp = CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS;
0af14961 750
a2326b5b 751 cupsFilePrintf(temp, "BrowseLocalProtocols %s\n", localp);
0af14961
MS
752
753 cupsd_num_settings = cupsAddOption("BrowseLocalProtocols", localp,
754 cupsd_num_settings,
755 &cupsd_settings);
757d2cad 756 }
757 else
758 {
a2326b5b 759 cupsFilePuts(temp, "# Disable printer sharing.\n");
757d2cad 760 cupsFilePuts(temp, "Browsing Off\n");
761 }
762 }
763 }
88f9aafc 764 else if (!_cups_strcasecmp(line, "LogLevel") && debug_logging >= 0)
757d2cad 765 {
766 wrote_loglevel = 1;
767
768 if (debug_logging)
769 {
480ef0fe 770 cupsFilePuts(temp,
771 "# Show troubleshooting information in error_log.\n");
757d2cad 772 cupsFilePuts(temp, "LogLevel debug\n");
773 }
774 else
775 {
776 cupsFilePuts(temp, "# Show general information in error_log.\n");
1f0275e3 777 cupsFilePuts(temp, "LogLevel " CUPS_DEFAULT_LOG_LEVEL "\n");
757d2cad 778 }
779 }
88f9aafc 780 else if (!_cups_strcasecmp(line, "<Policy"))
757d2cad 781 {
88f9aafc 782 in_default_policy = !_cups_strcasecmp(value, "default");
757d2cad 783 in_policy = 1;
784
785 cupsFilePrintf(temp, "%s %s>\n", line, value);
786 indent += 2;
787 }
88f9aafc 788 else if (!_cups_strcasecmp(line, "</Policy>"))
757d2cad 789 {
790 indent -= 2;
791 if (!wrote_policy && in_default_policy)
792 {
793 wrote_policy = 1;
794
795 if (!user_cancel_any)
480ef0fe 796 cupsFilePuts(temp, " # Only the owner or an administrator can "
797 "cancel a job...\n"
757d2cad 798 " <Limit Cancel-Job>\n"
799 " Order deny,allow\n"
355e94dc 800 " Require user @OWNER "
b9faaae1 801 CUPS_DEFAULT_PRINTOPERATOR_AUTH "\n"
757d2cad 802 " </Limit>\n");
803 }
804
805 in_policy = 0;
806 in_default_policy = 0;
807
808 cupsFilePuts(temp, "</Policy>\n");
809 }
88f9aafc 810 else if (!_cups_strcasecmp(line, "<Location"))
757d2cad 811 {
812 in_location = 1;
813 indent += 2;
814 if (!strcmp(value, "/admin"))
815 in_admin_location = 1;
fcad6032 816 else if (!strcmp(value, "/admin/conf"))
757d2cad 817 in_conf_location = 1;
fcad6032
MS
818 else if (!strcmp(value, "/admin/log"))
819 in_log_location = 1;
757d2cad 820 else if (!strcmp(value, "/"))
821 in_root_location = 1;
822
823 cupsFilePrintf(temp, "%s %s>\n", line, value);
824 }
88f9aafc 825 else if (!_cups_strcasecmp(line, "</Location>"))
757d2cad 826 {
827 in_location = 0;
828 indent -= 2;
b86bc4cf 829 if (in_admin_location && remote_admin >= 0)
757d2cad 830 {
831 wrote_admin_location = 1;
832
833 if (remote_admin)
834 cupsFilePuts(temp, " # Allow remote administration...\n");
b86bc4cf 835 else if (remote_admin == 0)
757d2cad 836 cupsFilePuts(temp, " # Restrict access to the admin pages...\n");
837
838 cupsFilePuts(temp, " Order allow,deny\n");
839
840 if (remote_admin)
f7deaa1a 841 cupsFilePrintf(temp, " Allow %s\n",
842 remote_any > 0 ? "all" : "@LOCAL");
757d2cad 843 }
b86bc4cf 844 else if (in_conf_location && remote_admin >= 0)
757d2cad 845 {
846 wrote_conf_location = 1;
847
848 if (remote_admin)
480ef0fe 849 cupsFilePuts(temp, " # Allow remote access to the configuration "
850 "files...\n");
757d2cad 851 else
480ef0fe 852 cupsFilePuts(temp, " # Restrict access to the configuration "
853 "files...\n");
757d2cad 854
855 cupsFilePuts(temp, " Order allow,deny\n");
856
857 if (remote_admin)
f7deaa1a 858 cupsFilePrintf(temp, " Allow %s\n",
859 remote_any > 0 ? "all" : "@LOCAL");
757d2cad 860 }
fcad6032
MS
861 else if (in_log_location && remote_admin >= 0)
862 {
863 wrote_log_location = 1;
864
865 if (remote_admin)
866 cupsFilePuts(temp, " # Allow remote access to the log "
867 "files...\n");
868 else
869 cupsFilePuts(temp, " # Restrict access to the log "
870 "files...\n");
871
872 cupsFilePuts(temp, " Order allow,deny\n");
873
874 if (remote_admin)
875 cupsFilePrintf(temp, " Allow %s\n",
876 remote_any > 0 ? "all" : "@LOCAL");
877 }
ba55dc12 878 else if (in_root_location &&
6720d4f4 879 (remote_admin >= 0 || remote_any >= 0 || share_printers >= 0))
757d2cad 880 {
881 wrote_root_location = 1;
882
b86bc4cf 883 if (remote_admin > 0 && share_printers > 0)
480ef0fe 884 cupsFilePuts(temp, " # Allow shared printing and remote "
885 "administration...\n");
b86bc4cf 886 else if (remote_admin > 0)
757d2cad 887 cupsFilePuts(temp, " # Allow remote administration...\n");
b86bc4cf 888 else if (share_printers > 0)
757d2cad 889 cupsFilePuts(temp, " # Allow shared printing...\n");
ba55dc12
MS
890 else if (remote_any > 0)
891 cupsFilePuts(temp, " # Allow remote access...\n");
757d2cad 892 else
893 cupsFilePuts(temp, " # Restrict access to the server...\n");
894
895 cupsFilePuts(temp, " Order allow,deny\n");
896
ba55dc12 897 if (remote_admin > 0 || remote_any > 0 || share_printers > 0)
f7deaa1a 898 cupsFilePrintf(temp, " Allow %s\n",
899 remote_any > 0 ? "all" : "@LOCAL");
757d2cad 900 }
901
902 in_admin_location = 0;
903 in_conf_location = 0;
fcad6032 904 in_log_location = 0;
757d2cad 905 in_root_location = 0;
906
907 cupsFilePuts(temp, "</Location>\n");
908 }
88f9aafc 909 else if (!_cups_strcasecmp(line, "<Limit"))
757d2cad 910 {
7cf5915e 911 if (in_default_policy)
757d2cad 912 {
913 /*
7cf5915e 914 * See if the policy limit is for the Cancel-Job operation...
757d2cad 915 */
88f9aafc 916
7cf5915e 917 char *valptr; /* Pointer into value */
88f9aafc
MS
918
919
920 if (!_cups_strcasecmp(value, "cancel-job") && user_cancel_any >= 0)
757d2cad 921 {
7cf5915e
MS
922 /*
923 * Don't write anything for this limit section...
924 */
88f9aafc 925
7cf5915e
MS
926 in_cancel_job = 2;
927 }
928 else
929 {
930 cupsFilePrintf(temp, "%*s%s", indent, "", line);
88f9aafc 931
7cf5915e 932 while (*value)
757d2cad 933 {
7cf5915e 934 for (valptr = value; *valptr && !_cups_isspace(*valptr); valptr ++);
88f9aafc 935
7cf5915e
MS
936 if (*valptr)
937 *valptr++ = '\0';
88f9aafc
MS
938
939 if (!_cups_strcasecmp(value, "cancel-job") && user_cancel_any >= 0)
7cf5915e
MS
940 {
941 /*
942 * Write everything except for this definition...
943 */
88f9aafc 944
7cf5915e
MS
945 in_cancel_job = 1;
946 }
947 else
948 cupsFilePrintf(temp, " %s", value);
88f9aafc 949
7cf5915e 950 for (value = valptr; _cups_isspace(*value); value ++);
757d2cad 951 }
88f9aafc 952
7cf5915e 953 cupsFilePuts(temp, ">\n");
757d2cad 954 }
757d2cad 955 }
7cf5915e
MS
956 else
957 cupsFilePrintf(temp, "%*s%s %s>\n", indent, "", line, value);
958
959 indent += 2;
757d2cad 960 }
88f9aafc 961 else if (!_cups_strcasecmp(line, "</Limit>") && in_cancel_job)
757d2cad 962 {
963 indent -= 2;
964
965 if (in_cancel_job == 1)
7cf5915e 966 cupsFilePuts(temp, " </Limit>\n");
757d2cad 967
968 wrote_policy = 1;
969
970 if (!user_cancel_any)
480ef0fe 971 cupsFilePuts(temp, " # Only the owner or an administrator can cancel "
7cf5915e
MS
972 "a job...\n"
973 " <Limit Cancel-Job>\n"
974 " Order deny,allow\n"
975 " Require user @OWNER "
b9faaae1 976 CUPS_DEFAULT_PRINTOPERATOR_AUTH "\n"
757d2cad 977 " </Limit>\n");
978
979 in_cancel_job = 0;
980 }
b86bc4cf 981 else if ((((in_admin_location || in_conf_location || in_root_location) &&
6720d4f4 982 (remote_admin >= 0 || remote_any >= 0)) ||
b86bc4cf 983 (in_root_location && share_printers >= 0)) &&
88f9aafc
MS
984 (!_cups_strcasecmp(line, "Allow") || !_cups_strcasecmp(line, "Deny") ||
985 !_cups_strcasecmp(line, "Order")))
757d2cad 986 continue;
987 else if (in_cancel_job == 2)
988 continue;
757d2cad 989 else if (line[0] == '<')
990 {
991 if (value)
992 {
993 cupsFilePrintf(temp, "%*s%s %s>\n", indent, "", line, value);
994 indent += 2;
995 }
996 else
997 {
998 if (line[1] == '/')
999 indent -= 2;
1000
1001 cupsFilePrintf(temp, "%*s%s\n", indent, "", line);
1002 }
1003 }
1004 else if (!in_policy && !in_location &&
7594b224 1005 (val = cupsGetOption(line, num_settings, settings)) != NULL)
757d2cad 1006 {
1007 /*
7594b224 1008 * Replace this directive's value with the new one...
757d2cad 1009 */
1010
7594b224 1011 cupsd_num_settings = cupsAddOption(line, val, cupsd_num_settings,
757d2cad 1012 &cupsd_settings);
1013
1014 /*
1015 * Write the new value in its place, without indentation since we
1016 * only support setting root directives, not in sections...
1017 */
1018
7594b224 1019 cupsFilePrintf(temp, "%s %s\n", line, val);
757d2cad 1020 }
1021 else if (value)
1022 {
1023 if (!in_policy && !in_location)
1024 {
1025 /*
1026 * Record the non-policy, non-location directives that we find
1027 * in the server settings, since we cache this info and record it
1106b00e 1028 * in cupsAdminGetServerSettings()...
757d2cad 1029 */
1030
1031 cupsd_num_settings = cupsAddOption(line, value, cupsd_num_settings,
1032 &cupsd_settings);
1033 }
1034
1035 cupsFilePrintf(temp, "%*s%s %s\n", indent, "", line, value);
1036 }
1037 else
1038 cupsFilePrintf(temp, "%*s%s\n", indent, "", line);
1039 }
1040
1041 /*
1042 * Write any missing info...
1043 */
1044
a2326b5b 1045 if (!wrote_browsing && share_printers >= 0)
757d2cad 1046 {
a2326b5b 1047 if (share_printers > 0)
757d2cad 1048 {
a2326b5b 1049 cupsFilePuts(temp, "# Share local printers on the local network.\n");
757d2cad 1050 cupsFilePuts(temp, "Browsing On\n");
757d2cad 1051 }
1052 else
1053 {
1054 cupsFilePuts(temp, "# Disable printer sharing and shared printers.\n");
1055 cupsFilePuts(temp, "Browsing Off\n");
1056 }
1057 }
1058
b86bc4cf 1059 if (!wrote_loglevel && debug_logging >= 0)
757d2cad 1060 {
1061 if (debug_logging)
1062 {
1063 cupsFilePuts(temp, "# Show troubleshooting information in error_log.\n");
1064 cupsFilePuts(temp, "LogLevel debug\n");
1065 }
1066 else
1067 {
1068 cupsFilePuts(temp, "# Show general information in error_log.\n");
1f0275e3 1069 cupsFilePuts(temp, "LogLevel " CUPS_DEFAULT_LOG_LEVEL "\n");
757d2cad 1070 }
1071 }
1072
ba55dc12 1073 if (!wrote_port_listen &&
6720d4f4 1074 (remote_admin >= 0 || remote_any >= 0 || share_printers >= 0))
757d2cad 1075 {
ba55dc12 1076 if (remote_admin > 0 || remote_any > 0 || share_printers > 0)
757d2cad 1077 {
1078 cupsFilePuts(temp, "# Allow remote access\n");
1079 cupsFilePrintf(temp, "Port %d\n", ippPort());
1080 }
1081 else
1082 {
480ef0fe 1083 cupsFilePuts(temp,
1084 "# Only listen for connections from the local machine.\n");
d09495fa 1085 cupsFilePrintf(temp, "Listen localhost:%d\n", ippPort());
757d2cad 1086 }
1087
1088#ifdef CUPS_DEFAULT_DOMAINSOCKET
1089 if (!access(CUPS_DEFAULT_DOMAINSOCKET, 0))
1090 cupsFilePuts(temp, "Listen " CUPS_DEFAULT_DOMAINSOCKET "\n");
1091#endif /* CUPS_DEFAULT_DOMAINSOCKET */
1092 }
1093
ba55dc12 1094 if (!wrote_root_location &&
6720d4f4 1095 (remote_admin >= 0 || remote_any >= 0 || share_printers >= 0))
757d2cad 1096 {
b86bc4cf 1097 if (remote_admin > 0 && share_printers > 0)
480ef0fe 1098 cupsFilePuts(temp,
1099 "# Allow shared printing and remote administration...\n");
b86bc4cf 1100 else if (remote_admin > 0)
757d2cad 1101 cupsFilePuts(temp, "# Allow remote administration...\n");
b86bc4cf 1102 else if (share_printers > 0)
757d2cad 1103 cupsFilePuts(temp, "# Allow shared printing...\n");
ba55dc12
MS
1104 else if (remote_any > 0)
1105 cupsFilePuts(temp, "# Allow remote access...\n");
757d2cad 1106 else
1107 cupsFilePuts(temp, "# Restrict access to the server...\n");
1108
1109 cupsFilePuts(temp, "<Location />\n"
1110 " Order allow,deny\n");
1111
ba55dc12 1112 if (remote_admin > 0 || remote_any > 0 || share_printers > 0)
f7deaa1a 1113 cupsFilePrintf(temp, " Allow %s\n", remote_any > 0 ? "all" : "@LOCAL");
757d2cad 1114
1115 cupsFilePuts(temp, "</Location>\n");
1116 }
1117
b86bc4cf 1118 if (!wrote_admin_location && remote_admin >= 0)
757d2cad 1119 {
1120 if (remote_admin)
1121 cupsFilePuts(temp, "# Allow remote administration...\n");
1122 else
1123 cupsFilePuts(temp, "# Restrict access to the admin pages...\n");
1124
1125 cupsFilePuts(temp, "<Location /admin>\n"
1126 " Order allow,deny\n");
1127
1128 if (remote_admin)
f7deaa1a 1129 cupsFilePrintf(temp, " Allow %s\n", remote_any > 0 ? "all" : "@LOCAL");
757d2cad 1130
1131 cupsFilePuts(temp, "</Location>\n");
1132 }
1133
b86bc4cf 1134 if (!wrote_conf_location && remote_admin >= 0)
757d2cad 1135 {
1136 if (remote_admin)
480ef0fe 1137 cupsFilePuts(temp,
1138 "# Allow remote access to the configuration files...\n");
757d2cad 1139 else
1140 cupsFilePuts(temp, "# Restrict access to the configuration files...\n");
1141
1142 cupsFilePuts(temp, "<Location /admin/conf>\n"
0a682745 1143 " AuthType Default\n"
fcad6032
MS
1144 " Require user @SYSTEM\n"
1145 " Order allow,deny\n");
1146
1147 if (remote_admin)
1148 cupsFilePrintf(temp, " Allow %s\n", remote_any > 0 ? "all" : "@LOCAL");
1149
1150 cupsFilePuts(temp, "</Location>\n");
1151 }
1152
1153 if (!wrote_log_location && remote_admin >= 0)
1154 {
1155 if (remote_admin)
1156 cupsFilePuts(temp,
1157 "# Allow remote access to the log files...\n");
1158 else
1159 cupsFilePuts(temp, "# Restrict access to the log files...\n");
1160
1161 cupsFilePuts(temp, "<Location /admin/log>\n"
1162 " AuthType Default\n"
757d2cad 1163 " Require user @SYSTEM\n"
1164 " Order allow,deny\n");
1165
1166 if (remote_admin)
f7deaa1a 1167 cupsFilePrintf(temp, " Allow %s\n", remote_any > 0 ? "all" : "@LOCAL");
757d2cad 1168
1169 cupsFilePuts(temp, "</Location>\n");
1170 }
1171
b86bc4cf 1172 if (!wrote_policy && user_cancel_any >= 0)
757d2cad 1173 {
1174 cupsFilePuts(temp, "<Policy default>\n"
480ef0fe 1175 " # Job-related operations must be done by the owner "
355e94dc 1176 "or an administrator...\n"
757d2cad 1177 " <Limit Send-Document Send-URI Hold-Job Release-Job "
1178 "Restart-Job Purge-Jobs Set-Job-Attributes "
1179 "Create-Job-Subscription Renew-Subscription "
1180 "Cancel-Subscription Get-Notifications Reprocess-Job "
1181 "Cancel-Current-Job Suspend-Current-Job Resume-Job "
1182 "CUPS-Move-Job>\n"
1183 " Require user @OWNER @SYSTEM\n"
1184 " Order deny,allow\n"
1185 " </Limit>\n"
480ef0fe 1186 " # All administration operations require an "
355e94dc 1187 "administrator to authenticate...\n"
757d2cad 1188 " <Limit Pause-Printer Resume-Printer "
1189 "Set-Printer-Attributes Enable-Printer "
1190 "Disable-Printer Pause-Printer-After-Current-Job "
1191 "Hold-New-Jobs Release-Held-New-Jobs Deactivate-Printer "
1192 "Activate-Printer Restart-Printer Shutdown-Printer "
1193 "Startup-Printer Promote-Job Schedule-Job-After "
1194 "CUPS-Add-Printer CUPS-Delete-Printer "
1195 "CUPS-Add-Class CUPS-Delete-Class "
1196 "CUPS-Accept-Jobs CUPS-Reject-Jobs "
1197 "CUPS-Set-Default CUPS-Add-Device CUPS-Delete-Device>\n"
0a682745 1198 " AuthType Default\n"
757d2cad 1199 " Require user @SYSTEM\n"
1200 " Order deny,allow\n"
1201 "</Limit>\n");
1202
1203 if (!user_cancel_any)
480ef0fe 1204 cupsFilePuts(temp, " # Only the owner or an administrator can cancel "
1205 "a job...\n"
757d2cad 1206 " <Limit Cancel-Job>\n"
757d2cad 1207 " Order deny,allow\n"
355e94dc 1208 " Require user @OWNER "
b9faaae1 1209 CUPS_DEFAULT_PRINTOPERATOR_AUTH "\n"
757d2cad 1210 " </Limit>\n");
1211
1212 cupsFilePuts(temp, " <Limit All>\n"
1213 " Order deny,allow\n"
1214 " </Limit>\n"
1215 "</Policy>\n");
1216 }
1217
1218 for (i = num_settings, setting = settings; i > 0; i --, setting ++)
1219 if (setting->name[0] != '_' &&
88f9aafc
MS
1220 _cups_strcasecmp(setting->name, "Listen") &&
1221 _cups_strcasecmp(setting->name, "Port") &&
757d2cad 1222 !cupsGetOption(setting->name, cupsd_num_settings, cupsd_settings))
1223 {
1224 /*
1225 * Add this directive to the list of directives we have written...
1226 */
1227
1228 cupsd_num_settings = cupsAddOption(setting->name, setting->value,
1229 cupsd_num_settings, &cupsd_settings);
1230
1231 /*
7594b224 1232 * Write the new value, without indentation since we only support
1233 * setting root directives, not in sections...
757d2cad 1234 */
1235
1236 cupsFilePrintf(temp, "%s %s\n", setting->name, setting->value);
1237 }
1238
1239 cupsFileClose(cupsd);
1240 cupsFileClose(temp);
1241
1242 /*
1243 * Upload the configuration file to the server...
1244 */
1245
1246 status = cupsPutFile(http, "/admin/conf/cupsd.conf", tempfile);
1247
cb7f98ee 1248 if (status == HTTP_STATUS_CREATED)
757d2cad 1249 {
1250 /*
1251 * Updated OK, add the basic settings...
1252 */
1253
b86bc4cf 1254 if (debug_logging >= 0)
1255 cupsd_num_settings = cupsAddOption(CUPS_SERVER_DEBUG_LOGGING,
1256 debug_logging ? "1" : "0",
1257 cupsd_num_settings, &cupsd_settings);
1258 else
1259 cupsd_num_settings = cupsAddOption(CUPS_SERVER_DEBUG_LOGGING,
1260 old_debug_logging ? "1" : "0",
1261 cupsd_num_settings, &cupsd_settings);
1262
1263 if (remote_admin >= 0)
1264 cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ADMIN,
1265 remote_admin ? "1" : "0",
1266 cupsd_num_settings, &cupsd_settings);
1267 else
1268 cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ADMIN,
1269 old_remote_admin ? "1" : "0",
1270 cupsd_num_settings, &cupsd_settings);
1271
6720d4f4
MS
1272 if (remote_any >= 0)
1273 cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ANY,
1274 remote_any ? "1" : "0",
1275 cupsd_num_settings, &cupsd_settings);
1276 else
1277 cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ANY,
1278 old_remote_any ? "1" : "0",
1279 cupsd_num_settings, &cupsd_settings);
f7deaa1a 1280
b86bc4cf 1281 if (share_printers >= 0)
1282 cupsd_num_settings = cupsAddOption(CUPS_SERVER_SHARE_PRINTERS,
1283 share_printers ? "1" : "0",
1284 cupsd_num_settings, &cupsd_settings);
1285 else
1286 cupsd_num_settings = cupsAddOption(CUPS_SERVER_SHARE_PRINTERS,
1287 old_share_printers ? "1" : "0",
1288 cupsd_num_settings, &cupsd_settings);
1289
1290 if (user_cancel_any >= 0)
1291 cupsd_num_settings = cupsAddOption(CUPS_SERVER_USER_CANCEL_ANY,
1292 user_cancel_any ? "1" : "0",
1293 cupsd_num_settings, &cupsd_settings);
1294 else
1295 cupsd_num_settings = cupsAddOption(CUPS_SERVER_USER_CANCEL_ANY,
1296 old_user_cancel_any ? "1" : "0",
1297 cupsd_num_settings, &cupsd_settings);
757d2cad 1298
1299 /*
1300 * Save the new values...
1301 */
1302
1303 invalidate_cupsd_cache(cg);
1304
1305 cg->cupsd_num_settings = cupsd_num_settings;
1306 cg->cupsd_settings = cupsd_settings;
1307 cg->cupsd_update = time(NULL);
1308
1309 httpGetHostname(http, cg->cupsd_hostname, sizeof(cg->cupsd_hostname));
1310 }
1311 else
1312 cupsFreeOptions(cupsd_num_settings, cupsd_settings);
1313
1314 /*
1315 * Remote our temp files and return...
1316 */
1317
1318 if (remote)
1319 unlink(cupsdconf);
1320
1321 unlink(tempfile);
1322
cb7f98ee 1323 return (status == HTTP_STATUS_CREATED);
757d2cad 1324}
1325
1326
757d2cad 1327/*
1328 * 'get_cupsd_conf()' - Get the current cupsd.conf file.
1329 */
1330
1331static http_status_t /* O - Status of request */
1332get_cupsd_conf(
1333 http_t *http, /* I - Connection to server */
1334 _cups_globals_t *cg, /* I - Global data */
1335 time_t last_update, /* I - Last update time for file */
1336 char *name, /* I - Filename buffer */
07623986 1337 size_t namesize, /* I - Size of filename buffer */
757d2cad 1338 int *remote) /* O - Remote file? */
1339{
1340 int fd; /* Temporary file descriptor */
19dc16f7 1341#ifndef _WIN32
757d2cad 1342 struct stat info; /* cupsd.conf file information */
19dc16f7 1343#endif /* _WIN32 */
757d2cad 1344 http_status_t status; /* Status of getting cupsd.conf */
1345 char host[HTTP_MAX_HOST]; /* Hostname for connection */
1346
1347
1348 /*
1349 * See if we already have the data we need...
1350 */
1351
1352 httpGetHostname(http, host, sizeof(host));
1353
88f9aafc 1354 if (_cups_strcasecmp(cg->cupsd_hostname, host))
757d2cad 1355 invalidate_cupsd_cache(cg);
1356
1357 snprintf(name, namesize, "%s/cupsd.conf", cg->cups_serverroot);
1358 *remote = 0;
1359
19dc16f7 1360#ifndef _WIN32
88f9aafc 1361 if (!_cups_strcasecmp(host, "localhost") && !access(name, R_OK))
757d2cad 1362 {
1363 /*
1364 * Read the local file rather than using HTTP...
1365 */
1366
1367 if (stat(name, &info))
1368 {
480ef0fe 1369 char message[1024]; /* Message string */
757d2cad 1370
480ef0fe 1371
1372 snprintf(message, sizeof(message),
1373 _cupsLangString(cupsLangDefault(), _("stat of %s failed: %s")),
1374 name, strerror(errno));
cb7f98ee 1375 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, message, 0);
480ef0fe 1376
1377 *name = '\0';
757d2cad 1378
cb7f98ee 1379 return (HTTP_STATUS_SERVER_ERROR);
757d2cad 1380 }
1381 else if (last_update && info.st_mtime <= last_update)
cb7f98ee 1382 status = HTTP_STATUS_NOT_MODIFIED;
757d2cad 1383 else
cb7f98ee 1384 status = HTTP_STATUS_OK;
757d2cad 1385 }
1386 else
19dc16f7 1387#endif /* !_WIN32 */
757d2cad 1388 {
1389 /*
1390 * Read cupsd.conf via a HTTP GET request...
1391 */
1392
df0f06ae 1393 if ((fd = cupsTempFd(name, (int)namesize)) < 0)
757d2cad 1394 {
1395 *name = '\0';
1396
cb7f98ee 1397 _cupsSetError(IPP_STATUS_ERROR_INTERNAL, NULL, 0);
757d2cad 1398
1399 invalidate_cupsd_cache(cg);
1400
cb7f98ee 1401 return (HTTP_STATUS_SERVER_ERROR);
757d2cad 1402 }
1403
1404 *remote = 1;
1405
1406 httpClearFields(http);
1407
1408 if (last_update)
1409 httpSetField(http, HTTP_FIELD_IF_MODIFIED_SINCE,
1410 httpGetDateString(last_update));
1411
1412 status = cupsGetFd(http, "/admin/conf/cupsd.conf", fd);
1413
1414 close(fd);
1415
cb7f98ee 1416 if (status != HTTP_STATUS_OK)
757d2cad 1417 {
1418 unlink(name);
1419 *name = '\0';
1420 }
1421 }
1422
1423 return (status);
1424}
1425
1426
1427/*
1428 * 'invalidate_cupsd_cache()' - Invalidate the cached cupsd.conf settings.
1429 */
1430
1431static void
1432invalidate_cupsd_cache(
1433 _cups_globals_t *cg) /* I - Global data */
1434{
1435 cupsFreeOptions(cg->cupsd_num_settings, cg->cupsd_settings);
1436
1437 cg->cupsd_hostname[0] = '\0';
1438 cg->cupsd_update = 0;
1439 cg->cupsd_num_settings = 0;
1440 cg->cupsd_settings = NULL;
1441}