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 | } |
---|