1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-26 21:57:41 +03:00

untest fix for wide links parameter bug.

it work properly on 2.2 and the patch apply so I think it should be ok.
This commit is contained in:
Simo Sorce -
parent e6f87c7ee5
commit 36b2f6c932

View File

@ -780,6 +780,63 @@ char *vfs_GetWd(connection_struct *conn, char *path)
return (path);
}
/* check if the file 'nmae' is a symlink, in that case check that it point to
a file that reside under the 'dir' tree */
static BOOL readlink_check(connection_struct *conn, char *dir, char *name)
{
BOOL ret = True;
pstring flink;
pstring cleanlink;
pstring savedir;
pstring realdir;
size_t reallen;
if (!vfs_GetWd(conn, savedir)) {
DEBUG(0,("couldn't vfs_GetWd for %s %s\n", name, dir));
return False;
}
if (vfs_ChDir(conn, dir) != 0) {
DEBUG(0,("couldn't vfs_ChDir to %s\n", dir));
return False;
}
if (!vfs_GetWd(conn, realdir)) {
DEBUG(0,("couldn't vfs_GetWd for %s\n", dir));
vfs_ChDir(conn, savedir);
return(False);
}
reallen = strlen(realdir);
if (realdir[reallen -1] == '/') {
reallen--;
realdir[reallen] = 0;
}
if (conn->vfs_ops.readlink(conn, name, flink, sizeof(pstring) -1) != -1) {
DEBUG(3,("reduce_name: file path name %s is a symlink\nChecking it's path\n", name));
if (*flink == '/') {
pstrcpy(cleanlink, flink);
} else {
pstrcpy(cleanlink, realdir);
pstrcat(cleanlink, "/");
pstrcat(cleanlink, flink);
}
unix_clean_name(cleanlink);
if (strncmp(cleanlink, realdir, reallen) != 0) {
DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n", name, realdir, cleanlink, (int)reallen));
ret = False;
}
}
vfs_ChDir(conn, savedir);
return ret;
}
/*******************************************************************
Reduce a file name, removing .. elements and checking that
it is below dir in the heirachy. This uses vfs_GetWd() and so must be run
@ -824,7 +881,7 @@ BOOL reduce_name(connection_struct *conn, pstring s, const char *dir,BOOL wideli
p = strrchr_m(base_name,'/');
if (!p)
return(True);
return readlink_check(conn, dir, s);
if (!vfs_GetWd(conn,wd)) {
DEBUG(0,("couldn't vfs_GetWd for %s %s\n",s,dir));
@ -858,7 +915,7 @@ BOOL reduce_name(connection_struct *conn, pstring s, const char *dir,BOOL wideli
if (!vfs_GetWd(conn,newname)) {
vfs_ChDir(conn,wd);
DEBUG(2,("couldn't get vfs_GetWd for %s %s\n",s,dir2));
DEBUG(2,("couldn't get vfs_GetWd for %s %s\n",s,base_name));
return(False);
}
@ -878,6 +935,11 @@ BOOL reduce_name(connection_struct *conn, pstring s, const char *dir,BOOL wideli
return(False);
}
if (!readlink_check(conn, dir, newname)) {
DEBUG(2, ("Bad access attemt? %s is a symlink outside the share path", s));
return(False);
}
if (relative) {
if (newname[l] == '/')
pstrcpy(s,newname + l + 1);
@ -896,3 +958,4 @@ BOOL reduce_name(connection_struct *conn, pstring s, const char *dir,BOOL wideli
return(True);
#endif
}