bootparamd.c revision 1.1 1 1.1 deraadt /*
2 1.1 deraadt * This code is not copyright, and is placed in the public domain.
3 1.1 deraadt * Feel free to use and modify. Please send modifications and/or
4 1.1 deraadt * suggestions + bug fixes to Klas Heggemann <klas (at) nada.kth.se>
5 1.1 deraadt *
6 1.1 deraadt * Various small changes by Theo de Raadt <deraadt (at) fsa.ca>
7 1.1 deraadt *
8 1.1 deraadt * $Id: bootparamd.c,v 1.1 1994/01/08 13:22:04 deraadt Exp $
9 1.1 deraadt */
10 1.1 deraadt
11 1.1 deraadt #include <sys/types.h>
12 1.1 deraadt #include <sys/ioctl.h>
13 1.1 deraadt #include <sys/stat.h>
14 1.1 deraadt #include <sys/socket.h>
15 1.1 deraadt #include <rpc/rpc.h>
16 1.1 deraadt #include <rpcsvc/bootparam_prot.h>
17 1.1 deraadt #include <stdio.h>
18 1.1 deraadt #include <netdb.h>
19 1.1 deraadt #include <ctype.h>
20 1.1 deraadt #include <syslog.h>
21 1.1 deraadt
22 1.1 deraadt #define MAXLEN 800
23 1.1 deraadt
24 1.1 deraadt struct hostent *he;
25 1.1 deraadt static char buffer[MAXLEN];
26 1.1 deraadt static char hostname[MAX_MACHINE_NAME];
27 1.1 deraadt static char askname[MAX_MACHINE_NAME];
28 1.1 deraadt static char path[MAX_PATH_LEN];
29 1.1 deraadt static char domain_name[MAX_MACHINE_NAME];
30 1.1 deraadt
31 1.1 deraadt extern void bootparamprog_1();
32 1.1 deraadt
33 1.1 deraadt int debug = 0;
34 1.1 deraadt int dolog = 0;
35 1.1 deraadt unsigned long route_addr, inet_addr();
36 1.1 deraadt struct sockaddr_in my_addr;
37 1.1 deraadt char *progname;
38 1.1 deraadt char *bootpfile = "/etc/bootparams";
39 1.1 deraadt
40 1.1 deraadt extern char *optarg;
41 1.1 deraadt extern int optind;
42 1.1 deraadt
43 1.1 deraadt void
44 1.1 deraadt usage()
45 1.1 deraadt {
46 1.1 deraadt fprintf(stderr,
47 1.1 deraadt "usage: rpc.bootparamd [-d] [-s] [-r router] [-f bootparmsfile]\n");
48 1.1 deraadt }
49 1.1 deraadt
50 1.1 deraadt
51 1.1 deraadt /*
52 1.1 deraadt * ever familiar
53 1.1 deraadt */
54 1.1 deraadt int
55 1.1 deraadt main(argc, argv)
56 1.1 deraadt int argc;
57 1.1 deraadt char **argv;
58 1.1 deraadt {
59 1.1 deraadt SVCXPRT *transp;
60 1.1 deraadt int i, s, pid;
61 1.1 deraadt char *rindex();
62 1.1 deraadt struct hostent *he;
63 1.1 deraadt struct stat buf;
64 1.1 deraadt char *optstring;
65 1.1 deraadt char c;
66 1.1 deraadt
67 1.1 deraadt progname = rindex(argv[0], '/');
68 1.1 deraadt if (progname)
69 1.1 deraadt progname++;
70 1.1 deraadt else
71 1.1 deraadt progname = argv[0];
72 1.1 deraadt
73 1.1 deraadt while ((c = getopt(argc, argv, "dsr:f:")) != EOF)
74 1.1 deraadt switch (c) {
75 1.1 deraadt case 'd':
76 1.1 deraadt debug = 1;
77 1.1 deraadt break;
78 1.1 deraadt case 'r':
79 1.1 deraadt if (isdigit(*optarg)) {
80 1.1 deraadt route_addr = inet_addr(optarg);
81 1.1 deraadt break;
82 1.1 deraadt }
83 1.1 deraadt he = gethostbyname(optarg);
84 1.1 deraadt if (!he) {
85 1.1 deraadt fprintf(stderr, "%s: No such host %s\n",
86 1.1 deraadt progname, optarg);
87 1.1 deraadt usage();
88 1.1 deraadt exit(1);
89 1.1 deraadt }
90 1.1 deraadt bcopy(he->h_addr, (char *) &route_addr, sizeof(route_addr));
91 1.1 deraadt break;
92 1.1 deraadt case 'f':
93 1.1 deraadt bootpfile = optarg;
94 1.1 deraadt break;
95 1.1 deraadt case 's':
96 1.1 deraadt dolog = 1;
97 1.1 deraadt #ifndef LOG_DAEMON
98 1.1 deraadt openlog(progname, 0, 0);
99 1.1 deraadt #else
100 1.1 deraadt openlog(progname, 0, LOG_DAEMON);
101 1.1 deraadt setlogmask(LOG_UPTO(LOG_NOTICE));
102 1.1 deraadt #endif
103 1.1 deraadt break;
104 1.1 deraadt default:
105 1.1 deraadt usage();
106 1.1 deraadt exit(1);
107 1.1 deraadt }
108 1.1 deraadt
109 1.1 deraadt if (stat(bootpfile, &buf)) {
110 1.1 deraadt fprintf(stderr, "%s: ", progname);
111 1.1 deraadt perror(bootpfile);
112 1.1 deraadt exit(1);
113 1.1 deraadt }
114 1.1 deraadt if (!route_addr) {
115 1.1 deraadt get_myaddress(&my_addr);
116 1.1 deraadt bcopy(&my_addr.sin_addr.s_addr, &route_addr, sizeof(route_addr));
117 1.1 deraadt }
118 1.1 deraadt if (!debug)
119 1.1 deraadt daemon();
120 1.1 deraadt
121 1.1 deraadt (void) pmap_unset(BOOTPARAMPROG, BOOTPARAMVERS);
122 1.1 deraadt
123 1.1 deraadt transp = svcudp_create(RPC_ANYSOCK);
124 1.1 deraadt if (transp == NULL) {
125 1.1 deraadt fprintf(stderr, "cannot create udp service.\n");
126 1.1 deraadt exit(1);
127 1.1 deraadt }
128 1.1 deraadt if (!svc_register(transp, BOOTPARAMPROG, BOOTPARAMVERS,
129 1.1 deraadt bootparamprog_1, IPPROTO_UDP)) {
130 1.1 deraadt fprintf(stderr,
131 1.1 deraadt "bootparamd: unable to register BOOTPARAMPROG version %d, udp)\n",
132 1.1 deraadt BOOTPARAMVERS);
133 1.1 deraadt exit(1);
134 1.1 deraadt }
135 1.1 deraadt svc_run();
136 1.1 deraadt fprintf(stderr, "svc_run returned\n");
137 1.1 deraadt exit(1);
138 1.1 deraadt }
139 1.1 deraadt
140 1.1 deraadt bp_whoami_res *
141 1.1 deraadt bootparamproc_whoami_1(whoami)
142 1.1 deraadt bp_whoami_arg *whoami;
143 1.1 deraadt {
144 1.1 deraadt long haddr;
145 1.1 deraadt static bp_whoami_res res;
146 1.1 deraadt if (debug)
147 1.1 deraadt fprintf(stderr, "whoami got question for %d.%d.%d.%d\n",
148 1.1 deraadt 255 & whoami->client_address.bp_address_u.ip_addr.net,
149 1.1 deraadt 255 & whoami->client_address.bp_address_u.ip_addr.host,
150 1.1 deraadt 255 & whoami->client_address.bp_address_u.ip_addr.lh,
151 1.1 deraadt 255 & whoami->client_address.bp_address_u.ip_addr.impno);
152 1.1 deraadt if (dolog)
153 1.1 deraadt syslog(LOG_NOTICE, "whoami got question for %d.%d.%d.%d\n",
154 1.1 deraadt 255 & whoami->client_address.bp_address_u.ip_addr.net,
155 1.1 deraadt 255 & whoami->client_address.bp_address_u.ip_addr.host,
156 1.1 deraadt 255 & whoami->client_address.bp_address_u.ip_addr.lh,
157 1.1 deraadt 255 & whoami->client_address.bp_address_u.ip_addr.impno);
158 1.1 deraadt
159 1.1 deraadt bcopy((char *) &whoami->client_address.bp_address_u.ip_addr, (char *) &haddr,
160 1.1 deraadt sizeof(haddr));
161 1.1 deraadt he = gethostbyaddr((char *) &haddr, sizeof(haddr), AF_INET);
162 1.1 deraadt if (!he)
163 1.1 deraadt goto failed;
164 1.1 deraadt
165 1.1 deraadt if (debug)
166 1.1 deraadt fprintf(stderr, "This is host %s\n", he->h_name);
167 1.1 deraadt if (dolog)
168 1.1 deraadt syslog(LOG_NOTICE, "This is host %s\n", he->h_name);
169 1.1 deraadt
170 1.1 deraadt strcpy(askname, he->h_name);
171 1.1 deraadt if (checkhost(askname, hostname)) {
172 1.1 deraadt res.client_name = hostname;
173 1.1 deraadt getdomainname(domain_name, MAX_MACHINE_NAME);
174 1.1 deraadt res.domain_name = domain_name;
175 1.1 deraadt
176 1.1 deraadt if (res.router_address.address_type != IP_ADDR_TYPE) {
177 1.1 deraadt res.router_address.address_type = IP_ADDR_TYPE;
178 1.1 deraadt bcopy(&route_addr, &res.router_address.bp_address_u.ip_addr, 4);
179 1.1 deraadt }
180 1.1 deraadt if (debug)
181 1.1 deraadt fprintf(stderr, "Returning %s %s %d.%d.%d.%d\n",
182 1.1 deraadt res.client_name, res.domain_name,
183 1.1 deraadt 255 & res.router_address.bp_address_u.ip_addr.net,
184 1.1 deraadt 255 & res.router_address.bp_address_u.ip_addr.host,
185 1.1 deraadt 255 & res.router_address.bp_address_u.ip_addr.lh,
186 1.1 deraadt 255 & res.router_address.bp_address_u.ip_addr.impno);
187 1.1 deraadt if (dolog)
188 1.1 deraadt syslog(LOG_NOTICE, "Returning %s %s %d.%d.%d.%d\n",
189 1.1 deraadt res.client_name, res.domain_name,
190 1.1 deraadt 255 & res.router_address.bp_address_u.ip_addr.net,
191 1.1 deraadt 255 & res.router_address.bp_address_u.ip_addr.host,
192 1.1 deraadt 255 & res.router_address.bp_address_u.ip_addr.lh,
193 1.1 deraadt 255 & res.router_address.bp_address_u.ip_addr.impno);
194 1.1 deraadt
195 1.1 deraadt return (&res);
196 1.1 deraadt }
197 1.1 deraadt failed:
198 1.1 deraadt if (debug)
199 1.1 deraadt fprintf(stderr, "whoami failed\n");
200 1.1 deraadt if (dolog)
201 1.1 deraadt syslog(LOG_NOTICE, "whoami failed\n");
202 1.1 deraadt return (NULL);
203 1.1 deraadt }
204 1.1 deraadt
205 1.1 deraadt
206 1.1 deraadt bp_getfile_res *
207 1.1 deraadt bootparamproc_getfile_1(getfile)
208 1.1 deraadt bp_getfile_arg *getfile;
209 1.1 deraadt {
210 1.1 deraadt char *where, *index();
211 1.1 deraadt static bp_getfile_res res;
212 1.1 deraadt
213 1.1 deraadt if (debug)
214 1.1 deraadt fprintf(stderr, "getfile got question for \"%s\" and file \"%s\"\n",
215 1.1 deraadt getfile->client_name, getfile->file_id);
216 1.1 deraadt
217 1.1 deraadt if (dolog)
218 1.1 deraadt syslog(LOG_NOTICE, "getfile got question for \"%s\" and file \"%s\"\n",
219 1.1 deraadt getfile->client_name, getfile->file_id);
220 1.1 deraadt
221 1.1 deraadt he = NULL;
222 1.1 deraadt he = gethostbyname(getfile->client_name);
223 1.1 deraadt if (!he)
224 1.1 deraadt goto failed;
225 1.1 deraadt
226 1.1 deraadt strcpy(askname, he->h_name);
227 1.1 deraadt if (getthefile(askname, getfile->file_id, buffer)) {
228 1.1 deraadt if (where = index(buffer, ':')) {
229 1.1 deraadt /* buffer is re-written to contain the name of the
230 1.1 deraadt * info of file */
231 1.1 deraadt strncpy(hostname, buffer, where - buffer);
232 1.1 deraadt hostname[where - buffer] = '\0';
233 1.1 deraadt where++;
234 1.1 deraadt strcpy(path, where);
235 1.1 deraadt he = gethostbyname(hostname);
236 1.1 deraadt if (!he)
237 1.1 deraadt goto failed;
238 1.1 deraadt bcopy(he->h_addr, &res.server_address.bp_address_u.ip_addr, 4);
239 1.1 deraadt res.server_name = hostname;
240 1.1 deraadt res.server_path = path;
241 1.1 deraadt res.server_address.address_type = IP_ADDR_TYPE;
242 1.1 deraadt } else { /* special for dump, answer with null strings */
243 1.1 deraadt if (!strcmp(getfile->file_id, "dump")) {
244 1.1 deraadt res.server_name[0] = '\0';
245 1.1 deraadt res.server_path[0] = '\0';
246 1.1 deraadt bzero(&res.server_address.bp_address_u.ip_addr, 4);
247 1.1 deraadt } else
248 1.1 deraadt goto failed;
249 1.1 deraadt }
250 1.1 deraadt if (debug)
251 1.1 deraadt fprintf(stderr,
252 1.1 deraadt "returning server:%s path:%s address: %d.%d.%d.%d\n",
253 1.1 deraadt res.server_name, res.server_path,
254 1.1 deraadt 255 & res.server_address.bp_address_u.ip_addr.net,
255 1.1 deraadt 255 & res.server_address.bp_address_u.ip_addr.host,
256 1.1 deraadt 255 & res.server_address.bp_address_u.ip_addr.lh,
257 1.1 deraadt 255 & res.server_address.bp_address_u.ip_addr.impno);
258 1.1 deraadt if (dolog)
259 1.1 deraadt syslog(LOG_NOTICE,
260 1.1 deraadt "returning server:%s path:%s address: %d.%d.%d.%d\n",
261 1.1 deraadt res.server_name, res.server_path,
262 1.1 deraadt 255 & res.server_address.bp_address_u.ip_addr.net,
263 1.1 deraadt 255 & res.server_address.bp_address_u.ip_addr.host,
264 1.1 deraadt 255 & res.server_address.bp_address_u.ip_addr.lh,
265 1.1 deraadt 255 & res.server_address.bp_address_u.ip_addr.impno);
266 1.1 deraadt return (&res);
267 1.1 deraadt }
268 1.1 deraadt failed:
269 1.1 deraadt if (debug)
270 1.1 deraadt fprintf(stderr, "getfile failed for %s\n", getfile->client_name);
271 1.1 deraadt if (dolog)
272 1.1 deraadt syslog(LOG_NOTICE,
273 1.1 deraadt "getfile failed for %s\n", getfile->client_name);
274 1.1 deraadt return (NULL);
275 1.1 deraadt }
276 1.1 deraadt
277 1.1 deraadt
278 1.1 deraadt /*
279 1.1 deraadt * getthefile return 1 and fills the buffer with the information
280 1.1 deraadt * of the file, e g "host:/export/root/client" if it can be found.
281 1.1 deraadt * If the host is in the database, but the file is not, the buffer
282 1.1 deraadt * will be empty. (This makes it possible to give the special
283 1.1 deraadt * empty answer for the file "dump")
284 1.1 deraadt */
285 1.1 deraadt getthefile(askname, fileid, buffer)
286 1.1 deraadt char *askname;
287 1.1 deraadt char *fileid, *buffer;
288 1.1 deraadt {
289 1.1 deraadt FILE *bpf;
290 1.1 deraadt char *where;
291 1.1 deraadt
292 1.1 deraadt int ch, pch, fid_len, res = 0;
293 1.1 deraadt int match = 0;
294 1.1 deraadt char info[MAX_FILEID + MAX_PATH_LEN + MAX_MACHINE_NAME + 3];
295 1.1 deraadt
296 1.1 deraadt bpf = fopen(bootpfile, "r");
297 1.1 deraadt if (!bpf) {
298 1.1 deraadt fprintf(stderr, "No %s\n", bootpfile);
299 1.1 deraadt exit(1);
300 1.1 deraadt }
301 1.1 deraadt while (fscanf(bpf, "%s", hostname) > 0 && !match) {
302 1.1 deraadt if (*hostname != '#') { /* comment */
303 1.1 deraadt if (!strcmp(hostname, askname)) {
304 1.1 deraadt match = 1;
305 1.1 deraadt } else {
306 1.1 deraadt he = gethostbyname(hostname);
307 1.1 deraadt if (he && !strcmp(he->h_name, askname))
308 1.1 deraadt match = 1;
309 1.1 deraadt }
310 1.1 deraadt }
311 1.1 deraadt /* skip to next entry */
312 1.1 deraadt if (match)
313 1.1 deraadt break;
314 1.1 deraadt pch = ch = getc(bpf);
315 1.1 deraadt while (!(ch == '\n' && pch != '\\') && ch != EOF) {
316 1.1 deraadt pch = ch;
317 1.1 deraadt ch = getc(bpf);
318 1.1 deraadt }
319 1.1 deraadt }
320 1.1 deraadt
321 1.1 deraadt /* if match is true we read the rest of the line to get the info of
322 1.1 deraadt * the file */
323 1.1 deraadt
324 1.1 deraadt if (match) {
325 1.1 deraadt fid_len = strlen(fileid);
326 1.1 deraadt while (!res && (fscanf(bpf, "%s", info)) > 0) { /* read a string */
327 1.1 deraadt ch = getc(bpf); /* and a character */
328 1.1 deraadt if (*info != '#') { /* Comment ? */
329 1.1 deraadt if (!strncmp(info, fileid, fid_len) &&
330 1.1 deraadt *(info + fid_len) == '=') {
331 1.1 deraadt where = info + fid_len + 1;
332 1.1 deraadt if (isprint(*where)) {
333 1.1 deraadt strcpy(buffer, where);
334 1.1 deraadt res = 1;
335 1.1 deraadt break;
336 1.1 deraadt }
337 1.1 deraadt } else {
338 1.1 deraadt while (isspace(ch) && ch != '\n')
339 1.1 deraadt ch = getc(bpf);
340 1.1 deraadt if (ch == '\n') {
341 1.1 deraadt res = -1;
342 1.1 deraadt break;
343 1.1 deraadt }
344 1.1 deraadt if (ch == '\\') {
345 1.1 deraadt ch = getc(bpf);
346 1.1 deraadt if (ch == '\n')
347 1.1 deraadt continue;
348 1.1 deraadt ungetc(ch, bpf);
349 1.1 deraadt ungetc('\\', bpf);
350 1.1 deraadt } else
351 1.1 deraadt ungetc(ch, bpf);
352 1.1 deraadt }
353 1.1 deraadt } else
354 1.1 deraadt break;
355 1.1 deraadt }
356 1.1 deraadt }
357 1.1 deraadt if (fclose(bpf)) {
358 1.1 deraadt fprintf(stderr, "Could not close %s\n", bootpfile);
359 1.1 deraadt }
360 1.1 deraadt if (res == -1)
361 1.1 deraadt buffer[0] = '\0'; /* host found, file not */
362 1.1 deraadt return (match);
363 1.1 deraadt }
364 1.1 deraadt
365 1.1 deraadt
366 1.1 deraadt /*
367 1.1 deraadt * checkhost puts the hostname found in the database file in
368 1.1 deraadt * the hostname-variable and returns 1, if askname is a valid
369 1.1 deraadt * name for a host in the database
370 1.1 deraadt */
371 1.1 deraadt checkhost(askname, hostname)
372 1.1 deraadt char *askname;
373 1.1 deraadt char *hostname;
374 1.1 deraadt {
375 1.1 deraadt int ch, pch;
376 1.1 deraadt FILE *bpf;
377 1.1 deraadt int res = 0;
378 1.1 deraadt
379 1.1 deraadt bpf = fopen(bootpfile, "r");
380 1.1 deraadt if (!bpf) {
381 1.1 deraadt fprintf(stderr, "No %s\n", bootpfile);
382 1.1 deraadt exit(1);
383 1.1 deraadt }
384 1.1 deraadt while (fscanf(bpf, "%s", hostname) > 0) {
385 1.1 deraadt if (!strcmp(hostname, askname)) {
386 1.1 deraadt /* return true for match of hostname */
387 1.1 deraadt res = 1;
388 1.1 deraadt break;
389 1.1 deraadt } else {
390 1.1 deraadt /* check the alias list */
391 1.1 deraadt he = NULL;
392 1.1 deraadt he = gethostbyname(hostname);
393 1.1 deraadt if (he && !strcmp(askname, he->h_name)) {
394 1.1 deraadt res = 1;
395 1.1 deraadt break;
396 1.1 deraadt }
397 1.1 deraadt }
398 1.1 deraadt /* skip to next entry */
399 1.1 deraadt pch = ch = getc(bpf);
400 1.1 deraadt while (!(ch == '\n' && pch != '\\') && ch != EOF) {
401 1.1 deraadt pch = ch;
402 1.1 deraadt ch = getc(bpf);
403 1.1 deraadt }
404 1.1 deraadt }
405 1.1 deraadt fclose(bpf);
406 1.1 deraadt return (res);
407 1.1 deraadt }
408