]> git.neil.brown.name Git - portmap.git/commitdiff
Allow uid/gid to be set at compile or run time.
authorNeil Brown <neilb@suse.de>
Mon, 23 Apr 2007 06:20:17 +0000 (16:20 +1000)
committerNeil Brown <neilb@suse.de>
Mon, 23 Apr 2007 06:20:17 +0000 (16:20 +1000)
New compile time options to set uid and gid rather than default of '1'.
Also compile-time configurable username to provide uid/gid.
Also -u and -g runtime options to set same.

Makefile
pmap_check.c
pmap_check.h
portmap.8
portmap.c

index 1376ea79dec13050a589cae4cde2e9c0a66e0d7d..23f361bddccdf615168b51929f13a4484e2df4b1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -28,6 +28,23 @@ endif
 
 CPPFLAGS += -DCHECK_PORT
 
+# The portmap daemon runs a uid=1/gid=1 by default.  You can change that
+# be defining DAEMON_UID and DAMEON_GID to numbers, or RPCUSER to a
+# name, though you must be sure that name lookup will not require use
+# of portmap.
+ifdef RPCUSER
+CPPFLAGS += -DRPCUSER=\"$(RPCUSER)\"
+MAN_SED += -e 's/RPCUSER/$(RPCUSER)/'
+else
+MAN_SED += -e 's/RPCUSER//'
+endif
+ifdef DAEMON_UID
+CPPFLAGS += -DDAEMON_UID=$(DAEMON_UID) -DDAEMON_GID=$(DAEMON_GID)
+MAN_SED += -e 's/DAEMON_UID/$(DAEMON_UID)/' -e 's/DAEMON_GID/$(DAEMON_GID)/'
+else
+MAN_SED += -e 's/DAEMON_UID/1/' -e 's/DAEMON_GID/1/'
+endif
+
 # Warning: troublesome feature ahead!! Enable only when you are really
 # desperate!!
 #
@@ -98,7 +115,7 @@ CPPFLAGS += -DFACILITY=$(FACILITY)
 CFLAGS   ?= -O2
 CFLAGS   += -Wall -Wstrict-prototypes
 
-all:   portmap pmap_dump pmap_set
+all:   portmap pmap_dump pmap_set portmap.man
 
 CPPFLAGS += $(HOSTS_ACCESS)
 portmap: CFLAGS   += -fpie
@@ -108,17 +125,20 @@ portmap: portmap.o pmap_check.o from_local.o
 
 from_local: CPPFLAGS += -DTEST
 
+portmap.man : portmap.8
+       sed $(MAN_SED) < portmap.8 > portmap.man
+
 install: all
        install -o root -g root -m 0755 -s portmap ${BASEDIR}/sbin
        install -o root -g root -m 0755 -s pmap_dump ${BASEDIR}/sbin
        install -o root -g root -m 0755 -s pmap_set ${BASEDIR}/sbin
-       install -o root -g root -m 0644 portmap.8 ${BASEDIR}/usr/share/man/man8
+       install -o root -g root -m 0644 portmap.man ${BASEDIR}/usr/share/man/man8/portmap.8
        install -o root -g root -m 0644 pmap_dump.8 ${BASEDIR}/usr/share/man/man8
        install -o root -g root -m 0644 pmap_set.8 ${BASEDIR}/usr/share/man/man8
 
 clean:
        rm -f *.o portmap pmap_dump pmap_set from_local \
-           core
+           core portmap.man
 
 -include .depend
 .depend: *.c
index 1fed2e1e30781ffb709acdbb3c7bebad0550aa10..116eb49153460c3dc6fdcf5d522d4d25d330b93d 100644 (file)
@@ -106,9 +106,9 @@ void check_startup(void)
      * Give up root privileges so that we can never allocate a privileged
      * port when forwarding an rpc request.
      */
-    setgid(1);
+    setgid(daemon_gid);
     setgroups(0, NULL);
