chiark / gitweb /
yaid.8.in: Fix formatting.
[yaid] / yaid.c
1 /* -*-c-*-
2  *
3  * Main daemon
4  *
5  * (c) 2012 Straylight/Edgeware
6  */
7
8 /*----- Licensing notice --------------------------------------------------*
9  *
10  * This file is part of Yet Another Ident Daemon (YAID).
11  *
12  * YAID is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * YAID is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with YAID; if not, write to the Free Software Foundation,
24  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25  */
26
27 /*----- Header files ------------------------------------------------------*/
28
29 #include "yaid.h"
30
31 /*----- Data structures ---------------------------------------------------*/
32
33 /* A write buffer is the gadget which keeps track of our output and writes
34  * portions of it out as and when connections are ready for it.
35  */
36 #define WRBUFSZ 1024
37 struct writebuf {
38   size_t o;                             /* Offset of remaining data */
39   size_t n;                             /* Length of remaining data */
40   sel_file wr;                          /* Write selector */
41   void (*func)(int /*err*/, void *);    /* Function to call on completion */
42   void *p;                              /* Context for `func' */
43   unsigned char buf[WRBUFSZ];           /* Output buffer */
44 };
45
46 /* Structure for a listening socket.  There's one of these for each address
47  * family we're looking after.
48  */
49 struct listen {
50   const struct addrops *ao;             /* Address family operations */
51   sel_file f;                           /* Watch for incoming connections */
52 };
53
54 /* The main structure for a client. */
55 struct client {
56   int fd;                               /* The connection to the client */
57   selbuf b;                             /* Accumulate lines of input */
58   union addr raddr;                     /* Remote address */
59   struct query q;                       /* The clients query and our reply */
60   struct sel_timer t;                   /* Timeout for idle or doomed conn */
61   struct listen *l;                     /* Back to the listener (and ops) */
62   struct writebuf wb;                   /* Write buffer for our reply */
63   struct proxy *px;                     /* Proxy if conn goes via NAT */
64 };
65
66 /* A proxy connection. */
67 struct proxy {
68   int fd;                               /* Connection; -1 if in progress */
69   struct client *c;                     /* Back to the client */
70   conn cn;                              /* Nonblocking connection */
71   selbuf b;                             /* Accumulate the response line */
72   struct writebuf wb;                   /* Write buffer for query */
73   char nat[ADDRLEN];                    /* Server address, as text */
74 };
75
76 /*----- Static variables --------------------------------------------------*/
77
78 static sel_state sel;                   /* I/O multiplexer state */
79
80 static const char *pidfile = 0;         /* Where to write daemon's pid */
81
82 static const char *policyfile = POLICYFILE; /* Filename for global policy */
83 static const struct policy default_policy = POLICY_INIT(A_NAME);
84 static policy_v policy = DA_INIT;       /* Vector of global policy rules */
85 static fwatch polfw;                    /* Watch policy file for changes */
86
87 static unsigned char tokenbuf[4096];    /* Random-ish data for tokens */
88 static size_t tokenptr = sizeof(tokenbuf); /* Current read position */
89 static int randfd;                      /* File descriptor for random data */
90
91 static unsigned flags = 0;              /* Various interesting flags */
92 #define F_SYSLOG 1u                     /*   Use syslog for logging */
93 #define F_RUNNING 2u                    /*   Running properly now */
94
95 /*----- Ident protocol parsing --------------------------------------------*/
96
97 /* Advance *PP over whitespace characters. */
98 static void skipws(const char **pp)
99   { while (isspace((unsigned char )**pp)) (*pp)++; }
100
101 /* Copy a token of no more than N bytes starting at *PP into Q, advancing *PP
102  * over it.
103  */
104 static int idtoken(const char **pp, char *q, size_t n)
105 {
106   const char *p = *pp;
107
108   skipws(&p);
109   n--;
110   for (;;) {
111     if (*p == ':' || *p <= 32 || *p >= 127) break;
112     if (!n) return (-1);
113     *q++ = *p++;
114     n--;
115   }
116   *q++ = 0;
117   *pp = p;
118   return (0);
119 }
120
121 /* Read an unsigned decimal number from *PP, and store it in *II.  Check that
122  * it's between MIN and MAX, and advance *PP over it.  Return zero for
123  * success, or nonzero if something goes wrong.
124  */
125 static int unum(const char **pp, unsigned *ii, unsigned min, unsigned max)
126 {
127   char *q;
128   unsigned long i;
129   int e;
130
131   skipws(pp);
132   if (!isdigit((unsigned char)**pp)) return (-1);
133   e = errno; errno = 0;
134   i = strtoul(*pp, &q, 10);
135   if (errno) return (-1);
136   *pp = q;
137   errno = e;
138   if (i < min || i > max) return (-1);
139   *ii = i;
140   return (0);
141 }
142
143 /*----- Asynchronous writing ----------------------------------------------*/
144
145 /* Callback for actually writing stuff from a `writebuf'. */
146 static void write_out(int fd, unsigned mode, void *p)
147 {
148   ssize_t n;
149   struct writebuf *wb = p;
150
151   /* Try to write something. */
152   if ((n = write(fd, wb->buf + wb->o, wb->n)) < 0) {
153     if (errno == EAGAIN || errno == EWOULDBLOCK) return;
154     wb->n = 0;
155     sel_rmfile(&wb->wr);
156     wb->func(errno, wb->p);
157   }
158   wb->o += n;
159   wb->n -= n;
160
161   /* If there's nothing left then restore the buffer to its empty state. */
162   if (!wb->n) {
163     wb->o = 0;
164     sel_rmfile(&wb->wr);
165     wb->func(0, wb->p);
166   }
167 }
168
169 /* Queue N bytes starting at P to be written. */
170 static int queue_write(struct writebuf *wb, const void *p, size_t n)
171 {
172   /* Maybe there's nothing to actually do. */
173   if (!n) return (0);
174
175   /* Make sure it'll fit. */
176   if (wb->n - wb->o + n > WRBUFSZ) return (-1);
177
178   /* If there's anything there already, then make sure it's at the start of
179    * the available space.
180    */
181   if (wb->o) {
182     memmove(wb->buf, wb->buf + wb->o, wb->n);
183     wb->o = 0;
184   }
185
186   /* If there's nothing currently there, then we're not requesting write
187    * notifications, so set that up, and force an initial wake-up.
188    */
189   if (!wb->n) {
190     sel_addfile(&wb->wr);
191     sel_force(&wb->wr);
192   }
193
194   /* Copy the new material over. */
195   memcpy(wb->buf + wb->n, p, n);
196   wb->n += n;
197
198   /* Done. */
199   return (0);
200 }
201
202 /* Release resources allocated to WB. */
203 static void free_writebuf(struct writebuf *wb)
204   { if (wb->n) sel_rmfile(&wb->wr); }
205
206 /* Initialize a writebuf in *WB, writing to file descriptor FD.  On
207  * completion, call FUNC, passing it P and an error indicator: either 0 for
208  * success or an `errno' value on failure.
209  */
210 static void init_writebuf(struct writebuf *wb,
211                           int fd, void (*func)(int, void *), void *p)
212 {
213   sel_initfile(&sel, &wb->wr, fd, SEL_WRITE, write_out, wb);
214   wb->func = func;
215   wb->p = p;
216   wb->n = wb->o = 0;
217 }
218
219 /*----- General utilities -------------------------------------------------*/
220
221 /* Format and log MSG somewhere sensible, at the syslog(3) priority PRIO.
222  * Prefix it with a description of the query Q, if non-null.
223  */
224 void logmsg(const struct query *q, int prio, const char *msg, ...)
225 {
226   va_list ap;
227   dstr d = DSTR_INIT;
228   time_t t;
229   struct tm *tm;
230   char buf[64];
231
232   va_start(ap, msg);
233   if (q) {
234     dputsock(&d, q->ao, &q->s[L]);
235     dstr_puts(&d, " <-> ");
236     dputsock(&d, q->ao, &q->s[R]);
237     dstr_puts(&d, ": ");
238   }
239   dstr_vputf(&d, msg, &ap);
240   va_end(ap);
241
242   if (!(flags & F_RUNNING))
243     moan("%s", d.buf);
244   else if (flags & F_SYSLOG)
245     syslog(prio, "%s", d.buf);
246   else {
247     t = time(0);
248     tm = localtime(&t);
249     strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %z", tm);
250     fprintf(stderr, "%s %s: %s\n", buf, QUIS, d.buf);
251   }
252
253   dstr_destroy(&d);
254 }
255
256 /* Fix up a socket FD so that it won't bite us.  Returns zero on success, or
257  * nonzero on error.
258  */
259 static int fix_up_socket(int fd, const char *what)
260 {
261   int yes = 1;
262
263   if (fdflags(fd, O_NONBLOCK, O_NONBLOCK, 0, 0)) {
264     logmsg(0, LOG_ERR, "failed to set %s connection nonblocking: %s",
265            what, strerror(errno));
266     return (-1);
267   }
268
269   if (setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, &yes, sizeof(yes))) {
270     logmsg(0, LOG_ERR,
271            "failed to disable `out-of-band' data on %s connection: %s",
272            what, strerror(errno));
273     return (-1);
274   }
275
276   return (0);
277 }
278
279 /*----- Client output functions -------------------------------------------*/
280
281 static void disconnect_client(struct client *c);
282
283 /* Notification that output has been written.  If successful, re-enable the
284  * input buffer and prepare for another query.
285  */
286 static void done_client_write(int err, void *p)
287 {
288   struct client *c = p;
289
290   if (!err)
291     selbuf_enable(&c->b);
292   else {
293     logmsg(&c->q, LOG_ERR, "failed to send reply: %s", strerror(err));
294     disconnect_client(c);
295   }
296 }
297
298 /* Format the message FMT and queue it to be sent to the client.  Client
299  * input will be disabled until the write completes.
300  */
301 static void write_to_client(struct client *c, const char *fmt, ...)
302 {
303   va_list ap;
304   char buf[WRBUFSZ];
305   ssize_t n;
306
307   va_start(ap, fmt);
308   n = vsnprintf(buf, sizeof(buf), fmt, ap);
309   if (n < 0) {
310     logmsg(&c->q, LOG_ERR, "failed to format output: %s", strerror(errno));
311     disconnect_client(c);
312     return;
313   } else if (n > sizeof(buf)) {
314     logmsg(&c->q, LOG_ERR, "output too long for client send buffer");
315     disconnect_client(c);
316     return;
317   }
318
319   selbuf_disable(&c->b);
320   if (queue_write(&c->wb, buf, n)) {
321     logmsg(&c->q, LOG_ERR, "write buffer overflow");
322     disconnect_client(c);
323   }
324 }
325
326 /* Format a reply to the client, with the form LPORT:RPORT:TY:TOK0[:TOK1].
327  * Typically, TY will be `ERROR' or `USERID'.  In the former case, TOK0 will
328  * be the error token and TOK1 will be null; in the latter case, TOK0 will be
329  * the operating system and TOK1 the user name.
330  */
331 static void reply(struct client *c, const char *ty,
332                   const char *tok0, const char *tok1)
333 {
334   write_to_client(c, "%u,%u:%s:%s%s%s\r\n",
335                   c->q.s[L].port, c->q.s[R].port, ty,
336                   tok0, tok1 ? ":" : "", tok1 ? tok1 : "");
337 }
338
339 /* Mapping from error codes to their protocol tokens. */
340 const char *const errtok[] = {
341 #define DEFTOK(err, tok) tok,
342   ERROR(DEFTOK)
343 #undef DEFTOK
344 };
345
346 /* Report an error with code ERR to the client. */
347 static void reply_error(struct client *c, unsigned err)
348 {
349   assert(err < E_LIMIT);
350   reply(c, "ERROR", errtok[err], 0);
351 }
352
353 /*----- NAT proxy functions -----------------------------------------------*/
354
355 /* Cancel the proxy operation PX, closing the connection and releasing
356  * resources.  This is used for both normal and unexpected closures.
357  */
358 static void cancel_proxy(struct proxy *px)
359 {
360   if (px->fd == -1)
361     conn_kill(&px->cn);
362   else {
363     close(px->fd);
364     selbuf_destroy(&px->b);
365     free_writebuf(&px->wb);
366   }
367   selbuf_enable(&px->c->b);
368   px->c->px = 0;
369   xfree(px);
370 }
371
372 /* Notification that a line (presumably a reply) has been received from the
373  * server.  We should check it, log it, and propagate the answer back.
374  * Whatever happens, this proxy operation is now complete.
375  */
376 static void proxy_line(char *line, size_t sz, void *p)
377 {
378   struct proxy *px = p;
379   char buf[1024];
380   const char *q = line;
381   unsigned lp, rp;
382
383   /* Trim trailing space. */
384   while (sz && isspace((unsigned char)line[sz - 1])) sz--;
385
386   /* Parse the port numbers.  These should match the request. */
387   if (unum(&q, &lp, 1, 65535)) goto syntax;
388   skipws(&q); if (*q != ',') goto syntax; q++;
389   if (unum(&q, &rp, 1, 65535)) goto syntax;
390   skipws(&q); if (*q != ':') goto syntax; q++;
391   if (lp != px->c->q.u.nat.port || rp != px->c->q.s[R].port) goto syntax;
392
393   /* Find out what kind of reply this is. */
394   if (idtoken(&q, buf, sizeof(buf))) goto syntax;
395   skipws(&q); if (*q != ':') goto syntax; q++;
396
397   if (strcmp(buf, "ERROR") == 0) {
398
399     /* Report the error without interpreting it.  It might be meaningful to
400      * the client.
401      */
402     skipws(&q);
403     logmsg(&px->c->q, LOG_ERR, "proxy error from %s: %s", px->nat, q);
404     reply(px->c, "ERROR", q, 0);
405
406   } else if (strcmp(buf, "USERID") == 0) {
407
408     /* Parse out the operating system and user name, and pass them on. */
409     if (idtoken(&q, buf, sizeof(buf))) goto syntax;
410     skipws(&q); if (*q != ':') goto syntax; q++;
411     skipws(&q);
412     logmsg(&px->c->q, LOG_ERR, "user `%s'; proxy = %s, os = %s",
413            q, px->nat, buf);
414     reply(px->c, "USERID", buf, q);
415
416   } else
417     goto syntax;
418   goto done;
419
420 syntax:
421   /* We didn't understand the message from the client. */
422   logmsg(&px->c->q, LOG_ERR, "failed to parse response from %s", px->nat);
423   reply_error(px->c, E_UNKNOWN);
424 done:
425   /* All finished, no matter what. */
426   cancel_proxy(px);
427 }
428
429 /* Notification that we have written the query to the server.  Await a
430  * response if successful.
431  */
432 static void done_proxy_write(int err, void *p)
433 {
434   struct proxy *px = p;
435
436   if (err) {
437     logmsg(&px->c->q, LOG_ERR, "failed to proxy query to %s: %s",
438            px->nat, strerror(errno));
439     reply_error(px->c, E_UNKNOWN);
440     cancel_proxy(px);
441     return;
442   }
443   selbuf_enable(&px->b);
444 }
445
446 /* Notification that the connection to the server is either established or
447  * failed.  In the former case, queue the right query.
448  */
449 static void proxy_connected(int fd, void *p)
450 {
451   struct proxy *px = p;
452   char buf[16];
453   int n;
454
455   /* If the connection failed then report the problem and give up. */
456   if (fd < 0) {
457     logmsg(&px->c->q, LOG_ERR,
458            "failed to make %s proxy connection to %s: %s",
459            px->c->l->ao->name, px->nat, strerror(errno));
460     reply_error(px->c, E_UNKNOWN);
461     cancel_proxy(px);
462     return;
463   }
464
465   /* We're now ready to go, so set things up. */
466   px->fd = fd;
467   selbuf_init(&px->b, &sel, fd, proxy_line, px);
468   selbuf_setsize(&px->b, 1024);
469   selbuf_disable(&px->b);
470   init_writebuf(&px->wb, fd, done_proxy_write, px);
471
472   /* Write the query.  This buffer is large enough because we've already
473    * range-checked the remote the port number and the local one came from the
474    * kernel, which we trust not to do anything stupid.
475    */
476   n = sprintf(buf, "%u,%u\r\n", px->c->q.u.nat.port, px->c->q.s[R].port);
477   queue_write(&px->wb, buf, n);
478 }
479
480 /* Proxy the query through to a client machine for which we're providing NAT
481  * disservice.
482  */
483 static void proxy_query(struct client *c)
484 {
485   struct socket s;
486   struct sockaddr_storage ss;
487   size_t ssz;
488   struct proxy *px;
489   int fd;
490
491   /* Allocate the context structure for the NAT. */
492   px = xmalloc(sizeof(*px));
493
494   /* We'll use the client host's address in lots of log messages, so we may
495    * as well format it once and use it over and over.
496    */
497   inet_ntop(c->q.ao->af, &c->q.u.nat.addr, px->nat, sizeof(px->nat));
498
499   /* Create the socket for the connection. */
500   if ((fd = socket(c->q.ao->af, SOCK_STREAM, 0)) < 0) {
501     logmsg(&c->q, LOG_ERR, "failed to make %s socket for proxy: %s",
502            c->l->ao->name, strerror(errno));
503     goto err_0;
504   }
505   if (fix_up_socket(fd, "proxy")) goto err_1;
506
507   /* Set up the connection to the client host.  The connection interface is a
508    * bit broken: if the connection completes immediately, then the callback
509    * function is called synchronously, and that might decide to shut
510    * everything down.  So we must have fully initialized our context before
511    * calling `conn_init', and mustn't touch it again afterwards -- since the
512    * block may have been freed.
513    */
514   s = c->q.u.nat;
515   s.port = 113;
516   c->l->ao->socket_to_sockaddr(&s, &ss, &ssz);
517   selbuf_disable(&c->b);
518   c->px = px; px->c = c;
519   px->fd = -1;
520   if (conn_init(&px->cn, &sel, fd, (struct sockaddr *)&ss, ssz,
521                 proxy_connected, px)) {
522     logmsg(&c->q, LOG_ERR, "failed to make %s proxy connection to %s: %s",
523            c->l->ao->name, px->nat, strerror(errno));
524     goto err_2;
525   }
526
527   /* All ready to go. */
528   return;
529
530   /* Tidy up after various kinds of failures. */
531 err_2:
532   selbuf_enable(&c->b);
533 err_1:
534   close(px->fd);
535 err_0:
536   xfree(px);
537   reply_error(c, E_UNKNOWN);
538 }
539
540 /*----- Client connection functions ---------------------------------------*/
541
542 /* Disconnect a client, freeing up any associated resources. */
543 static void disconnect_client(struct client *c)
544 {
545   close(c->fd);
546   selbuf_destroy(&c->b);
547   sel_rmtimer(&c->t);
548   free_writebuf(&c->wb);
549   if (c->px) cancel_proxy(c->px);
550   xfree(c);
551 }
552
553 /* Time out a client because it's been idle for too long. */
554 static void timeout_client(struct timeval *tv, void *p)
555 {
556   struct client *c = p;
557   logmsg(&c->q, LOG_NOTICE, "timing out idle or stuck client");
558   sel_addtimer(&sel, &c->t, tv, timeout_client, 0);
559   disconnect_client(c);
560 }
561
562 /* Reset the client idle timer, as a result of activity.  Set EXISTP if
563  * there is an existing timer which needs to be removed.
564  */
565 static void reset_client_timer(struct client *c, int existp)
566 {
567   struct timeval tv;
568
569   gettimeofday(&tv, 0);
570   tv.tv_sec += 30;
571   if (existp) sel_rmtimer(&c->t);
572   sel_addtimer(&sel, &c->t, &tv, timeout_client, c);
573 }
574
575 /* Write a pseudorandom token into the buffer at P, which must have space for
576  * at least TOKENSZ bytes.
577  */
578 #define TOKENRANDSZ 8
579 #define TOKENSZ ((4*TOKENRANDSZ + 5)/3)
580 static void user_token(char *p)
581 {
582   unsigned a = 0;
583   unsigned b = 0;
584   int i;
585   static const char tokmap[64] =
586     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-";
587
588   /* If there's not enough pseudorandom stuff lying around, then read more
589    * from the kernel.
590    */
591   if (tokenptr + TOKENRANDSZ >= sizeof(tokenbuf)) {
592     if (read(randfd, tokenbuf, sizeof(tokenbuf)) < sizeof(tokenbuf))
593       die(1, "unexpected short read or error from `/dev/urandom'");
594     tokenptr = 0;
595   }
596
597   /* Now encode the bytes using a slightly tweaked base-64 encoding.  Read
598    * bytes into the accumulator and write out characters while there's
599    * enough material.
600    */
601   for (i = 0; i < TOKENRANDSZ; i++) {
602     a = (a << 8) | tokenbuf[tokenptr++]; b += 8;
603     while (b >= 6) {
604       b -= 6;
605       *p++ = tokmap[(a >> b) & 0x3f];
606     }
607   }
608
609   /* If there's anything left in the accumulator then flush it out. */
610   if (b)
611     *p++ = tokmap[(a << (6 - b)) & 0x3f];
612
613   /* Null-terminate the token. */
614   *p++ = 0;
615 }
616
617 /* Notification that a line has been received from the client.  Parse it,
618  * find out about the connection it's referring to, apply the relevant
619  * policy rules, and produce a response.  This is where almost everything
620  * interesting happens.
621  */
622 static void client_line(char *line, size_t len, void *p)
623 {
624   struct client *c = p;
625   const char *q;
626   struct passwd *pw = 0;
627   const struct policy *pol;
628   dstr d = DSTR_INIT;
629   struct policy upol = POLICY_INIT(A_LIMIT);
630   struct policy_file pf;
631   char buf[16];
632   int i, t;
633
634   /* If the connection has closed, then tidy stuff away. */
635   c->q.s[L].port = c->q.s[R].port = 0;
636   if (!line) {
637     disconnect_client(c);
638     return;
639   }
640
641   /* Client activity, so update the timer. */
642   reset_client_timer(c, 1);
643
644   /* See if the policy file has changed since we last looked.  If so, try to
645    * read the new version.
646    */
647   if (fwatch_update(&polfw, policyfile)) {
648     logmsg(0, LOG_INFO, "reload master policy file `%s'", policyfile);
649     load_policy_file(policyfile, &policy);
650   }
651
652   /* Read the local and remote port numbers into the query structure. */
653   q = line;
654   if (unum(&q, &c->q.s[L].port, 1, 65535)) goto bad;
655   skipws(&q); if (*q != ',') goto bad; q++;
656   if (unum(&q, &c->q.s[R].port, 1, 65535)) goto bad;
657   skipws(&q); if (*q) goto bad;
658
659   /* Identify the connection.  Act on the result. */
660   c->q.s[R].addr = c->raddr;
661   identify(&c->q);
662   switch (c->q.resp) {
663
664     case R_UID:
665       /* We found a user.  Track down the user's password entry, because
666        * we'll want that later.  Most of the processing for this case is
667        * below.
668        */
669       if ((pw = getpwuid(c->q.u.uid)) == 0) {
670         logmsg(&c->q, LOG_ERR, "no passwd entry for user %d", c->q.u.uid);
671         reply_error(c, E_NOUSER);
672         return;
673       }
674       break;
675
676     case R_NAT:
677       /* We've acted as a NAT for this connection.  Proxy the query through
678        * to the actal client host.
679        */
680       proxy_query(c);
681       return;
682
683     case R_ERROR:
684       /* We failed to identify the connection for some reason.  We should
685        * already have logged an error, so there's not much to do here.
686        */
687       reply_error(c, c->q.u.error);
688       return;
689
690     default:
691       /* Something happened that we don't understand. */
692       abort();
693   }
694
695   /* Search the table of policy rules to find a match. */
696   for (i = 0; i < DA_LEN(&policy); i++) {
697     pol = &DA(&policy)[i];
698     if (!match_policy(pol, &c->q)) continue;
699
700     /* If this is something simple, then apply the resulting policy rule. */
701     if (pol->act.act != A_USER) goto match;
702
703     /* The global policy has decided to let the user have a say, so we must
704      * parse the user file.
705      */
706     DRESET(&d);
707     dstr_putf(&d, "%s/.yaid.policy", pw->pw_dir);
708     if (open_policy_file(&pf, d.buf, "user policy file", &c->q, OPF_NOENTOK))
709       continue;
710     while ((t = read_policy_file(&pf)) < T_ERROR) {
711
712       /* Give up after 100 lines or if there's an error.  If the user's
713        * policy is that complicated, something's gone very wrong.  Or there's
714        * too much commentary or something.
715        */
716       if (pf.lno > 100) {
717         logmsg(&c->q, LOG_ERR, "%s:%d: user policy file too long",
718                pf.name, pf.lno);
719         break;
720       }
721
722       /* If this was a blank line, just go around again. */
723       if (t != T_OK) continue;
724
725       /* If this isn't a match, go around for the next rule. */
726       if (!match_policy(&pf.p, &c->q)) continue;
727
728       /* Check that the user is allowed to request this action.  If not, see
729        * if there's a more acceptable action later on.
730        */
731       if (!(pol->act.u.user & (1 << pf.p.act.act))) {
732         logmsg(&c->q, LOG_ERR,
733                "%s:%d: user action forbidden by global policy",
734                pf.name, pf.lno);
735         continue;
736       }
737
738       /* We've found a match, so grab it, close the file, and say we're
739        * done.
740        */
741       upol = pf.p; pol = &upol;
742       init_policy(&pf.p);
743       close_policy_file(&pf);
744       DDESTROY(&d);
745       goto match;
746     }
747     close_policy_file(&pf);
748     DDESTROY(&d);
749   }
750
751   /* No match: apply the built-in default policy. */
752   pol = &default_policy;
753
754 match:
755   switch (pol->act.act) {
756
757     case A_NAME:
758       /* Report the actual user's name. */
759       logmsg(&c->q, LOG_INFO, "user `%s' (%d)", pw->pw_name, c->q.u.uid);
760       reply(c, "USERID", "UNIX", pw->pw_name);
761       break;
762
763     case A_TOKEN:
764       /* Report an arbitrary token which we can look up in our log file. */
765       user_token(buf);
766       logmsg(&c->q, LOG_INFO, "user `%s' (%d); token = %s",
767              pw->pw_name, c->q.u.uid, buf);
768       reply(c, "USERID", "OTHER", buf);
769       break;
770
771     case A_DENY:
772       /* Deny that there's anyone there at all. */
773       logmsg(&c->q, LOG_INFO, "user `%s' (%d); denying",
774              pw->pw_name, c->q.u.uid);
775       break;
776
777     case A_HIDE:
778       /* Report the user as being hidden. */
779       logmsg(&c->q, LOG_INFO, "user `%s' (%d); hiding",
780              pw->pw_name, c->q.u.uid);
781       reply_error(c, E_HIDDEN);
782       break;
783
784     case A_LIE:
785       /* Tell an egregious lie about who the user is. */
786       logmsg(&c->q, LOG_INFO, "user `%s' (%d); lie = `%s'",
787              pw->pw_name, c->q.u.uid, pol->act.u.lie);
788       reply(c, "USERID", "UNIX", pol->act.u.lie);
789       break;
790
791     default:
792       /* Something has gone very wrong. */
793       abort();
794   }
795
796   /* All done. */
797   free_policy(&upol);
798   return;
799
800 bad:
801   logmsg(&c->q, LOG_ERR, "failed to parse query from client");
802   disconnect_client(c);
803 }
804
805 /* Notification that a new client has connected.  Prepare to read a query. */
806 static void accept_client(int fd, unsigned mode, void *p)
807 {
808   struct listen *l = p;
809   struct client *c;
810   struct sockaddr_storage ssr, ssl;
811   size_t ssz = sizeof(ssr);
812   int sk;
813
814   /* Accept the new connection. */
815   if ((sk = accept(fd, (struct sockaddr *)&ssr, &ssz)) < 0) {
816     if (errno != EAGAIN && errno == EWOULDBLOCK) {
817       logmsg(0, LOG_ERR, "failed to accept incoming %s connection: %s",
818              l->ao->name, strerror(errno));
819     }
820     return;
821   }
822   if (fix_up_socket(sk, "incoming client")) { close(sk); return; }
823
824   /* Build a client block and fill it in. */
825   c = xmalloc(sizeof(*c));
826   c->l = l;
827   c->q.ao = l->ao;
828
829   /* Collect the local and remote addresses. */
830   l->ao->sockaddr_to_addr(&ssr, &c->raddr);
831   ssz = sizeof(ssl);
832   if (getsockname(sk, (struct sockaddr *)&ssl, &ssz)) {
833     logmsg(0, LOG_ERR,
834            "failed to read local address for incoming %s connection: %s",
835            l->ao->name, strerror(errno));
836     close(sk);
837     xfree(c);
838     return;
839   }
840   l->ao->sockaddr_to_addr(&ssl, &c->q.s[L].addr);
841   c->q.s[L].port = c->q.s[R].port = 0;
842
843   /* Set stuff up for reading the query and sending responses. */
844   selbuf_init(&c->b, &sel, sk, client_line, c);
845   selbuf_setsize(&c->b, 1024);
846   reset_client_timer(c, 0);
847   c->fd = sk;
848   c->px = 0;
849   init_writebuf(&c->wb, sk, done_client_write, c);
850 }
851
852 /*----- Main code ---------------------------------------------------------*/
853
854 /* Set up a listening socket for the address family described by AO,
855  * listening on PORT.
856  */
857 static int make_listening_socket(const struct addrops *ao, int port)
858 {
859   int fd;
860   int yes = 1;
861   struct socket s;
862   struct sockaddr_storage ss;
863   struct listen *l;
864   size_t ssz;
865
866   /* Make the socket. */
867   if ((fd = socket(ao->af, SOCK_STREAM, 0)) < 0) {
868     if (errno == EAFNOSUPPORT) return (-1);
869     die(1, "failed to create %s listening socket: %s",
870         ao->name, strerror(errno));
871   }
872
873   /* Build the appropriate local address. */
874   s.addr = *ao->any;
875   s.port = port;
876   ao->socket_to_sockaddr(&s, &ss, &ssz);
877
878   /* Perform any initialization specific to the address type. */
879   if (ao->init_listen_socket(fd)) {
880     die(1, "failed to initialize %s listening socket: %s",
881         ao->name, strerror(errno));
882   }
883
884   /* Bind to the address. */
885   setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
886   if (bind(fd, (struct sockaddr *)&ss, ssz)) {
887     die(1, "failed to bind %s listening socket: %s",
888         ao->name, strerror(errno));
889   }
890
891   /* Avoid unpleasant race conditions. */
892   if (fdflags(fd, O_NONBLOCK, O_NONBLOCK, 0, 0)) {
893     die(1, "failed to set %s listening socket nonblocking: %s",
894         ao->name, strerror(errno));
895   }
896
897   /* Prepare to listen. */
898   if (listen(fd, 5))
899     die(1, "failed to listen for %s: %s", ao->name, strerror(errno));
900
901   /* Make a record of all of this. */
902   l = xmalloc(sizeof(*l));
903   l->ao = ao;
904   sel_initfile(&sel, &l->f, fd, SEL_READ, accept_client, l);
905   sel_addfile(&l->f);
906
907   /* Done. */
908   return (0);
909 }
910
911 /* Quit because of a fatal signal. */
912 static void quit(int sig, void *p)
913 {
914   const char *signame = p;
915
916   logmsg(0, LOG_NOTICE, "shutting down on %s", signame);
917   if (pidfile) unlink(pidfile);
918   exit(0);
919 }
920
921 /* Answer whether the string pointed to by P consists entirely of digits. */
922 static int numericp(const char *p)
923 {
924   while (*p)
925     if (!isdigit((unsigned char)*p++)) return (0);
926   return (1);
927 }
928
929 static void usage(FILE *fp)
930 {
931   pquis(fp, "Usage: $ [-Dl] [-G GROUP] [-U USER] [-P FILE] "
932         "[-c FILE] [-p PORT]\n");
933 }
934
935 static void version(FILE *fp)
936   { pquis(fp, "$, version " VERSION "\n"); }
937
938 static void help(FILE *fp)
939 {
940   version(fp); fputc('\n', fp);
941   usage(fp);
942   fputs("\n\
943 Yet Another Ident Daemon.  Really, the world doesn't need such a thing.\n\
944 It's just a shame none of the others do the right things.\n\
945 \n\
946 Options:\n\
947 \n\
948   -h, --help            Show this help message.\n\
949   -v, --version         Show the version number.\n\
950   -u, --usage           Show a very short usage summary.\n\
951 \n\
952   -D, --daemon          Become a daemon, running in the background.\n\
953   -G, --group=GROUP     Set group after initialization.\n\
954   -P, --pidfile=FILE    Write process id to FILE.\n\
955   -U, --user=USER       Set user after initialization.\n\
956   -c, --config=FILE     Read global policy from FILE.\n\
957   -l, --syslog          Write log messages using syslog(3).\n\
958   -p, --port=PORT       Listen for connections on this port.\n",
959         fp);
960 }
961
962 int main(int argc, char *argv[])
963 {
964   int port = 113;
965   uid_t u = -1;
966   gid_t g = -1;
967   struct passwd *pw = 0;
968   struct group *gr;
969   struct servent *s;
970   sig sigint, sigterm;
971   FILE *fp = 0;
972   int i;
973   unsigned f = 0;
974 #define f_bogus 1u
975 #define f_daemon 2u
976   const struct addrops *ao;
977   int any = 0;
978
979   ego(argv[0]);
980
981   /* Parse command-line options. */
982   for (;;) {
983     const struct option opts[] = {
984       { "help",         0,              0,      'h' },
985       { "version",      0,              0,      'v' },
986       { "usage",        0,              0,      'u' },
987       { "daemon",       0,              0,      'D' },
988       { "group",        OPTF_ARGREQ,    0,      'G' },
989       { "pidfile",      OPTF_ARGREQ,    0,      'P' },
990       { "user",         OPTF_ARGREQ,    0,      'U' },
991       { "config",       OPTF_ARGREQ,    0,      'c' },
992       { "syslog",       0,              0,      'l' },
993       { "port",         OPTF_ARGREQ,    0,      'p' },
994       { 0,              0,              0,      0 }
995     };
996
997     if ((i = mdwopt(argc, argv, "hvuDG:P:U:c:lp:", opts, 0, 0, 0)) < 0)
998       break;
999     switch (i) {
1000       case 'h': help(stdout); exit(0);
1001       case 'v': version(stdout); exit(0);
1002       case 'u': usage(stdout); exit(0);
1003       case 'D': f |= f_daemon; break;
1004       case 'P': pidfile = optarg; break;
1005       case 'c': policyfile = optarg; break;
1006       case 'l': flags |= F_SYSLOG; break;
1007       case 'G':
1008         if (numericp(optarg))
1009           g = atoi(optarg);
1010         else if ((gr = getgrnam(optarg)) == 0)
1011           die(1, "unknown group `%s'", optarg);
1012         else
1013           g = gr->gr_gid;
1014         break;
1015       case 'U':
1016         if (numericp(optarg))
1017           u = atoi(optarg);
1018         else if ((pw = getpwnam(optarg)) == 0)
1019           die(1, "unknown user `%s'", optarg);
1020         else
1021           u = pw->pw_uid;
1022         break;
1023       case 'p':
1024         if (numericp(optarg))
1025           port = atoi(optarg);
1026         else if ((s = getservbyname(optarg, "tcp")) == 0)
1027           die(1, "unknown service name `%s'", optarg);
1028         else
1029           port = ntohs(s->s_port);
1030         break;
1031       default: f |= f_bogus; break;
1032     }
1033   }
1034   if (optind < argc) f |= f_bogus;
1035   if (f & f_bogus) { usage(stderr); exit(1); }
1036
1037   /* If a user has been requested, but no group, then find the user's primary
1038    * group.  If the user was given by name, then we already have a password
1039    * entry and should use that, in case two differently-named users have the
1040    * same uid but distinct gids.
1041    */
1042   if (u != -1 && g == -1) {
1043     if (!pw && (pw = getpwuid(u)) == 0) {
1044       die(1, "failed to find password entry for user %d: "
1045           "request group explicitly", u);
1046     }
1047     g = pw->pw_gid;
1048   }
1049
1050   /* Initialize system-specific machinery. */
1051   init_sys();
1052
1053   /* Load the global policy rules. */
1054   fwatch_init(&polfw, policyfile);
1055   if (load_policy_file(policyfile, &policy))
1056     exit(1);
1057
1058   /* Open the random data source. */
1059   if ((randfd = open("/dev/urandom", O_RDONLY)) < 0) {
1060     die(1, "failed to open `/dev/urandom' for reading: %s",
1061         strerror(errno));
1062   }
1063
1064   /* Set up the I/O event system. */
1065   sel_init(&sel);
1066
1067   /* Watch for some interesting signals. */
1068   sig_init(&sel);
1069   sig_add(&sigint, SIGINT, quit, "SIGINT");
1070   sig_add(&sigterm, SIGTERM, quit, "SIGTERM");
1071
1072   /* Listen for incoming connections. */
1073   for (ao = addroptab; ao->name; ao++)
1074     if (!make_listening_socket(ao, port)) any = 1;
1075   if (!any) die(1, "no IP protocols supported");
1076
1077   /* Open the pidfile now, in case it's somewhere we can't write. */
1078   if (pidfile && (fp = fopen(pidfile, "w")) == 0) {
1079     die(1, "failed to open pidfile `%s' for writing: %s",
1080         pidfile, strerror(errno));
1081   }
1082
1083   /* If we're meant to use syslog, then open the log. */
1084   if (flags & F_SYSLOG)
1085     openlog(QUIS, 0, LOG_DAEMON);
1086
1087   /* Drop privileges. */
1088   if ((g != -1 && (setegid(g) || setgid(g) ||
1089                    (getuid() == 0 && setgroups(1, &g)))) ||
1090       (u != -1 && setuid(u)))
1091     die(1, "failed to drop privileges: %s", strerror(errno));
1092
1093   /* Become a background process, if requested. */
1094   if ((f & f_daemon) && daemonize())
1095     die(1, "failed to become daemon: %s", strerror(errno));
1096
1097   /* Write the process id to the pidfile. */
1098   if (fp) {
1099     fprintf(fp, "%d\n", getpid());
1100     fclose(fp);
1101   }
1102
1103   /* And now we're going. */
1104   flags |= F_RUNNING;
1105
1106   /* Read events and process them. */
1107   for (;;) {
1108     if (sel_select(&sel) && errno != EINTR)
1109       die(1, "select failed: %s", strerror(errno));
1110   }
1111
1112   /* This just keeps the compiler happy. */
1113   return (0);
1114 }
1115
1116 /*----- That's all, folks -------------------------------------------------*/