144743Smarkm /*
244743Smarkm  * Front end to the ULTRIX miscd service. The front end logs the remote host
344743Smarkm  * name and then invokes the real miscd daemon. Install as "/usr/etc/miscd",
444743Smarkm  * after renaming the real miscd daemon to the name defined with the
544743Smarkm  * REAL_MISCD macro.
644743Smarkm  *
744743Smarkm  * Connections and diagnostics are logged through syslog(3).
844743Smarkm  *
944743Smarkm  * The Ultrix miscd program implements (among others) the systat service, which
1044743Smarkm  * pipes the output from who(1) to stdout. This information is potentially
1144743Smarkm  * useful to systems crackers.
1244743Smarkm  *
1344743Smarkm  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
1444743Smarkm  */
1544743Smarkm
1644743Smarkm#ifndef lint
1744743Smarkmstatic char sccsid[] = "@(#) miscd.c 1.10 96/02/11 17:01:30";
1844743Smarkm#endif
1944743Smarkm
2044743Smarkm/* System libraries. */
2144743Smarkm
2244743Smarkm#include <sys/types.h>
2344743Smarkm#include <sys/param.h>
2444743Smarkm#include <sys/stat.h>
2544743Smarkm#include <sys/socket.h>
2644743Smarkm#include <netinet/in.h>
2744743Smarkm#include <stdio.h>
2844743Smarkm#include <syslog.h>
2944743Smarkm
3044743Smarkm#ifndef MAXPATHNAMELEN
3144743Smarkm#define MAXPATHNAMELEN	BUFSIZ
3244743Smarkm#endif
3344743Smarkm
3444743Smarkm#ifndef STDIN_FILENO
3544743Smarkm#define STDIN_FILENO	0
3644743Smarkm#endif
3744743Smarkm
3844743Smarkm/* Local stuff. */
3944743Smarkm
4044743Smarkm#include "patchlevel.h"
4144743Smarkm#include "tcpd.h"
4244743Smarkm
4344743Smarkmint     allow_severity = SEVERITY;	/* run-time adjustable */
4444743Smarkmint     deny_severity = LOG_WARNING;	/* ditto */
4544743Smarkm
4644743Smarkmmain(argc, argv)
4744743Smarkmint     argc;
4844743Smarkmchar  **argv;
4944743Smarkm{
5044743Smarkm    struct request_info request;
5144743Smarkm    char    path[MAXPATHNAMELEN];
5244743Smarkm
5344743Smarkm    /* Attempt to prevent the creation of world-writable files. */
5444743Smarkm
5544743Smarkm#ifdef DAEMON_UMASK
5644743Smarkm    umask(DAEMON_UMASK);
5744743Smarkm#endif
5844743Smarkm
5944743Smarkm    /*
6044743Smarkm     * Open a channel to the syslog daemon. Older versions of openlog()
6144743Smarkm     * require only two arguments.
6244743Smarkm     */
6344743Smarkm
6444743Smarkm#ifdef LOG_MAIL
6544743Smarkm    (void) openlog(argv[0], LOG_PID, FACILITY);
6644743Smarkm#else
6744743Smarkm    (void) openlog(argv[0], LOG_PID);
6844743Smarkm#endif
6944743Smarkm
7044743Smarkm    /*
7144743Smarkm     * Find out the endpoint addresses of this conversation. Host name
7244743Smarkm     * lookups and double checks will be done on demand.
7344743Smarkm     */
7444743Smarkm
7544743Smarkm    request_init(&request, RQ_DAEMON, argv[0], RQ_FILE, STDIN_FILENO, 0);
7644743Smarkm    fromhost(&request);
7744743Smarkm
7844743Smarkm    /*
7944743Smarkm     * Optionally look up and double check the remote host name. Sites
8044743Smarkm     * concerned with security may choose to refuse connections from hosts
8144743Smarkm     * that pretend to have someone elses host name.
8244743Smarkm     */
8344743Smarkm
8444743Smarkm#ifdef PARANOID
8544743Smarkm    if (STR_EQ(eval_hostname(request.client), paranoid))
8644743Smarkm	refuse(&request);
8744743Smarkm#endif
8844743Smarkm
8944743Smarkm    /*
9044743Smarkm     * The BSD rlogin and rsh daemons that came out after 4.3 BSD disallow
9144743Smarkm     * socket options at the IP level. They do so for a good reason.
9244743Smarkm     * Unfortunately, we cannot use this with SunOS 4.1.x because the
9344743Smarkm     * getsockopt() system call can panic the system.
9444743Smarkm     */
9544743Smarkm
9644743Smarkm#ifdef KILL_IP_OPTIONS
9744743Smarkm    fix_options(&request);
9844743Smarkm#endif
9944743Smarkm
10044743Smarkm    /*
10144743Smarkm     * Check whether this host can access the service in argv[0]. The
10244743Smarkm     * access-control code invokes optional shell commands as specified in
10344743Smarkm     * the access-control tables.
10444743Smarkm     */
10544743Smarkm
10644743Smarkm#ifdef HOSTS_ACCESS
10744743Smarkm    if (!hosts_access(&request))
10844743Smarkm	refuse(&request);
10944743Smarkm#endif
11044743Smarkm
11144743Smarkm    /* Report request and invoke the real daemon program. */
11244743Smarkm
11344743Smarkm    syslog(allow_severity, "connect from %s", eval_client(&request));
11444743Smarkm    sprintf(path, "%s/miscd", REAL_DAEMON_DIR);
11544743Smarkm    closelog();
11644743Smarkm    (void) execv(path, argv);
11744743Smarkm    syslog(LOG_ERR, "error: cannot execute %s: %m", path);
11844743Smarkm    clean_exit(&request);
11944743Smarkm    /* NOTREACHED */
12044743Smarkm}
121