[11716] | 1 | /* |
---|
| 2 | * General front end for stream and datagram IP services. This program logs |
---|
| 3 | * the remote host name and then invokes the real daemon. For example, |
---|
| 4 | * install as /usr/etc/{tftpd,fingerd,telnetd,ftpd,rlogind,rshd,rexecd}, |
---|
| 5 | * after saving the real daemons in the directory specified with the |
---|
| 6 | * REAL_DAEMON_DIR macro. This arrangement requires that the network daemons |
---|
| 7 | * are started by inetd or something similar. Connections and diagnostics |
---|
| 8 | * are logged through syslog(3). |
---|
| 9 | * |
---|
| 10 | * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands. |
---|
| 11 | */ |
---|
| 12 | |
---|
| 13 | #ifndef lint |
---|
| 14 | static char sccsid[] = "@(#) tcpd.c 1.10 96/02/11 17:01:32"; |
---|
| 15 | #endif |
---|
| 16 | |
---|
| 17 | /* System libraries. */ |
---|
| 18 | |
---|
| 19 | #include <sys/types.h> |
---|
| 20 | #include <sys/param.h> |
---|
| 21 | #include <sys/stat.h> |
---|
| 22 | #include <sys/socket.h> |
---|
| 23 | #include <netinet/in.h> |
---|
| 24 | #include <stdio.h> |
---|
| 25 | #include <syslog.h> |
---|
| 26 | #include <string.h> |
---|
| 27 | |
---|
| 28 | #ifndef MAXPATHNAMELEN |
---|
| 29 | #define MAXPATHNAMELEN BUFSIZ |
---|
| 30 | #endif |
---|
| 31 | |
---|
| 32 | #ifndef STDIN_FILENO |
---|
| 33 | #define STDIN_FILENO 0 |
---|
| 34 | #endif |
---|
| 35 | |
---|
| 36 | /* Local stuff. */ |
---|
| 37 | |
---|
| 38 | #include "patchlevel.h" |
---|
| 39 | #include "tcpd.h" |
---|
| 40 | |
---|
| 41 | int allow_severity = SEVERITY; /* run-time adjustable */ |
---|
| 42 | int deny_severity = LOG_WARNING; /* ditto */ |
---|
| 43 | |
---|
| 44 | main(argc, argv) |
---|
| 45 | int argc; |
---|
| 46 | char **argv; |
---|
| 47 | { |
---|
| 48 | struct request_info request; |
---|
| 49 | char path[MAXPATHNAMELEN]; |
---|
| 50 | |
---|
| 51 | /* Attempt to prevent the creation of world-writable files. */ |
---|
| 52 | |
---|
| 53 | #ifdef DAEMON_UMASK |
---|
| 54 | umask(DAEMON_UMASK); |
---|
| 55 | #endif |
---|
| 56 | |
---|
| 57 | /* |
---|
| 58 | * If argv[0] is an absolute path name, ignore REAL_DAEMON_DIR, and strip |
---|
| 59 | * argv[0] to its basename. |
---|
| 60 | */ |
---|
| 61 | |
---|
| 62 | if (argv[0][0] == '/') { |
---|
| 63 | strcpy(path, argv[0]); |
---|
| 64 | argv[0] = strrchr(argv[0], '/') + 1; |
---|
| 65 | } else { |
---|
| 66 | sprintf(path, "%s/%s", REAL_DAEMON_DIR, argv[0]); |
---|
| 67 | } |
---|
| 68 | |
---|
| 69 | /* |
---|
| 70 | * Open a channel to the syslog daemon. Older versions of openlog() |
---|
| 71 | * require only two arguments. |
---|
| 72 | */ |
---|
| 73 | |
---|
| 74 | #ifdef LOG_MAIL |
---|
| 75 | (void) openlog(argv[0], LOG_PID, FACILITY); |
---|
| 76 | #else |
---|
| 77 | (void) openlog(argv[0], LOG_PID); |
---|
| 78 | #endif |
---|
| 79 | |
---|
| 80 | /* |
---|
| 81 | * Find out the endpoint addresses of this conversation. Host name |
---|
| 82 | * lookups and double checks will be done on demand. |
---|
| 83 | */ |
---|
| 84 | |
---|
| 85 | request_init(&request, RQ_DAEMON, argv[0], RQ_FILE, STDIN_FILENO, 0); |
---|
| 86 | fromhost(&request); |
---|
| 87 | |
---|
| 88 | /* |
---|
| 89 | * Optionally look up and double check the remote host name. Sites |
---|
| 90 | * concerned with security may choose to refuse connections from hosts |
---|
| 91 | * that pretend to have someone elses host name. |
---|
| 92 | */ |
---|
| 93 | |
---|
| 94 | #ifdef PARANOID |
---|
| 95 | if (STR_EQ(eval_hostname(request.client), paranoid)) |
---|
| 96 | refuse(&request); |
---|
| 97 | #endif |
---|
| 98 | |
---|
| 99 | /* |
---|
| 100 | * The BSD rlogin and rsh daemons that came out after 4.3 BSD disallow |
---|
| 101 | * socket options at the IP level. They do so for a good reason. |
---|
| 102 | * Unfortunately, we cannot use this with SunOS 4.1.x because the |
---|
| 103 | * getsockopt() system call can panic the system. |
---|
| 104 | */ |
---|
| 105 | |
---|
| 106 | #ifdef KILL_IP_OPTIONS |
---|
| 107 | fix_options(&request); |
---|
| 108 | #endif |
---|
| 109 | |
---|
| 110 | /* |
---|
| 111 | * Check whether this host can access the service in argv[0]. The |
---|
| 112 | * access-control code invokes optional shell commands as specified in |
---|
| 113 | * the access-control tables. |
---|
| 114 | */ |
---|
| 115 | |
---|
| 116 | #ifdef HOSTS_ACCESS |
---|
| 117 | if (!hosts_access(&request)) |
---|
| 118 | refuse(&request); |
---|
| 119 | #endif |
---|
| 120 | |
---|
| 121 | /* Report request and invoke the real daemon program. */ |
---|
| 122 | |
---|
| 123 | syslog(allow_severity, "connect from %s", eval_client(&request)); |
---|
| 124 | closelog(); |
---|
| 125 | (void) execv(path, argv); |
---|
| 126 | syslog(LOG_ERR, "error: cannot execute %s: %m", path); |
---|
| 127 | clean_exit(&request); |
---|
| 128 | /* NOTREACHED */ |
---|
| 129 | } |
---|