1 #pragma ident   "%Z%%M% %I%     %E% SMI"
   2 
   3 /****************************************************************************    
   4   Copyright (c) 1999,2000 WU-FTPD Development Group.  
   5   All rights reserved.
   6    
   7   Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994  
   8     The Regents of the University of California. 
   9   Portions Copyright (c) 1993, 1994 Washington University in Saint Louis.  
  10   Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc.  
  11   Portions Copyright (c) 1989 Massachusetts Institute of Technology.  
  12   Portions Copyright (c) 1998 Sendmail, Inc.  
  13   Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P.  Allman.  
  14   Portions Copyright (c) 1997 by Stan Barber.  
  15   Portions Copyright (c) 1997 by Kent Landfield.  
  16   Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997  
  17     Free Software Foundation, Inc.    
  18    
  19   Use and distribution of this software and its source code are governed   
  20   by the terms and conditions of the WU-FTPD Software License ("LICENSE").  
  21    
  22   If you did not receive a copy of the license, it may be obtained online  
  23   at http://www.wu-ftpd.org/license.html.  
  24    
  25   $Id: restrict.c,v 1.14 2000/07/01 18:17:39 wuftpd Exp $  
  26    
  27 ****************************************************************************/
  28 /*
  29  * Contributed by Glenn Nielsen <glenn@more.net>
  30  * Mon, 18 Jan 1999 20:04:07 -0600
  31  */
  32 #include "config.h"
  33 
  34 #include <sys/param.h>
  35 #include <stdlib.h>
  36 #include <string.h>
  37 #include <syslog.h>
  38 #include "proto.h"
  39 
  40 #ifdef HAVE_GETCWD
  41 extern char *getcwd(char *, size_t);
  42 #else
  43 extern char *getwd(char *);
  44 #endif
  45 
  46 #ifndef TRUE
  47 #define TRUE 1
  48 #define FALSE 0
  49 #endif
  50 
  51 extern char *home;
  52 extern int restricted_user;
  53 
  54 /*
  55  * name is the function parameter
  56  * home is a global string containing the user's home directory
  57  *
  58  * rhome is the resolved home directory
  59  * rname is the resolved requested filename
  60  * curwd is the current working directory
  61  * path is name, possibly prepended by the current working directory
  62  */
  63 
  64 int restrict_check(char *name)
  65 {
  66     if (!test_restriction(name))
  67         return 0;
  68     reply(550, "Permission denied on server.  You are restricted to your account.");
  69     return 1;
  70 }
  71 
  72 int test_restriction(char *name)
  73 {
  74     char rhome[MAXPATHLEN + 1], rname[MAXPATHLEN + 1], path[MAXPATHLEN + 1];
  75 
  76     /* we're not in restrict mode so all access is OK */
  77     if (restricted_user == FALSE)
  78         return 0;
  79 
  80     /* get resolved equivalent of user's home directory */
  81     fb_realpath(home, rhome);
  82 
  83     path[0] = '\0';
  84 
  85     /* a relative path is specified, so resolve it w.r.t. current working directory */
  86     if ((name)[0] != '/') {
  87 
  88         char curwd[MAXPATHLEN + 1];
  89 
  90         /* determine current working directory */
  91 #ifdef HAVE_GETCWD
  92         if (getcwd(curwd, MAXPATHLEN) == (char *) NULL) {
  93 #else
  94         if (getwd(curwd) == (char *) NULL) {
  95 #endif
  96             return 1;
  97         }                       /* if */
  98 
  99         strcpy(path, curwd);
 100         strcat(path, "/");
 101 
 102     }                           /* if */
 103 
 104     if ((strlen(path) + strlen(name) + 2) > sizeof(path)) {
 105         return 1;
 106     }
 107 
 108     strcat(path, name);
 109     fb_realpath(path, rname);
 110     strcat(rname, "/");
 111 
 112     if (strncmp(rhome, rname, strlen(rhome))) {
 113         return 1;
 114     }                           /* if */
 115 
 116     return 0;
 117 }                               /* restrict_check */
 118 
 119 int restrict_list_check(char *name)
 120 {
 121     char *beg, *copy, *end;
 122     int flag;
 123 
 124     beg = name;
 125 
 126     while (*beg != '\0') {
 127 
 128         flag = 0;
 129         end = beg;
 130         while (*end && !isspace(*end))
 131             ++end;
 132         if (!*end)
 133             flag = 1;
 134         if (!flag)
 135             *end = '\0';
 136         copy = strdup(beg);
 137         if (!flag)
 138             *end = ' ';
 139 
 140         if (!copy) {
 141             reply(550, "Permission denied on server.  Out of memory.");
 142             return 1;
 143 
 144         }                       /* if */
 145 
 146         if (restrict_check(copy)) {
 147             free(copy);
 148             return 1;
 149         }
 150         free(copy);
 151         beg = end;
 152         if (!flag)
 153             ++beg;
 154 
 155     }                           /* while */
 156 
 157     return 0;
 158 
 159 }                               /* restrict_list_check */
 160 
 161 /*
 162  * $Log: restrict.c,v $
 163  * Revision 1.14  2000/07/01 18:17:39  wuftpd
 164  *
 165  * Updated copyright statement for the WU-FTPD Development Group.
 166  *
 167  * Revision 1.13  1999/10/08 03:42:12  wuftpd
 168  * Fixed a bug in restrict_check which could allow access outside the users home
 169  *
 170  * Revision 1.12  1999/09/05 02:31:50  wuftpd
 171  * Add virtual and defaultserver support for email notification
 172  *
 173  * Revision 1.11  1999/09/02 19:35:48  wuftpd
 174  * CDUP was leaking information about restrictions.
 175  *
 176  * Revision 1.10  1999/09/02 14:04:29  wuftpd
 177  * Cleaning up.  Indented and removed some STDC checks
 178  *
 179  * Revision 1.9  1999/08/24 23:41:39  wuftpd
 180  * wu-ftpd-2.4.x RCS Ids removed and new Ids added for wu-ftpd.org usage.
 181  * WU-FTPD Development Group copyright headers added.
 182  * Original Copyright headers moved into the COPYRIGHT file.
 183  * COPYPRIGHT.c added to build for ftpshut and ftpd.
 184  *
 185  * Revision 1.2  1996/02/20 04:54:04  root
 186  * added #define to make gcc use HAVE_GETCWD
 187  *
 188  * Revision 1.1  1996/02/20 03:52:48  root
 189  * Initial revision
 190  *
 191  */