diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/client/client.c | 3 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 77 |
2 files changed, 8 insertions, 72 deletions
diff --git a/source3/client/client.c b/source3/client/client.c index f2f43656cb..a0470315f8 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -1650,7 +1650,6 @@ static int cmd_symlink(void) return 1; } - pstrcpy(oldname,cur_dir); pstrcpy(newname,cur_dir); if (!next_token_nr(NULL,buf,NULL,sizeof(buf)) || @@ -1659,7 +1658,7 @@ static int cmd_symlink(void) return 1; } - pstrcat(oldname,buf); + pstrcpy(oldname,buf); pstrcat(newname,buf2); if (!cli_unix_symlink(cli, oldname, newname)) { diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index f948b06718..23272752c6 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -2400,7 +2400,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, if (lp_dos_filetime_resolution(SNUM(conn))) { c_time &= ~1; sbuf.st_atime &= ~1; - sbuf.st_mtime &= ~1; + sbuf.st_ctime &= ~1; sbuf.st_mtime &= ~1; } @@ -2862,70 +2862,6 @@ NTSTATUS set_delete_on_close_over_all(files_struct *fsp, BOOL delete_on_close) } /**************************************************************************** - Returns true if this pathname is within the share, and thus safe. -****************************************************************************/ - -static int ensure_link_is_safe(connection_struct *conn, const char *link_dest_in) -{ -#ifdef PATH_MAX - char resolved_name[PATH_MAX+1]; -#else - pstring resolved_name; -#endif - fstring last_component; - pstring link_dest; - pstring link_test; - char *p; - BOOL bad_path = False; - SMB_STRUCT_STAT sbuf; - - pstrcpy(link_dest, link_dest_in); - unix_convert(link_dest,conn,0,&bad_path,&sbuf); - - p = strrchr_m(link_dest, '/'); - if (p) { - fstrcpy(last_component, p+1); - *p = '\0'; - } else { - fstrcpy(last_component, link_dest); - pstrcpy(link_dest, "./"); - } - - if (SMB_VFS_REALPATH(conn,link_dest,resolved_name) == NULL) - return -1; - - DEBUG(10,("ensure_link_is_safe: realpath: link_dest (%s) -> real name (%s)\n", - link_dest, resolved_name )); - - pstrcpy(link_dest, resolved_name); - pstrcat(link_dest, "/"); - pstrcat(link_dest, last_component); - - if (*link_dest != '/') { - /* Relative path. */ - pstrcpy(link_test, conn->connectpath); - pstrcat(link_test, "/"); - pstrcat(link_test, link_dest); - } else { - pstrcpy(link_test, link_dest); - } - - DEBUG(10,("ensure_link_is_safe: connectpath = %s, absolute resolved path = %s\n", - conn->connectpath, link_test )); - - /* - * Check if the link is within the share. - */ - - if (strncmp(conn->connectpath, link_test, strlen(conn->connectpath))) { - errno = EACCES; - return -1; - } - - return 0; -} - -/**************************************************************************** Set a hard link (called by UNIX extensions and by NT rename with HARD link code. ****************************************************************************/ @@ -3506,12 +3442,16 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", srvstr_pull(inbuf, link_target, pdata, sizeof(link_target), -1, STR_TERMINATE); /* !widelinks forces the target path to be within the share. */ + /* This means we can interpret the target as a pathname. */ if (!lp_widelinks(SNUM(conn))) { pstring rel_name; char *last_dirp = NULL; unix_format(link_target); - + if (*link_target == '/') { + /* No absolute paths allowed. */ + return(UNIXERROR(ERRDOS,ERRnoaccess)); + } pstrcpy(rel_name, newname); last_dirp = strrchr_m(rel_name, '/'); if (last_dirp) { @@ -3520,11 +3460,8 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", pstrcpy(rel_name, "./"); } pstrcat(rel_name, link_target); - if (ensure_link_is_safe(conn, rel_name) != 0) { - return(UNIXERROR(ERRDOS,ERRnoaccess)); - } - if (check_name(link_target, conn)) { + if (!check_name(rel_name, conn)) { return(UNIXERROR(ERRDOS,ERRnoaccess)); } } |