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