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