Major overhaul. Now uses DSA signatures rather than the bogus symmetric
[become] / src / become.c
index 6236855..d383084 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: become.c,v 1.21 1999/07/28 09:31:01 mdw Exp $
+ * $Id: become.c,v 1.22 2003/10/12 00:14:55 mdw Exp $
  *
  * Main code for `become'
  *
 /*----- Revision history --------------------------------------------------*
  *
  * $Log: become.c,v $
+ * Revision 1.22  2003/10/12 00:14:55  mdw
+ * Major overhaul.  Now uses DSA signatures rather than the bogus symmetric
+ * encrypt-and-hope thing.  Integrated with mLib and Catacomb.
+ *
  * Revision 1.21  1999/07/28 09:31:01  mdw
  * Empty path components are equivalent to `.'.
  *
 
 extern char **environ;
 
+/* --- mLib --- */
+
+#include <mLib/alloc.h>
+#include <mLib/mdwopt.h>
+#include <mLib/quis.h>
+#include <mLib/report.h>
+#include <mLib/sym.h>
+#include <mLib/trace.h>
+
 /* --- Local headers --- */
 
 #include "become.h"
@@ -153,12 +166,9 @@ extern char **environ;
 #include "check.h"
 #include "daemon.h"
 #include "lexer.h"
-#include "mdwopt.h"
 #include "name.h"
 #include "parse.h"
 #include "rule.h"
-#include "sym.h"
-#include "utils.h"
 #include "userdb.h"
 
 /*----- Type definitions --------------------------------------------------*/
@@ -464,7 +474,7 @@ static void bc__help(FILE *fp, int suid)
 "-f FILE, --config-file=FILE   In daemon mode, read config from FILE\n"
 #endif
     );
