Subject: noretrieve for directory

From: Per Foreby <[email-masked]>
Date: Tue, 11 Jul 1995 16:54:40 +0200

The noretrieve keyword makes it possible to deny access for
an absolute or relative FILENAME, but what if I want to deny
access to a directory (and its subdirs?)

If there currently is no way to do this, I would like to
suggest a traling slash in the noretrieve filenames to
get this behaviour:

	notretrive /usr/bin/ls core /etc/ /var/yp/mydomain/

would mean:

Deny access to the file /usr/bin/ls, the file core (anywhere)
and to all files in /etc and /var/yp/mydomain and it's subdirectories.

This level of security would suit my needs perfectly. I would be
able to allow my students access to home directories and source
archives, but deny access to other files on the ftp server (which
is a sort of privilliged machine which they can't log in to).

If there is no way to do this today, I would be more than happy
to do the implementation (which is trivial).
--
Per Foreby

---

From: Per Foreby <[email-masked]>
Date: Wed, 12 Jul 1995 17:26:12 +0200

> to do the implementation (which is trivial).

I needed this feature, so I made a small change to checknoretrieve()
in extensions.c (wu-ftpd-2.4.2-beta-5). I seems to work just
like I wanted it to.

If anyone wants to use this, or maybe even merge it into the
distribution, here is the diff (I have tried to indent the code
according to the existing code even if it isn't my preferred
indentation):

-----------------------<cut here>------------------------------------------
*** extensions.c.ORIG	Tue Jul 11 13:08:56 1995
--- extensions.c	Wed Jul 12 16:40:52 1995
***************
*** 973,979 ****
  checknoretrieve (char *name)
  {
    char cwd[MAXPATHLEN+1], realwd[MAXPATHLEN+1], realname[MAXPATHLEN+1];
!   int i;
    struct aclmember *entry = NULL;
  
    if (name == (char *)NULL || *name == '\0')
--- 973,979 ----
  checknoretrieve (char *name)
  {
    char cwd[MAXPATHLEN+1], realwd[MAXPATHLEN+1], realname[MAXPATHLEN+1];
!   int i, len;
    struct aclmember *entry = NULL;
  
    if (name == (char *)NULL || *name == '\0')
***************
*** 993,1004 ****
              continue;
  	for (i = 0; i< MAXARGS && 
  	     (entry->arg[i] != (char *)NULL) && (*(entry->arg[i]) !='\0'); i++)
! 	  if (strcmp (((*(entry->arg[i]) == '/') ? realname : 
  			lbasename (realname)), entry->arg[i]) == 0)
  	  {
  	    reply (550, "%s is marked unretrievable", entry->arg[i]);
  	    return 1;
  	  }
        }
     return 0;
  }
--- 993,1013 ----
              continue;
  	for (i = 0; i< MAXARGS && 
  	     (entry->arg[i] != (char *)NULL) && (*(entry->arg[i]) !='\0'); i++)
! 	{
! 	  len = strlen(entry->arg[i]);
! 	  if (entry->arg[i][len-1] == '/' &&
! 	      strncmp(entry->arg[i], realname, len) == 0)
! 	  {
! 	    reply (550, "%s is marked unretrievable", entry->arg[i]);
! 	    return 1;
! 	  }
! 	  else if (strcmp (((*(entry->arg[i]) == '/') ? realname : 
  			lbasename (realname)), entry->arg[i]) == 0)
  	  {
  	    reply (550, "%s is marked unretrievable", entry->arg[i]);
  	    return 1;
  	  }
+ 	}
        }
     return 0;
  }
-----------------------<cut here>------------------------------------------

--
Per Foreby