]> andersk Git - moira.git/blobdiff - gen/print.pc
Command line printer manipulation client, and build goo.
[moira.git] / gen / print.pc
index f7bde0f808ba0c29f2d7125e57c2dc369e17865a..6399b6fccdd389a46c8b04ca85769f6350dce095 100644 (file)
@@ -28,7 +28,6 @@ char *whoami = "print.gen";
 char *db = "moira/moira";
 
 void do_host(char *host);
-void dump_acl(FILE *out, int id, int realms);
 void sqlerr(void);
 #ifndef MAX
 #define MAX(a, b) ( (a) > (b) ? (a) : (b) )
@@ -40,6 +39,8 @@ int main(int argc, char **argv)
   char name[MACHINE_NAME_SIZE];
   EXEC SQL END DECLARE SECTION;
 
+  init_acls();
+
   EXEC SQL CONNECT :db;
 
   EXEC SQL WHENEVER SQLERROR DO sqlerr();
@@ -67,37 +68,39 @@ 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], hostname[MACHINE_NAME_SIZE];
-  char rm[MACHINE_NAME_SIZE], rq[MACHINE_NAME_SIZE];
+  char hwtype[PRINTERS_HWTYPE_SIZE], lowerhwtype[PRINTERS_HWTYPE_SIZE];
   char modtime[PRINTERS_MODTIME_SIZE], lmodtime[LIST_MODTIME_SIZE];
-  char contact[PRINTERS_CONTACT_SIZE];
-  char *spoolhost = host, *unixtime_fmt = UNIXTIME_FMT;
-  int ka, pc, ac, lpc_acl, banner;
+  char contact[PRINTERS_CONTACT_SIZE], hostname[MACHINE_NAME_SIZE];
+  char *spoolhost = host, *unixtime_fmt = UNIXTIME_FMT, *p;
+  int ka, pc, ac, lpc_acl, banner, rm;
   EXEC SQL END DECLARE SECTION;
   TARFILE *tf;
   FILE *out;
-  char filename[MAXPATHLEN];
+  char filename[MAXPATHLEN], *duptc;
   time_t mtime, now = time(NULL);
 
+  EXEC SQL SELECT mach_id INTO :rm FROM machine
+    WHERE name = :spoolhost;
+
   sprintf(filename, "%s/print/%s", DCM_DIR, host);
   tf = tarfile_open(filename);
 
+  /* printcap */
   out = tarfile_start(tf, "/etc/printcap.moira", 0644, 0, 0,
                      "root", "root", now);
 
   EXEC SQL DECLARE csr_printcap CURSOR FOR
     SELECT pr.rp, pr.name, pr.duplexname, pr.hwtype,
