]> andersk Git - moira.git/blame - gen/cups-print.pc
cups-lpd DCM.
[moira.git] / gen / cups-print.pc
CommitLineData
f50216d7 1/* $Id$
2 *
3 * This generates printcaps and other files for Athena print servers
4 *
5 * Copyright (C) 1992-1998 by the Massachusetts Institute of Technology.
6 * For copying and distribution information, please see the file
7 * <mit-copyright.h>.
8 */
9
10#include <mit-copyright.h>
11#include <moira.h>
12#include <moira_site.h>
13
14#include <sys/stat.h>
15#include <sys/types.h>
16
17#include <ctype.h>
18#include <stdio.h>
19#include <string.h>
20
21#include <time.h>
cb974713 22#ifdef HAVE_KRB4
f50216d7 23#include <krb.h>
cb974713 24#endif
f50216d7 25#include <krb5.h>
26
27#include "util.h"
28
f50216d7 29EXEC SQL INCLUDE sqlca;
30
31RCSID("$Header$");
32
33char *whoami = "cups-print.gen";
34char *db = "moira/moira";
35
36/* OMG, I hate this, but it's cleaner, I guess? */
37
ea998f5e 38const char *alterjob = "<Limit Hold-Job Release-Job\
39 Restart-Job Purge-Jobs Reprocess-Job Set-Job-Attributes\
f50216d7 40 Cancel-Current-Job Suspend-Current-Job Resume-Job CUPS-Move-Job>";
ea998f5e 41const char *submitjob = "<Limit Create-Job Print-Job Print-URI Send-Document\
42 Set-Job-Attributes Send-URI Create-Job-Subscription Renew-Subscription\
43 Cancel-Subscription Get-Notifications CUPS-Move-Job>";
f50216d7 44const char *alterpntr = "<Limit CUPS-Add-Modify-Printer CUPS-Delete-Printer\
45 CUPS-Add-Modify-Class CUPS-Delete-Class CUPS-Set-Default>";
46const char *lpcpntr = "<Limit Pause-Printer Resume-Printer Enable-Printer\
47 Disable-Printer Pause-Printer-After-Current-Job Hold-New-Jobs\
48 Release-Held-New-Jobs Deactivate-Printer Activate-Printer Restart-Printer\
49 Shutdown-Printer Startup-Printer Promote-Job Schedule-Job-After\
50 CUPS-Accept-Jobs CUPS-Reject-Jobs>";
51const char *canceljob = "<Limit Cancel-Job CUPS-Authenticate-Job>";
52const char *catchall = "<Limit All>";
200545fb 53const char *phost = "printers.MIT.EDU";
f50216d7 54
55void do_host(char *host);
56void sqlerr(void);
57#ifndef MAX
58#define MAX(a, b) ( (a) > (b) ? (a) : (b) )
59#endif
60
61int main(int argc, char **argv)
62{
63 EXEC SQL BEGIN DECLARE SECTION;
64 char name[MACHINE_NAME_SIZE];
65 EXEC SQL END DECLARE SECTION;
66
67 init_acls();
68
69 EXEC SQL CONNECT :db;
70
71 EXEC SQL WHENEVER SQLERROR DO sqlerr();
72
73 EXEC SQL DECLARE csr_hosts CURSOR FOR
74 SELECT m.name FROM machine m, serverhosts sh
c3c53552 75 WHERE m.mach_id = sh.mach_id AND sh.service = 'CUPS-PRINT' AND sh.enable = 1;
f50216d7 76 EXEC SQL OPEN csr_hosts;
77 while (1)
78 {
79 EXEC SQL FETCH csr_hosts INTO :name;
80 if (sqlca.sqlcode)
81 break;
82
83 strtrim(name);
84 do_host(name);
85 }
86 EXEC SQL CLOSE csr_hosts;
87
88 exit(MR_SUCCESS);
89}
90
91void printer_user_list(FILE *out, char *type, int id, char *str)
92{
93 struct save_queue *sq;
94 struct imember *m;
95
96 sq = get_acl(type, id, NULL);
97 while (sq_remove_data(sq, &m))
98 {
99 if (m->type == 'U')
100 fprintf(out, "%s %s\n", str, m->name);
101 freeimember(m);
102 }
103 sq_destroy(sq);
104}
105
106
107
108void do_host(char *host)
109{
110 EXEC SQL BEGIN DECLARE SECTION;
111 char rp[PRINTERS_RP_SIZE], name[PRINTERS_NAME_SIZE];
112 char duplexname[PRINTERS_DUPLEXNAME_SIZE], location[PRINTERS_LOCATION_SIZE];
113 char hwtype[PRINTERS_HWTYPE_SIZE], lowerhwtype[PRINTERS_HWTYPE_SIZE];
114 char modtime[PRINTERS_MODTIME_SIZE], lmodtime[LIST_MODTIME_SIZE];
115 char contact[PRINTERS_CONTACT_SIZE], hostname[MACHINE_NAME_SIZE];
116 char cupshosts[MACHINE_NAME_SIZE], prtype [PRINTERS_TYPE_SIZE];
117 char *spoolhost = host, *unixtime_fmt = UNIXTIME_FMT, *p;
118 char *lhost;
119 int ka, pc, ac, lpc_acl, top_lpc_acl, banner, rm;
120 EXEC SQL END DECLARE SECTION;
121 TARFILE *tf;
122 FILE *out;
123 char filename[MAXPATHLEN], *duptc;
124 time_t mtime, now = time(NULL);
125
126 lhost = (char *) strdup (host);
127 for (p = lhost; *p; p++)
128 *p = tolower(*p);
129
130 EXEC SQL SELECT mach_id INTO :rm FROM machine
131 WHERE name = :spoolhost;
132
c3c53552 133 sprintf(filename, "%s/cups-print/%s", DCM_DIR, host);
f50216d7 134 tf = tarfile_open(filename);
135
136 /* printers.conf */
137 out = tarfile_start(tf, "/etc/cups/printers.conf", 0644, 0, 0,
200545fb 138 "lp", "lp", now);
f50216d7 139
140 EXEC SQL DECLARE csr_printers CURSOR FOR
141 SELECT pr.rp, pr.name, pr.duplexname, pr.hwtype,
142 m.name, pr.banner, pr.location, pr.contact, pr.ka,
143 pr.ac
144 FROM printers pr, machine m
145 WHERE pr.rm = :rm AND m.mach_id = pr.mach_id
146 AND pr.type != 'ALIAS';
147 EXEC SQL OPEN csr_printers;
148 while (1)
149 {
150 EXEC SQL FETCH csr_printers INTO :rp, :name, :duplexname,
151 :hwtype, :hostname, :banner, :location, :contact, :ka, :ac;
152 if (sqlca.sqlcode)
153 break;
154
155 strtrim(rp);
156 strtrim(name);
157 strtrim(duplexname);
158 strtrim(hwtype);
159 strtrim(hostname);
160 strtrim(location);
161 strtrim(contact);
162 strcpy(lowerhwtype, hwtype);
163 for (p = lowerhwtype; *p; p++)
164 *p = tolower(*p);
165
166 fprintf(out, "<Printer %s>\n",rp);
167 fprintf(out, "Info %s:%s\n", rp, hwtype);
168 /* Note the use of "beh" to keep the CUPS from disabling print queues
169 * should they not respond versus discarding the job.
170 * See the "beh" page for details.
171 * The 1/0/60 says "don't disable/try 20 times/try every 60s */
172 if (!strncmp(hwtype, "HP", 2))
173 fprintf(out, "DeviceURI beh:/1/20/60/socket://%s:9100\n", hostname);
174 else
175 fprintf(out, "DeviceURI beh:/1/20/60/socket://%s\n", hostname);
176 fprintf(out, "State Idle\n"); // Always with the Idle
177 fprintf(out, "StateTime %ld\n", (long)time(NULL));
178 fprintf(out, "Accepting Yes\n");
179 fprintf(out, "Shared Yes\n");
180 fprintf(out, "QuotaPeriod 0\n");
181 fprintf(out, "PageLimit 0\n");
182 fprintf(out, "Klimit 0\n");
183 fprintf(out, "Option sides one-sided\n");
184 if (location[0])
185 fprintf(out, "Location %s\n", location);
186 fprintf(out, "ErrorPolicy abort-job\n");
187 if (! ka || ! lpc_acl)
188 fprintf(out, "OpPolicy default\n");
189 else
190 fprintf(out, "OpPolicy %s-policy\n", rp);
191
192 /* Access-control list. */
193 if (ac)
194 {
195 if (ka)
196 fprintf(out, "AuthType Negotiate\n");
197 else
198 fprintf(out, "AuthType Negotiate\n");
199 printer_user_list(out, "LIST", ac, "AllowUser");
200 }
201
202 if (banner == PRN_BANNER_NONE)
203 fprintf(out, "JobSheets none none\n");
204 else
205 fprintf(out, "JobSheets athena none\n");
206 fprintf(out, "</Printer>\n");
207
208 }
209 EXEC SQL CLOSE csr_printers;
210 tarfile_end(tf);
211
212
213 /* aliases are in classes.conf */
214 out = tarfile_start(tf, "/etc/cups/classes.conf", 0644, 0, 0,
200545fb 215 "lp", "lp", now);
f50216d7 216 EXEC SQL DECLARE csr_duplexqs CURSOR FOR
217 SELECT pr.rp, pr.name, pr.duplexname, pr.hwtype,
218 m.name, pr.banner, pr.location, pr.contact, pr.ka,
219 pr.type as prtype, pr.ac
220 FROM printers pr, machine m
221 WHERE pr.rm = :rm AND m.mach_id = pr.mach_id;
222 EXEC SQL OPEN csr_duplexqs;
223 while (1)
224 {
225 EXEC SQL FETCH csr_duplexqs INTO :rp, :name, :duplexname,
226 :hwtype, :hostname, :banner, :location, :contact, :ka, :prtype, :ac;
227 if (sqlca.sqlcode)
228 break;
229
230 strtrim(hwtype);
231 strtrim(rp);
232 strtrim(location);
233 strtrim(contact);
234 strtrim(prtype);
235
236 /* Define alias queues as classes to the regular queues for
237 * accounting reasons. Annoyingly, classes don't always inherit
238 * their printer definitions.
239 */
240 if (!strcmp(prtype,"ALIAS"))
241 {
242 strtrim(name);
243 fprintf(out, "<Class %s>\n",name);
244 fprintf(out, "Info Alias Queue to %s:%s\n", rp, hwtype);
245 fprintf(out, "Printer %s\n", rp);
246 fprintf(out, "Option sides one-sided\n");
247 fprintf(out, "State Idle\n"); // Always with the Idle
248 fprintf(out, "StateTime %ld\n", (long)time(NULL));
249 fprintf(out, "Accepting Yes\n");
250 fprintf(out, "Shared Yes\n");
251 fprintf(out, "QuotaPeriod 0\n");
252 fprintf(out, "PageLimit 0\n");
253 if (location[0])
254 fprintf(out, "Location %s\n", location);
255 fprintf(out, "ErrorPolicy abort-job\n");
256 if (! ka || ! lpc_acl)
257 fprintf(out, "OpPolicy default\n");
258 else
259 fprintf(out, "OpPolicy %s-policy\n", rp);
260
261 /* Access-control list. */
262 if (ac)
263 {
264 if (ka)
265 fprintf(out, "AuthType Negotiate\n");
266 else
267 fprintf(out, "AuthType Negotiate\n");
268 printer_user_list(out, "LIST", ac, "AllowUser");
269 }
270
271 if (banner == PRN_BANNER_NONE)
272 fprintf(out, "JobSheets none none\n");
273 else
274 fprintf(out, "JobSheets athena none\n");
275 fprintf(out, "</Class>\n");
276 }
277
278 /* Define duplex queues as aliases to the regular queues for
279 * accounting reasons. Annoyingly, classes don't always inherit
280 * their printer definitions.
281 */
282 if (*duplexname)
283 {
284 strtrim(duplexname);
285 fprintf(out, "<Class %s>\n",duplexname);
286 if (!strcmp(prtype,"ALIAS"))
287 fprintf(out, "Info Duplex Alias Queue to %s:%s\n", rp, hwtype);
288 else
289 fprintf(out, "Info Duplex Queue for %s:%s\n", rp, hwtype);
290 fprintf(out, "Option sides two-sided-long-edge\n"); // duplex
291 fprintf(out, "Printer %s\n", rp);
292 fprintf(out, "State Idle\n"); // Always with the Idle
293 fprintf(out, "StateTime %ld\n", (long)time(NULL));
294 fprintf(out, "Accepting Yes\n");
295 fprintf(out, "Shared Yes\n");
296 fprintf(out, "QuotaPeriod 0\n");
297 fprintf(out, "PageLimit 0\n");
298 if (location[0])
299 fprintf(out, "Location %s\n", location);
300 fprintf(out, "ErrorPolicy abort-job\n");
301 if (! ka || ! lpc_acl)
302 fprintf(out, "OpPolicy default\n");
303 else
304 fprintf(out, "OpPolicy %s-policy\n", rp);
305
306 /* Access-control list. */
307 if (ac)
308 {
309 if (ka)
310 fprintf(out, "AuthType Negotiate\n");
311 else
312 fprintf(out, "AuthType Negotiate\n");
313 printer_user_list(out, "LIST", ac, "AllowUser");
314 }
315
316 if (banner == PRN_BANNER_NONE)
317 fprintf(out, "JobSheets none none\n");
318 else if (banner == PRN_BANNER_LAST)
319 fprintf(out, "JobSheets athena none\n");
320 fprintf(out, "</Class>\n");
321 }
322 }
323 EXEC SQL CLOSE csr_duplexqs;
324 tarfile_end(tf);
325
326 /* cups.conf */
327 out = tarfile_start(tf, "/etc/cups/cupsd.conf", 0755, 1, 1,
328 "root", "lp", now);
329
330 fprintf(out, "LogLevel info\n");
331 fprintf(out, "SystemGroup sys root ops-group\n");
332 fprintf(out, "Port 631\n");
333 fprintf(out, "Listen /var/run/cups/cups.sock\n");
334 fprintf(out, "Browsing On\n");
335 fprintf(out, "BrowseOrder allow,deny\n");
336 fprintf(out, "BrowseAllow all\n");
337 fprintf(out, "BrowseAddress @LOCAL\n");
338 fprintf(out, "DefaultAuthType Negotiate\n");
339 fprintf(out, "ServerCertificate /etc/cups/ssl/%s-ipp-crt.pem\n", lhost);
340 fprintf(out, "ServerKey /etc/cups/ssl/%s-ipp-key.pem\n", lhost);
341 fprintf(out, "ServerName %s\n", lhost);
200545fb 342 fprintf(out, "ServerAlias %s\n", phost);
f50216d7 343 fprintf(out, "Krb5Keytab /etc/krb5-ipp.keytab\n");
f50216d7 344
345 /* The other CUPS servers should be aware of the other hosts'
346 queues, so we'll let them browse each other. */
72a62bdc 347 fprintf(out, "Include cups.local.conf\n");
72a62bdc 348 fprintf(out, "Include cups.locations.conf\n");
349 fprintf(out, "Include cups.policies.conf\n");
350 tarfile_end(tf);
f50216d7 351
72a62bdc 352 /* cups.hosts.conf */
353 out = tarfile_start(tf, "/etc/cups/cups.hosts.conf", 0755, 1, 1,
354 "root", "lp", now);
f50216d7 355 EXEC SQL DECLARE csr_cupshosts CURSOR FOR
356 SELECT m.name AS cupshosts FROM machine m, printservers ps
357 WHERE m.mach_id = ps.mach_id AND ps.kind = 'CUPS';
358 EXEC SQL OPEN csr_cupshosts;
359 while (1)
360 {
361 EXEC SQL FETCH csr_cupshosts INTO :cupshosts;
362 if (sqlca.sqlcode)
363 break;
364
365 strtrim(cupshosts);
366
367 /* Don't poll yourself looking for answers! */
368 if (strcmp(cupshosts,host))
369 fprintf(out, "BrowsePoll %s\n", cupshosts);
370 }
371 EXEC SQL CLOSE csr_cupshosts;
f50216d7 372
373 tarfile_end(tf);
374
375 /* cups.policies.conf */
376 out = tarfile_start(tf, "/etc/cups/cups.policies.conf", 0755, 1, 1,
377 "root", "lp", now);
378 fprintf(out, "# Printer-specific LPC and LPR ACLs\n");
379 /* lpcaccess.top */
380 EXEC SQL SELECT ps.lpc_acl INTO :top_lpc_acl
381 FROM printservers ps, machine m
382 WHERE m.name = :spoolhost AND m.mach_id = ps.mach_id;
383 if (!sqlca.sqlcode && lpc_acl)
384 {
385 fprintf (out, "<Policy default>\n");
386 fprintf (out, "%s\n", alterjob);
387 fprintf (out, "AuthType Default\n");
388 fprintf (out, "Require user @OWNER @SYSTEM\n");
389 printer_user_list(out, "LIST", top_lpc_acl, "Require user");
390 fprintf (out, "Order deny,allow\n");
391 fprintf (out, "</Limit>\n");
392 fprintf (out, "%s\n", submitjob);
11bc6bdc 393 fprintf (out, "AuthType None\n");
f50216d7 394 fprintf (out, "Order deny,allow\n");
11bc6bdc 395 fprintf (out, "Allow from all\n");
f50216d7 396 fprintf (out, "</Limit>\n");
397 fprintf (out, "%s\n", alterpntr);
398 fprintf (out, "AuthType Default\n");
399 fprintf (out, "Require user @SYSTEM\n");
400 fprintf (out, "Order deny,allow\n");
401 fprintf (out, "</Limit>\n");
402 fprintf (out, "%s\n", lpcpntr);
403 fprintf (out, "AuthType Default\n");
404 fprintf (out, "Require user @SYSTEM\n");
405 printer_user_list(out, "LIST", top_lpc_acl, "Require user");
406 fprintf (out, "Order deny,allow\n");
407 fprintf (out, "</Limit>\n");
408 fprintf (out, "%s\n", canceljob);
409 fprintf (out, "AuthType Default\n");
410 fprintf (out, "Require user @OWNER @SYSTEM\n");
411 printer_user_list(out, "LIST", top_lpc_acl, "Require user");
412 fprintf (out, "Order deny,allow\n");
03e05c1a 413 fprintf (out, "Allow from all\n");
f50216d7 414 fprintf (out, "</Limit>\n");
415 fprintf (out, "%s\n", catchall);
81b41491 416 fprintf (out, "AuthType None\n");
f50216d7 417 fprintf (out, "Order deny,allow\n");
11bc6bdc 418 fprintf (out, "Allow from all\n");
f50216d7 419 fprintf (out, "</Limit>\n");
420 fprintf (out, "</Policy>\n");
421 }
422
423 /* restrict lists and lpcaccess policies. Sadly, we have to put the
424 top level for each new policy since CUPS doesn't have a way of
425 doing it otherwise (well, Unix groups, but not moira) */
426 EXEC SQL DECLARE csr_lpc CURSOR FOR
427 SELECT UNIQUE rp, ka, ac, lpc_acl
428 FROM printers
429 WHERE rm = :rm AND ( ac != 0 OR lpc_acl != 0);
430 EXEC SQL OPEN csr_lpc;
431 while (1)
432 {
433 EXEC SQL FETCH csr_lpc INTO :name, :ka, :ac, :lpc_acl;
434 if (sqlca.sqlcode)
435 break;
436
437 strtrim(name);
438
439 fprintf (out, "<Policy %s-policy>\n", name);
440 fprintf (out, "%s\n", alterjob);
441 fprintf (out, "AuthType Default\n");
442 fprintf (out, "Require user @OWNER @SYSTEM\n");
443 printer_user_list(out, "LIST", lpc_acl, "Require user");
444 fprintf (out, "Order deny,allow\n");
03e05c1a 445 fprintf (out, "Allow from all\n");
f50216d7 446 fprintf (out, "</Limit>\n");
447 fprintf (out, "%s\n", submitjob);
448 /* If the printer is Kerberized? */
449 if (ka)
450 fprintf (out, "AuthType Negotiate\n");
451 else
452 fprintf (out, "AuthType None\n");
453 /* Access-control list. */
454 if (ac)
455 printer_user_list(out, "LIST", ac, "Require user");
456 else if (ka)
457 fprintf (out, "Require valid-user\n");
458 fprintf (out, "Order deny,allow\n");
11bc6bdc 459 fprintf (out, "Allow from all\n");
f50216d7 460 fprintf (out, "</Limit>\n");
461 fprintf (out, "%s\n", alterpntr);
462 fprintf (out, "AuthType Default\n");
463 fprintf (out, "Require user @SYSTEM\n");
464 fprintf (out, "Order deny,allow\n");
465 fprintf (out, "</Limit>\n");
466 fprintf (out, "%s\n", lpcpntr);
467 fprintf (out, "AuthType Default\n");
468 fprintf (out, "Require user @SYSTEM\n");
469 /* printer-specific lpc access. */
470 if (lpc_acl)
471 printer_user_list(out, "LIST", lpc_acl, "Require user");
472 printer_user_list(out, "LIST", top_lpc_acl, "Require user");
473 fprintf (out, "Order deny,allow\n");
474 fprintf (out, "</Limit>\n");
475 fprintf (out, "%s\n", canceljob);
476 fprintf (out, "AuthType Default\n");
477 fprintf (out, "Require user @OWNER @SYSTEM\n");
478 printer_user_list(out, "LIST", lpc_acl, "Require user");
479 printer_user_list(out, "LIST", top_lpc_acl, "Require user");
480 fprintf (out, "Order deny,allow\n");
11bc6bdc 481 fprintf (out, "Allow from all\n");
f50216d7 482 fprintf (out, "</Limit>\n");
483 fprintf (out, "%s\n", catchall);
11bc6bdc 484 fprintf (out, "AuthType None\n");
f50216d7 485 fprintf (out, "Order deny,allow\n");
11bc6bdc 486 fprintf (out, "Allow from all\n");
f50216d7 487 fprintf (out, "</Limit>\n");
488 fprintf (out, "</Policy>\n");
489 }
490 EXEC SQL CLOSE csr_lpc;
491 fprintf(out, "\n");
492 tarfile_end(tf);
493 tarfile_close(tf);
494}
495
496void sqlerr(void)
497{
498 db_error(sqlca.sqlcode);
499}
This page took 0.151505 seconds and 5 git commands to generate.