-#ifdef TRACING
+#ifndef NTRACE
   bc__write(fp, "\n");
   if (!suid) {
     bc__write(fp,
@@ -550,7 +560,7 @@ int main(int argc, char *argv[])
   {
     char **p;
 
-    sym_createTable(&bc__env);
+    sym_create(&bc__env);
     for (p = environ; *p; p++)
       bc__putenv(0, *p, 0, 0);
   }
@@ -597,7 +607,7 @@ int main(int argc, char *argv[])
 
       /* --- Tracing options --- */
 
-#ifdef TRACING
+#ifndef NTRACE
       { "impersonate", gFlag_argReq,   0,      'I' },
       { "trace",       gFlag_argOpt,   0,      'T' },
       { "trace-level", gFlag_argOpt,   0,      'L' },
@@ -619,7 +629,7 @@ int main(int argc, char *argv[])
 #ifndef NONETWORK
               "dp:f:"                  /* Server options */
 #endif
-#ifdef TRACING
+#ifndef NTRACE
               "I:T::L::"               /* Tracing options */
 #endif
               ,
@@ -664,7 +674,7 @@ int main(int argc, char *argv[])
        else {
          struct group *gr = getgrnam(optarg);
          if (!gr)
-           die("unknown group `%s'", optarg);
+           die(1, "unknown group `%s'", optarg);
          group = gr->gr_gid;
        }
        flags |= f_havegroup;
@@ -695,7 +705,7 @@ int main(int argc, char *argv[])
        else {
          struct servent *s = getservbyname(optarg, "udp");
          if (!s)
-           die("unknown service name `%s'", optarg);
+           die(1, "unknown service name `%s'", optarg);
          port = s->s_port;
        }
        break;
@@ -713,7 +723,7 @@ int main(int argc, char *argv[])
        * allow it if we're running setuid.  Disable the actual login anyway.
        */
 
-#ifdef TRACING
+#ifndef NTRACE
 
       case 'I':
        if (flags & f_setuid)
@@ -725,7 +735,7 @@ int main(int argc, char *argv[])
          else
            pw = getpwnam(optarg);
          if (!pw)
-           die("can't impersonate unknown user `%s'", optarg);
+           die(1, "can't impersonate unknown user `%s'", optarg);
          from_pw = userdb_copyUser(pw);
          rq.from = from_pw->pw_uid;
          flags |= f_dummy;
@@ -740,7 +750,7 @@ int main(int argc, char *argv[])
        * to!
        */
 
-#ifdef TRACING
+#ifndef TRACE
 
       case 'T': {
        FILE *fp;
@@ -756,12 +766,12 @@ int main(int argc, char *argv[])
          if (seteuid(ru))
 #endif
          {
-           die("couldn't temporarily give up privileges: %s",
+           die(1, "couldn't temporarily give up privileges: %s",
                strerror(errno));
          }
 
          if ((fp = fopen(optarg, "w")) == 0) {
-           die("couldn't open trace file `%s' for writing: %s",
+           die(1, "couldn't open trace file `%s' for writing: %s",
                optarg, strerror(errno));
          }
 
@@ -770,9 +780,9 @@ int main(int argc, char *argv[])
 #else
           if (seteuid(eu))
 #endif
-           die("couldn't regain privileges: %s", strerror(errno));
+           die(1, "couldn't regain privileges: %s", strerror(errno));
        }
-       traceon(fp, TRACE_DFL);
+       trace_on(fp, TRACE_DFL);
        trace(TRACE_MISC, "become: tracing enabled");
       } break;
 
@@ -780,22 +790,13 @@ int main(int argc, char *argv[])
 
       /* --- Setting trace levels --- */
 
-#ifdef TRACING
+#ifndef NTRACE
 
       case 'L': {
-       int sense = 1;
-       unsigned int lvl = 0, l;
-       const char *p = optarg;
 
        /* --- Table of tracing facilities --- */
 
-       typedef struct tr {
-         char ch;
-         unsigned int l;
-         const char *help;
-       } tr;
-
-       static tr lvltbl[] = {
+       static trace_opt lvltbl[] = {
          { 'm', TRACE_MISC,    "miscellaneous messages" },
          { 's', TRACE_SETUP,   "building the request block" },
          { 'r', TRACE_RULE,    "ruleset scanning" },
@@ -811,51 +812,11 @@ int main(int argc, char *argv[])
          { 'A', TRACE_ALL,     "all tracing options" },
          { 0,   0,             0 }
        };
-       tr *tp;
 
        /* --- Output some help if there's no arguemnt --- */
 
-       if (!optarg) {
-         bc__banner(stdout);
-         bc__write(stdout,
-                   "\n"
-                   "Tracing options:\n"
-                   "\n");
-         for (tp = lvltbl; tp->l; tp++) {
-           if ((flags & f_setuid) == 0 || tp->l & ~TRACE_PRIV)
-             printf("%c -- %s\n", tp->ch, tp->help);
-         }
-         bc__write(stdout,
-"\n"
-"Also, `+' and `-' options are recognised to turn on and off various\n"
-"tracing options.  For example, `A-r' enables everything except ruleset\n"
-"tracing, and `A-D+c' is everything except the defaults, but with request\n"
-"check tracing.\n"
-);
-         exit(0);
-       }
-
-       while (*p) {
-         if (*p == '+')
-           sense = 1;
-         else if (*p == '-')
-           sense = 0;
-         else {
-           for (tp = lvltbl; tp->l && *p != tp->ch; tp++)
-             ;
-           l = tp->l;
-           if (flags & f_setuid)
-             l &= ~TRACE_PRIV;
-           if (l)
-             lvl = sense ? (lvl | l) : (lvl & ~l);
-           else
-             moan("unknown trace option `%c'", *p);
-         }
-         p++;
-       }
-
-       tracesetlvl(lvl);
-       yydebug = ((lvl & TRACE_YACC) != 0);
+       trace_level(traceopt(lvltbl, optarg, TRACE_DFL,
+                            (flags & f_setuid) ? TRACE_PRIV : 0));
       } break;
 
 #endif
@@ -950,7 +911,7 @@ done_options:
     else
       pw = getpwnam(who);
     if (!pw)
-      die("unknown user `%s'", who);
+      die(1, "unknown user `%s'", who);
     to_pw = userdb_copyUser(pw);
     rq.to = pw->pw_uid;
   }
@@ -963,7 +924,7 @@ done_options:
     rq.from = getuid();
     pw = getpwuid(rq.from);
     if (!pw)
-      die("who are you? (can't find user %li)", (long)rq.from);
+      die(1, "who are you? (can't find user %li)", (long)rq.from);
     from_pw = userdb_copyUser(pw);
   }
 
@@ -974,7 +935,7 @@ done_options:
     struct hostent *he;
     uname(&u);
     if ((he = gethostbyname(u.nodename)) == 0)
-      die("who am I? (can't resolve `%s')", u.nodename);
+      die(1, "who am I? (can't resolve `%s')", u.nodename);
     memcpy(&rq.host, he->h_addr, sizeof(rq.host));
   }
 
@@ -996,7 +957,7 @@ done_options:
     /* --- Check that it's valid --- */
 
     if (group != from_pw->pw_gid && group != to_pw->pw_gid)
-      die("invalid default group");
+      die(1, "invalid default group");
 
 #else
 
@@ -1055,7 +1016,7 @@ done_options:
        if (group == to_gr[i])
          goto group_ok;
       }
