Add option to change user and group after initialization. Naughtily 1.2.3
authormdw <mdw>
Thu, 23 Mar 2000 00:37:33 +0000 (00:37 +0000)
committermdw <mdw>
Thu, 23 Mar 2000 00:37:33 +0000 (00:37 +0000)
reassign short equivalents of --grammar and --options.

fw.1
fw.c

diff --git a/fw.1 b/fw.1
index 2d23b0d..df52079 100644 (file)
--- a/fw.1
+++ b/fw.1
@@ -1,6 +1,6 @@
 .\" -*-nroff-*-
 .\"
 .\" -*-nroff-*-
 .\"
-.\" $Id: fw.1,v 1.8 1999/12/22 15:44:43 mdw Exp $
+.\" $Id: fw.1,v 1.9 2000/03/23 00:37:33 mdw Exp $
 .\"
 .\" Manual page for fw
 .\"
 .\"
 .\" Manual page for fw
 .\"
 .\" ---- Revision history ---------------------------------------------------
 .\" 
 .\" $Log: fw.1,v $
 .\" ---- Revision history ---------------------------------------------------
 .\" 
 .\" $Log: fw.1,v $
+.\" Revision 1.9  2000/03/23 00:37:33  mdw
+.\" Add option to change user and group after initialization.  Naughtily
+.\" reassign short equivalents of --grammar and --options.
+.\"
 .\" Revision 1.8  1999/12/22 15:44:43  mdw
 .\" Fix some errors, and document new option.
 .\"
 .\" Revision 1.8  1999/12/22 15:44:43  mdw
 .\" Fix some errors, and document new option.
 .\"
@@ -129,6 +133,10 @@ fw \- port forwarder
 .RB [ \-dlq ]
 .RB [ \-f
 .IR file ]
 .RB [ \-dlq ]
 .RB [ \-f
 .IR file ]
+.RB [ \-s
+.IR user ]
+.RB [ \-g
+.IR group ]
 .IR config-stmt ...
 .
 .\"--------------------------------------------------------------------------
 .IR config-stmt ...
 .
 .\"--------------------------------------------------------------------------
@@ -175,6 +183,14 @@ Writes the version number to standard output and exits successfully.
 .B "\-u, \-\-usage"
 Writes a terse usage summary to standard output and exits successfully.
 .TP
 .B "\-u, \-\-usage"
 Writes a terse usage summary to standard output and exits successfully.
 .TP
+.B "\-G, \-\-grammar"
+Writes a summary of the configuration file grammar to standard output
+and exits successfully.
+.TP
+.B "\-O, \-\-options"
+Writes a summary of the source and target options to standard output and
+exits successfully.
+.TP
 .BI "\-f, \-\-file=" file
 Read configuration information from
 .IR file .
 .BI "\-f, \-\-file=" file
 Read configuration information from
 .IR file .
@@ -190,10 +206,24 @@ initializing properly.
 .B "\-l, \-\-syslog, \-\-log"
 Emit logging information to the system log, rather than standard error.
 .TP
 .B "\-l, \-\-syslog, \-\-log"
 Emit logging information to the system log, rather than standard error.
 .TP
-.B "-q, \-\-quiet"
+.B "\-q, \-\-quiet"
 Don't output any logging information.  This option is not recommended
 for normal use, although it can make system call traces clearer so I use
 it when debugging.
 Don't output any logging information.  This option is not recommended
 for normal use, although it can make system call traces clearer so I use
 it when debugging.
+.TP
+.BI "\-s, \-\-setuid=" user
+Change uid to that of
+.IR user ,
+which may be either a user name or uid number, after initializing all
+the sources.  This will usually require elevated privileges.
+.TP
+.BI "\-g, \-\-setgid=" group
+Change gid to that of
+.IR group ,
+which may be either a group name or gid number, after initializing all
+the sources.  If the operating system understands supplementary groups
+then the supplementary groups list is altered to include only
+.IR group .
 .PP
 Any further command line arguments are interpreted as configuration
 lines to be read.  Configuration supplied in command line arguments has
 .PP
 Any further command line arguments are interpreted as configuration
 lines to be read.  Configuration supplied in command line arguments has
