xref: /openbsd/usr.sbin/smtpd/forward.c (revision cca36db2)
1 /*	$OpenBSD: forward.c,v 1.24 2011/05/16 21:05:51 gilles Exp $	*/
2 
3 /*
4  * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 #include <sys/queue.h>
21 #include <sys/tree.h>
22 #include <sys/param.h>
23 #include <sys/socket.h>
24 #include <sys/stat.h>
25 
26 #include <ctype.h>
27 #include <event.h>
28 #include <imsg.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 
33 #include "smtpd.h"
34 #include "log.h"
35 
36 int
37 forwards_get(int fd, struct expandtree *expandtree, char *as_user)
38 {
39 	FILE *fp;
40 	char *buf, *lbuf, *p, *cp;
41 	size_t len;
42 	size_t nbaliases = 0;
43 	int quoted;
44 	struct expandnode expnode;
45 
46 	fp = fdopen(fd, "r");
47 	if (fp == NULL)
48 		return 0;
49 
50 	lbuf = NULL;
51 	while ((buf = fgetln(fp, &len))) {
52 		if (buf[len - 1] == '\n')
53 			buf[len - 1] = '\0';
54 		else {
55 			/* EOF without EOL, copy and add the NUL */
56 			if ((lbuf = malloc(len + 1)) == NULL)
57 				fatal("malloc");
58 			memcpy(lbuf, buf, len);
59 			lbuf[len] = '\0';
60 			buf = lbuf;
61 		}
62 
63 		/* ignore empty lines and comments */
64 		if (buf[0] == '#' || buf[0] == '\0')
65 			continue;
66 
67 		quoted = 0;
68 		cp = buf;
69 		do {
70 			/* skip whitespace */
71 			while (isspace((int)*cp))
72 				cp++;
73 
74 			/* parse line */
75 			for (p = cp; *p != '\0'; p++) {
76 				if (*p == ',' && !quoted) {
77 					*p++ = '\0';
78 					break;
79 				} else if (*p == '"')
80 					quoted = !quoted;
81 			}
82 			buf = cp;
83 			cp = p;
84 
85 			bzero(&expnode, sizeof (struct expandnode));
86 			if (! alias_parse(&expnode, buf)) {
87 				log_debug("bad entry in ~/.forward");
88 				continue;
89 			}
90 
91 			if (expnode.type == EXPAND_INCLUDE) {
92 				log_debug(
93 				    "includes are forbidden in ~/.forward");
94 				continue;
95 			}
96 
97 			(void)strlcpy(expnode.as_user, as_user, sizeof(expnode.as_user));
98 
99 			expandtree_increment_node(expandtree, &expnode);
100 			nbaliases++;
101 		} while (*cp != '\0');
102 	}
103 	free(lbuf);
104 	fclose(fp);
105 	return (nbaliases);
106 }
107