Code to hide inaccessible files/directories

Bill Moran wmoran at iowna.com
Sat Apr 14 05:58:19 GMT 2001


I asked about this ability a few weeks ago and the reply was basically
that folks would be interested in seeing it happen. Well, the client
insisted, so I've put together a hack that accomplishes it.
The basic design requirement was that users would not see
files/directories that they did not have at least read access to. This
request came about because we were migrating from a Novell server, and
this is apparently the default behaviour for Netware.
This hack was implemented on a FreeBSD 4.2-STABLE box using samba 2.0.7,
and it has been working predictably for about a week.

A few coding notes:

1. I'm not too sure about the size of fullPath. 2048 seemed a value that
wouldn't normally be exceeded, but I don't have any proof that it's a
good size. It may be too large or too small (compared to system limits,
of course) In the final analysis, it should be the same size as the max
path size of the system it's running on.
2. This a pretty much a hack. It should really be implemented as a
config option, possibly with per-share capibilities. As it stands,
modifying dir.c and recompiling turns this on for everything, period.
3. The access() command is considered "a security hole that should never
be used" by the BSD documentation. However, I can not see how access()
is a security concern _in this particular implementation_, and nobody
has been able to give me an example of how it could be. If using
access() makes you nervious, you could replace it with open()-with a
test for success. I didn't want to do this because of the potential
performance hit. Also, I don't know whether or not access() is portable
to other systems (such as Linux)

So, the upshot of the story is to replace the function OpenDir() in
dir.c with the one shown below, recompile and you'll find that machines
connected via samba will no longer be able to see files/directories
listed that they do not have read rights to.
(yes, I know I could have sent diffs, but this change was made *after*
FreeBSD specific patches were applied to the samba source, and I don't
know how that would affect a diff)

Hope this is useful to people.
-Bill

void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
{
  Dir *dirp;
  char *n;
  DIR *p = dos_opendir(name);
  int used=0;
  char *fullPath;

  if (!p) return(NULL);
  dirp = (Dir *)malloc(sizeof(Dir));
  if (!dirp) {
    closedir(p);
    return(NULL);
  }
  fullPath = (char *)malloc(2048);
  if (!fullPath) {
    closedir(p);
    return(NULL);
  }
  dirp->pos = dirp->numentries = dirp->mallocsize = 0;
  dirp->data = dirp->current = NULL;

  while ((n = dos_readdirname(p)))
  {
    int l = strlen(n)+1;

    /* If it's a vetoed file, pretend it doesn't even exist */
    if (use_veto && conn && IS_VETO_PATH(conn, n)) continue;
    /* hack to hide files that the user doesn't have read perms to */
    snprintf(fullPath,2048,"%s/%s/%s",conn->origpath,name,n);
    if (access(fullPath,R_OK) ) continue;
    if (used + l > dirp->mallocsize) {
      int s = MAX(used+l,used+2000);
      char *r;
      r = (char *)Realloc(dirp->data,s);
      if (!r) {
        DEBUG(0,("Out of memory in OpenDir\n"));
        break;
      }
      dirp->data = r;
      dirp->mallocsize = s;
      dirp->current = dirp->data;
    }
    pstrcpy(dirp->data+used,n);
    used += l;
    dirp->numentries++;
  }

  closedir(p);
  return((void *)dirp);
}




More information about the samba-technical mailing list