]> andersk Git - moira.git/blob - gen/print.pc
Command line printer manipulation client, and build goo.
[moira.git] / gen / print.pc
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 "util.h"
22
23 EXEC SQL INCLUDE sqlca;
24
25 RCSID("$Header$");
26
27 char *whoami = "print.gen";
28 char *db = "moira/moira";
29
30 void do_host(char *host);
31 void sqlerr(void);
32 #ifndef MAX
33 #define MAX(a, b) ( (a) > (b) ? (a) : (b) )
34 #endif
35
36 int main(int argc, char **argv)
37 {
38   EXEC SQL BEGIN DECLARE SECTION;
39   char name[MACHINE_NAME_SIZE];
40   EXEC SQL END DECLARE SECTION;
41
42   init_acls();
43
44   EXEC SQL CONNECT :db;
45
46   EXEC SQL WHENEVER SQLERROR DO sqlerr();
47
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;
52   while (1)
53     {
54       EXEC SQL FETCH csr_hosts INTO :name;
55       if (sqlca.sqlcode)
56         break;
57
58       strtrim(name);
59       do_host(name);
60     }
61   EXEC SQL CLOSE csr_hosts;
62
63   exit(MR_SUCCESS);
64 }
65
66 void do_host(char *host)
67 {
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;
77   TARFILE *tf;
78   FILE *out;
79   char filename[MAXPATHLEN], *duptc;
80   time_t mtime, now = time(NULL);
81
82   EXEC SQL SELECT mach_id INTO :rm FROM machine
83     WHERE name = :spoolhost;
84
85   sprintf(filename, "%s/print/%s", DCM_DIR, host);
86   tf = tarfile_open(filename);
87
88   /* printcap */
89   out = tarfile_start(tf, "/etc/printcap.moira", 0644, 0, 0,
90                       "root", "root", now);
91
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;
100   while (1)
101     {
102       EXEC SQL FETCH csr_printcap INTO :rp, :name, :duplexname,
103         :hwtype, :hostname, :banner, :location, :contact;
104       if (sqlca.sqlcode)
105         break;
106
107       strtrim(rp);
108       strtrim(name);
109       strtrim(duplexname);
110       strtrim(hwtype);
111       strtrim(hostname);
112       strtrim(location);
113       strtrim(contact);
114       strcpy(lowerhwtype, hwtype);
115       for (p = lowerhwtype; *p; p++)
116         *p = tolower(*p);
117
118       if (location[0])
119         fprintf(out, "# %s: %s\n", name, location);
120       else
121         fprintf(out, "# %s\n", name);
122       if (strcmp(location, contact))
123         fprintf(out, "# contact: %s\n", contact);
124
125       fprintf(out, "%s\n\t:server:cm=%s %s\n\t", rp, hwtype, location);
126       if (banner == PRN_BANNER_NONE)
127         fprintf(out, ":sh");
128       else if (banner == PRN_BANNER_LAST)
129         fprintf(out, ":hl");
130
131       if (!strncmp(hwtype, "HP", 2))
132         {
133           fprintf(out, ":lp=%s%%9100:ifhp=model=%s:tc=.hp\n\n",
134                   hostname, lowerhwtype);
135           duptc = ".hp2";
136         }
137       else if (!strncmp(hwtype, "LPR", 3))
138         {
139           fprintf(out, ":lp=raw@%s:tc=.apple\n\n", hostname);
140           duptc = ".apple2";
141         }
142
143       if (*duplexname)
144         {
145           fprintf(out, "%s\n\t:server:bq=%s:cm=%s duplex queue\n\t", 
146                   duplexname, rp, rp);
147           if (!strncmp(hwtype, "HP", 2))
148             fprintf(out, ":ifhp=model=%s", lowerhwtype);
149           fprintf(out, ":tc=%s\n\n", duptc);
150         }
151     }
152   EXEC SQL CLOSE csr_printcap;
153   tarfile_end(tf);
154
155   /* lpd.perms */
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");
161
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");
168
169   fprintf(out, "# Allow root to control and remove jobs\n");
170   fprintf(out, "ACCEPT SERVICE=C,R SERVER REMOTEUSER=root\n\n");
171
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");
174
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;
180   while (1)
181     {
182       EXEC SQL FETCH csr_lpc INTO :name, :duplexname;
183       if (sqlca.sqlcode)
184         break;
185
186       strtrim(name);
187       strtrim(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);
191     }
192   EXEC SQL CLOSE csr_lpc;
193   fprintf(out, "\n");
194
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;
200   while (1)
201     {
202       EXEC SQL FETCH csr_ac INTO :name, :duplexname, ka;
203       if (sqlca.sqlcode)
204         break;
205
206       strtrim(name);
207       strtrim(duplexname);
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);
212     }
213   EXEC SQL CLOSE csr_ac;
214   fprintf(out, "\n");
215
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");
222
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");
226
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");
229
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");
232   
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");
236   tarfile_end(tf);
237
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;
245   while (1)
246     {
247       EXEC SQL FETCH csr_kq INTO :name, :duplexname;
248       if (sqlca.sqlcode)
249         break;
250
251       strtrim(name);
252       strtrim(duplexname);
253       fprintf(out, "%s\n", name);
254       if (*duplexname)
255         fprintf(out, "%s\n", duplexname);
256     }
257   tarfile_end(tf);
258
259   /* restrict lists and lpcaccess files */
260   EXEC SQL DECLARE csr_spool CURSOR FOR
261     SELECT UNIQUE rp, ka, ac, lpc_acl
262     FROM printers
263     WHERE rm = :rm AND ( ac != 0 OR lpc_acl != 0);
264   EXEC SQL OPEN csr_spool;
265   while (1)
266     {
267       EXEC SQL FETCH csr_spool INTO :name, :ka, :ac, :lpc_acl;
268       if (sqlca.sqlcode)
269         break;
270
271       strtrim(name);
272
273       sprintf(filename, "/var/spool/printer/%s", name);
274       tarfile_mkdir(tf, filename, 0755, 1, 1, "daemon", "daemon", now);
275
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
278        * to now.
279        */
280
281       /* Access-control list. */
282       if (ac)
283         {
284           sprintf(filename, "/var/spool/printer/%s/restrict.list", name);
285           out = tarfile_start(tf, filename, 0755, 1, 1, "daemon", "daemon",
286                               now);
287           if (ka)
288             dump_krb_acl(out, "LIST", ac, 5);
289           else
290             dump_user_list(out, "LIST", ac);
291           tarfile_end(tf);
292         }
293
294       /* printer-specific lpc access. */
295       if (lpc_acl)
296         {
297           sprintf(filename, "/var/spool/printer/%s/lpcaccess", name);
298           out = tarfile_start(tf, filename, 0755, 1, 1, "daemon", "daemon",
299                               now);
300           dump_krb_acl(out, "LIST", lpc_acl, 5);
301           tarfile_end(tf);
302         }
303     }
304
305   /* lpcaccess.top */
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)
310     {
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);
314       tarfile_end(tf);
315     }
316
317   EXEC SQL CLOSE csr_spool;
318
319   tarfile_close(tf);
320 }
321
322 void sqlerr(void)
323 {
324   db_error(sqlca.sqlcode);
325 }
This page took 0.261294 seconds and 5 git commands to generate.