3 * This generates printcaps and other files for Athena print servers
5 * Copyright (C) 1992-1998 by the Massachusetts Institute of Technology.
6 * For copying and distribution information, please see the file
10 #include <mit-copyright.h>
12 #include <moira_site.h>
15 #include <sys/types.h>
23 EXEC SQL INCLUDE sqlca;
27 char *whoami = "print.gen";
28 char *db = "moira/moira";
30 void do_host(char *host);
33 #define MAX(a, b) ( (a) > (b) ? (a) : (b) )
36 int main(int argc, char **argv)
38 EXEC SQL BEGIN DECLARE SECTION;
39 char name[MACHINE_NAME_SIZE];
40 EXEC SQL END DECLARE SECTION;
46 EXEC SQL WHENEVER SQLERROR DO sqlerr();
48 EXEC SQL DECLARE csr_hosts CURSOR FOR
49 SELECT m.name FROM machine m, serverhosts sh
50 WHERE m.mach_id = sh.mach_id AND sh.service = 'PRINT' AND sh.enable = 1;
51 EXEC SQL OPEN csr_hosts;
54 EXEC SQL FETCH csr_hosts INTO :name;
61 EXEC SQL CLOSE csr_hosts;
66 void do_host(char *host)
68 EXEC SQL BEGIN DECLARE SECTION;
69 char rp[PRINTERS_RP_SIZE], name[PRINTERS_NAME_SIZE];
70 char duplexname[PRINTERS_DUPLEXNAME_SIZE], location[PRINTERS_LOCATION_SIZE];
71 char hwtype[PRINTERS_HWTYPE_SIZE], lowerhwtype[PRINTERS_HWTYPE_SIZE];
72 char modtime[PRINTERS_MODTIME_SIZE], lmodtime[LIST_MODTIME_SIZE];
73 char contact[PRINTERS_CONTACT_SIZE], hostname[MACHINE_NAME_SIZE];
74 char *spoolhost = host, *unixtime_fmt = UNIXTIME_FMT, *p;
75 int ka, pc, ac, lpc_acl, banner, rm;
76 EXEC SQL END DECLARE SECTION;
79 char filename[MAXPATHLEN], *duptc;
80 time_t mtime, now = time(NULL);
82 EXEC SQL SELECT mach_id INTO :rm FROM machine
83 WHERE name = :spoolhost;
85 sprintf(filename, "%s/print/%s", DCM_DIR, host);
86 tf = tarfile_open(filename);
89 out = tarfile_start(tf, "/etc/printcap.moira", 0644, 0, 0,
92 EXEC SQL DECLARE csr_printcap CURSOR FOR
93 SELECT pr.rp, pr.name, pr.duplexname, pr.hwtype,
94 m.name, pr.banner, pr.location, pr.contact
95 FROM printers pr, machine m
96 WHERE pr.rm = :rm AND m.mach_id = pr.mach_id
97 AND pr.type != 'ALIAS'
98 AND ( pr.hwtype LIKE 'HP%' OR pr.hwtype LIKE 'LPR%' );
99 EXEC SQL OPEN csr_printcap;
102 EXEC SQL FETCH csr_printcap INTO :rp, :name, :duplexname,
103 :hwtype, :hostname, :banner, :location, :contact;
114 strcpy(lowerhwtype, hwtype);
115 for (p = lowerhwtype; *p; p++)
119 fprintf(out, "# %s: %s\n", name, location);
121 fprintf(out, "# %s\n", name);
122 if (strcmp(location, contact))
123 fprintf(out, "# contact: %s\n", contact);
125 fprintf(out, "%s\n\t:server:cm=%s %s\n\t", rp, hwtype, location);
126 if (banner == PRN_BANNER_NONE)
128 else if (banner == PRN_BANNER_LAST)
131 if (!strncmp(hwtype, "HP", 2))
133 fprintf(out, ":lp=%s%%9100:ifhp=model=%s:tc=.hp\n\n",
134 hostname, lowerhwtype);
137 else if (!strncmp(hwtype, "LPR", 3))
139 fprintf(out, ":lp=raw@%s:tc=.apple\n\n", hostname);
145 fprintf(out, "%s\n\t:server:bq=%s:cm=%s duplex queue\n\t",
147 if (!strncmp(hwtype, "HP", 2))
148 fprintf(out, ":ifhp=model=%s", lowerhwtype);
149 fprintf(out, ":tc=%s\n\n", duptc);
152 EXEC SQL CLOSE csr_printcap;
156 out = tarfile_start(tf, "/etc/lpd.perms", 0755, 1, 1,
157 "daemon", "daemon", now);
158 fprintf(out, "# Allow anybody to connect, get status, list queue, or "
159 "print (once a\n# job is spooled)\n");
160 fprintf(out, "ACCEPT SERVICE=X,S,Q,P\nACCEPT LPC=status,lpq,printcap\n\n");
162 fprintf(out, "# Only trust certain host keys to forward jobs/commands\n");
163 fprintf(out, "REJECT SERVICE=R AUTHFROM=?* "
164 "PRINTER=</var/spool/printer/queues.secure "
165 "NOT AUTHFROM=</var/spool/printer/hostkeys.allow FORWARD\n");
166 fprintf(out, "REJECT SERVICE=R AUTHFROM=?* AUTHJOB "
167 "NOT AUTHFROM=</var/spool/printer/hostkeys.allow FORWARD\n\n");
169 fprintf(out, "# Allow root to control and remove jobs\n");
170 fprintf(out, "ACCEPT SERVICE=C,R SERVER REMOTEUSER=root\n\n");
172 fprintf(out, "# Allow admins to control and remove jobs\n");
173 fprintf(out, "ACCEPT SERVICE=C,R AUTH=USER AUTHUSER=</var/spool/printer/lpcaccess.top\n\n");
175 fprintf(out, "# Printer-specific LPC ACLs\n");
176 EXEC SQL DECLARE csr_lpc CURSOR FOR
177 SELECT rp, duplexname FROM printers
178 WHERE rm = :rm AND lpc_acl != 0;
179 EXEC SQL OPEN csr_lpc;
182 EXEC SQL FETCH csr_lpc INTO :name, :duplexname;
188 fprintf(out, "ACCEPT SERVICE=C,R PRINTER=%s%s%s AUTH=USER "
189 "AUTHUSER=</var/spool/printer/%s/lpcaccess\n",
190 name, *duplexname ? "," : "", duplexname, name);
192 EXEC SQL CLOSE csr_lpc;
195 fprintf(out, "# Reject jobs from unauthorized users to restricted queues\n");
196 EXEC SQL DECLARE csr_ac CURSOR FOR
197 SELECT rp, duplexname, ka FROM printers
198 WHERE rm = :rm AND ac != 0;
199 EXEC SQL OPEN csr_ac;
202 EXEC SQL FETCH csr_ac INTO :name, :duplexname, ka;
208 fprintf(out, "REJECT SERVICE=R PRINTER=%s%s%s NOT "
209 "%sUSER=</var/spool/printer/%s/restrict.list\n",
210 name, *duplexname ? "," : "", duplexname,
211 ka ? "AUTH" : "", name);
213 EXEC SQL CLOSE csr_ac;
216 fprintf(out, "# Allow us to lock out users\n");
217 fprintf(out, "REJECT SERVICE=R USER=</var/spool/printer/users.deny\n");
218 fprintf(out, "# Accept authenticated jobs to all other printers\n");
219 fprintf(out, "ACCEPT SERVICE=R AUTH=USER,FWD\n");
220 fprintf(out, "# Allow authenticated users to lprm their jobs\n");
221 fprintf(out, "ACCEPT SERVICE=M AUTH=USER,FWD AUTHJOB AUTHSAMEUSER\n\n");
223 fprintf(out, "# Reject unauthentic print/lprm requests to authenticated queues\n");
224 fprintf(out, "REJECT SERVICE=R,M NOT AUTH "
225 "PRINTER=</var/spool/printer/queues.secure\n\n");
227 fprintf(out, "# Reject unauthentic print requests from off MITnet\n");
228 fprintf(out, "REJECT SERVICE=R NOT REMOTEIP=</var/spool/printer/masks.allow\n\n\n");
230 fprintf(out, "# Accept unauthentic print requests if same user and on MITnet\n");
231 fprintf(out, "ACCEPT SERVICE=M NOT AUTHJOB SAMEUSER REMOTEIP=</var/spool/printer/masks.allow\n\n");
233 fprintf(out, "# Reject any other lpc, or lprm. Accept all else\n");
234 fprintf(out, "REJECT SERVICE=C,M\n");
235 fprintf(out, "DEFAULT ACCEPT\n");
238 /* list of kerberized queues */
239 out = tarfile_start(tf, "/var/spool/printer/queues.secure", 0755, 1, 1,
240 "daemon", "daemon", now);
241 EXEC SQL DECLARE csr_kq CURSOR FOR
242 SELECT rp, duplexname FROM printers
243 WHERE rm = :rm AND ka = 1;
244 EXEC SQL OPEN csr_kq;
247 EXEC SQL FETCH csr_kq INTO :name, :duplexname;
253 fprintf(out, "%s\n", name);
255 fprintf(out, "%s\n", duplexname);
259 /* restrict lists and lpcaccess files */
260 EXEC SQL DECLARE csr_spool CURSOR FOR
261 SELECT UNIQUE rp, ka, ac, lpc_acl
263 WHERE rm = :rm AND ( ac != 0 OR lpc_acl != 0);
264 EXEC SQL OPEN csr_spool;
267 EXEC SQL FETCH csr_spool INTO :name, :ka, :ac, :lpc_acl;
273 sprintf(filename, "/var/spool/printer/%s", name);
274 tarfile_mkdir(tf, filename, 0755, 1, 1, "daemon", "daemon", now);
276 /* The ac and lpc_acl lists may have sublists, and changes to those
277 * won't affect the superlist's modtime. So we just set the modtime
281 /* Access-control list. */
284 sprintf(filename, "/var/spool/printer/%s/restrict.list", name);
285 out = tarfile_start(tf, filename, 0755, 1, 1, "daemon", "daemon",
288 dump_krb_acl(out, "LIST", ac, 5);
290 dump_user_list(out, "LIST", ac);
294 /* printer-specific lpc access. */
297 sprintf(filename, "/var/spool/printer/%s/lpcaccess", name);
298 out = tarfile_start(tf, filename, 0755, 1, 1, "daemon", "daemon",
300 dump_krb_acl(out, "LIST", lpc_acl, 5);
306 EXEC SQL SELECT ps.lpc_acl INTO :lpc_acl
307 FROM printservers ps, machine m
308 WHERE m.name = :spoolhost AND m.mach_id = ps.mach_id;
309 if (!sqlca.sqlcode && lpc_acl)
311 out = tarfile_start(tf, "/var/spool/printer/lpcaccess.top",
312 0755, 1, 1, "daemon", "daemon", now);
313 dump_krb_acl(out, "LIST", lpc_acl, 5);
317 EXEC SQL CLOSE csr_spool;
324 db_error(sqlca.sqlcode);