BUG: Wide Links - does not work as documented

Jani Jaakkola jjaakkol at cs.Helsinki.FI
Thu Apr 13 15:22:20 GMT 2000



On Tue, 11 Apr 2000, Jeremy Allison wrote:

> Jani Jaakkola wrote:
> 
> > My vote is, that "wide symlinks" should either be fixed or completely
> > removed. The current behaviour is useless and dangerous.
> 
> Well obviously not, as you have been using it for a while
> with its current implementation.

Only because I failed to test it properly :(

> I will look forward to that, thanks.

Thinks are getting complicated. After looking around the code and trying
to find out how things work, I have found more problems:

- "follow symlinks = no" tests only if last component of the path is a
   symlink. If you have a directory hierarchy looking like this:
<CLIP>
$ ls -ld test
drwx------   2 jjaakkol 4000         4096 Apr 13 17:26 test/
$ ls -l test/root
lrwxrwxrwx   1 jjaakkol 4000            1 Apr 13 17:20 test/root -> //
$ ls -l test/root/etc/passwd
-rw-r--r--   1 root     root         1152 Mar 29 18:10 test/root/etc/passwd
</CLIP>
   you can get test/root/etc/passwd even if "follow symlinks = no" is
   set in the configuration file.

- In any case, there is a race condition between check_name() and 
  the actual open or opendir system call. So:
  o samba sees a file which is not a symlink
  o a context switch happens. User removes the file and creates a symlink
    in its place
  o context is switched back to samba. Samba opens the file which is
    a symlink to /etc/passwd

So in conclusion: "wide links" and "follow symlinks" are _not_ useful as
security features (even when both are used, which actually stops all
trivial attempts). A determined cracker will certainly find his way around
both if symlinks can somehow (most probably through NFS) be created in the
share directory. And this cannot be completely fixed by simply editing
check_name() and reduce_name().

The correct solution is to move symlink checks to dos_open() and
dos_opendir() (and probably all dos_* calls). If "follow symlinks=no" is
set, samba should do the following:

1. chdir() to the directory of the file to be opened
2. check with getcwd() that directory is the same directory as the 
   directory we chdir():red to
3. open the basename of the file with O_NOFOLLOW given to open.

If "wide links = no":

1. find out the real file name with realpath().
2. check that the real file name is under the share directory
3. open the real file name just like when "follow symlinks=no" is set.

My problem is, that I want to enable symlinks, but only allow them
followed inside the share directory and also make it work securely so
that there is no way around it. I am still willing to provide a
patch for this, but it will not be as simple as it first seemed to me.

- Jani



More information about the samba-technical mailing list