Package: openbsd-inetd / 0.20160825-4

misc_portability Patch series | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
--- a/inetd.8
+++ b/inetd.8
@@ -42,11 +42,7 @@
 .Op Ar configuration_file
 .Sh DESCRIPTION
 .Nm inetd
-should be run at boot time by
-.Pa /etc/rc
-(see
-.Xr rc 8 ) .
-It then listens for connections on certain internet sockets.
+listens for connections on certain internet sockets.
 When a connection is found on one
 of its sockets, it decides what service the socket
 corresponds to, and invokes a program to service the request.
@@ -149,7 +145,8 @@ The
 .Em service name
 entry is the name of a valid service in
 the file
-.Pa /etc/services .
+.Pa /etc/services
+or a port number.
 For
 .Dq internal
 services (discussed below), the service
@@ -166,7 +163,7 @@ The part on the right of the
 is the RPC version number.
 This can simply be a single numeric argument or a range of versions.
 A range is bounded by the low version to the high version -
-.Dq rusers/1-3 .
+.Dq rusers/1\-3 .
 For
 .Ux Ns -domain
 sockets this field specifies the path name of the socket.
@@ -186,7 +183,8 @@ reliably delivered message, or sequenced
 The
 .Em protocol
 must be a valid protocol as given in
-.Pa /etc/protocols .
+.Pa /etc/protocols or
+.Dq unix .
 Examples might be
 .Dq tcp
 or
@@ -364,9 +362,7 @@ If you have only one server on
 only IPv6 traffic will be routed to the server.
 .El
 .Sh SEE ALSO
-.Xr comsat 8 ,
 .Xr fingerd 8 ,
-.Xr ftp-proxy 8 ,
 .Xr ftpd 8 ,
 .Xr identd 8 ,
 .Xr talkd 8
@@ -379,7 +375,23 @@ Support for Sun-RPC
 based services is modelled after that
 provided by SunOS 4.1.
 IPv6 support was added by the KAME project in 1999.
+.Pp
+Marco d'Itri ported this code from OpenBSD in summer 2002 and added
+socket buffers tuning and libwrap support from the NetBSD source tree.
 .Sh BUGS
+On Linux systems, the daemon cannot reload its configuration and needs
+to be restarted when the host address for a service is changed between
+.Dq \&*
+and a specific address.
+.Pp
+Server programs used with
+.Dq dgram
+.Dq udp
+.Dq nowait
+must read from the network socket, or
+.Nm inetd
+will spawn processes until the maximum is reached.
+.Pp
 Host address specifiers, while they make conceptual sense for RPC
 services, do not work entirely correctly.
 This is largely because the
--- a/inetd.c
+++ b/inetd.c
@@ -127,6 +127,7 @@
 #include <sys/un.h>
 #include <sys/file.h>
 #include <sys/wait.h>
+#include <time.h>
 #include <sys/time.h>
 #include <sys/resource.h>
 
@@ -147,14 +148,21 @@
 #include <unistd.h>
 #include <limits.h>
 #include <string.h>
+#ifdef HAVE_SETUSERCONTEXT
 #include <login_cap.h>
+#endif
+#ifdef HAVE_GETIFADDRS
 #include <ifaddrs.h>
+#endif
 #include <rpc/rpc.h>
 #include <rpc/pmap_clnt.h>
-#include <rpcsvc/nfs_prot.h>
 #include <event.h>
 #include "pathnames.h"
 
+#ifndef HAVE_PLEDGE
+#define pledge(a, b) (0)
+#endif
+
 #define MINIMUM(a, b)	(((a) < (b)) ? (a) : (b))
 
 #define	TOOMANY		256		/* don't start more than TOOMANY */
@@ -342,8 +350,10 @@ main(int argc, char *argv[])
 	umask(022);
 	if (debug == 0) {
 		daemon(0, 0);
+#ifdef HAVE_SETLOGIN
 		if (uid == 0)
 			(void) setlogin("");
+#endif
 	}
 
 	if (pledge("stdio rpath cpath getpw dns inet unix proc exec id", NULL) == -1)
