source: trunk/third/moira/gen/print.pc @ 25198

Revision 25198, 9.8 KB checked in by jdreed, 13 years ago (diff)
In moira: * Snapshot moira@r4042 (6/28/11) * Update version number to include moira revision number
Line 
1/* $Id: print.pc 4030 2011-03-04 21:01:14Z zacheiss $
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
23EXEC SQL INCLUDE sqlca;
24
25RCSID("$HeadURL: svn+ssh://svn.mit.edu/moira/trunk/moira/gen/print.pc $ $Id: print.pc 4030 2011-03-04 21:01:14Z zacheiss $");
26
27char *whoami = "print.gen";
28char *db = "moira/moira";
29
30void do_host(char *host);
31void sqlerr(void);
32#ifndef MAX
33#define MAX(a, b) ( (a) > (b) ? (a) : (b) )
34#endif
35
36int 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
66void 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.status = 1 OR pr.status = 2) AND m.status != 3
98    AND pr.type != 'ALIAS'
99    AND ( pr.hwtype LIKE 'HP%' OR pr.hwtype LIKE 'LPR%' );
100  EXEC SQL OPEN csr_printcap;
101  while (1)
102    {
103      EXEC SQL FETCH csr_printcap INTO :rp, :name, :duplexname,
104        :hwtype, :hostname, :banner, :location, :contact;
105      if (sqlca.sqlcode)
106        break;
107
108      strtrim(rp);
109      strtrim(name);
110      strtrim(duplexname);
111      strtrim(hwtype);
112      strtrim(hostname);
113      strtrim(location);
114      strtrim(contact);
115      strcpy(lowerhwtype, hwtype);
116      for (p = lowerhwtype; *p; p++)
117        *p = tolower(*p);
118
119      if (location[0])
120        fprintf(out, "# %s: %s\n", name, location);
121      else
122        fprintf(out, "# %s\n", name);
123      if (strcmp(location, contact))
124        fprintf(out, "# contact: %s\n", contact);
125
126      fprintf(out, "%s\n\t:server:cm=%s %s\n\t", rp, hwtype, location);
127      if (banner == PRN_BANNER_NONE)
128        fprintf(out, ":sh");
129      else if (banner == PRN_BANNER_LAST)
130        fprintf(out, ":hl");
131
132      if (!strncmp(hwtype, "HP", 2))
133        {
134          fprintf(out, ":lp=%s%%9100:ifhp=model=%s:tc=.hp\n\n",
135                  hostname, lowerhwtype);
136          duptc = ".hp2";
137        }
138      else if (!strncmp(hwtype, "LPR", 3))
139        {
140          fprintf(out, ":lp=raw@%s:tc=.apple\n\n", hostname);
141          duptc = ".apple2";
142        }
143
144      if (*duplexname)
145        {
146          fprintf(out, "%s\n\t:server:bq=%s:cm=%s duplex queue\n\t",
147                  duplexname, rp, rp);
148          if (!strncmp(hwtype, "HP", 2))
149            fprintf(out, ":ifhp=model=%s", lowerhwtype);
150          fprintf(out, ":tc=%s\n\n", duptc);
151        }
152    }
153  EXEC SQL CLOSE csr_printcap;
154  tarfile_end(tf);
155
156  /* lpd.perms */
157  out = tarfile_start(tf, "/etc/lpd.perms", 0755, 1, 1,
158                      "daemon", "daemon", now);
159  fprintf(out, "# Allow anybody to connect, get status, list queue, or "
160          "print (once a\n# job is spooled)\n");
161  fprintf(out, "ACCEPT SERVICE=X,S,Q,P\nACCEPT LPC=status,lpq,printcap\n\n");
162
163  fprintf(out, "# Only trust certain host keys to forward jobs/commands\n");
164  fprintf(out, "REJECT SERVICE=R AUTHFROM=?* "
165          "PRINTER=</var/spool/printer/queues.secure "
166          "NOT AUTHFROM=</var/spool/printer/hostkeys.allow FORWARD\n");
167  fprintf(out, "REJECT SERVICE=R AUTHFROM=?* AUTHJOB "
168          "NOT AUTHFROM=</var/spool/printer/hostkeys.allow FORWARD\n\n");
169
170  fprintf(out, "# Allow root to control and remove jobs\n");
171  fprintf(out, "ACCEPT SERVICE=C,R SERVER REMOTEUSER=root\n\n");
172
173  fprintf(out, "# Allow admins to control and remove jobs\n");
174  fprintf(out, "ACCEPT SERVICE=C,R AUTH=USER AUTHUSER=</var/spool/printer/lpcaccess.top\n\n");
175
176  fprintf(out, "# Printer-specific LPC ACLs\n");
177  EXEC SQL DECLARE csr_lpc CURSOR FOR
178    SELECT pr.rp, pr.duplexname FROM printers pr, machine m
179    WHERE pr.rm = :rm AND pr.lpc_acl != 0
180    AND (pr.status = 1 OR pr.status = 2) and pr.mach_id = m.mach_id AND m.status !=3;
181  EXEC SQL OPEN csr_lpc;
182  while (1)
183    {
184      EXEC SQL FETCH csr_lpc INTO :name, :duplexname;
185      if (sqlca.sqlcode)
186        break;
187
188      strtrim(name);
189      strtrim(duplexname);
190      fprintf(out, "ACCEPT SERVICE=C,R PRINTER=%s%s%s AUTH=USER "
191              "AUTHUSER=</var/spool/printer/%s/lpcaccess\n",
192              name, *duplexname ? "," : "", duplexname, name);
193    }
194  EXEC SQL CLOSE csr_lpc;
195  fprintf(out, "\n");
196
197  fprintf(out, "# Reject jobs from unauthorized users to restricted queues\n");
198  EXEC SQL DECLARE csr_ac CURSOR FOR
199    SELECT pr.rp, pr.duplexname, pr.ka FROM printers pr, machine m
200    WHERE pr.rm = :rm AND pr.ac != 0
201    AND (pr.status = 1 OR pr.status = 2) and pr.mach_id = m.mach_id AND m.status !=3;
202  EXEC SQL OPEN csr_ac;
203  while (1)
204    {
205      EXEC SQL FETCH csr_ac INTO :name, :duplexname, ka;
206      if (sqlca.sqlcode)
207        break;
208
209      strtrim(name);
210      strtrim(duplexname);
211      fprintf(out, "REJECT SERVICE=R PRINTER=%s%s%s NOT "
212              "%sUSER=</var/spool/printer/%s/restrict.list\n",
213              name, *duplexname ? "," : "", duplexname,
214              ka ? "AUTH" : "", name);
215    }
216  EXEC SQL CLOSE csr_ac;
217  fprintf(out, "\n");
218
219  fprintf(out, "# Allow us to lock out users\n");
220  fprintf(out, "REJECT SERVICE=R USER=</var/spool/printer/users.deny\n");
221  fprintf(out, "# Accept authenticated jobs to all other printers\n");
222  fprintf(out, "ACCEPT SERVICE=R AUTH=USER,FWD\n");
223  fprintf(out, "# Allow authenticated users to lprm their jobs\n");
224  fprintf(out, "ACCEPT SERVICE=M AUTH=USER,FWD AUTHJOB AUTHSAMEUSER\n\n");
225
226  fprintf(out, "# Reject unauthentic print/lprm requests to authenticated queues\n");
227  fprintf(out, "REJECT SERVICE=R,M NOT AUTH "
228          "PRINTER=</var/spool/printer/queues.secure\n\n");
229
230  fprintf(out, "# Reject unauthentic print requests from off MITnet\n");
231  fprintf(out, "REJECT SERVICE=R NOT REMOTEIP=</var/spool/printer/masks.allow\n\n\n");
232
233  fprintf(out, "# Accept unauthentic print requests if same user and on MITnet\n");
234  fprintf(out, "ACCEPT SERVICE=M NOT AUTHJOB SAMEUSER REMOTEIP=</var/spool/printer/masks.allow\n\n");
235 
236  fprintf(out, "# Reject any other lpc, or lprm. Accept all else\n");
237  fprintf(out, "REJECT SERVICE=C,M\n");
238  fprintf(out, "DEFAULT ACCEPT\n");
239  tarfile_end(tf);
240
241  /* list of kerberized queues */
242  out = tarfile_start(tf, "/var/spool/printer/queues.secure", 0755, 1, 1,
243                     "daemon", "daemon", now);
244  EXEC SQL DECLARE csr_kq CURSOR FOR
245    SELECT pr.rp, pr.duplexname FROM printers pr, machine m
246    WHERE pr.rm = :rm AND pr.ka = 1
247    AND (pr.status = 1 OR pr.status = 2) AND pr.mach_id = m.mach_id AND m.status !=3;
248  EXEC SQL OPEN csr_kq;
249  while (1)
250    {
251      EXEC SQL FETCH csr_kq INTO :name, :duplexname;
252      if (sqlca.sqlcode)
253        break;
254
255      strtrim(name);
256      strtrim(duplexname);
257      fprintf(out, "%s\n", name);
258      if (*duplexname)
259        fprintf(out, "%s\n", duplexname);
260    }
261  tarfile_end(tf);
262
263  /* restrict lists and lpcaccess files */
264  EXEC SQL DECLARE csr_spool CURSOR FOR
265    SELECT UNIQUE pr.rp, pr.ka, pr.ac, pr.lpc_acl
266    FROM printers pr, machine m
267    WHERE pr.rm = :rm AND ( pr.ac != 0 OR pr.lpc_acl != 0)
268    AND (pr.status = 1 OR pr.status = 2) AND pr.mach_id = m.mach_id AND m.status !=3;
269  EXEC SQL OPEN csr_spool;
270  while (1)
271    {
272      EXEC SQL FETCH csr_spool INTO :name, :ka, :ac, :lpc_acl;
273      if (sqlca.sqlcode)
274        break;
275
276      strtrim(name);
277
278      sprintf(filename, "/var/spool/printer/%s", name);
279      tarfile_mkdir(tf, filename, 0755, 1, 1, "daemon", "daemon", now);
280
281      /* The ac and lpc_acl lists may have sublists, and changes to those
282       * won't affect the superlist's modtime. So we just set the modtime
283       * to now.
284       */
285
286      /* Access-control list. */
287      if (ac)
288        {
289          sprintf(filename, "/var/spool/printer/%s/restrict.list", name);
290          out = tarfile_start(tf, filename, 0755, 1, 1, "daemon", "daemon",
291                              now);
292          if (ka)
293            dump_krb_acl(out, "LIST", ac, 5);
294          else
295            dump_user_list(out, "LIST", ac);
296          tarfile_end(tf);
297        }
298
299      /* printer-specific lpc access. */
300      if (lpc_acl)
301        {
302          sprintf(filename, "/var/spool/printer/%s/lpcaccess", name);
303          out = tarfile_start(tf, filename, 0755, 1, 1, "daemon", "daemon",
304                              now);
305          dump_krb_acl(out, "LIST", lpc_acl, 5);
306          tarfile_end(tf);
307        }
308    }
309
310  /* lpcaccess.top */
311  EXEC SQL SELECT ps.lpc_acl INTO :lpc_acl
312    FROM printservers ps, machine m
313    WHERE m.name = :spoolhost AND m.mach_id = ps.mach_id;
314  if (!sqlca.sqlcode && lpc_acl)
315    {
316      out = tarfile_start(tf, "/var/spool/printer/lpcaccess.top",
317                          0755, 1, 1, "daemon", "daemon", now);
318      dump_krb_acl(out, "LIST", lpc_acl, 5);
319      tarfile_end(tf);
320    }
321
322  EXEC SQL CLOSE csr_spool;
323
324  tarfile_close(tf);
325}
326
327void sqlerr(void)
328{
329  db_error(sqlca.sqlcode);
330}
Note: See TracBrowser for help on using the repository browser.