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 
 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 }