summaryrefslogtreecommitdiff
path: root/source3/smbd/trans2.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd/trans2.c')
-rw-r--r--source3/smbd/trans2.c164
1 files changed, 109 insertions, 55 deletions
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index ca90c5ae69..a7d5c427d3 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -1395,14 +1395,17 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
}
if (INFO_LEVEL_IS_UNIX(info_level)) {
- if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) {
+ if (vfs_lstat_smb_fname(conn, pathreal,
+ &sbuf) != 0) {
DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
pathreal,strerror(errno)));
TALLOC_FREE(pathreal);
TALLOC_FREE(fname);
continue;
}
- } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
+ } else if (!VALID_STAT(sbuf) &&
+ vfs_stat_smb_fname(conn, pathreal,
+ &sbuf) != 0) {
/* Needed to show the msdfs symlinks as
* directories */
@@ -2626,7 +2629,7 @@ static void call_trans2qfsinfo(connection_struct *conn,
DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
- if(SMB_VFS_STAT(conn,".",&st)!=0) {
+ if(vfs_stat_smb_fname(conn,".",&st)!=0) {
DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
reply_doserror(req, ERRSRV, ERRinvdevice);
return;
@@ -3871,13 +3874,13 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
char *lock_data = NULL;
bool ms_dfs_link = false;
TALLOC_CTX *ctx = talloc_tos();
+ NTSTATUS status = NT_STATUS_OK;
if (!params) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
return;
}
- ZERO_STRUCT(sbuf);
ZERO_STRUCT(write_time_ts);
if (tran_call == TRANSACT2_QFILEINFO) {
@@ -3915,6 +3918,13 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
return;
}
+ status = create_synthetic_smb_fname_split(talloc_tos(), fname,
+ NULL, &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ return;
+ }
+
if(fsp->fake_file_handle) {
/*
* This is actually for the QUOTA_FAKE_FILE --metze
@@ -3931,18 +3941,25 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
if (INFO_LEVEL_IS_UNIX(info_level)) {
/* Always do lstat for UNIX calls. */
- if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
- DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
+ if (SMB_VFS_LSTAT(conn, smb_fname)) {
+ DEBUG(3,("call_trans2qfilepathinfo: "
+ "SMB_VFS_LSTAT of %s failed "
+ "(%s)\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno)));
reply_unixerror(req,ERRDOS,ERRbadpath);
return;
}
- } else if (SMB_VFS_STAT(conn,fname,&sbuf)) {
- DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
+ } else if (SMB_VFS_STAT(conn, smb_fname)) {
+ DEBUG(3,("call_trans2qfilepathinfo: "
+ "SMB_VFS_STAT of %s failed (%s)\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno)));
reply_unixerror(req, ERRDOS, ERRbadpath);
return;
}
- fileid = vfs_file_id_from_sbuf(conn, &sbuf);
+ fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
get_file_infos(fileid, &delete_pending, &write_time_ts);
} else {
/*
@@ -3952,19 +3969,18 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
return;
}
- if (SMB_VFS_FSTAT(fsp, &sbuf) != 0) {
- DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
+ if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
+ DEBUG(3, ("fstat of fnum %d failed (%s)\n",
+ fsp->fnum, strerror(errno)));
reply_unixerror(req, ERRDOS, ERRbadfid);
return;
}
pos = fsp->fh->position_information;
- fileid = vfs_file_id_from_sbuf(conn, &sbuf);
+ fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
get_file_infos(fileid, &delete_pending, &write_time_ts);
}
} else {
- NTSTATUS status = NT_STATUS_OK;
-
/* qpathinfo */
if (total_params < 7) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
@@ -4005,41 +4021,50 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
return;
}
- sbuf = smb_fname->st;
-
+ /* If this is a stream, check if there is a delete_pending. */
if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
- && is_ntfs_stream_name(fname)) {
- char *base;
- SMB_STRUCT_STAT bsbuf;
-
- status = split_ntfs_stream_name(talloc_tos(), fname,
- &base, NULL);
+ && is_ntfs_stream_smb_fname(smb_fname)) {
+ struct smb_filename *smb_fname_base = NULL;
+
+ /* Create an smb_filename with stream_name == NULL. */
+ status =
+ create_synthetic_smb_fname(talloc_tos(),
+ smb_fname->base_name,
+ NULL, NULL,
+ &smb_fname_base);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(10, ("create_file_unixpath: "
- "split_ntfs_stream_name failed: %s\n",
- nt_errstr(status)));
reply_nterror(req, status);
return;
}
- SMB_ASSERT(!is_ntfs_stream_name(base)); /* paranoia.. */
-
if (INFO_LEVEL_IS_UNIX(info_level)) {
/* Always do lstat for UNIX calls. */
- if (SMB_VFS_LSTAT(conn,base,&bsbuf)) {
- DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",base,strerror(errno)));
+ if (SMB_VFS_LSTAT(conn, smb_fname_base) != 0) {
+ DEBUG(3,("call_trans2qfilepathinfo: "
+ "SMB_VFS_LSTAT of %s failed "
+ "(%s)\n",
+ smb_fname_str_dbg(smb_fname_base),
+ strerror(errno)));
+ TALLOC_FREE(smb_fname_base);
reply_unixerror(req,ERRDOS,ERRbadpath);
return;
}
} else {
- if (SMB_VFS_STAT(conn,base,&bsbuf) != 0) {
- DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",base,strerror(errno)));
+ if (SMB_VFS_STAT(conn, smb_fname_base) != 0) {
+ DEBUG(3,("call_trans2qfilepathinfo: "
+ "fileinfo of %s failed "
+ "(%s)\n",
+ smb_fname_str_dbg(smb_fname_base),
+ strerror(errno)));
+ TALLOC_FREE(smb_fname_base);
reply_unixerror(req,ERRDOS,ERRbadpath);
return;
}
}
- fileid = vfs_file_id_from_sbuf(conn, &bsbuf);
+ fileid = vfs_file_id_from_sbuf(conn,
+ &smb_fname_base->st);
+ TALLOC_FREE(smb_fname_base);
get_file_infos(fileid, &delete_pending, NULL);
if (delete_pending) {
reply_nterror(req, NT_STATUS_DELETE_PENDING);
@@ -4049,23 +4074,32 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
if (INFO_LEVEL_IS_UNIX(info_level)) {
/* Always do lstat for UNIX calls. */
- if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
- DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
+ if (SMB_VFS_LSTAT(conn, smb_fname)) {
+ DEBUG(3,("call_trans2qfilepathinfo: "
+ "SMB_VFS_LSTAT of %s failed (%s)\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno)));
reply_unixerror(req, ERRDOS, ERRbadpath);
return;
}
- } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf) && (info_level != SMB_INFO_IS_NAME_VALID)) {
- ms_dfs_link = check_msdfs_link(conn,fname,&sbuf);
+ } else if (!VALID_STAT(smb_fname->st) &&
+ SMB_VFS_STAT(conn, smb_fname) &&
+ (info_level != SMB_INFO_IS_NAME_VALID)) {
+ ms_dfs_link = check_msdfs_link(conn, fname,
+ &smb_fname->st);
if (!ms_dfs_link) {
- DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
+ DEBUG(3,("call_trans2qfilepathinfo: "
+ "SMB_VFS_STAT of %s failed (%s)\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno)));
reply_unixerror(req, ERRDOS, ERRbadpath);
return;
}
}
- fileid = vfs_file_id_from_sbuf(conn, &sbuf);
+ fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
get_file_infos(fileid, &delete_pending, &write_time_ts);
if (delete_pending) {
reply_nterror(req, NT_STATUS_DELETE_PENDING);
@@ -4073,6 +4107,9 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
}
}
+ /* Set sbuf for use below. */
+ sbuf = smb_fname->st;
+
if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
reply_nterror(req, NT_STATUS_INVALID_LEVEL);
return;
@@ -4511,7 +4548,6 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
case SMB_FILE_STREAM_INFORMATION: {
unsigned int num_streams;
struct stream_struct *streams;
- NTSTATUS status;
DEBUG(10,("call_trans2qfilepathinfo: "
"SMB_FILE_STREAM_INFORMATION\n"));
@@ -4738,7 +4774,6 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
case SMB_QUERY_POSIX_LOCK:
{
- NTSTATUS status = NT_STATUS_INVALID_LEVEL;
uint64_t count;
uint64_t offset;
uint32 lock_pid;
@@ -6024,7 +6059,7 @@ static NTSTATUS smb_unix_mknod(connection_struct *conn,
TALLOC_FREE(parent);
}
- if (SMB_VFS_STAT(conn, fname, psbuf) != 0) {
+ if (vfs_stat_smb_fname(conn, fname, psbuf) != 0) {
status = map_nt_error_from_unix(errno);
SMB_VFS_UNLINK(conn,fname);
return status;
@@ -6742,8 +6777,6 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
return;
}
- ZERO_STRUCT(sbuf);
-
if (tran_call == TRANSACT2_SETFILEINFO) {
if (total_params < 4) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
@@ -6763,6 +6796,13 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
return;
}
+ status = create_synthetic_smb_fname_split(talloc_tos(), fname,
+ NULL, &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ return;
+ }
+
if(fsp->is_directory || fsp->fh->fd == -1) {
/*
* This is actually a SETFILEINFO on a directory
@@ -6771,14 +6811,21 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
*/
if (INFO_LEVEL_IS_UNIX(info_level)) {
/* Always do lstat for UNIX calls. */
- if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
- DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
+ if (SMB_VFS_LSTAT(conn, smb_fname)) {
+ DEBUG(3,("call_trans2setfilepathinfo: "
+ "SMB_VFS_LSTAT of %s failed "
+ "(%s)\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno)));
reply_unixerror(req,ERRDOS,ERRbadpath);
return;
}
} else {
- if (SMB_VFS_STAT(conn,fname,&sbuf) != 0) {
- DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
+ if (SMB_VFS_STAT(conn, smb_fname) != 0) {
+ DEBUG(3,("call_trans2setfilepathinfo: "
+ "fileinfo of %s failed (%s)\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno)));
reply_unixerror(req,ERRDOS,ERRbadpath);
return;
}
@@ -6809,8 +6856,10 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
return;
}
- if (SMB_VFS_FSTAT(fsp, &sbuf) != 0) {
- DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
+ if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
+ DEBUG(3,("call_trans2setfilepathinfo: fstat "
+ "of fnum %d failed (%s)\n", fsp->fnum,
+ strerror(errno)));
reply_unixerror(req, ERRDOS, ERRbadfid);
return;
}
@@ -6847,23 +6896,28 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
return;
}
- sbuf = smb_fname->st;
-
if (INFO_LEVEL_IS_UNIX(info_level)) {
/*
* For CIFS UNIX extensions the target name may not exist.
*/
/* Always do lstat for UNIX calls. */
- SMB_VFS_LSTAT(conn,fname,&sbuf);
-
- } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf)) {
- DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
+ SMB_VFS_LSTAT(conn, smb_fname);
+
+ } else if (!VALID_STAT(smb_fname->st) &&
+ SMB_VFS_STAT(conn, smb_fname)) {
+ DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of "
+ "%s failed (%s)\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno)));
reply_unixerror(req, ERRDOS, ERRbadpath);
return;
}
}
+ /* Set sbuf for use below. */
+ sbuf = smb_fname->st;
+
if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
reply_nterror(req, NT_STATUS_INVALID_LEVEL);
return;