xref: /onnv-gate/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/acl.c (revision 0:68f95e015346)
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