1 /*
2 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 #pragma ident "%Z%%M% %I% %E% SMI"
7
8 /****************************************************************************
9 Copyright (c) 1999,2000 WU-FTPD Development Group.
10 All rights reserved.
11
12 Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994
13 The Regents of the University of California.
14 Portions Copyright (c) 1993, 1994 Washington University in Saint Louis.
15 Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc.
16 Portions Copyright (c) 1989 Massachusetts Institute of Technology.
17 Portions Copyright (c) 1998 Sendmail, Inc.
18 Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman.
19 Portions Copyright (c) 1997 by Stan Barber.
20 Portions Copyright (c) 1997 by Kent Landfield.
21 Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997
22 Free Software Foundation, Inc.
23
24 Use and distribution of this software and its source code are governed
25 by the terms and conditions of the WU-FTPD Software License ("LICENSE").
26
27 If you did not receive a copy of the license, it may be obtained online
28 at http://www.wu-ftpd.org/license.html.
29
30 $Id: paths.c,v 1.7 2000/07/01 18:17:39 wuftpd Exp $
31
32 ****************************************************************************/
33 /*
34 * paths.c - setting up the correct pathing to support files/directories
35 *
36 * INITAL AUTHOR - Kent Landfield <kent@landfield.com>
37 */
38 #include "config.h"
39
40 #include <stdio.h>
41 #include <unistd.h>
42 #include <string.h>
43 #include <syslog.h>
44 #include <sys/param.h>
45
46 #include "pathnames.h"
47 #include "proto.h"
48
49 #ifdef VIRTUAL
50
51 #include <sys/types.h>
52 #include <sys/stat.h>
53 #include <sys/socket.h>
54 #include <netinet/in.h>
55 #include <arpa/inet.h>
56 #include <netdb.h>
57
58 int virtual_mode = 0;
59 int virtual_ftpaccess = 0;
60
61 extern int debug;
62 extern char virtual_hostname[];
63 extern char virtual_address[];
64
65 #endif
66
67 #ifndef MAXHOSTNAMELEN
68 #define MAXHOSTNAMELEN 64
69 #endif
70
71 /*
72 ** Pathing storage
73 */
74
75 #define _PATHS_DEFINED_ 1
76 char _path_ftpaccess[MAXPATHLEN];
77 char _path_ftpusers[MAXPATHLEN];
78 char _path_ftphosts[MAXPATHLEN];
79 char _path_private[MAXPATHLEN];
80 char _path_cvt[MAXPATHLEN];
81
82 extern char logfile[];
83 extern char hostname[];
84
85 void setup_paths(void);
86
87 /*
88 ** Virtual hosting has to support many different types of needs. There
89 ** must be complete support for the various ftpd system files and their
90 ** functionality.
91 **
92 ** Full support on a virtual host basis:
93 ** -------------------------------------
94 ** _PATH_FTPACCESS
95 ** _PATH_FTPUSERS
96 ** _PATH_PRIVATE
97 ** _PATH_FTPHOSTS
98 ** _PATH_CVT
99 **
100 ** Set in a site's ftpaccess file
101 ** _PATH_XFERLOG
102 **
103 ** Supported on a site basis:
104 ** --------------------------
105 ** _PATH_FTPSERVERS
106 ** _PATH_EXECPATH
107 ** _PATH_PIDNAMES
108 ** _PATH_UTMP
109 ** _PATH_WTMP
110 ** _PATH_LASTLOG
111 ** _PATH_BSHELL
112 ** _PATH_DEVNULL
113 */
114
115 /* ------------------------------------------------------------------------ */
116 /* FUNCTION : setup_paths */
117 /* PURPOSE : Determine appropriate paths to various configuration files. */
118 /* ARGUMENTS : None */
119 /* RETURNS : None */
120 /* ------------------------------------------------------------------------ */
121
setup_paths(void)122 void setup_paths(void)
123 {
124 #ifdef VIRTUAL
125 char *sp;
126 char configdir[MAXPATHLEN];
127 char filepath[MAXPATHLEN];
128 #ifdef INET6
129 char hostaddress[INET6_ADDRSTRLEN];
130 #else
131 char hostaddress[32];
132 #endif
133 FILE *svrfp;
134 struct stat st;
135 #if defined(UNIXWARE) || defined(AIX)
136 size_t virtual_len;
137 #else
138 int virtual_len;
139 #endif
140 struct SOCKSTORAGE virtual_addr;
141 #endif
142
143 (void) strlcpy(_path_ftpaccess, _PATH_FTPACCESS, sizeof(_path_ftpaccess));
144 (void) strlcpy(_path_ftpusers, _PATH_FTPUSERS, sizeof(_path_ftpusers));
145 (void) strlcpy(_path_private, _PATH_PRIVATE, sizeof(_path_private));
146 (void) strlcpy(_path_cvt, _PATH_CVT, sizeof(_path_cvt));
147 (void) strlcpy(logfile, _PATH_XFERLOG, MAXPATHLEN);
148 (void) strlcpy(_path_ftphosts, _PATH_FTPHOSTS, sizeof(_path_ftphosts));
149
150 #ifdef VIRTUAL
151 /*
152 ** Open PATH_FTPSERVERS config file. If the file does not
153 ** exist then revert to using the standard _PATH_* path defines.
154 */
155
156 if ((svrfp = fopen(_PATH_FTPSERVERS, "r")) != NULL) {
157 /*
158 ** OK. The ftpservers file exists and is open.
159 **
160 ** Format of the file is:
161 ** ipaddr/hostname directory-containing-configuration-files
162 **
163 ** 208.196.145.10 /etc/ftpd/ftpaccess.somedomain/
164 ** 208.196.145.200 /etc/ftpd/ftpaccess.someotherdomain/
165 ** some.domain INTERNAL
166 **
167 ** Parse the file and try to match the IP address to one found
168 ** in the file. If a match is found then return the path to
169 ** the specified directory that contains the configuration files
170 ** for that specific domain. If a match is not found, or an invalid
171 ** directory path is encountered like above, return standard paths.
172 **
173 ** As usual, comments and blanklines are ignored.
174 */
175
176 /* get our address */
177
178 virtual_len = sizeof(virtual_addr);
179 if (getsockname(0, (struct sockaddr *) &virtual_addr, &virtual_len) == 0) {
180 while (read_servers_line(svrfp, hostaddress, sizeof(hostaddress),
181 configdir, sizeof(configdir)) == 1) {
182 if (!strcmp(hostaddress, inet_stop(&virtual_addr))) {
183 if (debug)
184 syslog(LOG_DEBUG, "VirtualFTP Connect to: %s", hostaddress);
185 (void) strlcpy(virtual_address, hostaddress,
186 MAXHOSTNAMELEN);
187 if (hostname != NULL) {
188 /* reset hostname to this virtual name */
189 wu_gethostbyaddr(&virtual_addr, hostname, MAXHOSTNAMELEN);
190 (void) strlcpy(virtual_hostname, hostname,
191 MAXHOSTNAMELEN);
192 }
193
194 /* get rid of trailing slash */
195 sp = configdir + (strlen(configdir) - 1);
196 if (*sp == '/')
197 *sp = '\0';
198
199 /*
200 ** check to see that a valid directory value was
201 ** supplied and not something such as "INTERNAL"
202 */
203
204 if ((stat(configdir, &st) == 0) &&
205 ((st.st_mode & S_IFMT) == S_IFDIR)) {
206
207 (void) snprintf(filepath, sizeof(filepath),
208 "%s/ftpaccess", configdir);
209 if (access(filepath, R_OK) == 0) {
210 (void) strlcpy(_path_ftpaccess, filepath,
211 sizeof(_path_ftpaccess));
212 virtual_mode = 1;
213 virtual_ftpaccess = 1;
214 }
215
216 (void) snprintf(filepath, sizeof(filepath),
217 "%s/ftpusers", configdir);
218 if (access(filepath, R_OK) == 0)
219 (void) strlcpy(_path_ftpusers, filepath,
220 sizeof(_path_ftpusers));
221
222 (void) snprintf(filepath, sizeof(filepath),
223 "%s/ftpgroups", configdir);
224 if (access(filepath, R_OK) == 0)
225 (void) strlcpy(_path_private, filepath,
226 sizeof(_path_private));
227
228 (void) snprintf(filepath, sizeof(filepath),
229 "%s/ftphosts", configdir);
230 if (access(filepath, R_OK) == 0)
231 (void) strlcpy(_path_ftphosts, filepath,
232 sizeof(_path_ftphosts));
233
234 (void) snprintf(filepath, sizeof(filepath),
235 "%s/ftpconversions", configdir);
236 if (access(filepath, R_OK) == 0)
237 (void) strlcpy(_path_cvt, filepath,
238 sizeof(_path_cvt));
239 }
240 (void) fclose(svrfp);
241 return;
242 }
243 }
244 }
245 (void) fclose(svrfp);
246 }
247 #endif /* VIRTUAL */
248
249 return;
250 }
251