From cfba011a7a75bbc269df787d9d2fe17eaf5b2e37 Mon Sep 17 00:00:00 2001 From: zacheiss Date: Fri, 13 Nov 2009 23:05:07 +0000 Subject: [PATCH] Alas, LDAP. --- gen/Makefile.in | 12 +- gen/cups-cluster.pc | 657 ++++++++++++++++++++++++++++++++++++++++++++ gen/cups-cluster.sh | 50 ++++ gen/cups-print.pc | 155 ++++++++++- 4 files changed, 863 insertions(+), 11 deletions(-) create mode 100644 gen/cups-cluster.pc create mode 100755 gen/cups-cluster.sh diff --git a/gen/Makefile.in b/gen/Makefile.in index f48d3907..1a8ba98e 100644 --- a/gen/Makefile.in +++ b/gen/Makefile.in @@ -32,21 +32,21 @@ LIB_OBJS=util.o tar.o genacl.o LIB_CFILES=genacl.c LIB_TARGET=libdcm.a -OBJS= acl.lo boot.lo confluence.lo cups-print.lo cups-lpd.lo dhcp.lo directory.lo events.lo \ +OBJS= acl.lo boot.lo confluence.lo cups-print.lo cups-cluster.lo dhcp.lo directory.lo events.lo \ hesiod.lo hosts.lo lpcaccess.lo mailhub.lo ndb.lo network.lo nfs.lo pobox.lo \ postoffice.lo print.lo warehouse-lists.lo winad.lo www.lo zephyr.lo -CFILES= acl.c boot.c confluence.c cups-print.c cups-lpd.c dhcp.c directory.c events.c \ +CFILES= acl.c boot.c confluence.c cups-print.c cups-cluster.c dhcp.c directory.c events.c \ hesiod.c hosts.c lpcaccess.c mailhub.c ndb.c network.c nfs.c pobox.c \ postoffice.c print.c warehouse-lists.c winad.c www.c zephyr.c -TARGET= acl.gen boot.gen confluence.gen cups-print.gen cups-lpd.gen dhcp.gen directory.gen \ +TARGET= acl.gen boot.gen confluence.gen cups-print.gen cups-cluster.gen dhcp.gen directory.gen \ events.gen hesiod.gen hosts.gen lpcaccess.gen mailhub.gen ndb.gen \ network.gen nfs.gen pobox.gen postoffice.gen print.gen \ warehouse-lists.gen winad.gen www.gen zephyr.gen SCRIPTS=access.gen access.sh acl.sh aliases.sh boot.sh ca.gen calendar.gen \ - cups-print.sh cups-lpd.sh dhcp.sh events.sh hesiod.sh ip-billing.gen \ + cups-print.sh cups-cluster.sh dhcp.sh events.sh hesiod.sh ip-billing.gen \ ip-billing.sh ldap.gen longjobs.gen longjobs.sh mailhosts.gen \ mailhub.sh mailman.gen mailman.sh nagios-cluster.gen \ nagios-cluster.sh nagios-colo.gen nagios-colo.sh \ @@ -151,5 +151,5 @@ warehouse-lists.gen: warehouse-lists.lo libdcm.a $(MR_LIBDEP) cups-print.gen: cups-print.lo libdcm.a $(MR_LIBDEP) $(LIBTOOL) --mode=link $(CC) -static -o $@ $(LDFLAGS) cups-print.lo libdcm.a $(SQL_LIBS) $(LIBS) -cups-lpd.gen: cups-lpd.lo libdcm.a $(MR_LIBDEP) - $(LIBTOOL) --mode=link $(CC) -static -o $@ $(LDFLAGS) cups-lpd.lo libdcm.a $(SQL_LIBS) $(LIBS) +cups-cluster.gen: cups-cluster.lo libdcm.a $(MR_LIBDEP) + $(LIBTOOL) --mode=link $(CC) -static -o $@ $(LDFLAGS) cups-cluster.lo libdcm.a $(SQL_LIBS) $(LIBS) diff --git a/gen/cups-cluster.pc b/gen/cups-cluster.pc new file mode 100644 index 00000000..11c96050 --- /dev/null +++ b/gen/cups-cluster.pc @@ -0,0 +1,657 @@ +/* $Id$ + * + * This generates printcaps and other files for Athena print servers + * + * Copyright (C) 1992-1998 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * . + */ + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#ifdef HAVE_KRB4 +#include +#endif +#include + +#include "util.h" + +EXEC SQL INCLUDE sqlca; + +RCSID("$Header$"); + +char *whoami = "cups-print.gen"; +char *db = "moira/moira"; + +const int krbvers = 5; /* use Kerberos 5 */ + +/* OMG, I hate this, but it's cleaner, I guess? */ + +const char *alterjob = ""; +const char *submitjob = ""; +const char *alterpntr = ""; +const char *lpcpntr = ""; +const char *canceljob = ""; +const char *catchall = ""; +const char *phost = "printers.MIT.EDU"; + +void do_host(char *host); +void sqlerr(void); +#ifndef MAX +#define MAX(a, b) ( (a) > (b) ? (a) : (b) ) +#endif + +int main(int argc, char **argv) +{ + EXEC SQL BEGIN DECLARE SECTION; + char name[MACHINE_NAME_SIZE]; + EXEC SQL END DECLARE SECTION; + + init_acls(); + + EXEC SQL CONNECT :db; + + EXEC SQL WHENEVER SQLERROR DO sqlerr(); + + EXEC SQL DECLARE csr_hosts CURSOR FOR + SELECT m.name FROM machine m, serverhosts sh + WHERE m.mach_id = sh.mach_id AND sh.service = 'CUPS-CLUSTER' AND sh.enable = 1; + EXEC SQL OPEN csr_hosts; + while (1) + { + EXEC SQL FETCH csr_hosts INTO :name; + if (sqlca.sqlcode) + break; + + strtrim(name); + do_host(name); + } + EXEC SQL CLOSE csr_hosts; + + exit(MR_SUCCESS); +} + +void printer_user_list(FILE *out, char *type, int id, char *str) +{ + struct save_queue *sq; + struct imember *m; + char kbuf[MAX_K_NAME_SZ]; + char *cp; + + sq = get_acl(type, id, NULL); + while (sq_remove_data(sq, &m)) + { + if (m->type != 'S' && m->type != NULL) { + /* CUPS wants mmanley/root, not mmanley.root@ATHENA.MIT.EDU */ + canon_krb(m, krbvers, kbuf, sizeof(kbuf)); + + /* now, take out all the @realm */ + for (cp=kbuf; *cp; cp++) { + if (*cp == '@') *cp = '\0'; + } + fprintf(out, "%s %s\n", str, kbuf); + } + freeimember(m); + } + sq_destroy(sq); +} + + + +void do_host(char *host) +{ + EXEC SQL BEGIN DECLARE SECTION; + char rp[PRINTERS_RP_SIZE], name[PRINTERS_NAME_SIZE]; + char duplexname[PRINTERS_DUPLEXNAME_SIZE], location[PRINTERS_LOCATION_SIZE]; + char hwtype[PRINTERS_HWTYPE_SIZE], lowerhwtype[PRINTERS_HWTYPE_SIZE]; + char modtime[PRINTERS_MODTIME_SIZE], lmodtime[LIST_MODTIME_SIZE]; + char contact[PRINTERS_CONTACT_SIZE], hostname[MACHINE_NAME_SIZE]; + char cupshosts[MACHINE_NAME_SIZE], prtype [PRINTERS_TYPE_SIZE]; + char *spoolhost = host, *unixtime_fmt = UNIXTIME_FMT, *p; + char *lhost; + int ka, pc, ac, lpc_acl, top_lpc_acl, banner, rm; + EXEC SQL END DECLARE SECTION; + TARFILE *tf; + FILE *out; + char filename[MAXPATHLEN], *duptc; + time_t mtime, now = time(NULL); + + lhost = (char *) strdup (host); + for (p = lhost; *p; p++) + *p = tolower(*p); + + EXEC SQL SELECT mach_id INTO :rm FROM machine + WHERE name = :spoolhost; + + sprintf(filename, "%s/cups-cluster/%s", DCM_DIR, host); + tf = tarfile_open(filename); + + /* printers.conf entries for locally run queues */ + out = tarfile_start(tf, "/etc/cups/printers.conf", 0644, 0, 0, + "lp", "lp", now); + + EXEC SQL DECLARE csr_printers CURSOR FOR + SELECT pr.rp, pr.name, pr.duplexname, pr.hwtype, + m.name, pr.banner, pr.location, pr.contact, pr.ka, + pr.ac, pr.lpc_acl + FROM printers pr, machine m + WHERE pr.rm = :rm AND m.mach_id = pr.mach_id + AND (pr.type = 'DORM' or pr.type = 'CLUSTER'); + EXEC SQL OPEN csr_printers; + while (1) + { + EXEC SQL FETCH csr_printers INTO :rp, :name, :duplexname, + :hwtype, :hostname, :banner, :location, :contact, :ka, :ac, :lpc_acl; + if (sqlca.sqlcode) + break; + + strtrim(rp); + strtrim(name); + strtrim(duplexname); + strtrim(hwtype); + strtrim(hostname); + strtrim(location); + strtrim(contact); + strcpy(lowerhwtype, hwtype); + for (p = rp; *p; p++) /* Because uppercased printer names suck */ + *p = tolower(*p); + for (p = lowerhwtype; *p; p++) + *p = tolower(*p); + + fprintf(out, "\n",rp); + fprintf(out, "Info %s:%s\n", rp, hwtype); + /* Note the use of "beh" to keep the CUPS from disabling print queues + * should they not respond versus discarding the job. + * See the "beh" page for details. + * The 1/0/60 says "don't disable/try 20 times/try every 60s */ + if (!strncmp(hwtype, "HP", 2)) + fprintf(out, "DeviceURI beh:/1/20/60/socket://%s:9100\n", hostname); + else + fprintf(out, "DeviceURI beh:/1/20/60/socket://%s\n", hostname); + fprintf(out, "State Idle\n"); // Always with the Idle + fprintf(out, "StateTime %ld\n", (long)time(NULL)); + fprintf(out, "Accepting Yes\n"); + fprintf(out, "Shared Yes\n"); + fprintf(out, "QuotaPeriod 0\n"); + fprintf(out, "PageLimit 0\n"); + fprintf(out, "Klimit 0\n"); + fprintf(out, "Option sides one-sided\n"); + fprintf(out, "Filter application/vnd.cups-raw 0 -\n"); + fprintf(out, "Filter application/vnd.cups-postscript 100 foomatic-rip\n"); + fprintf(out, "Filter application/vnd.cups-pdf 0 foomatic-rip\n"); + fprintf(out, "Filter application/vnd.apple-pdf 25 foomatic-rip\n"); + fprintf(out, "Filter application/vnd.cups-command 0 commandtops\n"); + if (location[0]) + fprintf(out, "Location %s\n", location); + fprintf(out, "ErrorPolicy abort-job\n"); + if (ka || lpc_acl) + fprintf(out, "OpPolicy %s-policy\n", rp); + else + fprintf(out, "OpPolicy default\n"); + + /* Access-control list. */ + if (ac) + { + if (ka) + fprintf(out, "AuthType Negotiate\n"); + else + fprintf(out, "AuthType Default\n"); + printer_user_list(out, "LIST", ac, "AllowUser"); + } + + if (banner == PRN_BANNER_NONE) + fprintf(out, "JobSheets none none\n"); + else + fprintf(out, "JobSheets athena none\n"); + fprintf(out, "\n"); + + } + EXEC SQL CLOSE csr_printers; + + /* printers.conf entries for non-local CUPS queues */ + EXEC SQL DECLARE csr_remote_printers CURSOR FOR + SELECT pr.rp, pr.name, pr.duplexname, pr.hwtype, + m.name, pr.banner, pr.location, pr.contact, pr.ka, + pr.ac, pr.lpc_acl, m.name as cupshosts + FROM printers pr, machine m, serverhosts sh + WHERE pr.rm = m.mach_id + AND (pr.type = 'CLUSTER' or pr.type = 'DORM') AND m.name <> :spoolhost AND + m.mach_id = sh.mach_id AND sh.service = 'CUPS-PRINT' AND + sh.enable = 1 AND m.mach_id = sh.mach_id; + + EXEC SQL OPEN csr_remote_printers; + while (1) + { + EXEC SQL FETCH csr_remote_printers INTO :rp, :name, :duplexname, + :hwtype, :hostname, :banner, :location, :contact, :ka, :ac, :lpc_acl, :cupshosts; + if (sqlca.sqlcode) + break; + + strtrim(rp); + strtrim(name); + strtrim(duplexname); + strtrim(hwtype); + strtrim(hostname); + strtrim(location); + strtrim(contact); + strtrim(cupshosts); + strcpy(lowerhwtype, hwtype); + for (p = rp; *p; p++) /* Because uppercased printer names suck */ + *p = tolower(*p); + for (p = lowerhwtype; *p; p++) + *p = tolower(*p); + + fprintf(out, "\n",rp); + fprintf(out, "Info %s:%s\n", rp, hwtype); + fprintf(out, "DeviceURI ipp://%s:631/printers/%s\n", cupshosts, rp); + fprintf(out, "State Idle\n"); // Always with the Idle + fprintf(out, "StateTime %ld\n", (long)time(NULL)); + fprintf(out, "Accepting Yes\n"); + fprintf(out, "Shared Yes\n"); + fprintf(out, "QuotaPeriod 0\n"); + fprintf(out, "PageLimit 0\n"); + fprintf(out, "Klimit 0\n"); + fprintf(out, "Option sides one-sided\n"); + fprintf(out, "Filter application/vnd.cups-raw 0 -\n"); + fprintf(out, "Filter application/vnd.cups-postscript 100 foomatic-rip\n"); + fprintf(out, "Filter application/vnd.cups-pdf 0 foomatic-rip\n"); + fprintf(out, "Filter application/vnd.apple-pdf 25 foomatic-rip\n"); + fprintf(out, "Filter application/vnd.cups-command 0 commandtops\n"); + if (location[0]) + fprintf(out, "Location %s\n", location); + fprintf(out, "ErrorPolicy abort-job\n"); + if (ka || lpc_acl) + fprintf(out, "OpPolicy %s-policy\n", rp); + else + fprintf(out, "OpPolicy default\n"); + + /* Access-control list. */ + if (ac) + { + if (ka) + fprintf(out, "AuthType Negotiate\n"); + else + fprintf(out, "AuthType Default\n"); + printer_user_list(out, "LIST", ac, "AllowUser"); + } + + if (banner == PRN_BANNER_NONE) + fprintf(out, "JobSheets none none\n"); + else + fprintf(out, "JobSheets athena none\n"); + fprintf(out, "\n"); + + } + EXEC SQL CLOSE csr_remote_printers; + + /* printers.conf entries for non-local LPRng queues */ + EXEC SQL DECLARE csr_lprng_printers CURSOR FOR + SELECT pr.rp, pr.name, pr.duplexname, pr.hwtype, + m.name, pr.banner, pr.location, pr.contact, pr.ka, + pr.ac, pr.lpc_acl, m.name as cupshosts + FROM printers pr, machine m, serverhosts sh + WHERE pr.rm = m.mach_id + AND (pr.type = 'DORM' or pr.type = 'CLUSTER') AND m.name <> :spoolhost AND + m.mach_id = sh.mach_id AND sh.service = 'PRINT' AND + sh.enable = 1; + + EXEC SQL OPEN csr_lprng_printers; + while (1) + { + EXEC SQL FETCH csr_lprng_printers INTO :rp, :name, :duplexname, + :hwtype, :hostname, :banner, :location, :contact, :ka, :ac, :lpc_acl, :cupshosts; + if (sqlca.sqlcode) + break; + + strtrim(rp); + strtrim(name); + strtrim(duplexname); + strtrim(hwtype); + strtrim(hostname); + strtrim(location); + strtrim(contact); + strtrim(cupshosts); + strcpy(lowerhwtype, hwtype); + for (p = rp; *p; p++) /* Because uppercased printer names suck */ + *p = tolower(*p); + for (p = lowerhwtype; *p; p++) + *p = tolower(*p); + + fprintf(out, "\n",rp); + fprintf(out, "Info %s:LPRng Queue on %s\n", rp, cupshosts); + fprintf(out, "DeviceURI lpd://%s/%s\n", cupshosts, rp); + fprintf(out, "State Idle\n"); // Always with the Idle + fprintf(out, "StateTime %ld\n", (long)time(NULL)); + fprintf(out, "Accepting Yes\n"); + fprintf(out, "Shared Yes\n"); + fprintf(out, "QuotaPeriod 0\n"); + fprintf(out, "PageLimit 0\n"); + fprintf(out, "Klimit 0\n"); + fprintf(out, "Option sides one-sided\n"); + fprintf(out, "Filter application/vnd.cups-raw 0 -\n"); + fprintf(out, "Filter application/vnd.cups-postscript 100 foomatic-rip\n"); + fprintf(out, "Filter application/vnd.cups-pdf 0 foomatic-rip\n"); + fprintf(out, "Filter application/vnd.apple-pdf 25 foomatic-rip\n"); + fprintf(out, "Filter application/vnd.cups-command 0 commandtops\n"); + if (location[0]) + fprintf(out, "Location %s\n", location); + fprintf(out, "ErrorPolicy abort-job\n"); + fprintf(out, "OpPolicy default\n"); + fprintf(out, "JobSheets none none\n"); + fprintf(out, "\n"); + + } + EXEC SQL CLOSE csr_lprng_printers; + tarfile_end(tf); + + + /* aliases are in classes.conf */ + out = tarfile_start(tf, "/etc/cups/classes.conf", 0644, 0, 0, + "lp", "lp", now); + EXEC SQL DECLARE csr_duplexqs CURSOR FOR + SELECT pr.rp, pr.name, pr.duplexname, pr.hwtype, + m.name, pr.banner, pr.location, pr.contact, pr.ka, + pr.type as prtype, pr.ac + FROM printers pr, machine m, serverhosts sh + WHERE pr.rm = m.mach_id + AND m.mach_id = sh.mach_id AND sh.enable = 1 + AND (pr.type = 'DORM' or pr.type = 'CLUSTER') + AND (sh.service = 'CUPS-PRINT' OR sh.service = 'PRINT'); + EXEC SQL OPEN csr_duplexqs; + while (1) + { + EXEC SQL FETCH csr_duplexqs INTO :rp, :name, :duplexname, + :hwtype, :hostname, :banner, :location, :contact, :ka, :prtype, :ac; + if (sqlca.sqlcode) + break; + + strtrim(hwtype); + strtrim(rp); + strtrim(location); + strtrim(contact); + strtrim(prtype); + + /* Define alias queues as classes to the regular queues for + * accounting reasons. Annoyingly, classes don't always inherit + * their printer definitions. + */ + if (!strcmp(prtype,"ALIAS")) + { + strtrim(name); + fprintf(out, "\n",name); + fprintf(out, "Info Alias Queue to %s:%s\n", rp, hwtype); + fprintf(out, "Printer %s\n", rp); + fprintf(out, "Option sides one-sided\n"); + fprintf(out, "State Idle\n"); // Always with the Idle + fprintf(out, "StateTime %ld\n", (long)time(NULL)); + fprintf(out, "Accepting Yes\n"); + fprintf(out, "Shared Yes\n"); + fprintf(out, "QuotaPeriod 0\n"); + fprintf(out, "PageLimit 0\n"); + if (location[0]) + fprintf(out, "Location %s\n", location); + /* fprintf(out, "ErrorPolicy abort-job\n"); */ + if (ka || lpc_acl) + fprintf(out, "OpPolicy %s-policy\n", rp); + else + fprintf(out, "OpPolicy default\n"); + + /* Access-control list. */ + if (ac) + { + if (ka) + fprintf(out, "AuthType Negotiate\n"); + else + fprintf(out, "AuthType Default\n"); + printer_user_list(out, "LIST", ac, "AllowUser"); + } + + if (banner == PRN_BANNER_NONE) + fprintf(out, "JobSheets none none\n"); + else + fprintf(out, "JobSheets athena none\n"); + fprintf(out, "\n"); + } + + /* Define duplex queues as aliases to the regular queues for + * accounting reasons. Annoyingly, classes don't always inherit + * their printer definitions. + */ + if (*duplexname) + { + strtrim(duplexname); + fprintf(out, "\n",duplexname); + if (!strcmp(prtype,"ALIAS")) + fprintf(out, "Info Duplex Alias Queue to %s:%s\n", rp, hwtype); + else + fprintf(out, "Info Duplex Queue for %s:%s\n", rp, hwtype); + fprintf(out, "Option sides two-sided-long-edge\n"); // duplex + fprintf(out, "Printer %s\n", rp); + fprintf(out, "State Idle\n"); // Always with the Idle + fprintf(out, "StateTime %ld\n", (long)time(NULL)); + fprintf(out, "Accepting Yes\n"); + fprintf(out, "Shared Yes\n"); + fprintf(out, "QuotaPeriod 0\n"); + fprintf(out, "PageLimit 0\n"); + if (location[0]) + fprintf(out, "Location %s\n", location); + fprintf(out, "ErrorPolicy abort-job\n"); + if (ka || lpc_acl) + fprintf(out, "OpPolicy %s-policy\n", rp); + else + fprintf(out, "OpPolicy default\n"); + + /* Access-control list. */ + if (ac) + { + if (ka) + fprintf(out, "AuthType Negotiate\n"); + else + fprintf(out, "AuthType Default\n"); + printer_user_list(out, "LIST", ac, "AllowUser"); + } + + if (banner == PRN_BANNER_NONE) + fprintf(out, "JobSheets none none\n"); + else if (banner == PRN_BANNER_LAST) + fprintf(out, "JobSheets athena none\n"); + fprintf(out, "\n"); + } + } + EXEC SQL CLOSE csr_duplexqs; + tarfile_end(tf); + + /* cups.conf */ + out = tarfile_start(tf, "/etc/cups/cupsd.conf", 0755, 1, 1, + "root", "lp", now); + + fprintf(out, "LogLevel info\n"); + fprintf(out, "SystemGroup sys root ops-group\n"); + fprintf(out, "Port 631\n"); + fprintf(out, "Listen /var/run/cups/cups.sock\n"); + fprintf(out, "Browsing On\n"); + fprintf(out, "BrowseOrder allow,deny\n"); + fprintf(out, "BrowseAllow all\n"); + fprintf(out, "BrowseAddress @LOCAL\n"); + fprintf(out, "DefaultAuthType Negotiate\n"); + fprintf(out, "ServerCertificate /etc/cups/ssl/%s-ipp-crt.pem\n", lhost); + fprintf(out, "ServerKey /etc/cups/ssl/%s-ipp-key.pem\n", lhost); + fprintf(out, "ServerName %s\n", lhost); + fprintf(out, "ServerAlias %s\n", phost); + fprintf(out, "Krb5Keytab /etc/krb5-ipp.keytab\n"); + + /* The other CUPS servers should be aware of the other hosts' + queues, so we'll let them browse each other. */ + fprintf(out, "Include cups.local.conf\n"); + fprintf(out, "Include cups.locations.conf\n"); + fprintf(out, "Include cups.policies.conf\n"); + tarfile_end(tf); + + /* cups.hosts.conf */ + out = tarfile_start(tf, "/etc/cups/cups.hosts.conf", 0755, 1, 1, + "root", "lp", now); + EXEC SQL DECLARE csr_cupshosts CURSOR FOR + SELECT m.name AS cupshosts FROM machine m, printservers ps + WHERE m.mach_id = ps.mach_id AND ps.kind = 'CUPS'; + EXEC SQL OPEN csr_cupshosts; + while (1) + { + EXEC SQL FETCH csr_cupshosts INTO :cupshosts; + if (sqlca.sqlcode) + break; + + strtrim(cupshosts); + + /* Don't poll yourself looking for answers! */ + if (strcmp(cupshosts,host)) + fprintf(out, "BrowsePoll %s\n", cupshosts); + } + EXEC SQL CLOSE csr_cupshosts; + + tarfile_end(tf); + + /* cups.policies.conf */ + out = tarfile_start(tf, "/etc/cups/cups.policies.conf", 0755, 1, 1, + "root", "lp", now); + fprintf(out, "# Printer-specific LPC and LPR ACLs\n"); + /* lpcaccess.top */ + EXEC SQL SELECT ps.lpc_acl INTO :top_lpc_acl + FROM printservers ps, machine m + WHERE m.name = :spoolhost AND m.mach_id = ps.mach_id; + if (!sqlca.sqlcode && lpc_acl) + { + fprintf (out, "\n"); + fprintf (out, "%s\n", alterjob); + fprintf (out, "AuthType Default\n"); + fprintf (out, "Require user @OWNER @SYSTEM\n"); + printer_user_list(out, "LIST", top_lpc_acl, "Require user"); + fprintf (out, "Order deny,allow\n"); + fprintf (out, "\n"); + fprintf (out, "%s\n", submitjob); + fprintf (out, "AuthType None\n"); + fprintf (out, "Order deny,allow\n"); + fprintf (out, "Allow from all\n"); + fprintf (out, "\n"); + fprintf (out, "%s\n", alterpntr); + fprintf (out, "AuthType Default\n"); + fprintf (out, "Require user @SYSTEM\n"); + fprintf (out, "Order deny,allow\n"); + fprintf (out, "\n"); + fprintf (out, "%s\n", lpcpntr); + fprintf (out, "AuthType Default\n"); + fprintf (out, "Require user @SYSTEM\n"); + printer_user_list(out, "LIST", top_lpc_acl, "Require user"); + fprintf (out, "Order deny,allow\n"); + fprintf (out, "\n"); + fprintf (out, "%s\n", canceljob); + fprintf (out, "AuthType Default\n"); + fprintf (out, "Require user @OWNER @SYSTEM\n"); + printer_user_list(out, "LIST", top_lpc_acl, "Require user"); + fprintf (out, "Order deny,allow\n"); + fprintf (out, "Allow from all\n"); + fprintf (out, "\n"); + fprintf (out, "%s\n", catchall); + fprintf (out, "AuthType None\n"); + fprintf (out, "Order deny,allow\n"); + fprintf (out, "Allow from all\n"); + fprintf (out, "\n"); + fprintf (out, "\n"); + } + + /* restrict lists and lpcaccess policies. Sadly, we have to put the + top level for each new policy since CUPS doesn't have a way of + doing it otherwise (well, Unix groups, but not moira) */ + EXEC SQL DECLARE csr_lpc CURSOR FOR + SELECT UNIQUE rp, ka, ac, lpc_acl + FROM printers + WHERE (ac != 0 OR lpc_acl != 0) AND rm in (SELECT m.mach_id FROM machine m, serverhosts sh + WHERE m.mach_id = sh.mach_id AND sh.service = 'CUPS-PRINT' AND sh.enable = 1); + EXEC SQL OPEN csr_lpc; + while (1) + { + EXEC SQL FETCH csr_lpc INTO :name, :ka, :ac, :lpc_acl; + if (sqlca.sqlcode) + break; + + strtrim(name); + + fprintf (out, "\n", name); + fprintf (out, "%s\n", alterjob); + fprintf (out, "AuthType Default\n"); + fprintf (out, "Require user @OWNER @SYSTEM\n"); + printer_user_list(out, "LIST", lpc_acl, "Require user"); + fprintf (out, "Order deny,allow\n"); + fprintf (out, "Allow from all\n"); + fprintf (out, "\n"); + fprintf (out, "%s\n", submitjob); + /* If the printer is Kerberized? */ + if (ka) + fprintf (out, "AuthType Negotiate\n"); + else + fprintf (out, "AuthType None\n"); + /* Access-control list. */ + if (ac) + printer_user_list(out, "LIST", ac, "Require user"); + else if (ka) + fprintf (out, "Require valid-user\n"); + fprintf (out, "Order deny,allow\n"); + fprintf (out, "Allow from all\n"); + fprintf (out, "\n"); + fprintf (out, "%s\n", alterpntr); + fprintf (out, "AuthType Default\n"); + fprintf (out, "Require user @SYSTEM\n"); + fprintf (out, "Order deny,allow\n"); + fprintf (out, "\n"); + fprintf (out, "%s\n", lpcpntr); + fprintf (out, "AuthType Default\n"); + fprintf (out, "Require user @SYSTEM\n"); + /* printer-specific lpc access. */ + if (lpc_acl) + printer_user_list(out, "LIST", lpc_acl, "Require user"); + printer_user_list(out, "LIST", top_lpc_acl, "Require user"); + fprintf (out, "Order deny,allow\n"); + fprintf (out, "\n"); + fprintf (out, "%s\n", canceljob); + fprintf (out, "AuthType Default\n"); + fprintf (out, "Require user @OWNER @SYSTEM\n"); + printer_user_list(out, "LIST", lpc_acl, "Require user"); + printer_user_list(out, "LIST", top_lpc_acl, "Require user"); + fprintf (out, "Order deny,allow\n"); + fprintf (out, "Allow from all\n"); + fprintf (out, "\n"); + fprintf (out, "%s\n", catchall); + fprintf (out, "AuthType None\n"); + fprintf (out, "Order deny,allow\n"); + fprintf (out, "Allow from all\n"); + fprintf (out, "\n"); + fprintf (out, "\n"); + } + EXEC SQL CLOSE csr_lpc; + fprintf(out, "\n"); + tarfile_end(tf); + tarfile_close(tf); +} + +void sqlerr(void) +{ + db_error(sqlca.sqlcode); +} diff --git a/gen/cups-cluster.sh b/gen/cups-cluster.sh new file mode 100755 index 00000000..0dae72bb --- /dev/null +++ b/gen/cups-cluster.sh @@ -0,0 +1,50 @@ +#! /bin/sh +# $Id$ + +if [ -d /var/athena ] && [ -w /var/athena ]; then + exec >/var/athena/moira_update.log 2>&1 +else + exec >/tmp/moira_update.log 2>&1 +fi + +# The following exit codes are defined and MUST BE CONSISTENT with the +# error codes the library uses: +MR_MISSINGFILE=47836473 +MR_MKCRED=47836474 +MR_TARERR=47836476 + +PATH=/bin +TARFILE=/var/tmp/cups-cluster.out +CUPSLOCAL=/etc/cups + +# Alert if the tar file or other needed files do not exist +test -r $TARFILE || exit $MR_MISSINGFILE +test -d $CUPSLOCAL || exit $MR_MISSINGFILE + +# Unpack the tar file, getting only files that are newer than the +# on-disk copies (-u). +cd / +tar xf $TARFILE || exit $MR_TARERR + +/etc/cups/bin/sync_lpd_ldap.pl 2>/dev/null +/etc/cups/bin/gen-ppd.pl 2>/dev/null + +/etc/init.d/cups stop +/etc/init.d/cups start + +# if Samba-enabled, then restart it too to have it pick up +# new definitions +if [ -x /etc/init.d/smb ]; then + /etc/init.d/smb restart +fi + +if [ $? != 0 ]; then + exit $MR_MKCRED +fi + +# cleanup +test -f $TARFILE && rm -f $TARFILE +test -f $0 && rm -f $0 + +exit 0 + diff --git a/gen/cups-print.pc b/gen/cups-print.pc index 74bcb507..48c153e8 100644 --- a/gen/cups-print.pc +++ b/gen/cups-print.pc @@ -145,7 +145,7 @@ void do_host(char *host) sprintf(filename, "%s/cups-print/%s", DCM_DIR, host); tf = tarfile_open(filename); - /* printers.conf */ + /* printers.conf entries for locally run queues */ out = tarfile_start(tf, "/etc/cups/printers.conf", 0644, 0, 0, "lp", "lp", now); @@ -172,6 +172,8 @@ void do_host(char *host) strtrim(location); strtrim(contact); strcpy(lowerhwtype, hwtype); + for (p = rp; *p; p++) /* Because uppercased printer names suck */ + *p = tolower(*p); for (p = lowerhwtype; *p; p++) *p = tolower(*p); @@ -193,6 +195,11 @@ void do_host(char *host) fprintf(out, "PageLimit 0\n"); fprintf(out, "Klimit 0\n"); fprintf(out, "Option sides one-sided\n"); + fprintf(out, "Filter application/vnd.cups-raw 0 -\n"); + fprintf(out, "Filter application/vnd.cups-postscript 100 foomatic-rip\n"); + fprintf(out, "Filter application/vnd.cups-pdf 0 foomatic-rip\n"); + fprintf(out, "Filter application/vnd.apple-pdf 25 foomatic-rip\n"); + fprintf(out, "Filter application/vnd.cups-command 0 commandtops\n"); if (location[0]) fprintf(out, "Location %s\n", location); fprintf(out, "ErrorPolicy abort-job\n"); @@ -219,6 +226,141 @@ void do_host(char *host) } EXEC SQL CLOSE csr_printers; + + /* printers.conf entries for non-local CUPS queues */ + EXEC SQL DECLARE csr_remote_printers CURSOR FOR + SELECT pr.rp, pr.name, pr.duplexname, pr.hwtype, + m.name, pr.banner, pr.location, pr.contact, pr.ka, + pr.ac, pr.lpc_acl, m.name as cupshosts + FROM printers pr, machine m, serverhosts sh + WHERE pr.rm = m.mach_id + AND pr.type != 'ALIAS' AND m.name <> :spoolhost AND + m.mach_id = sh.mach_id AND sh.service = 'CUPS-PRINT' AND + sh.enable = 1 AND m.mach_id = sh.mach_id; + + EXEC SQL OPEN csr_remote_printers; + while (1) + { + EXEC SQL FETCH csr_remote_printers INTO :rp, :name, :duplexname, + :hwtype, :hostname, :banner, :location, :contact, :ka, :ac, :lpc_acl, :cupshosts; + if (sqlca.sqlcode) + break; + + strtrim(rp); + strtrim(name); + strtrim(duplexname); + strtrim(hwtype); + strtrim(hostname); + strtrim(location); + strtrim(contact); + strtrim(cupshosts); + strcpy(lowerhwtype, hwtype); + for (p = rp; *p; p++) /* Because uppercased printer names suck */ + *p = tolower(*p); + for (p = lowerhwtype; *p; p++) + *p = tolower(*p); + + fprintf(out, "\n",rp); + fprintf(out, "Info %s:%s\n", rp, hwtype); + fprintf(out, "DeviceURI ipp://%s:631/printers/%s\n", cupshosts, rp); + fprintf(out, "State Idle\n"); // Always with the Idle + fprintf(out, "StateTime %ld\n", (long)time(NULL)); + fprintf(out, "Accepting Yes\n"); + fprintf(out, "Shared Yes\n"); + fprintf(out, "QuotaPeriod 0\n"); + fprintf(out, "PageLimit 0\n"); + fprintf(out, "Klimit 0\n"); + fprintf(out, "Option sides one-sided\n"); + fprintf(out, "Filter application/vnd.cups-raw 0 -\n"); + fprintf(out, "Filter application/vnd.cups-postscript 100 foomatic-rip\n"); + fprintf(out, "Filter application/vnd.cups-pdf 0 foomatic-rip\n"); + fprintf(out, "Filter application/vnd.apple-pdf 25 foomatic-rip\n"); + fprintf(out, "Filter application/vnd.cups-command 0 commandtops\n"); + if (location[0]) + fprintf(out, "Location %s\n", location); + fprintf(out, "ErrorPolicy abort-job\n"); + if (ka || lpc_acl) + fprintf(out, "OpPolicy %s-policy\n", rp); + else + fprintf(out, "OpPolicy default\n"); + + /* Access-control list. */ + if (ac) + { + if (ka) + fprintf(out, "AuthType Negotiate\n"); + else + fprintf(out, "AuthType Default\n"); + printer_user_list(out, "LIST", ac, "AllowUser"); + } + + if (banner == PRN_BANNER_NONE) + fprintf(out, "JobSheets none none\n"); + else + fprintf(out, "JobSheets athena none\n"); + fprintf(out, "\n"); + + } + EXEC SQL CLOSE csr_remote_printers; + + /* printers.conf entries for non-local LPRng queues */ + EXEC SQL DECLARE csr_lprng_printers CURSOR FOR + SELECT pr.rp, pr.name, pr.duplexname, pr.hwtype, + m.name, pr.banner, pr.location, pr.contact, pr.ka, + pr.ac, pr.lpc_acl, m.name as cupshosts + FROM printers pr, machine m, serverhosts sh + WHERE pr.rm = m.mach_id + AND pr.type != 'ALIAS' AND m.name <> :spoolhost AND + m.mach_id = sh.mach_id AND sh.service = 'PRINT' AND + sh.enable = 1; + + EXEC SQL OPEN csr_lprng_printers; + while (1) + { + EXEC SQL FETCH csr_lprng_printers INTO :rp, :name, :duplexname, + :hwtype, :hostname, :banner, :location, :contact, :ka, :ac, :lpc_acl, :cupshosts; + if (sqlca.sqlcode) + break; + + strtrim(rp); + strtrim(name); + strtrim(duplexname); + strtrim(hwtype); + strtrim(hostname); + strtrim(location); + strtrim(contact); + strtrim(cupshosts); + strcpy(lowerhwtype, hwtype); + for (p = rp; *p; p++) /* Because uppercased printer names suck */ + *p = tolower(*p); + for (p = lowerhwtype; *p; p++) + *p = tolower(*p); + + fprintf(out, "\n",rp); + fprintf(out, "Info %s:LPRng Queue on %s\n", rp, cupshosts); + fprintf(out, "DeviceURI lpd://%s/%s\n", cupshosts, rp); + fprintf(out, "State Idle\n"); // Always with the Idle + fprintf(out, "StateTime %ld\n", (long)time(NULL)); + fprintf(out, "Accepting Yes\n"); + fprintf(out, "Shared Yes\n"); + fprintf(out, "QuotaPeriod 0\n"); + fprintf(out, "PageLimit 0\n"); + fprintf(out, "Klimit 0\n"); + fprintf(out, "Option sides one-sided\n"); + fprintf(out, "Filter application/vnd.cups-raw 0 -\n"); + fprintf(out, "Filter application/vnd.cups-postscript 100 foomatic-rip\n"); + fprintf(out, "Filter application/vnd.cups-pdf 0 foomatic-rip\n"); + fprintf(out, "Filter application/vnd.apple-pdf 25 foomatic-rip\n"); + fprintf(out, "Filter application/vnd.cups-command 0 commandtops\n"); + if (location[0]) + fprintf(out, "Location %s\n", location); + fprintf(out, "ErrorPolicy abort-job\n"); + fprintf(out, "OpPolicy default\n"); + fprintf(out, "JobSheets none none\n"); + fprintf(out, "\n"); + + } + EXEC SQL CLOSE csr_lprng_printers; tarfile_end(tf); @@ -229,8 +371,10 @@ void do_host(char *host) SELECT pr.rp, pr.name, pr.duplexname, pr.hwtype, m.name, pr.banner, pr.location, pr.contact, pr.ka, pr.type as prtype, pr.ac - FROM printers pr, machine m - WHERE pr.rm = :rm AND m.mach_id = pr.mach_id; + FROM printers pr, machine m, serverhosts sh + WHERE pr.rm = m.mach_id + AND m.mach_id = sh.mach_id AND sh.enable = 1 + AND (sh.service = 'CUPS-PRINT' OR sh.service = 'PRINT'); EXEC SQL OPEN csr_duplexqs; while (1) { @@ -264,7 +408,7 @@ void do_host(char *host) fprintf(out, "PageLimit 0\n"); if (location[0]) fprintf(out, "Location %s\n", location); - fprintf(out, "ErrorPolicy abort-job\n"); + /* fprintf(out, "ErrorPolicy abort-job\n"); */ if (ka || lpc_acl) fprintf(out, "OpPolicy %s-policy\n", rp); else @@ -438,7 +582,8 @@ void do_host(char *host) EXEC SQL DECLARE csr_lpc CURSOR FOR SELECT UNIQUE rp, ka, ac, lpc_acl FROM printers - WHERE rm = :rm AND ( ac != 0 OR lpc_acl != 0); + WHERE (ac != 0 OR lpc_acl != 0) AND rm in (SELECT m.mach_id FROM machine m, serverhosts sh + WHERE m.mach_id = sh.mach_id AND sh.service = 'CUPS-PRINT' AND sh.enable = 1); EXEC SQL OPEN csr_lpc; while (1) { -- 2.45.1