From f5081325d7ecb908b890aa3407f6fe8b9fed1495 Mon Sep 17 00:00:00 2001 From: Enrico Weigelt Date: Tue, 13 May 2008 11:20:53 +1000 Subject: [PATCH] Various config and option improvements. - Various aspects of the Makefile are not configurable by setting macros on commandline or in environment - new config.h file to allow various tunables like daemon uid and path to record current mapping table. - new commandline to: Allow foreground running with syslog logging (-F) Change the file in which the mapping is stored (-f) Specify the username that portmap should run as (-U). Signed-off-by: Neil Brown --- Makefile | 61 ++++++++++++++++++++++++++++----- config.h | 33 ++++++++++++++++++ portmap.8 | 15 ++++++-- portmap.c | 100 ++++++++++++++++++++++++++++++++++-------------------- 4 files changed, 161 insertions(+), 48 deletions(-) create mode 100644 config.h diff --git a/Makefile b/Makefile index 5343428..b00c496 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,38 @@ MAN_SED += -e 's/USE_DNS/yes/' endif endif +ifeq ($(PREFIX),) +PREFIX = /usr +endif +ifeq ($(SBINDIR),) +SBINDIR = $(PREFIX)/sbin +endif +ifeq ($(DATADIR),) +DATADIR = $(PREFIX)/share +endif +ifeq ($(MANDIR),) +MANDIR = $(DATADIR)/man +endif +ifeq ($(MAN8DIR),) +MAN8DIR = $(MANDIR)/man8 +endif + +## backwards compatibility to older distro builders +ifeq ($(DESTDIR),) +DESTDIR = $(BASEDIR) +endif + +ifeq ($(INSTALL),) +INSTALL = install +endif +ifeq ($(INSTALL_MAN),) +INSTALL_MAN = $(INSTALL) -o root -g root -m 0644 +endif +ifeq ($(INSTALL_BIN),) +INSTALL_BIN = $(INSTALL) -s -o root -g root -m 0755 +endif + + # Comment out if your RPC library does not allocate privileged ports for # requests from processes with root privilege, or the new portmap will # always reject requests to register/unregister services on privileged @@ -135,14 +167,27 @@ from_local: CPPFLAGS += -DTEST portmap.man : portmap.8 sed $(MAN_SED) < portmap.8 > portmap.man -DESTDIR = $(BASEDIR) -install: all - install -o root -g root -m 0755 portmap $(DESTDIR)/sbin - install -o root -g root -m 0755 pmap_dump $(DESTDIR)/sbin - install -o root -g root -m 0755 pmap_set $(DESTDIR)/sbin - install -o root -g root -m 0644 portmap.man $(DESTDIR)/usr/share/man/man8/portmap.8 - install -o root -g root -m 0644 pmap_dump.8 $(DESTDIR)/usr/share/man/man8 - install -o root -g root -m 0644 pmap_set.8 $(DESTDIR)/usr/share/man/man8 +install: all install-portmap install-pmap_dump install-pmap_set install-man + +install-dirs-sbin: + mkdir -p $(DESTDIR)$(SBINDIR) + +install-dirs-man: + mkdir -p $(DESTDIR)$(MAN8DIR) + +install-man: install-dirs-man + $(INSTALL_MAN) portmap.man $(DESTDIR)$(MAN8DIR)/portmap.8 + $(INSTALL_MAN) pmap_dump.8 $(DESTDIR)$(MAN8DIR)/pmap_dump.8 + $(INSTALL_MAN) pmap_set.8 $(DESTDIR)$(MAN8DIR)/map_set.8 + +install-pmap_dump: pmap_dump install-dirs-sbin + $(INSTALL_BIN) pmap_dump $(DESTDIR)$(SBINDIR) + +install-pmap_set: pmap_set install-dirs-sbin + $(INSTALL_BIN) pmap_set $(DESTDIR)$(SBINDIR) + +install-portmap: portmap install-dirs-sbin + $(INSTALL_BIN) portmap $(DESTDIR)$(SBINDIR) clean: rm -f *.o portmap pmap_dump pmap_set from_local \ diff --git a/config.h b/config.h new file mode 100644 index 0000000..3a58e18 --- /dev/null +++ b/config.h @@ -0,0 +1,33 @@ + +#ifndef __PORTMAP_CONFIG_H +#define __PORTMAP_CONFIG_H + +#ifndef PORTMAP_MAPPING_FILE +#define PORTMAP_MAPPING_FILE "/var/run/portmap_mapping" +#endif + +#ifndef PORTMAP_MAPPING_FMODE +#define PORTMAP_MAPPING_FMODE 0600 +#endif + +#ifndef LOG_PERROR +#define LOG_PERROR 0 +#endif + +#ifndef RPCUSER +#define RPCUSER "bin" +#endif + +#ifndef LOG_DAEMON +#define LOG_DAEMON 0 +#endif + +#ifndef DAEMON_UID +#define DAEMON_UID 1 +#endif + +#ifndef DAEMON_GID +#define DAEMON_GID 1 +#endif + +#endif diff --git a/portmap.8 b/portmap.8 index 4c92cac..10ddc61 100644 --- a/portmap.8 +++ b/portmap.8 @@ -33,7 +33,7 @@ .\" from: @(#)portmap.8 5.3 (Berkeley) 3/16/91 .\" $Id: portmap.8,v 1.2 2004/04/03 09:30:21 herbert Exp $ .\" -.Dd Apr 20, 2007 +.Dd May 12, 2008 .Dt PORTMAP 8 .Os BSD 4.3 .Sh NAME @@ -47,6 +47,7 @@ program number mapper .Nm portmap .Op Fl d .Op Fl f +.Op Fl F .Op Fl t Ar dir .Op Fl v .Op Fl V @@ -117,6 +118,8 @@ to be printed to the standard error output. from running as a daemon, and causes log messages to be printed to the standard error output. +.It Fl F +(foreground) same as -f, but logging as usual .It Fl t Ar dir (chroot) tell .Nm portmap @@ -127,6 +130,9 @@ 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 m Ar file +(mapfile) specify an alternative mapping +.Ar file .It Fl u Ar uid .It Fl g Ar gid Set the user-id and group-id of the running process to those given, @@ -138,6 +144,10 @@ will look up the user .Nm RPCUSER and use the uid and gid of that user. .. +.It Fl U Ar username +Lets +.Nm portmap +run under this user (uid/gid) rather than compiled-in defaults of DEAMON_UID/DAEMON_GID. .It Fl v (verbose) run .Nm portmap @@ -195,14 +205,13 @@ names. Using netgroup names will likely cause to deadlock. Note that localhost will always be allowed access to the portmapper. .. - +.Pp For further information please have a look at the .Xr tcpd 8 , .Xr hosts_allow 5 and .Xr hosts_access 5 manual pages. - .Sh SEE ALSO .Xr inetd.conf 5 , .Xr rpcinfo 8 , diff --git a/portmap.c b/portmap.c index 2a98881..46bf7c5 100644 --- a/portmap.c +++ b/portmap.c @@ -99,13 +99,7 @@ static char sccsid[] = "@(#)portmap.c 1.32 87/08/06 Copyr 1984 Sun Micro"; #include #include -#ifndef LOG_PERROR -#define LOG_PERROR 0 -#endif - -#ifndef LOG_DAEMON -#define LOG_DAEMON 0 -#endif +#include "config.h" /* Older SYSV. */ #if !defined(SIGCHLD) && defined(SIGCLD) @@ -149,13 +143,9 @@ 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 +const char* mapping_file = PORTMAP_MAPPING_FILE; /* * We record with each registration a flag telling whether it was @@ -169,6 +159,37 @@ struct flagged_pml { int priv; }; +static inline int __getuid(const char* username) +{ + struct passwd* pw = getpwnam(username); + + if (!pw) + return 0; + + daemon_uid = pw->pw_uid; + daemon_gid = pw->pw_gid; + return 1; +} + +static void usage(char *progname) +{ + fprintf(stderr, "usage: %s [-dfFlv] [-t dir] [-i address] " + "[-u uid] [-g gid] [-U username] \n", + progname); + fprintf(stderr, "-v verbose logging\n"); + fprintf(stderr, "-d debugging mode\n"); + fprintf(stderr, "-f don't daemonize, log to standard error\n"); + fprintf(stderr, "-F don't daemonize, log as usual\n"); + fprintf(stderr, "-t chroot into dir\n"); + fprintf(stderr, "-i
bind to address\n"); + fprintf(stderr, "-l same as -i 127.0.0.1\n"); + fprintf(stderr, "-u run as this uid (default: %d)\n", DAEMON_UID); + fprintf(stderr, "-g run as this gid (default: %d)\n", DAEMON_GID); + fprintf(stderr, "-U suid/sgid to this user\n"); + fprintf(stderr, "-m specify the mapping file name " + "(default: "PORTMAP_MAPPING_FILE")\n"); +} + int main(int argc, char **argv) { @@ -184,13 +205,28 @@ main(int argc, char **argv) int foreground = 0; int have_uid = 0; - while ((c = getopt(argc, argv, "Vdflt:vi:u:g:")) != EOF) { + while ((c = getopt(argc, argv, "hVdfFlt:vi:u:U:g:m:")) != EOF) { switch (c) { case 'V': - printf("portmap version 6.0 - 2007-May-11\n"); + printf("portmap version 6.0.0.1 - 2008-05-10\n"); exit(1); + case 'm': + mapping_file = optarg; + break; + + case 'U': + /* try to fetch user-given uid/gid by name */ + if (!__getuid(optarg)) + { + fprintf(stderr, + "portmap: illegal username: \"%s\"\n", + optarg); + exit(1); + } + have_uid = 1; + break; case 'u': daemon_uid = atoi(optarg); if (daemon_uid <= 0) { @@ -214,6 +250,10 @@ main(int argc, char **argv) case 'f': foreground = 1; break; + case 'F': + /* run in foreground, but still log as usual */ + foreground = 2; + break; case 't': chroot_path = optarg; @@ -229,20 +269,9 @@ main(int argc, char **argv) case 'i': have_bindaddr = inet_aton(optarg, &bindaddr); break; + case 'h': default: - fprintf(stderr, - "usage: %s [-dflv] [-t dir] [-i address] " - "[-u uid] [-g gid]\n", - argv[0]); - fprintf(stderr, "-d: debugging mode\n"); - fprintf(stderr, - "-f: don't daemonize, log to standard error\n"); - fprintf(stderr, "-t dir: chroot into dir\n"); - 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"); + usage(argv[0]); exit(1); } } @@ -253,20 +282,17 @@ main(int argc, char **argv) } #ifdef LOG_DAEMON - openlog("portmap", LOG_PID|LOG_NDELAY | ( foreground ? LOG_PERROR : 0), - FACILITY); + openlog("portmap", + LOG_PID|LOG_NDELAY | ( (foreground==1) ? LOG_PERROR : 0), + FACILITY); #else - openlog("portmap", LOG_PID|LOG_NDELAY | ( foreground ? LOG_PERROR : 0)); + openlog("portmap", + LOG_PID|LOG_NDELAY | ( (foreground==1) ? 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 + if (!__getuid(RPCUSER)) syslog(LOG_WARNING, "user '" RPCUSER "' not found, reverting to default uid"); } @@ -369,7 +395,7 @@ main(int argc, char **argv) (void)svc_register(xprt, PMAPPROG, PMAPVERS, reg_service, FALSE); - store_fd = open("/var/run/portmap_mapping", O_RDWR|O_CREAT, 0600); + store_fd = open(mapping_file, O_RDWR|O_CREAT, PORTMAP_MAPPING_FMODE); load_table(); /* additional initializations */ -- 2.39.5