Commit c6fef975 authored by Marco d'Itri's avatar Marco d'Itri

Debian release 0.20080125-1

parent 682e6adb
CC := gcc
CFLAGS := -O2 -g
OPTS := -DLIBWRAP
LDFLAGS := -lwrap
DEFS := -DLIBWRAP
LIBS := -lwrap
inetd_OBJECTS := inetd.o setproctitle.o strlcpy.o
all: inetd
.c.o:
$(CC) $(CFLAGS) $(OPTS) -c $<
$(CC) $(DEFS) $(CFLAGS) -c $<
inetd: inetd.o setproctitle.o strlcpy.o
$(CC) $(LDFLAGS) -o $@ $^
inetd: $(inetd_OBJECTS)
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
clean:
rm -f inetd inetd.o setproctitle.o strlcpy.o
update:
cvs -z3 update
cvs -z3 log > ChangeLog
mkdir openbsd-inetd
cd openbsd-inetd
cvs -d anoncvs@anoncvs1.usa.openbsd.org:/cvs/src/usr.sbin/inetd/ co .
cvs2cl
rm -rf CVS
cd ..
mv openbsd-inetd openbsd-inetd-0...
openbsd-inetd (0.20080125-1) unstable; urgency=low
* New CVS snapshot.
* Package painfully converted to quilt.
* Fixed a typo in debian/control. (Closes: #125181)
* Fixed a typo in the init script. (Closes: #465613, #465732)
* Delete /etc/rc[2345].d/S20inetd too when upgrading from netkit-inetd.
(Closes: #416010)
* Do not use log_warning_msg in the init script when inetd.conf is emtpy,
this is not something deserving extra attention. (Closes: #435658)
* Document in inetd(8) that datagram services must read some network
input or inetd will continue spawning them.
Many thanks to James Cameron for the analysis. (Closes: #436803)
* Use a real characters class instead of character ranges with grep
in the init script, because some locales have weird ranges.
Spotted by Meelis Roos. (Closes: #458564)
-- Marco d'Itri <md@linux.it> Sun, 20 Apr 2008 15:12:31 +0200
openbsd-inetd (0.20050402-6) unstable; urgency=high
* Try again to fix #386469 by stopping the daemon in postinst before
......
......@@ -2,8 +2,8 @@ Source: openbsd-inetd
Section: net
Priority: standard
Maintainer: Marco d'Itri <md@linux.it>
Build-Depends: debhelper (>= 4.0), libwrap0-dev
Standards-Version: 3.7.2.2
Build-Depends: debhelper (>= 4.0), quilt (>= 0.40), libwrap0-dev
Standards-Version: 3.7.3
Package: openbsd-inetd
Architecture: any
......@@ -15,9 +15,8 @@ Description: The OpenBSD Internet Superserver
The inetd server is a network daemon program that specializes in managing
incoming network connections. Its configuration file tells it what
program needs to be run when an incoming connection is received. Any
service port may be configured for either of the tcp or udp protcols.
service port may be configured for either of the tcp or udp protocols.
.
This is a port of the OpenBSD daemon with some debian-specific features.
This package does not have many bugs of netkit-inetd and supports IPv6,
built-in libwrap, binding to specific addresses, UNIX domain sockets and
socket buffers tuning.
This package supports IPv6, built-in libwrap access control, binding to
specific addresses, UNIX domain sockets and socket buffers tuning.
......@@ -35,8 +35,8 @@ checkportmap () {
}
checknoservices () {
if ! grep -q "^[0-9A-Za-z/]" /etc/inetd.conf; then
log_warning_msg "Not starting internet superserver: no services enabled."
if ! grep -q "^[[:alnum:]/]" /etc/inetd.conf; then
log_action_msg "Not starting internet superserver: no services enabled"
exit 0
fi
}
......@@ -74,7 +74,7 @@ case "$1" in
log_end_msg 0
;;
*)
echo "Usage: /etc/init.d/inetd {start|stop|reload|force-reload|restart}"
echo "Usage: /etc/init.d/openbsd-inetd {start|stop|reload|force-reload|restart}"
exit 2
;;
esac
......
......@@ -71,7 +71,7 @@ upgrade_from_netkit_inetd() {
rm -f /etc/cron.daily/netkit-inetd
fi
if [ -e /etc/init.d/inetd ]; then
rm -f /etc/init.d/inetd
rm -f /etc/init.d/inetd /etc/rc[2345].d/S20inetd
fi
# be sure to kill the netkit-inetd daemon, which may still be active if
......
--- a/inetd.8
+++ b/inetd.8
@@ -107,7 +107,7 @@ The fields of the configuration file are
.Bd -unfilled -offset indent
service name
socket type
-protocol
+protocol[,sndbuf=size][,rcvbuf=size]
wait/nowait[.max]
user[.group] or user[:group]
server program
@@ -119,7 +119,7 @@ based service, the entry would contain t
.Bd -unfilled -offset indent
service name/version
socket type
-rpc/protocol
+rpc/protocol[,sndbuf=size][,rcvbuf=size]
wait/nowait[.max]
user[.group] or user[:group]
server program
@@ -234,6 +234,30 @@ is used to specify a socket in the
.Ux
domain.
.Pp
+In addition to the protocol, the configuration file may specify the
+send and receive socket buffer sizes for the listening socket.
+This is especially useful for
+.Tn TCP
+as the window scale factor, which is based on the receive socket
+buffer size, is advertised when the connection handshake occurs,
+thus the socket buffer size for the server must be set on the listen socket.
+By increasing the socket buffer sizes, better
+.Tn TCP
+performance may be realized in some situations.
+The socket buffer sizes are specified by appending their values to
+the protocol specification as follows:
+.Bd -literal -offset indent
+tcp,rcvbuf=16384
+tcp,sndbuf=64k
+tcp,rcvbuf=64k,sndbuf=1m
+.Ed
+.Pp
+A literal value may be specified, or modified using
+.Sq k
+to indicate kilobytes or
+.Sq m
+to indicate megabytes.
+.Pp
The
.Em wait/nowait
entry is used to tell
--- a/inetd.c
+++ b/inetd.c
@@ -206,6 +206,8 @@ struct servtab {
int se_socktype; /* type of socket to use */
int se_family; /* address family */
char *se_proto; /* protocol used */
+ int se_sndbuf; /* sndbuf size */
+ int se_rcvbuf; /* rcvbuf size */
int se_rpcprog; /* rpc program number */
int se_rpcversl; /* rpc program lowest version */
int se_rpcversh; /* rpc program highest version */
@@ -1252,6 +1254,8 @@ getconfigent(void)
{
struct servtab *sep, *tsep;
char *arg, *cp, *hostdelim, *s;
+ char *cp0, *buf0, *buf1, *sz0, *sz1;
+ int val;
int argc;
sep = (struct servtab *) malloc(sizeof(struct servtab));
@@ -1327,6 +1331,93 @@ more:
sep->se_proto = newstr(arg);
+#define MALFORMED(arg) \
+do { \
+ syslog(LOG_ERR, "%s: malformed buffer size option `%s'", \
+ sep->se_service, (arg)); \
+ goto more; \
+} while (0)
+
+#define GETVAL(arg) \
+do { \
+ if (!isdigit(*(arg))) \
+ MALFORMED(arg); \
+ val = strtol((arg), &cp0, 10); \
+ if (cp0 != NULL) { \
+ if (cp0[1] != '\0') \
+ MALFORMED((arg)); \
+ if (cp0[0] == 'k') \
+ val *= 1024; \
+ if (cp0[0] == 'm') \
+ val *= 1024 * 1024; \
+ } \
+ if (val < 1) { \
+ syslog(LOG_ERR, "%s: invalid buffer size `%s'", \
+ sep->se_service, (arg)); \
+ goto more; \
+ } \
+} while (0)
+
+#define ASSIGN(arg) \
+do { \
+ if (strcmp((arg), "sndbuf") == 0) \
+ sep->se_sndbuf = val; \
+ else if (strcmp((arg), "rcvbuf") == 0) \
+ sep->se_rcvbuf = val; \
+ else \
+ MALFORMED((arg)); \
+} while (0)
+
+ /*
+ * Extract the send and receive buffer sizes before parsing
+ * the protocol.
+ */
+ sep->se_sndbuf = sep->se_rcvbuf = 0;
+ buf0 = buf1 = sz0 = sz1 = NULL;
+ if ((buf0 = strchr(sep->se_proto, ',')) != NULL) {
+ /* Skip the , */
+ *buf0++ = '\0';
+
+ /* Check to see if another socket buffer size was specified. */
+ if ((buf1 = strchr(buf0, ',')) != NULL) {
+ /* Skip the , */
+ *buf1++ = '\0';
+
+ /* Make sure a 3rd one wasn't specified. */
+ if (strchr(buf1, ',') != NULL) {
+ syslog(LOG_ERR, "%s: too many buffer sizes",
+ sep->se_service);
+ goto more;
+ }
+
+ /* Locate the size. */
+ if ((sz1 = strchr(buf1, '=')) == NULL)
+ MALFORMED(buf1);
+
+ /* Skip the = */
+ *sz1++ = '\0';
+ }
+
+ /* Locate the size. */
+ if ((sz0 = strchr(buf0, '=')) == NULL)
+ MALFORMED(buf0);
+
+ /* Skip the = */
+ *sz0++ = '\0';
+
+ GETVAL(sz0);
+ ASSIGN(buf0);
+
+ if (buf1 != NULL) {
+ GETVAL(sz1);
+ ASSIGN(buf1);
+ }
+ }
+
+#undef ASSIGN
+#undef GETVAL
+#undef MALFORMED
+
if (strcmp(sep->se_proto, "unix") == 0) {
sep->se_family = AF_UNIX;
} else {
--- a/inetd.c
+++ b/inetd.c
@@ -301,6 +301,7 @@ int bump_nofile(void);
struct servtab *enter(struct servtab *);
int matchconf(struct servtab *, struct servtab *);
int dg_broadcast(struct in_addr *in);
+void discard_stupid_environment(void);
#define NUMINT (sizeof(intab) / sizeof(struct inent))
char *CONFIG = _PATH_INETDCONF;
@@ -333,6 +334,7 @@ main(int argc, char *argv[], char *envp[
{
fd_set *fdsrp = NULL;
int readablen = 0, ch;
+ int keepenv = 0;
struct servtab *sep;
extern char *optarg;
extern int optind;
@@ -342,11 +344,14 @@ main(int argc, char *argv[], char *envp[
initsetproctitle(argc, argv, envp);
- while ((ch = getopt(argc, argv, "dR:")) != -1)
+ while ((ch = getopt(argc, argv, "dER:")) != -1)
switch (ch) {
case 'd':
debug = 1;
break;
+ case 'E':
+ keepenv = 1;
+ break;
case 'R': { /* invocation rate */
char *p;
int val;
@@ -364,13 +369,17 @@ main(int argc, char *argv[], char *envp[
case '?':
default:
fprintf(stderr,
- "usage: %s [-d] [-R rate] [configuration file]\n",
+ "usage: %s [-dE] [-R rate] [configuration file]\n",
progname);
exit(1);
}
argc -= optind;
argv += optind;
+ /* This must be called _after_ initsetproctitle and arg parsing */
+ if (!keepenv)
+ discard_stupid_environment();
+
uid = getuid();
if (uid != 0)
CONFIG = NULL;
@@ -2071,3 +2080,45 @@ spawn(struct servtab *sep, int ctrl)
if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
close(ctrl);
}
+
+/* from netkit+USAGI */
+void
+discard_stupid_environment(void)
+{
+ static const char *const junk[] = {
+ /* these are prefixes */
+ "CVS",
+ "DISPLAY=",
+ "EDITOR=",
+ "GROUP=",
+ "HOME=",
+ "IFS=",
+ "LD_",
+ "LOGNAME=",
+ "MAIL=",
+ "PATH=",
+ "PRINTER=",
+ "PWD=",
+ "SHELL=",
+ "SHLVL=",
+ "SSH",
+ "TERM",
+ "TMP",
+ "USER=",
+ "VISUAL=",
+ NULL
+ };
+
+ int i, k = 0;
+
+ for (i = 0; __environ[i]; i++) {
+ int found = 0, j;
+
+ for (j = 0; junk[j]; j++)
+ if (!strncmp(__environ[i], junk[j], strlen(junk[j])))
+ found = 1;
+ if (!found)
+ __environ[k++] = __environ[i];
+ }
+ __environ[k] = NULL;
+}
--- a/inetd.8
+++ b/inetd.8
@@ -38,6 +38,7 @@
.Sh SYNOPSIS
.Nm inetd
.Op Fl d
+.Op Fl E
.Op Fl R Ar rate
.Op Ar configuration file
.Sh DESCRIPTION
@@ -62,6 +63,13 @@ The options are as follows:
.Bl -tag -width Ds
.It Fl d
Turns on debugging.
+.It Fl E
+Prevents
+.Nm inetd
+from laundering the environment. Without this option a selection of
+potentially harmful environent variables, including
+.Pa PATH ,
+will be removed and not inherited by services.
.It Fl R Ar rate
Specify the maximum number of times a service can be invoked
in one minute; the default is 256.
--- a/inetd.c
+++ b/inetd.c
@@ -178,6 +178,7 @@ int lflag = 0;
#endif
int debug = 0;
+int global_queuelen = 128;
int nsock, maxsock;
fd_set *allsockp;
int allsockn;
@@ -350,7 +351,7 @@ main(int argc, char *argv[], char *envp[
initsetproctitle(argc, argv, envp);
- while ((ch = getopt(argc, argv, "dEilR:")) != -1)
+ while ((ch = getopt(argc, argv, "dEilq:R:")) != -1)
switch (ch) {
case 'd':
debug = 1;
@@ -370,6 +371,11 @@ main(int argc, char *argv[], char *envp[
progname);
exit(1);
#endif
+ case 'q':
+ global_queuelen = atoi(optarg);
+ if (global_queuelen < 10)
+ global_queuelen = 10;
+ break;
case 'R': { /* invocation rate */
char *p;
int val;
@@ -387,7 +393,7 @@ main(int argc, char *argv[], char *envp[
case '?':
default:
fprintf(stderr,
- "usage: %s [-dEil] [-R rate] [configuration file]\n",
+ "usage: %s [-dEil] [-q len] [-R rate] [configuration file]\n",
progname);
exit(1);
}
@@ -1072,7 +1078,7 @@ setsockopt(fd, SOL_SOCKET, opt, &on, siz
return;
}
if (sep->se_socktype == SOCK_STREAM)
- listen(sep->se_fd, 10);
+ listen(sep->se_fd, global_queuelen);
fd_grow(&allsockp, &allsockn, sep->se_fd);
FD_SET(sep->se_fd, allsockp);
--- a/inetd.c
+++ b/inetd.c
@@ -172,6 +172,11 @@ static const char rcsid[] = "$OpenBSD: i
#define CNT_INTVL 60 /* servers in CNT_INTVL sec. */
#define RETRYTIME (60*10) /* retry after bind or server fail */
+#ifdef LIBWRAP
+# include <tcpd.h>
+int lflag = 0;
+#endif
+
int debug = 0;
int nsock, maxsock;
fd_set *allsockp;
@@ -344,7 +349,7 @@ main(int argc, char *argv[], char *envp[
initsetproctitle(argc, argv, envp);
- while ((ch = getopt(argc, argv, "dER:")) != -1)
+ while ((ch = getopt(argc, argv, "dElR:")) != -1)
switch (ch) {
case 'd':
debug = 1;
@@ -352,6 +357,15 @@ main(int argc, char *argv[], char *envp[
case 'E':
keepenv = 1;
break;
+ case 'l':
+#ifdef LIBWRAP
+ lflag = 1;
+ break;
+#else
+ fprintf(stderr, "%s: libwrap support not enabled",
+ progname);
+ exit(1);
+#endif
case 'R': { /* invocation rate */
char *p;
int val;
@@ -369,7 +383,7 @@ main(int argc, char *argv[], char *envp[
case '?':
default:
fprintf(stderr,
- "usage: %s [-dE] [-R rate] [configuration file]\n",
+ "usage: %s [-dEl] [-R rate] [configuration file]\n",
progname);
exit(1);
}
@@ -1967,6 +1981,47 @@ spawn(struct servtab *sep, int ctrl)
}
sigprocmask(SIG_SETMASK, &emptymask, NULL);
if (pid == 0) {
+#ifdef LIBWRAP
+ if (lflag && !sep->se_wait && sep->se_socktype == SOCK_STREAM) {
+ struct request_info req;
+ char *service;
+
+ /* do not execute tcpd if it is in the config */
+ if (strcmp(sep->se_server, "/usr/sbin/tcpd") == 0) {
+ char *p, *name;
+
+ free(sep->se_server);
+ sep->se_server = sep->se_argv[0];
+ for (p = sep->se_server; *p; p++)
+ if (*p == '/')
+ name = p;
+ sep->se_argv[0] = newstr(name + 1);
+ }
+
+ request_init(&req, RQ_DAEMON, sep->se_argv[0],
+ RQ_FILE, ctrl, NULL);
+ fromhost(&req);
+ if (getnameinfo(&sep->se_ctrladdr,
+ sizeof(sep->se_ctrladdr), NULL, 0, buf,
+ sizeof(buf), 0) != 0) {
+ /* shouldn't happen */
+ snprintf(buf, sizeof buf, "%d",
+ ntohs(sep->se_ctrladdr_in.sin_port));
+ }
+ service = buf;
+ if (!hosts_access(&req)) {
+ syslog(deny_severity, "refused connection"
+ " from %.500s, service %s (%s)",
+ eval_client(&req), service, sep->se_proto);
+ if (sep->se_socktype != SOCK_STREAM)
+ recv(0, buf, sizeof (buf), 0);
+ exit(1);
+ }
+ syslog(allow_severity,
+ "connection from %.500s, service %s (%s)",
+ eval_client(&req), service, sep->se_proto);
+ }
+#endif
if (sep->se_bi)
(*sep->se_bi->bi_fn)(ctrl, sep);
else {
--- a/inetd.8
+++ b/inetd.8
@@ -39,6 +39,7 @@
.Nm inetd
.Op Fl d
.Op Fl E
+.Op Fl l
.Op Fl R Ar rate
.Op Ar configuration file
.Sh DESCRIPTION
@@ -70,6 +71,13 @@ from laundering the environment. Withou
potentially harmful environent variables, including
.Pa PATH ,
will be removed and not inherited by services.
+.It Fl l
+Turns on libwrap connection logging and access control.
+Internal services cannot be wrapped. When enabled,
+.Pa /usr/sbin/tcpd
+is silently not executed even if present in
+.Pa /etc/inetd.conf
+and instead libwrap is called directly by inetd.
.It Fl R Ar rate
Specify the maximum number of times a service can be invoked
in one minute; the default is 256.
@@ -353,6 +361,23 @@ is reread.
creates a file
.Em /var/run/inetd.pid
that contains its process identifier.
+.Ss libwrap
+Support for
+.Tn TCP
+wrappers is included with
+.Nm
+to provide built-in tcpd-like access control functionality.
+An external tcpd program is not needed.
+You do not need to change the
+.Pa /etc/inetd.conf
+server-program entry to enable this capability.
+.Nm
+uses
+.Pa /etc/hosts.allow
+and
+.Pa /etc/hosts.deny
+for access control facility configurations, as described in
+.Xr hosts_access 5 .
.Ss IPv6 TCP/UDP behavior
If you wish to run a server for IPv4 and IPv6 traffic,
you'll need to run two separate processes for the same server program,
--- a/inetd.8
+++ b/inetd.8
@@ -166,7 +166,7 @@ The part on the right of the
is the RPC version number.
This can simply be a single numeric argument or a range of versions.
A range is bounded by the low version to the high version -
-.Dq rusers/1-3 .
+.Dq rusers/1\-3 .
For
.Ux
domain sockets this field specifies the path name of the socket.
@@ -186,7 +186,8 @@ reliably delivered message, or sequenced
The
.Em protocol
must be a valid protocol as given in
-.Pa /etc/protocols .
+.Pa /etc/protocols or
+.Dq unix .
Examples might be
.Dq tcp
or
@@ -378,9 +379,7 @@ If you have only one server on
only IPv6 traffic will be routed to the server.
.El
.Sh SEE ALSO
-.Xr comsat 8 ,
.Xr fingerd 8 ,
-.Xr ftp-proxy 8 ,
.Xr ftpd 8 ,
.Xr identd 8 ,
.Xr rshd 8 ,
@@ -395,7 +394,23 @@ Support for Sun-RPC
based services is modelled after that
provided by SunOS 4.1.
IPv6 support was added by the KAME project in 1999.
+.Pp
+Marco d'Itri ported this code from OpenBSD in summer 2002 and added
+socket buffers tuning and libwrap support from the NetBSD source tree.
.Sh BUGS
+On Linux systems, the daemon cannot reload its configuration and needs
+to be restarted when the host address for a service is changed between
+.Dq \&*
+and a specific address.
+.Pp
+Server programs used with
+.Dq dgram
+.Dq udp
+.Dq nowait
+must read from the network socket, or
+.Nm inetd
+will spawn processes until the maximum is reached.
+.Pp
Host address specifiers, while they make conceptual sense for RPC
services, do not work entirely correctly.
This is largely because the
--- a/inetd.c
+++ b/inetd.c
@@ -139,6 +139,7 @@ static const char rcsid[] = "$OpenBSD: i
#include <sys/un.h>
#include <sys/file.h>
#include <sys/wait.h>
+#include <time.h>
#include <sys/time.h>
#include <sys/resource.h>
@@ -157,11 +158,14 @@ static const char rcsid[] = "$OpenBSD: i
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#ifdef HAVE_SETUSERCONTEXT
#include <login_cap.h>
+#endif
+#ifdef HAVE_GETIFADDRS
#include <ifaddrs.h>
+#endif
#include <rpc/rpc.h>
#include <rpc/pmap_clnt.h>
-#include <rpcsvc/nfs_prot.h>
#include "pathnames.h"
#define TOOMANY 256 /* don't start more than TOOMANY */
@@ -340,7 +344,6 @@ main(int argc, char *argv[])
switch (ch) {
case 'd':
debug = 1;
- options |= SO_DEBUG;
break;
case 'R': { /* invocation rate */
char *p;
@@ -385,9 +388,13 @@ main(int argc, char *argv[])
umask(022);
if (debug == 0) {
daemon(0, 0);
+#ifdef HAVE_SETLOGIN
if (uid == 0)
(void) setlogin("");
+#endif
}
+ if (debug && uid == 0)
+ options |= SO_DEBUG;
if (uid == 0) {
gid_t gid = getgid();
@@ -432,6 +439,15 @@ main(int argc, char *argv[])
sa.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &sa, &sapipe);
+ /* space for daemons to overwrite environment for ps */
+ {
+#define DUMMYSIZE 100
+ char dummy[DUMMYSIZE];
+ memset(dummy, 'x', DUMMYSIZE - 1);
+ dummy[DUMMYSIZE - 1] = '\0';
+ setenv("inetd_dummy", dummy, 1);
+ }
+
for (;;) {
int n, ctrl = -1;
@@ -587,9 +603,6 @@ dg_badinput(struct sockaddr *sa)
return 0;
}
- if (port < IPPORT_RESERVED || port == NFS_PORT)
- goto bad;
-
return (0);
bad:
@@ -599,6 +612,7 @@ bad:
int
dg_broadcast(struct in_addr *in)
{
+#ifdef HAVE_GETIFADDRS
struct ifaddrs *ifa, *ifap;
struct sockaddr_in *sin;
@@ -615,6 +629,7 @@ dg_broadcast(struct in_addr *in)
}
}
freeifaddrs(ifap);
+#endif
return (0);
}
@@ -1861,7 +1876,7 @@ print_service(char *action, struct servt
fprintf(stderr,
" wait.max=%hd.%d user:group=%s:%s builtin=%lx server=%s\n",
sep->se_wait, sep->se_max, sep->se_user,
- sep->se_group ? sep->se_group : "wheel",
+ sep->se_group ? sep->se_group : "(default)",
(long)sep->se_bi, sep->se_server);
}
@@ -1969,6 +1984,7 @@ spawn(struct servtab *sep, int ctrl)
if (uid != pwd->pw_uid)
exit(1);
} else {
+#ifdef HAVE_SETUSERCONTEXT
tmpint = LOGIN_SETALL &
~(LOGIN_SETGROUP|LOGIN_SETLOGIN);
if (pwd->pw_uid)
@@ -1984,6 +2000,51 @@ spawn(struct servtab *sep, int ctrl)
sep->se_service, sep->se_proto);
exit(1);
}
+#else
+ /* what about setpriority(2), setrlimit(2),
+ * and umask(2)? The $PATH is cleared.
+ */
+ if (pwd->pw_uid) {
+ if (sep->se_group)
+ pwd->pw_gid = grp->gr_gid;
+ if (setgid(pwd->pw_gid) < 0) {
+ syslog(LOG_ERR,
+ "%s/%s: can't set gid %d: %m",
+ sep->se_service, sep->se_proto,
+ pwd->pw_gid);
+ exit(1);