summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2002-05-31 22:20:19 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2002-05-31 22:20:19 +0000
commit5fcf4bea9d3d83fd91071bdbe9449083ed0b61de (patch)
tree64e93e084fe27ba4812a6394c4265a9a6bcb4613 /usr.sbin
parent0502d24b0648ba8e93a41388d0a01866a61b53fc (diff)
split out two major function blocks which made the indentation horrible
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/inetd/inetd.c492
1 files changed, 258 insertions, 234 deletions
diff --git a/usr.sbin/inetd/inetd.c b/usr.sbin/inetd/inetd.c
index fe30972e4e6..84c19637001 100644
--- a/usr.sbin/inetd/inetd.c
+++ b/usr.sbin/inetd/inetd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: inetd.c,v 1.94 2002/05/31 20:20:53 itojun Exp $ */
+/* $OpenBSD: inetd.c,v 1.95 2002/05/31 22:20:18 deraadt Exp $ */
/* $NetBSD: inetd.c,v 1.11 1996/02/22 11:14:41 mycroft Exp $ */
/*
* Copyright (c) 1983,1991 The Regents of the University of California.
@@ -41,7 +41,7 @@ char copyright[] =
#ifndef lint
/*static char sccsid[] = "from: @(#)inetd.c 5.30 (Berkeley) 6/3/91";*/
-static char rcsid[] = "$OpenBSD: inetd.c,v 1.94 2002/05/31 20:20:53 itojun Exp $";
+static char rcsid[] = "$OpenBSD: inetd.c,v 1.95 2002/05/31 22:20:18 deraadt Exp $";
#endif /* not lint */
/*
@@ -174,15 +174,6 @@ static char rcsid[] = "$OpenBSD: inetd.c,v 1.94 2002/05/31 20:20:53 itojun Exp $
#define CNT_INTVL 60 /* servers in CNT_INTVL sec. */
#define RETRYTIME (60*10) /* retry after bind or server fail */
-void config(int);
-void doconfig(void);
-void reap(int);
-void doreap(void);
-void retry(int);
-void doretry(void);
-void die(int);
-void dodie(void);
-
int debug = 0;
int nsock, maxsock;
fd_set *allsockp;
@@ -292,12 +283,22 @@ volatile sig_atomic_t wantconfig;
volatile sig_atomic_t wantreap;
volatile sig_atomic_t wantdie;
+void config(int);
+void doconfig(void);
+void reap(int);
+void doreap(void);
+void retry(int);
+void doretry(void);
+void die(int);
+void dodie(void);
+void logpid(void);
+void spawn(struct servtab *, int);
+int gettcp(struct servtab *);
+
#define NUMINT (sizeof(intab) / sizeof(struct inent))
char *CONFIG = _PATH_INETDCONF;
char *progname;
-void logpid(void);
-
void
fd_grow(fd_set **fdsp, int *bytes, int fd)
{
@@ -318,29 +319,24 @@ fd_grow(fd_set **fdsp, int *bytes, int fd)
}
}
+struct sigaction sa, sapipe;
+
int
main(argc, argv)
int argc;
char *argv[];
{
+ fd_set *fdsrp = NULL;
+ int readablen = 0, ch;
+ struct servtab *sep;
extern char *optarg;
extern int optind;
- struct servtab *sep;
- struct passwd *pwd;
- struct group *grp = NULL;
- int tmpint;
- struct sigaction sa, sapipe;
- int ch, dofork;
- pid_t pid;
- char buf[50];
- fd_set *readablep = NULL;
- int readablen = 0;
progname = strrchr(argv[0], '/');
progname = progname ? progname + 1 : argv[0];
while ((ch = getopt(argc, argv, "dR:")) != -1)
- switch(ch) {
+ switch (ch) {
case 'd':
debug = 1;
options |= SO_DEBUG;
@@ -442,231 +438,118 @@ main(argc, argv)
}
for (;;) {
- int n, ctrl = -1;
-
- if (nsock == 0) {
- (void) sigprocmask(SIG_BLOCK, &blockmask, NULL);
- while (nsock == 0) {
- if (wantretry || wantconfig || wantreap)
- break;
- sigsuspend(&emptymask);
+ int n, ctrl = -1;
+
+ if (nsock == 0) {
+ (void) sigprocmask(SIG_BLOCK, &blockmask, NULL);
+ while (nsock == 0) {
+ if (wantretry || wantconfig || wantreap)
+ break;
+ sigsuspend(&emptymask);
+ }
+ (void) sigprocmask(SIG_SETMASK, &emptymask, NULL);
}
- (void) sigprocmask(SIG_SETMASK, &emptymask, NULL);
- }
- if (wantretry || wantconfig || wantreap || wantdie) {
- if (wantretry) {
- doretry();
- wantretry = 0;
- }
- if (wantconfig) {
- doconfig();
- wantconfig = 0;
- }
- if (wantreap) {
- doreap();
- wantreap = 0;
- }
- if (wantdie) {
- dodie();
- }
- continue;
- }
-
- if (readablen != allsockn) {
- if (readablep)
- free(readablep);
- readablep = (fd_set *)calloc(allsockn, 1);
- if (readablep == NULL) {
- syslog(LOG_ERR, "Out of memory.");
- exit(1);
- }
- readablen = allsockn;
- }
- bcopy(allsockp, readablep, allsockn);
-
- if ((n = select(maxsock + 1, readablep, NULL, NULL, NULL)) <= 0) {
- if (n < 0 && errno != EINTR) {
- syslog(LOG_WARNING, "select: %m");
- sleep(1);
- }
- continue;
- }
- for (sep = servtab; n && sep; sep = sep->se_next)
- if (sep->se_fd != -1 && FD_ISSET(sep->se_fd, readablep)) {
- n--;
- if (debug)
- fprintf(stderr, "someone wants %s\n", sep->se_service);
- if (!sep->se_wait && sep->se_socktype == SOCK_STREAM) {
- ctrl = accept(sep->se_fd, NULL, NULL);
- if (debug)
- fprintf(stderr, "accept, ctrl %d\n", ctrl);
- if (ctrl < 0) {
- if (errno == EINTR)
- continue;
- syslog(LOG_WARNING, "accept (for %s): %m",
- sep->se_service);
- continue;
+ if (wantretry || wantconfig || wantreap || wantdie) {
+ if (wantretry) {
+ doretry();
+ wantretry = 0;
}
- if ((sep->se_family == AF_INET ||
- sep->se_family == AF_INET6) &&
- sep->se_socktype == SOCK_STREAM) {
- struct sockaddr_storage peer;
- int plen = sizeof(peer);
- char sbuf[NI_MAXSERV];
-
- if (getpeername(ctrl, (struct sockaddr *)&peer,
- &plen) < 0) {
- syslog(LOG_WARNING, "could not getpeername");
- close(ctrl);
- continue;
- }
- if (getnameinfo((struct sockaddr *)&peer, plen,
- NULL, 0, sbuf, sizeof(sbuf),
- NI_NUMERICSERV) == 0 && atoi(sbuf) == 20) {
- /*
- * ignore things that look like
- * ftp bounce
- */
- close(ctrl);
- continue;
- }
+ if (wantconfig) {
+ doconfig();
+ wantconfig = 0;
}
- } else
- ctrl = sep->se_fd;
- (void) sigprocmask(SIG_BLOCK, &blockmask, NULL);
- pid = 0;
- dofork = (sep->se_bi == 0 || sep->se_bi->bi_fork);
- if (dofork) {
- if (sep->se_count++ == 0)
- (void)gettimeofday(&sep->se_time, NULL);
- else if (sep->se_count >= sep->se_max) {
- struct timeval now;
-
- (void)gettimeofday(&now, NULL);
- if (now.tv_sec - sep->se_time.tv_sec >
- CNT_INTVL) {
- sep->se_time = now;
- sep->se_count = 1;
- } else {
- if (!sep->se_wait &&
- sep->se_socktype == SOCK_STREAM)
- close(ctrl);
- if (sep->se_family == AF_INET &&
- ntohs(sep->se_ctrladdr_in.sin_port) >=
- IPPORT_RESERVED) {
- /*
- * Cannot close it -- there are
- * thieves on the system.
- * Simply ignore the connection.
- */
- --sep->se_count;
- continue;
- }
- syslog(LOG_ERR,
- "%s/%s server failing (looping), service terminated",
- sep->se_service, sep->se_proto);
- if (!sep->se_wait &&
- sep->se_socktype == SOCK_STREAM)
- close(ctrl);
- FD_CLR(sep->se_fd, allsockp);
- (void) close(sep->se_fd);
- sep->se_fd = -1;
- sep->se_count = 0;
- nsock--;
- sigprocmask(SIG_SETMASK, &emptymask,
- NULL);
- if (!timingout) {
- timingout = 1;
- alarm(RETRYTIME);
- }
- continue;
- }
+ if (wantreap) {
+ doreap();
+ wantreap = 0;
}
- pid = fork();
- }
- if (pid < 0) {
- syslog(LOG_ERR, "fork: %m");
- if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
- close(ctrl);
- sigprocmask(SIG_SETMASK, &emptymask, NULL);
- sleep(1);
+ if (wantdie)
+ dodie();
continue;
}
- if (pid && sep->se_wait) {
- sep->se_wait = pid;
- FD_CLR(sep->se_fd, allsockp);
- nsock--;
+
+ if (readablen != allsockn) {
+ if (fdsrp)
+ free(fdsrp);
+ fdsrp = (fd_set *)calloc(allsockn, 1);
+ if (fdsrp == NULL) {
+ syslog(LOG_ERR, "Out of memory.");
+ exit(1);
+ }
+ readablen = allsockn;
}
- sigprocmask(SIG_SETMASK, &emptymask, NULL);
- if (pid == 0) {
- if (sep->se_bi)
- (*sep->se_bi->bi_fn)(ctrl, sep);
- else {
- if ((pwd = getpwnam(sep->se_user)) == NULL) {
- syslog(LOG_ERR,
- "getpwnam: %s: No such user",
- sep->se_user);
- if (sep->se_socktype != SOCK_STREAM)
- recv(0, buf, sizeof (buf), 0);
- exit(1);
- }
- if (setsid() <0)
- syslog(LOG_ERR, "%s: setsid: %m",
- sep->se_service);
- if (sep->se_group &&
- (grp = getgrnam(sep->se_group)) == NULL) {
- syslog(LOG_ERR,
- "getgrnam: %s: No such group",
- sep->se_group);
- if (sep->se_socktype != SOCK_STREAM)
- recv(0, buf, sizeof (buf), 0);
- exit(1);
- }
- if (uid != 0) {
- /* a user running private inetd */
- if (uid != pwd->pw_uid)
- exit(1);
- } else {
- tmpint = LOGIN_SETALL &
- ~(LOGIN_SETGROUP|LOGIN_SETLOGIN);
- if (pwd->pw_uid)
- tmpint |= LOGIN_SETGROUP|LOGIN_SETLOGIN;
- if (sep->se_group) {
- pwd->pw_gid = grp->gr_gid;
- tmpint |= LOGIN_SETGROUP;
- }
- if (setusercontext(0, pwd, pwd->pw_uid,
- tmpint) < 0)
- syslog(LOG_ERR,
- "%s/%s: setusercontext: %m",
- sep->se_service,
- sep->se_proto);
- }
+ bcopy(allsockp, fdsrp, allsockn);
+
+ if ((n = select(maxsock + 1, fdsrp, NULL, NULL, NULL)) <= 0) {
+ if (n < 0 && errno != EINTR) {
+ syslog(LOG_WARNING, "select: %m");
+ sleep(1);
+ }
+ continue;
+ }
+
+ for (sep = servtab; n && sep; sep = sep->se_next) {
+ if (sep->se_fd != -1 &&
+ FD_ISSET(sep->se_fd, fdsrp)) {
+ n--;
if (debug)
- fprintf(stderr, "%ld execl %s\n",
- (long)getpid(), sep->se_server);
- dup2(ctrl, 0);
- close(ctrl);
- dup2(0, 1);
- dup2(0, 2);
- closelog();
- for (tmpint = rlim_ofile_cur-1; --tmpint > 2; )
- (void)close(tmpint);
- sigaction(SIGPIPE, &sapipe, NULL);
- execv(sep->se_server, sep->se_argv);
- if (sep->se_socktype != SOCK_STREAM)
- recv(0, buf, sizeof (buf), 0);
- syslog(LOG_ERR, "execv %s: %m", sep->se_server);
- exit(1);
+ fprintf(stderr, "someone wants %s\n",
+ sep->se_service);
+ if (!sep->se_wait &&
+ sep->se_socktype == SOCK_STREAM) {
+ ctrl = gettcp(sep);
+ if (ctrl == -1)
+ continue;
+ } else
+ ctrl = sep->se_fd;
+ (void) sigprocmask(SIG_BLOCK, &blockmask, NULL);
+ spawn(sep, ctrl);
}
}
- if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
+ }
+}
+
+int
+gettcp(sep)
+ struct servtab *sep;
+{
+ int ctrl;
+
+ ctrl = accept(sep->se_fd, NULL, NULL);
+ if (debug)
+ fprintf(stderr, "accept, ctrl %d\n", ctrl);
+ if (ctrl < 0) {
+ if (errno == EINTR)
+ return -1;
+ syslog(LOG_WARNING, "accept (for %s): %m", sep->se_service);
+ return -1;
+ }
+ if ((sep->se_family == AF_INET || sep->se_family == AF_INET6) &&
+ sep->se_socktype == SOCK_STREAM) {
+ struct sockaddr_storage peer;
+ int plen = sizeof(peer);
+ char sbuf[NI_MAXSERV];
+
+ if (getpeername(ctrl, (struct sockaddr *)&peer, &plen) < 0) {
+ syslog(LOG_WARNING, "could not getpeername");
+ close(ctrl);
+ return -1;
+ }
+ if (getnameinfo((struct sockaddr *)&peer, plen, NULL, 0,
+ sbuf, sizeof(sbuf), NI_NUMERICSERV) == 0 &&
+ atoi(sbuf) == 20) {
+ /*
+ * ignore things that
+ * look like ftp bounce
+ */
close(ctrl);
- }
+ return -1;
+ }
}
+ return (ctrl);
}
+
int
dg_badinput(sa)
struct sockaddr *sa;
@@ -2046,3 +1929,144 @@ print_service(action, sep)
sep->se_group ? sep->se_group : "wheel",
(long)sep->se_bi, sep->se_server);
}
+
+void
+spawn(sep, ctrl)
+ struct servtab *sep;
+ int ctrl;
+{
+ struct passwd *pwd;
+ int tmpint, dofork;
+ struct group *grp = NULL;
+ char buf[50];
+ pid_t pid;
+
+ pid = 0;
+ dofork = (sep->se_bi == 0 || sep->se_bi->bi_fork);
+ if (dofork) {
+ if (sep->se_count++ == 0)
+ (void)gettimeofday(&sep->se_time, NULL);
+ else if (sep->se_count >= sep->se_max) {
+ struct timeval now;
+
+ (void)gettimeofday(&now, NULL);
+ if (now.tv_sec - sep->se_time.tv_sec >
+ CNT_INTVL) {
+ sep->se_time = now;
+ sep->se_count = 1;
+ } else {
+ if (!sep->se_wait &&
+ sep->se_socktype == SOCK_STREAM)
+ close(ctrl);
+ if (sep->se_family == AF_INET &&
+ ntohs(sep->se_ctrladdr_in.sin_port) >=
+ IPPORT_RESERVED) {
+ /*
+ * Cannot close it -- there are
+ * thieves on the system.
+ * Simply ignore the connection.
+ */
+ --sep->se_count;
+ return;
+ }
+ syslog(LOG_ERR,
+ "%s/%s server failing (looping), service terminated",
+ sep->se_service, sep->se_proto);
+ if (!sep->se_wait &&
+ sep->se_socktype == SOCK_STREAM)
+ close(ctrl);
+ FD_CLR(sep->se_fd, allsockp);
+ (void) close(sep->se_fd);
+ sep->se_fd = -1;
+ sep->se_count = 0;
+ nsock--;
+ sigprocmask(SIG_SETMASK, &emptymask,
+ NULL);
+ if (!timingout) {
+ timingout = 1;
+ alarm(RETRYTIME);
+ }
+ return;
+ }
+ }
+ pid = fork();
+ }
+ if (pid < 0) {
+ syslog(LOG_ERR, "fork: %m");
+ if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
+ close(ctrl);
+ sigprocmask(SIG_SETMASK, &emptymask, NULL);
+ sleep(1);
+ return;
+ }
+ if (pid && sep->se_wait) {
+ sep->se_wait = pid;
+ FD_CLR(sep->se_fd, allsockp);
+ nsock--;
+ }
+ sigprocmask(SIG_SETMASK, &emptymask, NULL);
+ if (pid == 0) {
+ if (sep->se_bi)
+ (*sep->se_bi->bi_fn)(ctrl, sep);
+ else {
+ if ((pwd = getpwnam(sep->se_user)) == NULL) {
+ syslog(LOG_ERR,
+ "getpwnam: %s: No such user",
+ sep->se_user);
+ if (sep->se_socktype != SOCK_STREAM)
+ recv(0, buf, sizeof (buf), 0);
+ exit(1);
+ }
+ if (setsid() <0)
+ syslog(LOG_ERR, "%s: setsid: %m",
+ sep->se_service);
+ if (sep->se_group &&
+ (grp = getgrnam(sep->se_group)) == NULL) {
+ syslog(LOG_ERR,
+ "getgrnam: %s: No such group",
+ sep->se_group);
+ if (sep->se_socktype != SOCK_STREAM)
+ recv(0, buf, sizeof (buf), 0);
+ exit(1);
+ }
+ if (uid != 0) {
+ /* a user running private inetd */
+ if (uid != pwd->pw_uid)
+ exit(1);
+ } else {
+ tmpint = LOGIN_SETALL &
+ ~(LOGIN_SETGROUP|LOGIN_SETLOGIN);
+ if (pwd->pw_uid)
+ tmpint |= LOGIN_SETGROUP|LOGIN_SETLOGIN;
+ if (sep->se_group) {
+ pwd->pw_gid = grp->gr_gid;
+ tmpint |= LOGIN_SETGROUP;
+ }
+ if (setusercontext(0, pwd, pwd->pw_uid,
+ tmpint) < 0)
+ syslog(LOG_ERR,
+ "%s/%s: setusercontext: %m",
+ sep->se_service, sep->se_proto);
+ }
+ if (debug)
+ fprintf(stderr, "%ld execl %s\n",
+ (long)getpid(), sep->se_server);
+ dup2(ctrl, 0);
+ close(ctrl);
+ dup2(0, 1);
+ dup2(0, 2);
+ closelog();
+ for (tmpint = rlim_ofile_cur-1; --tmpint > 2; )
+ (void)close(tmpint);
+ sigaction(SIGPIPE, &sapipe, NULL);
+ execv(sep->se_server, sep->se_argv);
+ if (sep->se_socktype != SOCK_STREAM)
+ recv(0, buf, sizeof (buf), 0);
+ syslog(LOG_ERR, "execv %s: %m", sep->se_server);
+ exit(1);
+ }
+ }
+ if (!sep->se_wait && sep->se_socktype == SOCK_STREAM)
+ close(ctrl);
+}
+