diff -urN samba-3.0.1.orig/source/smbd/trans2.c samba-3.0.1/source/smbd/trans2.c --- samba-3.0.1.orig/source/smbd/trans2.c Wed Feb 25 00:21:53 2004 +++ samba-3.0.1/source/smbd/trans2.c Wed Feb 25 00:25:30 2004 @@ -2397,6 +2397,42 @@ } /**************************************************************************** + Makes link_dest path relative to link_src +****************************************************************************/ + +static void make_link_relative(const char *link_src, char *link_dest) +{ + const char *p1 = link_src; + char *p2 = link_dest; + pstring link_rel; + int sl = 0; + + while (*(++p1) == *(++p2)); + + if (p1 != link_src) { + p1--; + p2--; + }; + + for ( ;*p1 != '/' && p1 != link_src; p1--, p2--); + + while (*(++p1)) + sl = (*p1 == '/') ? sl + 1 : sl; + + if (sl) { + pstrcpy(link_rel, "../"); + for ( ;sl > 1; sl--) + pstrcat(link_rel, "../"); + pstrcat(link_rel, *p2 == '/' ? ++p2 : p2); + } else + pstrcpy(link_rel, *p2 == '/' ? ++p2 : p2); + + DEBUG(10,("before (%s -> %s), after (%s -> %s)\n", link_src, link_dest, link_src, link_rel)); + + pstrcpy(link_dest, link_rel); +} + +/**************************************************************************** Returns true if this pathname is within the share, and thus safe. ****************************************************************************/ @@ -2946,6 +2982,8 @@ if (ensure_link_is_safe(conn, link_dest, link_dest) != 0) return(UNIXERROR(ERRDOS,ERRnoaccess)); + + make_link_relative(fname, link_dest); DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n", fname, link_dest ));