-      die("invalid default group");
+      die(1, "invalid default group");
     group_ok:;
     }
 
@@ -1328,7 +1289,7 @@ done_options:
 
     sz = 0;
 
-    for (sym_createIter(&i, &bc__env); (e = sym_next(&i)) != 0; ) {
+    for (sym_mkiter(&i, &bc__env); (e = sym_next(&i)) != 0; ) {
 
       /* --- Login style expunges all unpreserved variables --- */
 
@@ -1357,7 +1318,7 @@ done_options:
 
     env = qq = xmalloc((sz + 1) * sizeof(*qq));
 
-    for (sym_createIter(&i, &bc__env); (e = sym_next(&i)) != 0; )
+    for (sym_mkiter(&i, &bc__env); (e = sym_next(&i)) != 0; )
       *qq++ = e->val;
     *qq++ = 0;
   }
@@ -1415,7 +1376,7 @@ done_options:
     }
 
     if (!p)
-      die("couldn't find `%s' in path", todo[0]);
+      die(1, "couldn't find `%s' in path", todo[0]);
     binary = rq.cmd;
     free(path);
   }
@@ -1434,7 +1395,7 @@ done_options:
     q = binary;
     if (*q != '/') {
       if (!getcwd(b, sizeof(b)))
-       die("couldn't read current directory: %s", strerror(errno));
+       die(1, "couldn't read current directory: %s", strerror(errno));
       p += strlen(p);
       *p++ = '/';
     }
@@ -1450,7 +1411,7 @@ done_options:
        */
 
       if (p >= b + sizeof(b) - 1)
-       die("internal error: buffer overflow while canonifying path");
+       die(1, "internal error: buffer overflow while canonifying path");
 
       /* --- Reduce multiple slashes to just one --- */
 
@@ -1522,7 +1483,7 @@ done_options:
           rq.cmd);
 
     if (!a)
-      die("permission denied");
+      die(1, "permission denied");
   }
 
   /* --- Now do the job --- */
@@ -1536,13 +1497,13 @@ done_options:
 
 #ifdef HAVE_SETGROUPS
   if (setgroups(ngroups, groups) < 0)
-    die("couldn't set groups: %s", strerror(errno));
+    die(1, "couldn't set groups: %s", strerror(errno));
 #endif
 
   if (setgid(group) < 0)
-    die("couldn't set default group: %s", strerror(errno));
+    die(1, "couldn't set default group: %s", strerror(errno));
   if (setuid(rq.to) < 0)
-    die("couldn't set uid: %s", strerror(errno));
+    die(1, "couldn't set uid: %s", strerror(errno));
 
   /* --- If this was a login, change current directory --- */
 
@@ -1558,7 +1519,7 @@ done_options:
   fflush(0);
   closelog();
   execve(rq.cmd, todo, env);
-  die("couldn't exec `%s': %s", rq.cmd, strerror(errno));
+  die(1, "couldn't exec `%s': %s", rq.cmd, strerror(errno));
   return (127);
 }