diff --git a/fw.c b/fw.c
index 4db1fdb..68871a6 100644 (file)
--- a/fw.c
+++ b/fw.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
 /* -*-c-*-
  *
- * $Id: fw.c,v 1.6 1999/12/22 15:44:10 mdw Exp $
+ * $Id: fw.c,v 1.7 2000/03/23 00:37:33 mdw Exp $
  *
  * Port forwarding thingy
  *
  *
  * Port forwarding thingy
  *
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: fw.c,v $
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: fw.c,v $
+ * Revision 1.7  2000/03/23 00:37:33  mdw
+ * Add option to change user and group after initialization.  Naughtily
+ * reassign short equivalents of --grammar and --options.
+ *
  * Revision 1.6  1999/12/22 15:44:10  mdw
  * Make syslog a separate option, and do it better.
  *
  * Revision 1.6  1999/12/22 15:44:10  mdw
  * Make syslog a separate option, and do it better.
  *
@@ -67,6 +71,9 @@
 #include <unistd.h>
 #include <syslog.h>
 
 #include <unistd.h>
 #include <syslog.h>
 
+#include <grp.h>
+#include <pwd.h>
+
 #include <mLib/bres.h>
 #include <mLib/dstr.h>
 #include <mLib/mdwopt.h>
 #include <mLib/bres.h>
 #include <mLib/dstr.h>
 #include <mLib/mdwopt.h>
@@ -212,13 +219,15 @@ are:\n\
 -v, --version    Display the program's version number.\n\
 -u, --usage      Display a terse usage summary.\n\
 \n\
 -v, --version    Display the program's version number.\n\
 -u, --usage      Display a terse usage summary.\n\
 \n\
--g, --grammar    Show a summary of the configuration language.\n\
--o, --options    Show a summary of the source and target options.\n\
+-G, --grammar    Show a summary of the configuration language.\n\
+-O, --options    Show a summary of the source and target options.\n\
 \n\
 -f, --file=FILE          Read configuration from a file.\n\
 -q, --quiet      Don't emit any logging information.\n\
 -d, --daemon     Fork into background after initializing.\n\
 -l, --syslog     Send log output to the system logger.\n\
 \n\
 -f, --file=FILE          Read configuration from a file.\n\
 -q, --quiet      Don't emit any logging information.\n\
 -d, --daemon     Fork into background after initializing.\n\
 -l, --syslog     Send log output to the system logger.\n\
+-s, --setuid=USER Change uid to USER after initializing sources.\n\
+-g, --setgid=GRP  Change gid to GRP after initializing sources.\n\
 \n\
 Configuration may be supplied in one or more configuration files, or on\n\
 the command line (or both).  If no `-f' option is present, and no\n\
 \n\
 Configuration may be supplied in one or more configuration files, or on\n\
 the command line (or both).  If no `-f' option is present, and no\n\
@@ -344,6 +353,8 @@ int main(int argc, char *argv[])
   sel_state sst;
   sig s_term, s_int;
   scanner sc;
   sel_state sst;
   sig s_term, s_int;
   scanner sc;
+  uid_t drop = -1;
+  gid_t dropg = -1;
 
   enum {
     f_bogus = 1,
 
   enum {
     f_bogus = 1,
@@ -405,12 +416,16 @@ int main(int argc, char *argv[])
       { "syslog",      0,              0,      'l' },
       { "log",         0,              0,      'l' },
       { "quiet",       0,              0,      'q' },
       { "syslog",      0,              0,      'l' },
       { "log",         0,              0,      'l' },
       { "quiet",       0,              0,      'q' },
+      { "setuid",      OPTF_ARGREQ,    0,      's' },
+      { "uid",         OPTF_ARGREQ,    0,      's' },
+      { "setgid",      OPTF_ARGREQ,    0,      'g' },
+      { "gid",         OPTF_ARGREQ,    0,      'g' },
 
       /* --- Magic terminator --- */
 
       { 0,             0,              0,      0 }
     };
 
       /* --- Magic terminator --- */
 
       { 0,             0,              0,      0 }
     };
-    int i = mdwopt(argc, argv, "+hvu go f:dl", opts, 0, 0, 0);
+    int i = mdwopt(argc, argv, "+hvu GO f:dls:g:", opts, 0, 0, 0);
 
     if (i < 0)
       break;
 
     if (i < 0)
       break;
@@ -427,11 +442,11 @@ int main(int argc, char *argv[])
        usage(stdout);
        exit(0);
        break;
        usage(stdout);
        exit(0);
        break;
-      case 'g':
+      case 'G':
        grammar(stdout);
        exit(0);
        break;
        grammar(stdout);
        exit(0);
        break;
-      case 'o':
+      case 'O':
        options(stdout);
        exit(0);
        break;
        options(stdout);
        exit(0);
        break;
@@ -455,6 +470,32 @@ int main(int argc, char *argv[])
       case 'q':
        flags |= FW_QUIET;
        break;
       case 'q':
        flags |= FW_QUIET;
        break;
+      case 's':
+        if (isdigit((unsigned char )optarg[0])) {
+         char *q;
+         drop = strtol(optarg, &q, 0);
+         if (*q)
+           die(1, "bad uid `%s'", optarg);
+       } else {
+         struct passwd *pw = getpwnam(optarg);
+         if (!pw)
+           die(1, "unknown user `%s'", optarg);
+         drop = pw->pw_uid;
+       }
+       break;
+      case 'g':
+        if (isdigit((unsigned char )optarg[0])) {
+         char *q;
+         dropg = strtol(optarg, &q, 0);
+         if (*q)
+           die(1, "bad gid `%s'", optarg);
+       } else {
+         struct group *gr = getgrnam(optarg);
+         if (!gr)
+           die(1, "unknown group `%s'", optarg);
+         dropg = gr->gr_gid;
+       }
+       break;
       default:
        f |= f_bogus;
        break;
       default:
        f |= f_bogus;
        break;
@@ -484,6 +525,16 @@ int main(int argc, char *argv[])
 
   conf_parse(&sc);
 
 
   conf_parse(&sc);
 
+  /* --- Drop privileges --- */
+
+#ifdef HAVE_SETGROUPS
+  if ((dropg != -1 && (setgid(dropg) || setgroups(1, &dropg))) ||
+#else
+  if ((dropg != -1 && setgid(dropg)) ||
+#endif
+      (drop != -1 && setuid(drop)))
+    die(1, "couldn't drop privileges: %s", strerror(errno));
+
   /* --- Fork into the background --- */
 
   if (f & f_fork) {
   /* --- Fork into the background --- */
 
   if (f & f_fork) {