xref: /onnv-gate/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/acl.c (revision 0:68f95e015346)
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 
getaclentry(char * keyword,struct aclmember ** next)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 
parseacl(void)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 
readacl(char * aclpath)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 }
196