-    m.name, mrm.name, mrq.name, pr.ka, pr.pc, pr.ac,
-    pr.location, pr.contact
-    FROM printers pr, machine m, machine mrm, machine mrq
-    WHERE m.mach_id = pr.mach_id AND mrq.mach_id = pr.rq
-    AND mrm.mach_id = pr.rm AND mrm.name = :spoolhost
-    AND pr.type != 'ALIAS';
+    m.name, pr.banner, pr.location, pr.contact
+    FROM printers pr, machine m
+    WHERE pr.rm = :rm AND m.mach_id = pr.mach_id
+    AND pr.type != 'ALIAS'
+    AND ( pr.hwtype LIKE 'HP%' OR pr.hwtype LIKE 'LPR%' );
   EXEC SQL OPEN csr_printcap;
   while (1)
     {
       EXEC SQL FETCH csr_printcap INTO :rp, :name, :duplexname,
-       :hwtype, :hostname, :rm, :rq, :ka, :pc, :ac, :location, :contact;
+       :hwtype, :hostname, :banner, :location, :contact;
       if (sqlca.sqlcode)
        break;
 
@@ -106,10 +109,11 @@ void do_host(char *host)
       strtrim(duplexname);
       strtrim(hwtype);
       strtrim(hostname);
-      strtrim(rm);
-      strtrim(rq);
       strtrim(location);
       strtrim(contact);
+      strcpy(lowerhwtype, hwtype);
+      for (p = lowerhwtype; *p; p++)
+       *p = tolower(*p);
 
       if (location[0])
        fprintf(out, "# %s: %s\n", name, location);
@@ -118,89 +122,156 @@ void do_host(char *host)
       if (strcmp(location, contact))
        fprintf(out, "# contact: %s\n", contact);
 
-      fprintf(out, "%s|%s %s", rp, location, hwtype);
-      if (*duplexname)
-       fprintf(out, "|%s", duplexname);
-      fprintf(out, ":\\\n\t:lp=/dev/null:rp=%s:rm=%s:\\\n"
-             "\t:sd=/var/spool/printer/%s:\\\n"
-             "\t:lf=/var/spool/printer/%s/%s-log:\\\n"
-             "\t:af=/var/spool/printer/%s/%s-acct:\\\n"
-             "\t:ka#%d:pc#%d:\\\n",
-             !strcmp(hwtype, "LPR") ? "raw" : rp,
-             !strncmp(hwtype, "HP", 2) ? rm : hostname,
-             rp, rp, rp, rp, rp, ka, pc);
-      if (strcmp(rq, "[NONE]"))
-       fprintf(out, "\t:rq=%s:\\\n", rq);
-      if (ac)
-       fprintf(out, "\t:ac=/var/spool/printer/%s/restrict.list:pa:\\\n", rp);
+      fprintf(out, "%s\n\t:server:cm=%s %s\n\t", rp, hwtype, location);
+      if (banner == PRN_BANNER_NONE)
+       fprintf(out, ":sh");
+      else if (banner == PRN_BANNER_LAST)
+       fprintf(out, ":hl");
 
       if (!strncmp(hwtype, "HP", 2))
        {
-         fprintf(out, "\t:if=/usr/athena/lib/lpdfilters/hpif:\\\n"
-                 "\t:of=/usr/athena/lib/lpdfilters/hpof:\\\n"
-                 "\t:gf=/usr/athena/lib/lpdfilters/hpgf:\\\n"
-                 "\t:nf=/usr/athena/lib/lpdfilters/hpnf:\\\n"
-                 "\t:tf=/usr/athena/lib/lpdfilters/hptf:\\\n"
-                 "\t:rf=/usr/athena/lib/lpdfilters/hprf:\\\n"
-                 "\t:vf=/usr/athena/lib/lpdfilters/hpvf:\\\n"
-                 "\t:cf=/usr/athena/lib/lpdfilters/hpcf:\\\n"
-                 "\t:df=/usr/athena/lib/lpdfilters/hpdf:\\\n"
-                 "\t:sf:sb:mx#0:\n\n");
+         fprintf(out, ":lp=%s%%9100:ifhp=model=%s:tc=.hp\n\n",
+                 hostname, lowerhwtype);
+         duptc = ".hp2";
+       }
+      else if (!strncmp(hwtype, "LPR", 3))
+       {
+         fprintf(out, ":lp=raw@%s:tc=.apple\n\n", hostname);
+         duptc = ".apple2";
+       }
+
+      if (*duplexname)
+       {
+         fprintf(out, "%s\n\t:server:bq=%s:cm=%s duplex queue\n\t", 
+                 duplexname, rp, rp);
+         if (!strncmp(hwtype, "HP", 2))
+           fprintf(out, ":ifhp=model=%s", lowerhwtype);
+         fprintf(out, ":tc=%s\n\n", duptc);
        }
-      else
-       fprintf(out, "\t:mx#0:\n\n");
     }
   EXEC SQL CLOSE csr_printcap;
   tarfile_end(tf);
 