-    if (setuid(1) == -1) {
+    if (setuid(daemon_uid) == -1) {
        syslog(LOG_ERR, "setuid(1) failed: %m");
        exit(1);
     }
index ba18f3378a85f31e61f31021902f83b06e988ed3..abc30d685332de6b840933a4ce990a308c8339d7 100644 (file)
@@ -28,3 +28,6 @@ extern int deny_severity __attribute__ ((visibility ("hidden")));
 #define CHECK_SETUNSET(xprt,ludp,ltcp,proc,prog,port) \
        check_setunset(svc_getcaller(xprt),proc,prog,port)
 #endif
+
+extern int daemon_uid;
+extern int daemon_gid;
index c021e1567ddff6b750f7db0775c0107271a23a21..f4d5d94bdb04f5e8e7aff5fd69dfc090e19171a8 100644 (file)
--- a/portmap.8
+++ b/portmap.8
@@ -51,6 +51,8 @@ program number mapper
 .Op Fl v
 .Op Fl i Ar address
 .Op Fl l
+.Op Fl u Ar uid
+.Op Fl g Ar gid
 .Sh DESCRIPTION
 .Nm Portmap
 is a server that converts
@@ -122,6 +124,17 @@ into
 .Ar dir
 should be empty, not writeable by the daemon user, and preferably on a
 filesystem mounted read-only, noexec, nodev, and nosuid.
+.It Fl u Ar uid
+.It Fl g Ar gid
+Set the user-id and group-id of the running process to those given,
+rather than the compiled-in defaults of DAEMON_UID/DAEMON_GID.
+.if 'RPCUSER'' .ig
+If neither are set, then
+.Nm portmap
+will look up the user
+.Nm RPCUSER
+and use the uid and gid of that user.
+..
 .It Fl v
 (verbose) run
 .Nm portmap
index e56141570610165e597a0c54e0ff2cb91ae04be1..d1dd8c2055b055467365929c0e0b97519cd9d06b 100644 (file)
--- a/portmap.c
+++ b/portmap.c
@@ -102,6 +102,7 @@ static char sccsid[] = "@(#)portmap.c 1.32 87/08/06 Copyr 1984 Sun Micro";
 #include <arpa/inet.h>
 
 #include <stdlib.h>
+#include <pwd.h>
 
 #ifndef LOG_PERROR
 #define LOG_PERROR 0
@@ -153,6 +154,14 @@ static int on = 1;
 #endif
 #endif
 
+#ifdef DAEMON_UID
+int daemon_uid = DAEMON_UID;
+int daemon_gid = DAEMON_GID;
+#else
+int daemon_uid = 1;
+int daemon_gid = 1;
+#endif
+
 /*
  * We record with each registration a flag telling whether it was
  * registered with a privilege port or not.
@@ -178,10 +187,29 @@ main(int argc, char **argv)
        struct in_addr bindaddr;
        int have_bindaddr = 0;
        int foreground = 0;
+       int have_uid = 0;
 
-       while ((c = getopt(argc, argv, "dflt:vi:")) != EOF) {
+       while ((c = getopt(argc, argv, "dflt:vi:u:g:")) != EOF) {
                switch (c) {
 
+               case 'u':
+                       daemon_uid = atoi(optarg);
+                       if (daemon_uid <= 0) {
+                               fprintf(stderr,
+                                       "portmap: illegal uid: %s\n", optarg);
+                               exit(1);
+                       }
+                       have_uid = 1;
+                       break;
+               case 'g':
+                       daemon_gid = atoi(optarg);
+                       if (daemon_gid <= 0) {
+                               fprintf(stderr,
+                                       "portmap: illegal gid: %s\n", optarg);
+                               exit(1);
+                       }
+                       have_uid = 1;
+                       break;
                case 'd':
                        debugging = 1;
                case 'f':
@@ -204,7 +232,8 @@ main(int argc, char **argv)
                        break;
                default:
                        fprintf(stderr,
-                               "usage: %s [-dflv] [-t dir] [-i address]\n",
+                               "usage: %s [-dflv] [-t dir] [-i address] "
+                               "[-u uid] [-g gid]\n",
                                argv[0]);
                        fprintf(stderr, "-d: debugging mode\n");
                        fprintf(stderr,
@@ -213,6 +242,8 @@ main(int argc, char **argv)
                        fprintf(stderr, "-v: verbose logging\n");
                        fprintf(stderr, "-i address: bind to address\n");
                        fprintf(stderr, "-l: same as -i 127.0.0.1\n");
+                       fprintf(stderr, "-u uid : setuid to this uid\n");
+                       fprintf(stderr, "-g uid : setgid to this gid\n");
                        exit(1);
                }
        }
@@ -229,6 +260,19 @@ main(int argc, char **argv)
        openlog("portmap", LOG_PID|LOG_NDELAY | ( foreground ? LOG_PERROR : 0));
 #endif
 
+#ifdef RPCUSER
+       if (!have_uid) {
+               struct passwd *pwent;
+               pwent = getpwnam(RPCUSER);
+               if (pwent) {
+                       daemon_uid = pwent->pw_uid;
+                       daemon_gid = pwent->pw_gid;
+               } else
+                       syslog(LOG_WARNING, "user '" RPCUSER
+                              "' not found, reverting to default uid");
+       }
+#endif
+
        if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
                syslog(LOG_ERR, "cannot create udp socket: %m");
                exit(1);