summaryrefslogtreecommitdiffstats
path: root/source3/smbd
diff options
context:
space:
mode:
authorTim Prouty <tprouty@samba.org>2009-06-04 18:39:55 -0700
committerTim Prouty <tprouty@samba.org>2009-06-10 13:13:26 -0700
commit6088e554f542c62405148c60fe5dedbee1c9cdd0 (patch)
tree1e5196c1b0893ff807577cd0af9f5c08b5863abf /source3/smbd
parentab779f5c345ef59308362781501e4ae1e1191496 (diff)
downloadsamba-6088e554f542c62405148c60fe5dedbee1c9cdd0.tar.gz
samba-6088e554f542c62405148c60fe5dedbee1c9cdd0.tar.xz
samba-6088e554f542c62405148c60fe5dedbee1c9cdd0.zip
s3: Make all callers of SMB_VFS_CREATEFILE call unix_convert first
This step is a requirement to change SMB_VFS_CREATEFILE to take an smb_filename struct.
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/nttrans.c114
-rw-r--r--source3/smbd/reply.c142
-rw-r--r--source3/smbd/smb2_create.c35
-rw-r--r--source3/smbd/trans2.c58
4 files changed, 209 insertions, 140 deletions
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 4c216cc6bef..11d1c4b8a92 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -416,6 +416,7 @@ static void do_ntcreate_pipe_open(connection_struct *conn,
void reply_ntcreate_and_X(struct smb_request *req)
{
connection_struct *conn = req->conn;
+ struct smb_filename *smb_fname = NULL;
char *fname = NULL;
uint32 flags;
uint32 access_mask;
@@ -429,7 +430,6 @@ void reply_ntcreate_and_X(struct smb_request *req)
reply bits separately. */
uint32 fattr=0;
SMB_OFF_T file_len = 0;
- SMB_STRUCT_STAT sbuf;
int info = 0;
files_struct *fsp = NULL;
char *p = NULL;
@@ -443,8 +443,6 @@ void reply_ntcreate_and_X(struct smb_request *req)
START_PROFILE(SMBntcreateX);
- SET_STAT_INVALID(sbuf);
-
if (req->wct < 24) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
return;
@@ -468,8 +466,7 @@ void reply_ntcreate_and_X(struct smb_request *req)
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBntcreateX);
- return;
+ goto out;
}
DEBUG(10,("reply_ntcreate_and_X: flags = 0x%x, access_mask = 0x%x "
@@ -498,12 +495,10 @@ void reply_ntcreate_and_X(struct smb_request *req)
if (IS_IPC(conn)) {
if (lp_nt_pipe_support()) {
do_ntcreate_pipe_open(conn, req);
- END_PROFILE(SMBntcreateX);
- return;
+ goto out;
}
reply_doserror(req, ERRDOS, ERRnoaccess);
- END_PROFILE(SMBntcreateX);
- return;
+ goto out;
}
oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
@@ -512,12 +507,24 @@ void reply_ntcreate_and_X(struct smb_request *req)
? BATCH_OPLOCK : 0;
}
+ status = unix_convert(ctx, conn, fname, &smb_fname, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ goto out;
+ }
+
+ status = get_full_smb_filename(ctx, smb_fname, &fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ goto out;
+ }
+
status = SMB_VFS_CREATE_FILE(
conn, /* conn */
req, /* req */
root_dir_fid, /* root_dir_fid */
fname, /* fname */
- CFF_DOS_PATH, /* create_file_flags */
+ 0, /* create_file_flags */
access_mask, /* access_mask */
share_access, /* share_access */
create_disposition, /* create_disposition*/
@@ -529,13 +536,12 @@ void reply_ntcreate_and_X(struct smb_request *req)
NULL, /* ea_list */
&fsp, /* result */
&info, /* pinfo */
- &sbuf); /* psbuf */
+ &smb_fname->st); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(req->mid)) {
/* We have re-scheduled this call, no error. */
- END_PROFILE(SMBntcreateX);
- return;
+ goto out;
}
if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
reply_botherror(req, status, ERRDOS, ERRfilexists);
@@ -543,8 +549,7 @@ void reply_ntcreate_and_X(struct smb_request *req)
else {
reply_nterror(req, status);
}
- END_PROFILE(SMBntcreateX);
- return;
+ goto out;
}
/*
@@ -572,8 +577,8 @@ void reply_ntcreate_and_X(struct smb_request *req)
oplock_granted = NO_OPLOCK_RETURN;
}
- file_len = sbuf.st_ex_size;
- fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
+ file_len = smb_fname->st.st_ex_size;
+ fattr = dos_mode(conn,fsp->fsp_name,&smb_fname->st);
if (fattr == 0) {
fattr = FILE_ATTRIBUTE_NORMAL;
}
@@ -606,9 +611,9 @@ void reply_ntcreate_and_X(struct smb_request *req)
p += 4;
/* Create time. */
- c_timespec = sbuf.st_ex_btime;
- a_timespec = sbuf.st_ex_atime;
- m_timespec = sbuf.st_ex_mtime;
+ c_timespec = smb_fname->st.st_ex_btime;
+ a_timespec = smb_fname->st.st_ex_atime;
+ m_timespec = smb_fname->st.st_ex_mtime;
if (lp_dos_filetime_resolution(SNUM(conn))) {
dos_filetime_timespec(&c_timespec);
@@ -626,7 +631,7 @@ void reply_ntcreate_and_X(struct smb_request *req)
p += 8;
SIVAL(p,0,fattr); /* File Attributes. */
p += 4;
- SOFF_T(p, 0, SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf));
+ SOFF_T(p, 0, SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&smb_fname->st));
p += 8;
SOFF_T(p,0,file_len);
p += 8;
@@ -639,8 +644,8 @@ void reply_ntcreate_and_X(struct smb_request *req)
if (flags & EXTENDED_RESPONSE_REQUIRED) {
uint32 perms = 0;
p += 25;
- if (fsp->is_directory
- || can_write_to_file(conn, fsp->fsp_name, &sbuf)) {
+ if (fsp->is_directory ||
+ can_write_to_file(conn, fsp->fsp_name, &smb_fname->st)) {
perms = FILE_GENERIC_ALL;
} else {
perms = FILE_GENERIC_READ|FILE_EXECUTE;
@@ -652,6 +657,8 @@ void reply_ntcreate_and_X(struct smb_request *req)
fsp->fnum, fsp->fsp_name));
chain_reply(req);
+ out:
+ TALLOC_FREE(smb_fname);
END_PROFILE(SMBntcreateX);
return;
}
@@ -837,13 +844,13 @@ static void call_nt_transact_create(connection_struct *conn,
char **ppdata, uint32 data_count,
uint32 max_data_count)
{
+ struct smb_filename *smb_fname = NULL;
char *fname = NULL;
char *params = *ppparams;
char *data = *ppdata;
/* Breakout the oplock request bits so we can set the reply bits separately. */
uint32 fattr=0;
SMB_OFF_T file_len = 0;
- SMB_STRUCT_STAT sbuf;
int info = 0;
files_struct *fsp = NULL;
char *p = NULL;
@@ -868,8 +875,6 @@ static void call_nt_transact_create(connection_struct *conn,
uint8_t oplock_granted;
TALLOC_CTX *ctx = talloc_tos();
- SET_STAT_INVALID(sbuf);
-
DEBUG(5,("call_nt_transact_create\n"));
/*
@@ -883,10 +888,10 @@ static void call_nt_transact_create(connection_struct *conn,
ppsetup, setup_count,
ppparams, parameter_count,
ppdata, data_count);
- return;
+ goto out;
}
reply_doserror(req, ERRDOS, ERRnoaccess);
- return;
+ goto out;
}
/*
@@ -896,7 +901,7 @@ static void call_nt_transact_create(connection_struct *conn,
if(parameter_count < 54) {
DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)parameter_count));
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
+ goto out;
}
flags = IVAL(params,0);
@@ -927,7 +932,7 @@ static void call_nt_transact_create(connection_struct *conn,
"%u, data_count = %u\n", (unsigned int)ea_len,
(unsigned int)sd_len, (unsigned int)data_count));
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
+ goto out;
}
if (sd_len) {
@@ -941,7 +946,7 @@ static void call_nt_transact_create(connection_struct *conn,
"unmarshall_sec_desc failed: %s\n",
nt_errstr(status)));
reply_nterror(req, status);
- return;
+ goto out;
}
}
@@ -951,7 +956,7 @@ static void call_nt_transact_create(connection_struct *conn,
"EA's not supported.\n",
(unsigned int)ea_len));
reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
- return;
+ goto out;
}
if (ea_len < 10) {
@@ -959,7 +964,7 @@ static void call_nt_transact_create(connection_struct *conn,
"too small (should be more than 10)\n",
(unsigned int)ea_len ));
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
+ goto out;
}
/* We have already checked that ea_len <= data_count here. */
@@ -967,7 +972,7 @@ static void call_nt_transact_create(connection_struct *conn,
ea_len);
if (ea_list == NULL) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
+ goto out;
}
}
@@ -976,7 +981,7 @@ static void call_nt_transact_create(connection_struct *conn,
STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- return;
+ goto out;
}
oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
@@ -985,12 +990,24 @@ static void call_nt_transact_create(connection_struct *conn,
? BATCH_OPLOCK : 0;
}
+ status = unix_convert(ctx, conn, fname, &smb_fname, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ goto out;
+ }
+
+ status = get_full_smb_filename(ctx, smb_fname, &fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ goto out;
+ }
+
status = SMB_VFS_CREATE_FILE(
conn, /* conn */
req, /* req */
root_dir_fid, /* root_dir_fid */
fname, /* fname */
- CFF_DOS_PATH, /* create_file_flags */
+ 0, /* create_file_flags */
access_mask, /* access_mask */
share_access, /* share_access */
create_disposition, /* create_disposition*/
@@ -1002,7 +1019,7 @@ static void call_nt_transact_create(connection_struct *conn,
ea_list, /* ea_list */
&fsp, /* result */
&info, /* pinfo */
- &sbuf); /* psbuf */
+ &smb_fname->st); /* psbuf */
if(!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(req->mid)) {
@@ -1010,7 +1027,7 @@ static void call_nt_transact_create(connection_struct *conn,
return;
}
reply_openerror(req, status);
- return;
+ goto out;
}
/*
@@ -1038,8 +1055,8 @@ static void call_nt_transact_create(connection_struct *conn,
oplock_granted = NO_OPLOCK_RETURN;
}
- file_len = sbuf.st_ex_size;
- fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
+ file_len = smb_fname->st.st_ex_size;
+ fattr = dos_mode(conn, fsp->fsp_name, &smb_fname->st);
if (fattr == 0) {
fattr = FILE_ATTRIBUTE_NORMAL;
}
@@ -1054,7 +1071,7 @@ static void call_nt_transact_create(connection_struct *conn,
params = nttrans_realloc(ppparams, param_len);
if(params == NULL) {
reply_doserror(req, ERRDOS, ERRnomem);
- return;
+ goto out;
}
p = params;
@@ -1072,9 +1089,9 @@ static void call_nt_transact_create(connection_struct *conn,
p += 8;
/* Create time. */
- c_timespec = sbuf.st_ex_btime;
- a_timespec = sbuf.st_ex_atime;
- m_timespec = sbuf.st_ex_mtime;
+ c_timespec = smb_fname->st.st_ex_btime;
+ a_timespec = smb_fname->st.st_ex_atime;
+ m_timespec = smb_fname->st.st_ex_mtime;
if (lp_dos_filetime_resolution(SNUM(conn))) {
dos_filetime_timespec(&c_timespec);
@@ -1092,7 +1109,7 @@ static void call_nt_transact_create(connection_struct *conn,
p += 8;
SIVAL(p,0,fattr); /* File Attributes. */
p += 4;
- SOFF_T(p, 0, SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf));
+ SOFF_T(p, 0, SMB_VFS_GET_ALLOC_SIZE(conn, fsp, &smb_fname->st));
p += 8;
SOFF_T(p,0,file_len);
p += 8;
@@ -1105,8 +1122,8 @@ static void call_nt_transact_create(connection_struct *conn,
if (flags & EXTENDED_RESPONSE_REQUIRED) {
uint32 perms = 0;
p += 25;
- if (fsp->is_directory
- || can_write_to_file(conn, fsp->fsp_name, &sbuf)) {
+ if (fsp->is_directory ||
+ can_write_to_file(conn, fsp->fsp_name, &smb_fname->st)) {
perms = FILE_GENERIC_ALL;
} else {
perms = FILE_GENERIC_READ|FILE_EXECUTE;
@@ -1118,7 +1135,8 @@ static void call_nt_transact_create(connection_struct *conn,
/* Send the required number of replies */
send_nt_replies(conn, req, NT_STATUS_OK, params, param_len, *ppdata, 0);
-
+ out:
+ TALLOC_FREE(smb_fname);
return;
}
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 70d5537e042..844bcc1882a 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -1702,12 +1702,12 @@ void reply_fclose(struct smb_request *req)
void reply_open(struct smb_request *req)
{
connection_struct *conn = req->conn;
+ struct smb_filename *smb_fname = NULL;
char *fname = NULL;
uint32 fattr=0;
SMB_OFF_T size = 0;
time_t mtime=0;
int info;
- SMB_STRUCT_STAT sbuf;
files_struct *fsp;
int oplock_request;
int deny_mode;
@@ -1721,12 +1721,9 @@ void reply_open(struct smb_request *req)
START_PROFILE(SMBopen);
- SET_STAT_INVALID(sbuf);
-
if (req->wct < 2) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- END_PROFILE(SMBopen);
- return;
+ goto out;
}
oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
@@ -1737,8 +1734,7 @@ void reply_open(struct smb_request *req)
STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBopen);
- return;
+ goto out;
}
if (!map_open_params_to_ntcreate(
@@ -1749,12 +1745,24 @@ void reply_open(struct smb_request *req)
return;
}
+ status = unix_convert(ctx, conn, fname, &smb_fname, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ goto out;
+ }
+
+ status = get_full_smb_filename(ctx, smb_fname, &fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ goto out;
+ }
+
status = SMB_VFS_CREATE_FILE(
conn, /* conn */
req, /* req */
0, /* root_dir_fid */
fname, /* fname */
- CFF_DOS_PATH, /* create_file_flags */
+ 0, /* create_file_flags */
access_mask, /* access_mask */
share_mode, /* share_access */
create_disposition, /* create_disposition*/
@@ -1766,29 +1774,26 @@ void reply_open(struct smb_request *req)
NULL, /* ea_list */
&fsp, /* result */
&info, /* pinfo */
- &sbuf); /* psbuf */
+ &smb_fname->st); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(req->mid)) {
/* We have re-scheduled this call. */
- END_PROFILE(SMBopen);
- return;
+ goto out;
}
reply_openerror(req, status);
- END_PROFILE(SMBopen);
- return;
+ goto out;
}
- size = sbuf.st_ex_size;
- fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
- mtime = convert_timespec_to_time_t(sbuf.st_ex_mtime);
+ size = smb_fname->st.st_ex_size;
+ fattr = dos_mode(conn,fsp->fsp_name,&smb_fname->st);
+ mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
if (fattr & aDIR) {
DEBUG(3,("attempt to open a directory %s\n",fsp->fsp_name));
close_file(req, fsp, ERROR_CLOSE);
reply_doserror(req, ERRDOS,ERRnoaccess);
- END_PROFILE(SMBopen);
- return;
+ goto out;
}
reply_outbuf(req, 7, 0);
@@ -1811,6 +1816,8 @@ void reply_open(struct smb_request *req)
SCVAL(req->outbuf,smb_flg,
CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
}
+ out:
+ TALLOC_FREE(smb_fname);
END_PROFILE(SMBopen);
return;
}
@@ -1822,6 +1829,7 @@ void reply_open(struct smb_request *req)
void reply_open_and_X(struct smb_request *req)
{
connection_struct *conn = req->conn;
+ struct smb_filename *smb_fname = NULL;
char *fname = NULL;
uint16 open_flags;
int deny_mode;
@@ -1838,7 +1846,6 @@ void reply_open_and_X(struct smb_request *req)
int smb_ofun;
uint32 fattr=0;
int mtime=0;
- SMB_STRUCT_STAT sbuf;
int smb_action = 0;
files_struct *fsp;
NTSTATUS status;
@@ -1854,12 +1861,9 @@ void reply_open_and_X(struct smb_request *req)
if (req->wct < 15) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- END_PROFILE(SMBopenX);
- return;
+ goto out;
}
- SET_STAT_INVALID(sbuf);
-
open_flags = SVAL(req->vwv+2, 0);
deny_mode = SVAL(req->vwv+3, 0);
smb_attr = SVAL(req->vwv+5, 0);
@@ -1876,8 +1880,7 @@ void reply_open_and_X(struct smb_request *req)
} else {
reply_doserror(req, ERRSRV, ERRaccess);
}
- END_PROFILE(SMBopenX);
- return;
+ goto out;
}
/* XXXX we need to handle passed times, sattr and flags */
@@ -1885,16 +1888,26 @@ void reply_open_and_X(struct smb_request *req)
STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBopenX);
- return;
+ goto out;
}
if (!map_open_params_to_ntcreate(
fname, deny_mode, smb_ofun, &access_mask,
&share_mode, &create_disposition, &create_options)) {
reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
- END_PROFILE(SMBopenX);
- return;
+ goto out;
+ }
+
+ status = unix_convert(ctx, conn, fname, &smb_fname, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ goto out;
+ }
+
+ status = get_full_smb_filename(ctx, smb_fname, &fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ goto out;
}
status = SMB_VFS_CREATE_FILE(
@@ -1902,7 +1915,7 @@ void reply_open_and_X(struct smb_request *req)
req, /* req */
0, /* root_dir_fid */
fname, /* fname */
- CFF_DOS_PATH, /* create_file_flags */
+ 0, /* create_file_flags */
access_mask, /* access_mask */
share_mode, /* share_access */
create_disposition, /* create_disposition*/
@@ -1914,16 +1927,15 @@ void reply_open_and_X(struct smb_request *req)
NULL, /* ea_list */
&fsp, /* result */
&smb_action, /* pinfo */
- &sbuf); /* psbuf */
+ &smb_fname->st); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBopenX);
if (open_was_deferred(req->mid)) {
/* We have re-scheduled this call. */
- return;
+ goto out;
}
reply_openerror(req, status);
- return;
+ goto out;
}
/* Setting the "size" field in vwv9 and vwv10 causes the file to be set to this size,
@@ -1933,26 +1945,24 @@ void reply_open_and_X(struct smb_request *req)
if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
close_file(req, fsp, ERROR_CLOSE);
reply_nterror(req, NT_STATUS_DISK_FULL);
- END_PROFILE(SMBopenX);
- return;
+ goto out;
}
retval = vfs_set_filelen(fsp, (SMB_OFF_T)allocation_size);
if (retval < 0) {
close_file(req, fsp, ERROR_CLOSE);
reply_nterror(req, NT_STATUS_DISK_FULL);
- END_PROFILE(SMBopenX);
- return;
+ goto out;
}
- sbuf.st_ex_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf);
+ smb_fname->st.st_ex_size =
+ SMB_VFS_GET_ALLOC_SIZE(conn, fsp, &smb_fname->st);
}
- fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
- mtime = convert_timespec_to_time_t(sbuf.st_ex_mtime);
+ fattr = dos_mode(conn,fsp->fsp_name,&smb_fname->st);
+ mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
if (fattr & aDIR) {
close_file(req, fsp, ERROR_CLOSE);
reply_doserror(req, ERRDOS, ERRnoaccess);
- END_PROFILE(SMBopenX);
- return;
+ goto out;
}
/* If the caller set the extended oplock request bit
@@ -1996,7 +2006,7 @@ void reply_open_and_X(struct smb_request *req)
} else {
srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime);
}
- SIVAL(req->outbuf,smb_vwv6,(uint32)sbuf.st_ex_size);
+ SIVAL(req->outbuf,smb_vwv6,(uint32)smb_fname->st.st_ex_size);
SSVAL(req->outbuf,smb_vwv8,GET_OPENX_MODE(deny_mode));
SSVAL(req->outbuf,smb_vwv11,smb_action);
@@ -2004,8 +2014,10 @@ void reply_open_and_X(struct smb_request *req)
SIVAL(req->outbuf, smb_vwv15, STD_RIGHT_ALL_ACCESS);
}
- END_PROFILE(SMBopenX);
chain_reply(req);
+ out:
+ TALLOC_FREE(smb_fname);
+ END_PROFILE(SMBopenX);
return;
}
@@ -2050,12 +2062,12 @@ void reply_ulogoffX(struct smb_request *req)
void reply_mknew(struct smb_request *req)
{
connection_struct *conn = req->conn;
+ struct smb_filename *smb_fname = NULL;
char *fname = NULL;
uint32 fattr = 0;
struct smb_file_time ft;
files_struct *fsp;
int oplock_request = 0;
- SMB_STRUCT_STAT sbuf;
NTSTATUS status;
uint32 access_mask = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
uint32 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
@@ -2065,12 +2077,10 @@ void reply_mknew(struct smb_request *req)
START_PROFILE(SMBcreate);
ZERO_STRUCT(ft);
- SET_STAT_INVALID(sbuf);
if (req->wct < 3) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- END_PROFILE(SMBcreate);
- return;
+ goto out;
}
fattr = SVAL(req->vwv+0, 0);
@@ -2083,8 +2093,7 @@ void reply_mknew(struct smb_request *req)
STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBcreate);
- return;
+ goto out;
}
if (fattr & aVOLID) {
@@ -2100,12 +2109,24 @@ void reply_mknew(struct smb_request *req)
create_disposition = FILE_OVERWRITE_IF;
}
+ status = unix_convert(ctx, conn, fname, &smb_fname, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ goto out;
+ }
+
+ status = get_full_smb_filename(ctx, smb_fname, &fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ goto out;
+ }
+
status = SMB_VFS_CREATE_FILE(
conn, /* conn */
req, /* req */
0, /* root_dir_fid */
fname, /* fname */
- CFF_DOS_PATH, /* create_file_flags */
+ 0, /* create_file_flags */
access_mask, /* access_mask */
share_mode, /* share_access */
create_disposition, /* create_disposition*/
@@ -2117,24 +2138,23 @@ void reply_mknew(struct smb_request *req)
NULL, /* ea_list */
&fsp, /* result */
NULL, /* pinfo */
- &sbuf); /* psbuf */
+ &smb_fname->st); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBcreate);
if (open_was_deferred(req->mid)) {
/* We have re-scheduled this call. */
- return;
+ goto out;
}
reply_openerror(req, status);
- return;
+ goto out;
}
- ft.atime = sbuf.st_ex_atime; /* atime. */
- status = smb_set_file_time(conn, fsp, fsp->fsp_name, &sbuf, &ft, true);
+ ft.atime = smb_fname->st.st_ex_atime; /* atime. */
+ status = smb_set_file_time(conn, fsp, fsp->fsp_name, &smb_fname->st,
+ &ft, true);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBcreate);
- reply_openerror(req, status);
- return;
+ goto out;
}
reply_outbuf(req, 1, 0);
@@ -2154,6 +2174,8 @@ void reply_mknew(struct smb_request *req)
DEBUG( 3, ( "reply_mknew %s fd=%d dmode=0x%x\n",
fsp->fsp_name, fsp->fh->fd, (unsigned int)fattr ) );
+ out:
+ TALLOC_FREE(smb_fname);
END_PROFILE(SMBcreate);
return;
}
diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index e264afab140..73c7cec63a5 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -252,6 +252,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
files_struct *result;
int info;
SMB_STRUCT_STAT sbuf;
+ struct smb_filename *smb_fname = NULL;
req = tevent_req_create(mem_ctx, &state,
struct smbd_smb2_create_state);
@@ -265,7 +266,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
smbreq = smbd_smb2_fake_smb_request(smb2req);
if (tevent_req_nomem(smbreq, req)) {
- return tevent_req_post(req, ev);
+ goto out;
}
if (IS_IPC(smbreq->conn)) {
@@ -273,7 +274,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
if (!lp_nt_pipe_support()) {
tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
- return tevent_req_post(req, ev);
+ goto out;
}
/* Strip \\ off the name. */
@@ -284,7 +285,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
status = open_np_file(smbreq, pipe_name, &result);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
- return tevent_req_post(req, ev);
+ goto out;
}
info = FILE_WAS_OPENED;
ZERO_STRUCT(sbuf);
@@ -292,7 +293,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
status = file_new(smbreq, smbreq->conn, &result);
if(!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
- return tevent_req_post(req, ev);
+ goto out;
}
status = print_fsp_open(smbreq,
@@ -304,19 +305,32 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
if (!NT_STATUS_IS_OK(status)) {
file_free(smbreq, result);
tevent_req_nterror(req, status);
- return tevent_req_post(req, ev);
+ goto out;
}
info = FILE_WAS_CREATED;
} else {
+ char *fname = NULL;
+
/* these are ignored for SMB2 */
in_create_options &= ~(0x10);/* NTCREATEX_OPTIONS_SYNC_ALERT */
in_create_options &= ~(0x20);/* NTCREATEX_OPTIONS_ASYNC_ALERT */
+ status = unix_convert(talloc_tos(), smbreq->conn, in_name,
+ &smb_fname, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+
+ status = get_full_smb_filename(talloc_tos(), smb_fname, &fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+
status = SMB_VFS_CREATE_FILE(smbreq->conn,
smbreq,
0, /* root_dir_fid */
- in_name,
- CFF_DOS_PATH, /* create_file_flags */
+ fname,
+ 0, /* create_file_flags */
in_desired_access,
in_share_access,
in_create_disposition,
@@ -328,11 +342,12 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
NULL, /* ea_list */
&result,
&info,
- &sbuf);
+ &smb_fname->st);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
- return tevent_req_post(req, ev);
+ goto out;
}
+ sbuf = smb_fname->st;
}
smb2req->compat_chain_fsp = smbreq->chain_fsp;
@@ -359,6 +374,8 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
state->out_file_id_volatile = result->fnum;
tevent_req_done(req);
+ out:
+ TALLOC_FREE(smb_fname);
return tevent_req_post(req, ev);
}
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index a8120d42fbe..a36e9f588ac 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -869,6 +869,7 @@ static void call_trans2open(connection_struct *conn,
char **ppdata, int total_data,
unsigned int max_data_bytes)
{
+ struct smb_filename *smb_fname = NULL;
char *params = *pparams;
char *pdata = *ppdata;
int deny_mode;
@@ -886,7 +887,6 @@ static void call_trans2open(connection_struct *conn,
SMB_OFF_T size=0;
int fattr=0,mtime=0;
SMB_INO_T inode = 0;
- SMB_STRUCT_STAT sbuf;
int smb_action = 0;
files_struct *fsp;
struct ea_list *ea_list = NULL;
@@ -898,15 +898,13 @@ static void call_trans2open(connection_struct *conn,
uint32 create_options = 0;
TALLOC_CTX *ctx = talloc_tos();
- SET_STAT_INVALID(sbuf);
-
/*
* Ensure we have enough parameters to perform the operation.
*/
if (total_params < 29) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
+ goto out;
}
flags = SVAL(params, 0);
@@ -928,7 +926,7 @@ static void call_trans2open(connection_struct *conn,
if (IS_IPC(conn)) {
reply_doserror(req, ERRSRV, ERRaccess);
- return;
+ goto out;
}
srvstr_get_path(ctx, params, req->flags2, &fname, pname,
@@ -936,7 +934,7 @@ static void call_trans2open(connection_struct *conn,
&status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- return;
+ goto out;
}
DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
@@ -945,7 +943,7 @@ static void call_trans2open(connection_struct *conn,
if (open_ofun == 0) {
reply_nterror(req, NT_STATUS_OBJECT_NAME_COLLISION);
- return;
+ goto out;
}
if (!map_open_params_to_ntcreate(fname, deny_mode, open_ofun,
@@ -954,37 +952,49 @@ static void call_trans2open(connection_struct *conn,
&create_disposition,
&create_options)) {
reply_doserror(req, ERRDOS, ERRbadaccess);
- return;
+ goto out;
}
/* Any data in this call is an EA list. */
if (total_data && (total_data != 4) && !lp_ea_support(SNUM(conn))) {
reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
- return;
+ goto out;
}
if (total_data != 4) {
if (total_data < 10) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
+ goto out;
}
if (IVAL(pdata,0) > total_data) {
DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
IVAL(pdata,0), (unsigned int)total_data));
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
+ goto out;
}
ea_list = read_ea_list(talloc_tos(), pdata + 4,
total_data - 4);
if (!ea_list) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
+ goto out;
}
} else if (IVAL(pdata,0) != 4) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
+ goto out;
+ }
+
+ status = unix_convert(ctx, conn, fname, &smb_fname, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ goto out;
+ }
+
+ status = get_full_smb_filename(ctx, smb_fname, &fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ goto out;
}
status = SMB_VFS_CREATE_FILE(
@@ -992,7 +1002,7 @@ static void call_trans2open(connection_struct *conn,
req, /* req */
0, /* root_dir_fid */
fname, /* fname */
- CFF_DOS_PATH, /* create_file_flags */
+ 0, /* create_file_flags */
access_mask, /* access_mask */
share_mode, /* share_access */
create_disposition, /* create_disposition*/
@@ -1004,32 +1014,32 @@ static void call_trans2open(connection_struct *conn,
ea_list, /* ea_list */
&fsp, /* result */
&smb_action, /* pinfo */
- &sbuf); /* psbuf */
+ &smb_fname->st); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(req->mid)) {
/* We have re-scheduled this call. */
- return;
+ goto out;
}
reply_openerror(req, status);
- return;
+ goto out;
}
- size = get_file_size_stat(&sbuf);
- fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
- mtime = convert_timespec_to_time_t(sbuf.st_ex_mtime);
- inode = sbuf.st_ex_ino;
+ size = get_file_size_stat(&smb_fname->st);
+ fattr = dos_mode(conn, fsp->fsp_name, &smb_fname->st);
+ mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
+ inode = smb_fname->st.st_ex_ino;
if (fattr & aDIR) {
close_file(req, fsp, ERROR_CLOSE);
reply_doserror(req, ERRDOS,ERRnoaccess);
- return;
+ goto out;
}
/* Realloc the size of parameters and data we will return */
*pparams = (char *)SMB_REALLOC(*pparams, 30);
if(*pparams == NULL ) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
+ goto out;
}
params = *pparams;
@@ -1061,6 +1071,8 @@ static void call_trans2open(connection_struct *conn,
/* Send the required number of replies */
send_trans2_replies(conn, req, params, 30, *ppdata, 0, max_data_bytes);
+ out:
+ TALLOC_FREE(smb_fname);
}
/*********************************************************