-  EXEC SQL DECLARE csr_spool CURSOR FOR
-    SELECT UNIQUE pr.rp, pr.duplexname, pr.hwtype, m.name, pr.ac,
-    pr.lpc_acl, pr.banner, TO_CHAR(pr.modtime, :unixtime_fmt)
-    FROM printers pr, machine m, machine mrm
-    WHERE m.mach_id = pr.mach_id
-    AND mrm.mach_id = pr.rm AND mrm.name = :spoolhost;
-  EXEC SQL OPEN csr_spool;
+  /* lpd.perms */
+  out = tarfile_start(tf, "/etc/lpd.perms", 0755, 1, 1,
+                     "daemon", "daemon", now);
+  fprintf(out, "# Allow anybody to connect, get status, list queue, or "
+         "print (once a\n# job is spooled)\n");
+  fprintf(out, "ACCEPT SERVICE=X,S,Q,P\nACCEPT LPC=status,lpq,printcap\n\n");
+
+  fprintf(out, "# Only trust certain host keys to forward jobs/commands\n");
+  fprintf(out, "REJECT SERVICE=R AUTHFROM=?* "
+         "PRINTER=</var/spool/printer/queues.secure "
+         "NOT AUTHFROM=</var/spool/printer/hostkeys.allow FORWARD\n");
+  fprintf(out, "REJECT SERVICE=R AUTHFROM=?* AUTHJOB "
+         "NOT AUTHFROM=</var/spool/printer/hostkeys.allow FORWARD\n\n");
+
+  fprintf(out, "# Allow root to control and remove jobs\n");
+  fprintf(out, "ACCEPT SERVICE=C,R SERVER REMOTEUSER=root\n\n");
+
+  fprintf(out, "# Allow admins to control and remove jobs\n");
+  fprintf(out, "ACCEPT SERVICE=C,R AUTH=USER AUTHUSER=</var/spool/printer/lpcaccess.top\n\n");
+
+  fprintf(out, "# Printer-specific LPC ACLs\n");
+  EXEC SQL DECLARE csr_lpc CURSOR FOR
+    SELECT rp, duplexname FROM printers
+    WHERE rm = :rm AND lpc_acl != 0;
+  EXEC SQL OPEN csr_lpc;
   while (1)
     {
-      EXEC SQL FETCH csr_spool INTO :name, :duplexname, :hwtype,
-       :hostname, :ac, :lpc_acl, :banner, :modtime;
+      EXEC SQL FETCH csr_lpc INTO :name, :duplexname;
       if (sqlca.sqlcode)
        break;
 
       strtrim(name);
       strtrim(duplexname);
-      strtrim(hwtype);
-      strtrim(hostname);
-      mtime = unixtime(strtrim(modtime));
+      fprintf(out, "ACCEPT SERVICE=C,R PRINTER=%s%s%s AUTH=USER "
+             "AUTHUSER=</var/spool/printer/%s/lpcaccess\n",
+             name, *duplexname ? "," : "", duplexname, name);
+    }
+  EXEC SQL CLOSE csr_lpc;
+  fprintf(out, "\n");
+
+  fprintf(out, "# Reject jobs from unauthorized users to restricted queues\n");
+  EXEC SQL DECLARE csr_ac CURSOR FOR
+    SELECT rp, duplexname, ka FROM printers
+    WHERE rm = :rm AND ac != 0;
+  EXEC SQL OPEN csr_ac;
+  while (1)
+    {
+      EXEC SQL FETCH csr_ac INTO :name, :duplexname, ka;
+      if (sqlca.sqlcode)
+       break;
 
-      sprintf(filename, "/var/spool/printer/%s", name);
-      tarfile_mkdir(tf, filename, 0755, 1, 1, "daemon", "daemon", mtime);
+      strtrim(name);
+      strtrim(duplexname);
+      fprintf(out, "REJECT SERVICE=R PRINTER=%s%s%s NOT "
+             "%sUSER=</var/spool/printer/%s/restrict.list\n",
+             name, *duplexname ? "," : "", duplexname,
+             ka ? "AUTH" : "", name);
+    }
+  EXEC SQL CLOSE csr_ac;
+  fprintf(out, "\n");
+
+  fprintf(out, "# Allow us to lock out users\n");
+  fprintf(out, "REJECT SERVICE=R USER=</var/spool/printer/users.deny\n");
+  fprintf(out, "# Accept authenticated jobs to all other printers\n");
+  fprintf(out, "ACCEPT SERVICE=R AUTH=USER,FWD\n");
+  fprintf(out, "# Allow authenticated users to lprm their jobs\n");
+  fprintf(out, "ACCEPT SERVICE=M AUTH=USER,FWD AUTHJOB AUTHSAMEUSER\n\n");
+
+  fprintf(out, "# Reject unauthentic print/lprm requests to authenticated queues\n");
+  fprintf(out, "REJECT SERVICE=R,M NOT AUTH "
+         "PRINTER=</var/spool/printer/queues.secure\n\n");
+
+  fprintf(out, "# Reject unauthentic print requests from off MITnet\n");
+  fprintf(out, "REJECT SERVICE=R NOT REMOTEIP=</var/spool/printer/masks.allow\n\n\n");
+
+  fprintf(out, "# Accept unauthentic print requests if same user and on MITnet\n");
+  fprintf(out, "ACCEPT SERVICE=M NOT AUTHJOB SAMEUSER REMOTEIP=</var/spool/printer/masks.allow\n\n");
+  
+  fprintf(out, "# Reject any other lpc, or lprm. Accept all else\n");
+  fprintf(out, "REJECT SERVICE=C,M\n");
+  fprintf(out, "DEFAULT ACCEPT\n");
+  tarfile_end(tf);
 
