diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2002-06-28 22:40:34 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2002-06-28 22:40:34 +0000 |
commit | 6fb332e54721e5b2abf5c257c5ddb183e58ffdc6 (patch) | |
tree | 26ae861143e40b917d4b31618931be674d029583 | |
parent | 1b9818fe36618e8bafb3f4c851dec6ff1d62fdb7 (diff) |
go back to running these as root from inetd. however once rpc.{rusersd,rstatd}
starts, do a chroot to /var/empty and change to user nobody.
hi mom, i'm in jail!
-rw-r--r-- | etc/inetd.conf | 6 | ||||
-rw-r--r-- | libexec/rpc.rstatd/rstat_proc.c | 42 | ||||
-rw-r--r-- | libexec/rpc.rstatd/rstatd.c | 46 | ||||
-rw-r--r-- | libexec/rpc.rusersd/rusers_proc.c | 161 | ||||
-rw-r--r-- | libexec/rpc.rusersd/rusersd.c | 49 |
5 files changed, 158 insertions, 146 deletions
diff --git a/etc/inetd.conf b/etc/inetd.conf index 0c29c4e99e2..2c8793c1cb7 100644 --- a/etc/inetd.conf +++ b/etc/inetd.conf @@ -1,4 +1,4 @@ -# $OpenBSD: inetd.conf,v 1.47 2002/06/05 21:48:14 deraadt Exp $ +# $OpenBSD: inetd.conf,v 1.48 2002/06/28 22:40:31 deraadt Exp $ # # Internet server configuration database # @@ -51,8 +51,8 @@ time stream tcp6 nowait root internal # Encrypted X connections #kx stream tcp nowait root /usr/X11R6/bin/kxd kxd # RPC based services -rstatd/1-3 dgram rpc/udp wait nobody /usr/libexec/rpc.rstatd rpc.rstatd -rusersd/1-3 dgram rpc/udp wait nobody /usr/libexec/rpc.rusersd rpc.rusersd +rstatd/1-3 dgram rpc/udp wait root /usr/libexec/rpc.rstatd rpc.rstatd +rusersd/1-3 dgram rpc/udp wait root /usr/libexec/rpc.rusersd rpc.rusersd #walld/1 dgram rpc/udp wait root /usr/libexec/rpc.rwalld rpc.rwalld #sprayd/1 dgram rpc/udp wait root /usr/libexec/rpc.sprayd rpc.sprayd #rquotad/1 dgram rpc/udp wait root /usr/libexec/rpc.rquotad rpc.rquotad diff --git a/libexec/rpc.rstatd/rstat_proc.c b/libexec/rpc.rstatd/rstat_proc.c index 0ae365812eb..ba422ec5229 100644 --- a/libexec/rpc.rstatd/rstat_proc.c +++ b/libexec/rpc.rstatd/rstat_proc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rstat_proc.c,v 1.21 2002/02/16 21:27:31 millert Exp $ */ +/* $OpenBSD: rstat_proc.c,v 1.22 2002/06/28 22:40:33 deraadt Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for @@ -31,7 +31,7 @@ #ifndef lint /*static char sccsid[] = "from: @(#)rpc.rstatd.c 1.1 86/09/25 Copyr 1984 Sun Micro";*/ /*static char sccsid[] = "from: @(#)rstat_proc.c 2.2 88/08/01 4.0 RPCSRC";*/ -static char rcsid[] = "$OpenBSD: rstat_proc.c,v 1.21 2002/02/16 21:27:31 millert Exp $"; +static char rcsid[] = "$OpenBSD: rstat_proc.c,v 1.22 2002/06/28 22:40:33 deraadt Exp $"; #endif /* @@ -100,7 +100,7 @@ static int stat_is_init = 0; #endif void -stat_init() +stat_init(void) { stat_is_init = 1; setup(); @@ -110,9 +110,7 @@ stat_init() } statstime * -rstatproc_stats_3_svc(arg, rqstp) - void *arg; - struct svc_req *rqstp; +rstatproc_stats_3_svc(void *arg, struct svc_req *rqstp) { if (!stat_is_init) stat_init(); @@ -121,9 +119,7 @@ rstatproc_stats_3_svc(arg, rqstp) } statsswtch * -rstatproc_stats_2_svc(arg, rqstp) - void *arg; - struct svc_req *rqstp; +rstatproc_stats_2_svc(void *arg, struct svc_req *rqstp) { if (!stat_is_init) stat_init(); @@ -132,9 +128,7 @@ rstatproc_stats_2_svc(arg, rqstp) } stats * -rstatproc_stats_1_svc(arg, rqstp) - void *arg; - struct svc_req *rqstp; +rstatproc_stats_1_svc(void *arg, struct svc_req *rqstp) { if (!stat_is_init) stat_init(); @@ -143,9 +137,7 @@ rstatproc_stats_1_svc(arg, rqstp) } u_int * -rstatproc_havedisk_3_svc(arg, rqstp) - void *arg; - struct svc_req *rqstp; +rstatproc_havedisk_3_svc(void *arg, struct svc_req *rqstp) { static u_int have; @@ -157,17 +149,13 @@ rstatproc_havedisk_3_svc(arg, rqstp) } u_int * -rstatproc_havedisk_2_svc(arg, rqstp) - void *arg; - struct svc_req *rqstp; +rstatproc_havedisk_2_svc(void *arg, struct svc_req *rqstp) { return (rstatproc_havedisk_3_svc(arg, rqstp)); } u_int * -rstatproc_havedisk_1_svc(arg, rqstp) - void *arg; - struct svc_req *rqstp; +rstatproc_havedisk_1_svc(void *arg, struct svc_req *rqstp) { return (rstatproc_havedisk_3_svc(arg, rqstp)); } @@ -179,7 +167,7 @@ updatestatsig(int sig) } void -updatestat() +updatestat(void) { int i, mib[2], save_errno = errno; struct uvmexp uvmexp; @@ -283,22 +271,20 @@ updatestat() } void -setup() +setup(void) { dkinit(0); } void -rstat_service(rqstp, transp) - struct svc_req *rqstp; - SVCXPRT *transp; +rstat_service(struct svc_req *rqstp, SVCXPRT *transp) { + char *(*local)(void *, struct svc_req *); + xdrproc_t xdr_argument, xdr_result; union { int fill; } argument; char *result; - xdrproc_t xdr_argument, xdr_result; - char *(*local)(void *, struct svc_req *); switch (rqstp->rq_proc) { case NULLPROC: diff --git a/libexec/rpc.rstatd/rstatd.c b/libexec/rpc.rstatd/rstatd.c index 863f219d92d..194e535d9c2 100644 --- a/libexec/rpc.rstatd/rstatd.c +++ b/libexec/rpc.rstatd/rstatd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rstatd.c,v 1.9 2002/03/24 04:39:38 deraadt Exp $ */ +/* $OpenBSD: rstatd.c,v 1.10 2002/06/28 22:40:33 deraadt Exp $ */ /*- * Copyright (c) 1993, John Brezak @@ -34,7 +34,7 @@ */ #ifndef lint -static char rcsid[] = "$OpenBSD: rstatd.c,v 1.9 2002/03/24 04:39:38 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: rstatd.c,v 1.10 2002/06/28 22:40:33 deraadt Exp $"; #endif /* not lint */ #include <sys/types.h> @@ -44,6 +44,7 @@ static char rcsid[] = "$OpenBSD: rstatd.c,v 1.9 2002/03/24 04:39:38 deraadt Exp #include <string.h> #include <unistd.h> #include <signal.h> +#include <pwd.h> #include <syslog.h> #include <errno.h> #include <stdlib.h> @@ -60,8 +61,17 @@ void my_svc_run(void); int from_inetd = 1; /* started from inetd ? */ int closedown = 20; /* how long to wait before going dormant */ +volatile sig_atomic_t gotsig; + +void +getsig(int signo) +{ + gotsig = 1; +} + + void -cleanup() +cleanup(void) { (void) pmap_unset(RSTATPROG, RSTATVERS_TIME); /* XXX signal races */ (void) pmap_unset(RSTATPROG, RSTATVERS_SWTCH); @@ -70,14 +80,28 @@ cleanup() } int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char *argv[]) { int sock = 0, proto = 0, fromlen; + struct passwd *pw; struct sockaddr_in from; SVCXPRT *transp; + pw = getpwnam("nobody"); + if (chroot("/var/empty") == -1) { + syslog(LOG_ERR, "cannot chdir to /var/empty."); + exit(1); + } + chdir("/"); + + if (pw) { + setgroups(1, &pw->pw_gid); + setegid(pw->pw_gid); + setgid(pw->pw_gid); + seteuid(pw->pw_uid); + setegid(pw->pw_uid); + } + if (argc == 2) closedown = atoi(argv[1]); if (closedown <= 0) @@ -100,9 +124,9 @@ main(argc, argv) (void)pmap_unset(RSTATPROG, RSTATVERS_SWTCH); (void)pmap_unset(RSTATPROG, RSTATVERS_ORIG); - (void) signal(SIGINT, cleanup); - (void) signal(SIGTERM, cleanup); - (void) signal(SIGHUP, cleanup); + (void) signal(SIGINT, getsig); + (void) signal(SIGTERM, getsig); + (void) signal(SIGHUP, getsig); } openlog("rpc.rstatd", LOG_CONS|LOG_PID, LOG_DAEMON); @@ -131,7 +155,7 @@ main(argc, argv) } void -my_svc_run() +my_svc_run(void) { extern volatile sig_atomic_t wantupdatestat; extern void updatestat(void); @@ -142,6 +166,8 @@ my_svc_run() updatestat(); wantupdatestat = 0; } + if (gotsig) + cleanup(); if (__svc_fdset) { int bytes = howmany(__svc_fdsetsize, NFDBITS) * diff --git a/libexec/rpc.rusersd/rusers_proc.c b/libexec/rpc.rusersd/rusers_proc.c index 0bfabdcb893..ecf0deeb7a4 100644 --- a/libexec/rpc.rusersd/rusers_proc.c +++ b/libexec/rpc.rusersd/rusers_proc.c @@ -1,9 +1,9 @@ -/* $OpenBSD: rusers_proc.c,v 1.15 2002/06/09 04:06:42 deraadt Exp $ */ +/* $OpenBSD: rusers_proc.c,v 1.16 2002/06/28 22:40:33 deraadt Exp $ */ /*- * Copyright (c) 1993 John Brezak * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -14,7 +14,7 @@ * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -29,7 +29,7 @@ */ #ifndef lint -static char rcsid[] = "$OpenBSD: rusers_proc.c,v 1.15 2002/06/09 04:06:42 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: rusers_proc.c,v 1.16 2002/06/28 22:40:33 deraadt Exp $"; #endif /* not lint */ #include <sys/param.h> @@ -40,16 +40,13 @@ static char rcsid[] = "$OpenBSD: rusers_proc.c,v 1.15 2002/06/09 04:06:42 deraad #include <utmp.h> #include <stdio.h> #include <syslog.h> +#include <unistd.h> #include <string.h> #include <rpc/rpc.h> #include <rpcsvc/rusers.h> /* New version */ #include <rpcsvc/rnusers.h> /* Old version */ -#define IGNOREUSER "sleeper" - -#ifndef _PATH_UTMP -#define _PATH_UTMP "/etc/utmp" -#endif +extern int utmp_fd; #ifndef _PATH_DEV #define _PATH_DEV "/dev" @@ -83,14 +80,13 @@ extern int from_inetd; FILE *ufp; static u_int -getidle(tty, display) - char *tty, *display; +getidle(char *tty, char *display) { - struct stat st; char devname[PATH_MAX]; - time_t now; + struct stat st; u_long idle; - + time_t now; + /* * If this is an X terminal or console, then try the * XIdle extension @@ -128,16 +124,21 @@ getidle(tty, display) return (idle); } - + int * -rusers_num_svc(arg, rqstp) - void *arg; - struct svc_req *rqstp; +rusers_num_svc(void *arg, struct svc_req *rqstp) { static int num_users = 0; struct utmp usr; + int fd; - ufp = fopen(_PATH_UTMP, "r"); + fd = dup(utmp_fd); + if (fd == -1) { + syslog(LOG_ERR, "%m"); + return (0); + } + lseek(fd, SEEK_SET, 0); + ufp = fdopen(fd, "r"); if (!ufp) { syslog(LOG_ERR, "%m"); return (0); @@ -145,15 +146,8 @@ rusers_num_svc(arg, rqstp) /* only entries with both name and line fields */ while (fread((char *)&usr, sizeof(usr), 1, ufp) == 1) - if (*usr.ut_name && *usr.ut_line && - strncmp(usr.ut_name, IGNOREUSER, - sizeof(usr.ut_name)) -#ifdef USER_PROCESS - && usr.ut_type == USER_PROCESS -#endif - ) { + if (*usr.ut_name && *usr.ut_line) num_users++; - } fclose(ufp); return (&num_users); @@ -165,11 +159,18 @@ do_names_3(int all) static utmp_array ut; struct utmp usr; int nusers = 0; - + int fd; + bzero((char *)&ut, sizeof(ut)); ut.utmp_array_val = &utmps[0]; - - ufp = fopen(_PATH_UTMP, "r"); + + fd = dup(utmp_fd); + if (fd == -1) { + syslog(LOG_ERR, "%m"); + return (0); + } + lseek(fd, SEEK_SET, 0); + ufp = fdopen(fd, "r"); if (!ufp) { syslog(LOG_ERR, "%m"); return (NULL); @@ -177,19 +178,11 @@ do_names_3(int all) /* only entries with both name and line fields */ while (fread((char *)&usr, sizeof(usr), 1, ufp) == 1 && - nusers < MAXUSERS) - if (*usr.ut_name && *usr.ut_line && - strncmp(usr.ut_name, IGNOREUSER, - sizeof(usr.ut_name)) -#ifdef USER_PROCESS - && usr.ut_type == USER_PROCESS -#endif - ) { + nusers < MAXUSERS) + if (*usr.ut_name && *usr.ut_line) { utmps[nusers].ut_type = RUSERS_USER_PROCESS; - utmps[nusers].ut_time = - usr.ut_time; - utmps[nusers].ut_idle = - getidle(usr.ut_line, usr.ut_host); + utmps[nusers].ut_time = usr.ut_time; + utmps[nusers].ut_idle = getidle(usr.ut_line, usr.ut_host); utmps[nusers].ut_line = line[nusers]; memset(line[nusers], 0, sizeof(line[nusers])); strlcpy(line[nusers], usr.ut_line, sizeof(line[nusers])); @@ -208,17 +201,13 @@ do_names_3(int all) } utmp_array * -rusersproc_names_3_svc(arg, rqstp) - void *arg; - struct svc_req *rqstp; +rusersproc_names_3_svc(void *arg, struct svc_req *rqstp) { return (do_names_3(0)); } utmp_array * -rusersproc_allnames_3_svc(arg, rqstp) - void *arg; - struct svc_req *rqstp; +rusersproc_allnames_3_svc(void *arg, struct svc_req *rqstp) { return (do_names_3(1)); } @@ -229,12 +218,19 @@ do_names_2(int all) static struct utmpidlearr ut; struct utmp usr; int nusers = 0; - + int fd; + bzero((char *)&ut, sizeof(ut)); ut.uia_arr = utmp_idlep; ut.uia_cnt = 0; - - ufp = fopen(_PATH_UTMP, "r"); + + fd = dup(utmp_fd); + if (fd == -1) { + syslog(LOG_ERR, "%m"); + return (0); + } + lseek(fd, SEEK_SET, 0); + ufp = fdopen(fd, "r"); if (!ufp) { syslog(LOG_ERR, "%m"); return (NULL); @@ -242,19 +238,11 @@ do_names_2(int all) /* only entries with both name and line fields */ while (fread((char *)&usr, sizeof(usr), 1, ufp) == 1 && - nusers < MAXUSERS) - if (*usr.ut_name && *usr.ut_line && - strncmp(usr.ut_name, IGNOREUSER, - sizeof(usr.ut_name)) -#ifdef USER_PROCESS - && usr.ut_type == USER_PROCESS -#endif - ) { + nusers < MAXUSERS) + if (*usr.ut_name && *usr.ut_line) { utmp_idlep[nusers] = &utmp_idle[nusers]; - utmp_idle[nusers].ui_utmp.ut_time = - usr.ut_time; - utmp_idle[nusers].ui_idle = - getidle(usr.ut_line, usr.ut_host); + utmp_idle[nusers].ui_utmp.ut_time = usr.ut_time; + utmp_idle[nusers].ui_idle = getidle(usr.ut_line, usr.ut_host); utmp_idle[nusers].ui_utmp.ut_line = line[nusers]; memset(line[nusers], 0, sizeof(line[nusers])); strlcpy(line[nusers], usr.ut_line, sizeof(line[nusers])); @@ -273,17 +261,13 @@ do_names_2(int all) } struct utmpidlearr * -rusersproc_names_2_svc(arg, rqstp) - void *arg; - struct svc_req *rqstp; +rusersproc_names_2_svc(void *arg, struct svc_req *rqstp) { return (do_names_2(0)); } struct utmpidlearr * -rusersproc_allnames_2_svc(arg, rqstp) - void *arg; - struct svc_req *rqstp; +rusersproc_allnames_2_svc(void *arg, struct svc_req *rqstp) { return (do_names_2(1)); } @@ -294,12 +278,19 @@ do_names_1(int all) static struct utmparr ut; struct utmp usr; int nusers = 0; - + int fd; + bzero((char *)&ut, sizeof(ut)); ut.uta_arr = ru_utmpp; ut.uta_cnt = 0; - - ufp = fopen(_PATH_UTMP, "r"); + + fd = dup(utmp_fd); + if (fd == -1) { + syslog(LOG_ERR, "%m"); + return (0); + } + lseek(fd, SEEK_SET, 0); + ufp = fdopen(fd, "r"); if (!ufp) { syslog(LOG_ERR, "%m"); return (NULL); @@ -307,14 +298,8 @@ do_names_1(int all) /* only entries with both name and line fields */ while (fread((char *)&usr, sizeof(usr), 1, ufp) == 1 && - nusers < MAXUSERS) - if (*usr.ut_name && *usr.ut_line && - strncmp(usr.ut_name, IGNOREUSER, - sizeof(usr.ut_name)) -#ifdef USER_PROCESS - && usr.ut_type == USER_PROCESS -#endif - ) { + nusers < MAXUSERS) + if (*usr.ut_name && *usr.ut_line) { ru_utmpp[nusers] = &ru_utmp[nusers]; ru_utmp[nusers].ut_time = usr.ut_time; ru_utmp[nusers].ut_line = line[nusers]; @@ -332,32 +317,26 @@ do_names_1(int all) } struct utmparr * -rusersproc_names_1_svc(arg, rqstp) - void *arg; - struct svc_req *rqstp; +rusersproc_names_1_svc(void *arg, struct svc_req *rqstp) { return (do_names_1(0)); } struct utmparr * -rusersproc_allnames_1_svc(arg, rqstp) - void *arg; - struct svc_req *rqstp; +rusersproc_allnames_1_svc(void *arg, struct svc_req *rqstp) { return (do_names_1(1)); } void -rusers_service(rqstp, transp) - struct svc_req *rqstp; - SVCXPRT *transp; +rusers_service(struct svc_req *rqstp, SVCXPRT *transp) { + char *(*local)(void *, struct svc_req *); + xdrproc_t xdr_argument, xdr_result; union { int fill; } argument; char *result; - xdrproc_t xdr_argument, xdr_result; - char *(*local)(void *, struct svc_req *); switch (rqstp->rq_proc) { case NULLPROC: diff --git a/libexec/rpc.rusersd/rusersd.c b/libexec/rpc.rusersd/rusersd.c index 559d83f0d09..00c60594683 100644 --- a/libexec/rpc.rusersd/rusersd.c +++ b/libexec/rpc.rusersd/rusersd.c @@ -1,9 +1,9 @@ -/* $OpenBSD: rusersd.c,v 1.6 2002/06/09 04:06:42 deraadt Exp $ */ +/* $OpenBSD: rusersd.c,v 1.7 2002/06/28 22:40:33 deraadt Exp $ */ /*- * Copyright (c) 1993 John Brezak * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -14,7 +14,7 @@ * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -29,27 +29,31 @@ */ #ifndef lint -static char rcsid[] = "$OpenBSD: rusersd.c,v 1.6 2002/06/09 04:06:42 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: rusersd.c,v 1.7 2002/06/28 22:40:33 deraadt Exp $"; #endif /* not lint */ #include <sys/types.h> #include <sys/socket.h> +#include <sys/file.h> #include <stdio.h> #include <signal.h> #include <unistd.h> #include <stdlib.h> +#include <pwd.h> #include <syslog.h> #include <rpc/rpc.h> #include <rpcsvc/rusers.h> /* New version */ #include <rpcsvc/rnusers.h> /* Old version */ #include <rpc/pmap_clnt.h> +#include <utmp.h> extern void rusers_service(struct svc_req *, SVCXPRT *); int from_inetd = 1; +int utmp_fd; void -cleanup() +cleanup(int signo) { (void) pmap_unset(RUSERSPROG, RUSERSVERS_3); /* XXX signal races */ (void) pmap_unset(RUSERSPROG, RUSERSVERS_IDLE); @@ -58,15 +62,32 @@ cleanup() } int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char *argv[]) { - SVCXPRT *transp; - int sock = 0; - int proto = 0; + int sock = 0, proto = 0, fromlen; struct sockaddr_in from; - int fromlen; + struct passwd *pw; + SVCXPRT *transp; + + if (utmp_fd = open(_PATH_UTMP, O_RDONLY) == -1) { + syslog(LOG_ERR, "cannot open %s", _PATH_UTMP); + exit(1); + } + + pw = getpwnam("nobody"); + if (chroot("/var/empty") == -1) { + syslog(LOG_ERR, "cannot chdir to /var/empty."); + exit(1); + } + chdir("/"); + + if (pw) { + setgroups(1, &pw->pw_gid); + setegid(pw->pw_gid); + setgid(pw->pw_gid); + seteuid(pw->pw_uid); + setegid(pw->pw_uid); + } /* * See if inetd started us @@ -77,7 +98,7 @@ main(argc, argv) sock = RPC_ANYSOCK; proto = IPPROTO_UDP; } - + if (!from_inetd) { daemon(0, 0); @@ -91,7 +112,7 @@ main(argc, argv) } openlog("rpc.rusersd", LOG_CONS|LOG_PID, LOG_DAEMON); - + transp = svcudp_create(sock); if (transp == NULL) { syslog(LOG_ERR, "cannot create udp service."); |