1 #pragma ident "%Z%%M% %I% %E% SMI" 2 3 /**************************************************************************** 4 5 Copyright (c) 1999,2000 WU-FTPD Development Group. 6 All rights reserved. 7 8 Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 9 The Regents of the University of California. 10 Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. 11 Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. 12 Portions Copyright (c) 1989 Massachusetts Institute of Technology. 13 Portions Copyright (c) 1998 Sendmail, Inc. 14 Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. 15 Portions Copyright (c) 1997 by Stan Barber. 16 Portions Copyright (c) 1997 by Kent Landfield. 17 Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 18 Free Software Foundation, Inc. 19 20 Use and distribution of this software and its source code are governed 21 by the terms and conditions of the WU-FTPD Software License ("LICENSE"). 22 23 If you did not receive a copy of the license, it may be obtained online 24 at http://www.wu-ftpd.org/license.html. 25 26 $Id: acl.c,v 1.9 2000/07/01 18:17:38 wuftpd Exp $ 27 28 ****************************************************************************/ 29 #include "config.h" 30 31 #include <stdio.h> 32 #include <errno.h> 33 #include <string.h> 34 #ifdef HAVE_SYS_SYSLOG_H 35 #include <sys/syslog.h> 36 #endif 37 #if defined(HAVE_SYSLOG_H) || (!defined(AUTOCONF) && !defined(HAVE_SYS_SYSLOG_H)) 38 #include <syslog.h> 39 #endif 40 41 #include <sys/types.h> 42 #include <sys/stat.h> 43 #include <sys/file.h> 44 45 #ifdef HAVE_PATHS_H 46 #include <paths.h> 47 #endif 48 #include "pathnames.h" 49 #include "extensions.h" 50 #include "proto.h" 51 52 char *aclbuf = NULL; 53 static struct aclmember *aclmembers; 54 55 /*************************************************************************/ 56 /* FUNCTION : getaclentry */ 57 /* PURPOSE : Retrieve a named entry from the ACL */ 58 /* ARGUMENTS : pointer to the keyword and a handle to the acl members */ 59 /* RETURNS : pointer to the acl member containing the keyword or NULL */ 60 /*************************************************************************/ 61 62 struct aclmember *getaclentry(char *keyword, struct aclmember **next) 63 { 64 do { 65 if (!*next) 66 *next = aclmembers; 67 else 68 *next = (*next)->next; 69 } while (*next && strcasecmp((*next)->keyword, keyword)); 70 71 return (*next); 72 } 73 74 /*************************************************************************/ 75 /* FUNCTION : parseacl */ 76 /* PURPOSE : Parse the acl buffer into its components */ 77 /* ARGUMENTS : A pointer to the acl file */ 78 /* RETURNS : nothing */ 79 /*************************************************************************/ 80 81 void parseacl(void) 82 { 83 char *ptr, *aclptr = aclbuf, *line; 84 int cnt; 85 struct aclmember *member, *acltail; 86 87 if (!aclbuf || !(*aclbuf)) 88 return; 89 90 aclmembers = (struct aclmember *) NULL; 91 acltail = (struct aclmember *) NULL; 92 93 while (*aclptr != '\0') { 94 line = aclptr; 95 while (*aclptr && *aclptr != '\n') 96 aclptr++; 97 *aclptr++ = (char) NULL; 98 99 /* deal with comments */ 100 if ((ptr = strchr(line, '#')) != NULL) 101 /* allowed escaped '#' chars for path-filter (DiB) */ 102 if ((ptr > aclbuf) && (*(ptr - 1) != '\\')) 103 *ptr = '\0'; 104 105 ptr = strtok(line, " \t"); 106 if (ptr) { 107 member = (struct aclmember *) calloc(1, sizeof(struct aclmember)); 108 109 if (member == NULL) { 110 syslog(LOG_ERR, "calloc error parsing acl"); 111 exit(1); 112 } 113 (void) strncpy(member->keyword, ptr, MAXKWLEN); 114 member->keyword[MAXKWLEN - 1] = '\0'; 115 cnt = 0; 116 while ((ptr = strtok(NULL, " \t")) != NULL) { 117 if (cnt >= MAXARGS) { 118 syslog(LOG_ERR, 119 "Too many args (>%d) in ftpaccess: %s %s %s %s %s ...", 120 MAXARGS - 1, member->keyword, member->arg[0], 121 member->arg[1], member->arg[2], member->arg[3]); 122 break; 123 } 124 member->arg[cnt++] = ptr; 125 } 126 if (acltail) 127 acltail->next = member; 128 acltail = member; 129 if (!aclmembers) 130 aclmembers = member; 131 } 132 } 133 } 134 135 /*************************************************************************/ 136 /* FUNCTION : readacl */ 137 /* PURPOSE : Read the acl into memory */ 138 /* ARGUMENTS : The pathname of the acl */ 139 /* RETURNS : 0 if error, 1 if no error */ 140 /*************************************************************************/ 141 142 int readacl(char *aclpath) 143 { 144 FILE *aclfile; 145 struct stat finfo; 146 struct aclmember *member; 147 extern int use_accessfile; 148 149 if (!use_accessfile) 150 return (0); 151 152 while (aclmembers) { 153 member = aclmembers->next; 154 free(aclmembers); 155 aclmembers = member; 156 } 157 158 if (aclbuf) { 159 free(aclbuf); 160 aclbuf = NULL; 161 } 162 163 if ((aclfile = fopen(aclpath, "r")) == NULL) { 164 syslog(LOG_ERR, "cannot open access file %s: %s", aclpath, 165 strerror(errno)); 166 return (0); 167 } 168 if (fstat(fileno(aclfile), &finfo) != 0) { 169 syslog(LOG_ERR, "cannot fstat access file %s: %s", aclpath, 170 strerror(errno)); 171 (void) fclose(aclfile); 172 return (0); 173 } 174 if (finfo.st_size == 0) { 175 aclbuf = (char *) calloc(1, 1); 176 } 177 else { 178 if (!(aclbuf = (char *) malloc((size_t) finfo.st_size + 1))) { 179 syslog(LOG_ERR, "could not malloc aclbuf (%d bytes)", (size_t) finfo.st_size + 1); 180 (void) fclose(aclfile); 181 return (0); 182 } 183 if (!fread(aclbuf, (size_t) finfo.st_size, 1, aclfile)) { 184 syslog(LOG_ERR, "error reading acl file %s: %s", aclpath, 185 strerror(errno)); 186 free(aclbuf); 187 aclbuf = NULL; 188 (void) fclose(aclfile); 189 return (0); 190 } 191 *(aclbuf + finfo.st_size) = '\0'; 192 } 193 (void) fclose(aclfile); 194 return (1); 195 }