-      /* If spooling to an HP printer, make a .options file. */
-      if (!strncmp(hwtype, "HP", 2))
-       {
-         sprintf(filename, "/var/spool/printer/%s/.options", name);
-         out = tarfile_start(tf, filename, 0755, 1, 1, "daemon", "daemon",
-                             mtime);
-         fprintf(out, "BANNERFIRST=%d\nBANNERLAST=%d\nREVERSE=\n"
-                 "DUPLEXING=0\nINTERFACE=0\nNETNAME=%s\nPRINTER=%s\n"
-                 "export BANNERFIRST BANNERLAST REVERSE DUPLEXING\n"
-                 "export PRINTER NETNAME INTERFACE VERBOSELOG\n",
-                 banner == PRN_BANNER_FIRST, banner == PRN_BANNER_LAST,
-                 hostname, name);
-         tarfile_end(tf);
-       }
+  /* list of kerberized queues */
+  out = tarfile_start(tf, "/var/spool/printer/queues.secure", 0755, 1, 1,
+                    "daemon", "daemon", now);
+  EXEC SQL DECLARE csr_kq CURSOR FOR
+    SELECT rp, duplexname FROM printers
+    WHERE rm = :rm AND ka = 1;
+  EXEC SQL OPEN csr_kq;
+  while (1)
+    {
+      EXEC SQL FETCH csr_kq INTO :name, :duplexname;
+      if (sqlca.sqlcode)
+       break;
 
-      /* If we have a duplex name, make a .spooler file. */
+      strtrim(name);
+      strtrim(duplexname);
+      fprintf(out, "%s\n", name);
       if (*duplexname)
-       {
-         sprintf(filename, "/var/spool/printer/%s/.spooler", name);
-         out = tarfile_start(tf, filename, 0755, 1, 1, "daemon", "daemon",
-                             mtime);
-         fprintf(out, "%s -F /usr/athena/lib/lpdfilters/duplex2\n",
-                 duplexname);
-         tarfile_end(tf);
-       }
+       fprintf(out, "%s\n", duplexname);
+    }
+  tarfile_end(tf);
+
+  /* restrict lists and lpcaccess files */
+  EXEC SQL DECLARE csr_spool CURSOR FOR
+    SELECT UNIQUE rp, ka, ac, lpc_acl
+    FROM printers
+    WHERE rm = :rm AND ( ac != 0 OR lpc_acl != 0);
+  EXEC SQL OPEN csr_spool;
+  while (1)
+    {
+      EXEC SQL FETCH csr_spool INTO :name, :ka, :ac, :lpc_acl;
+      if (sqlca.sqlcode)
+       break;
+
+      strtrim(name);
+
+      sprintf(filename, "/var/spool/printer/%s", name);
+      tarfile_mkdir(tf, filename, 0755, 1, 1, "daemon", "daemon", now);
 
       /* The ac and lpc_acl lists may have sublists, and changes to those
        * won't affect the superlist's modtime. So we just set the modtime
@@ -213,68 +284,39 @@ void do_host(char *host)
          sprintf(filename, "/var/spool/printer/%s/restrict.list", name);
          out = tarfile_start(tf, filename, 0755, 1, 1, "daemon", "daemon",
                              now);
-         dump_acl(out, ac, 0);
+         if (ka)
+           dump_krb_acl(out, "LIST", ac, 5);
+         else
+           dump_user_list(out, "LIST", ac);
          tarfile_end(tf);
        }
 
       /* printer-specific lpc access. */
       if (lpc_acl)
        {
-         sprintf(filename, "/var/spool/printer/%s/lpcaccess.%s", name, name);
+         sprintf(filename, "/var/spool/printer/%s/lpcaccess", name);
          out = tarfile_start(tf, filename, 0755, 1, 1, "daemon", "daemon",
                              now);
-         fprintf(out, "all:\n");
-         dump_acl(out, lpc_acl, 1);
+         dump_krb_acl(out, "LIST", lpc_acl, 5);
          tarfile_end(tf);
        }
     }