@@ -384,6 +394,15 @@ main(int argc, char *argv[])
 
 	signal(SIGPIPE, SIG_IGN);
 
+	/* space for daemons to overwrite environment for ps */
+	{
+#define DUMMYSIZE 100
+		char dummy[DUMMYSIZE];
+		memset(dummy, 'x', DUMMYSIZE - 1);
+		dummy[DUMMYSIZE - 1] = '\0';
+		setenv("inetd_dummy", dummy, 1);
+	}
+
 	event_dispatch();
 
 	return (0);
@@ -476,9 +495,6 @@ dg_badinput(struct sockaddr *sa)
 		goto bad;
 	}
 
-	if (port < IPPORT_RESERVED || port == NFS_PORT)
-		goto bad;
-
 	return (0);
 
 bad:
@@ -488,6 +504,7 @@ bad:
 int
 dg_broadcast(struct in_addr *in)
 {
+#ifdef HAVE_GETIFADDRS
 	struct ifaddrs *ifa, *ifap;
 	struct sockaddr_in *sin;
 
@@ -504,6 +521,7 @@ dg_broadcast(struct in_addr *in)
 		}
 	}
 	freeifaddrs(ifap);
+#endif
 	return (0);
 }
 
@@ -1690,7 +1708,7 @@ print_service(char *action, struct servt
 	fprintf(stderr,
 	    " wait.max=%d.%d user:group=%s:%s builtin=%lx server=%s\n",
 	    sep->se_wait, sep->se_max, sep->se_user,
-	    sep->se_group ? sep->se_group : "wheel",
+	    sep->se_group ? sep->se_group : "(default)",
 	    (long)sep->se_bi, sep->se_server);
 }
 
@@ -1799,6 +1817,7 @@ spawn(int ctrl, short events, void *xsep
 				if (uid != pwd->pw_uid)
 					exit(1);
 			} else {
+#ifdef HAVE_SETUSERCONTEXT
 				tmpint = LOGIN_SETALL &
 				    ~(LOGIN_SETGROUP|LOGIN_SETLOGIN);
 				if (pwd->pw_uid)
@@ -1814,6 +1833,53 @@ spawn(int ctrl, short events, void *xsep
 					    sep->se_service, sep->se_proto);
 					exit(1);
 				}
+#else
+				/* what about setpriority(2), setrlimit(2),
+				 * and umask(2)? The $PATH is cleared.
+				 */
+				if (pwd->pw_uid) {
+				    if (sep->se_group)
+					pwd->pw_gid = grp->gr_gid;
+				    if (setgid(pwd->pw_gid) < 0) {
+					syslog(LOG_ERR,
+					    "%s/%s: can't set gid %d: %m",
+					    sep->se_service, sep->se_proto,
+					    pwd->pw_gid);
+					exit(1);
+				    }
+				    if (initgroups(pwd->pw_name, pwd->pw_gid)
+					    < 0) {
+					syslog(LOG_ERR,
+					    "%s/%s: can't initgroups(%s): %m",
+					    sep->se_service, sep->se_proto,
+					    pwd->pw_name);
+					exit(1);
+				    }
+				    if (setuid(pwd->pw_uid) < 0) {
+					syslog(LOG_ERR,
+						"%s/%s: can't set uid %d: %m",
+						sep->se_service, sep->se_proto,
+						pwd->pw_uid);
+					exit(1);
+				    }
+				} else if (sep->se_group) {
+				    if (setgid(pwd->pw_gid) < 0) {
+					syslog(LOG_ERR,
+					    "%s/%s: can't set gid %d: %m",
+					    sep->se_service, sep->se_proto,
+					    pwd->pw_gid);
+					exit(1);
+				    }
+				    if (initgroups(pwd->pw_name, pwd->pw_gid)
+					    < 0) {
+					syslog(LOG_ERR,
+					    "%s/%s: can't initgroups(%s): %m",
+					    sep->se_service, sep->se_proto,
+					    pwd->pw_name);
+					exit(1);
+				    }
+				}
+#endif
 			}
 			if (debug)
 				fprintf(stderr, "%ld execv %s\n",