-  EXEC SQL CLOSE csr_spool;
-
-  tarfile_close(tf);
-}
 
-void dump_acl(FILE *out, int id, int realms)
-{
-  EXEC SQL BEGIN DECLARE SECTION;
-  int lid = id;
-  char login[USERS_LOGIN_SIZE], princ[STRINGS_STRING_SIZE];
-  EXEC SQL END DECLARE SECTION;
-
-  EXEC SQL DECLARE csr_users CURSOR FOR
-    SELECT u.login FROM users u, imembers im
-    WHERE u.users_id = im.member_id
-    AND im.member_type = 'USER' AND im.list_id = :lid;
-  EXEC SQL OPEN csr_users;
-  while (1)
+  /* lpcaccess.top */
+  EXEC SQL SELECT ps.lpc_acl INTO :lpc_acl
+    FROM printservers ps, machine m
+    WHERE m.name = :spoolhost AND m.mach_id = ps.mach_id;
+  if (!sqlca.sqlcode && lpc_acl)
     {
-      EXEC SQL FETCH csr_users INTO :login;
-      if (sqlca.sqlcode)
-       break;
-
-      fprintf(out, "%s%s\n", strtrim(login), realms ? "@ATHENA.MIT.EDU" : "");
+      out = tarfile_start(tf, "/var/spool/printer/lpcaccess.top",
+                         0755, 1, 1, "daemon", "daemon", now);
+      dump_krb_acl(out, "LIST", lpc_acl, 5);
+      tarfile_end(tf);
     }
-  EXEC SQL CLOSE csr_users;
-
-  EXEC SQL DECLARE csr_krb CURSOR FOR
-    SELECT s.string FROM strings s, imembers im
-    WHERE s.string_id = im.member_id
-    AND im.member_type = 'KERBEROS' AND im.list_id = :lid;
-  EXEC SQL OPEN csr_krb;
-  while (1)
-    {
-      EXEC SQL FETCH csr_krb INTO :princ;
-      if (sqlca.sqlcode)
-       break;
 
-      if (!realms)
-       {
-         if (strchr(princ, '@'))
-           *strchr(princ, '@') = '\0';
-       }
+  EXEC SQL CLOSE csr_spool;
 
-      fprintf(out, "%s\n", strtrim(princ));
-    }
-  EXEC SQL CLOSE csr_krb;
+  tarfile_close(tf);
 }
 
 void sqlerr(void)
This page took 0.045096 seconds and 4 git commands to generate.