summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/smbd/nttrans.c60
-rw-r--r--source3/smbd/trans2.c95
2 files changed, 126 insertions, 29 deletions
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 1d4acf2844..70b3f0d0e0 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -637,7 +637,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
if((smb_ofun = map_create_disposition( create_disposition )) == -1) {
END_PROFILE(SMBntcreateX);
- return(ERROR_DOS(ERRDOS,ERRnoaccess));
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
/*
@@ -1273,15 +1273,23 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
if ((ea_len + sd_len > data_count) ||
(ea_len > data_count) || (sd_len > data_count) ||
(ea_len + sd_len < ea_len) || (ea_len + sd_len < sd_len)) {
+ DEBUG(10,("call_nt_transact_create - ea_len = %u, sd_len = %u, data_count = %u\n",
+ (unsigned int)ea_len, (unsigned int)sd_len, (unsigned int)data_count ));
return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
- if (ea_len && !lp_ea_support(SNUM(conn))) {
- return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);
- }
+ if (ea_len) {
+ if (!lp_ea_support(SNUM(conn))) {
+ DEBUG(10,("call_nt_transact_create - ea_len = %u but EA's not supported.\n",
+ (unsigned int)ea_len ));
+ return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);
+ }
- if (ea_len < 10) {
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ if (ea_len < 10) {
+ DEBUG(10,("call_nt_transact_create - ea_len = %u - too small (should be more than 10)\n",
+ (unsigned int)ea_len ));
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
}
if (create_options & FILE_OPEN_BY_FILE_ID) {
@@ -1293,8 +1301,9 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
* NT values, as that's what our code is structured to accept.
*/
- if((smb_ofun = map_create_disposition( create_disposition )) == -1)
- return ERROR_DOS(ERRDOS,ERRbadmem);
+ if((smb_ofun = map_create_disposition( create_disposition )) == -1) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
/*
* Get the file name.
@@ -1416,21 +1425,23 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
}
}
- ctx = talloc_init("NTTRANS_CREATE_EA");
- if (!ctx) {
- talloc_destroy(ctx);
- restore_case_semantics(conn, file_attributes);
- return ERROR_NT(NT_STATUS_NO_MEMORY);
- }
+ if (ea_len) {
+ ctx = talloc_init("NTTRANS_CREATE_EA");
+ if (!ctx) {
+ talloc_destroy(ctx);
+ restore_case_semantics(conn, file_attributes);
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
- pdata = data + sd_len;
+ pdata = data + sd_len;
- /* We have already checked that ea_len <= data_count here. */
- ea_list = read_nttrans_ea_list(ctx, pdata, ea_len);
- if (!ea_list ) {
- talloc_destroy(ctx);
- restore_case_semantics(conn, file_attributes);
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ /* We have already checked that ea_len <= data_count here. */
+ ea_list = read_nttrans_ea_list(ctx, pdata, ea_len);
+ if (!ea_list ) {
+ talloc_destroy(ctx);
+ restore_case_semantics(conn, file_attributes);
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
}
/*
@@ -1551,7 +1562,8 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
fsp->desired_access = FILE_GENERIC_ALL;
- if (!NT_STATUS_IS_OK(status = set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION))) {
+ status = set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION);
+ if (!NT_STATUS_IS_OK(status)) {
talloc_destroy(ctx);
close_file(fsp,False);
restore_case_semantics(conn, file_attributes);
@@ -1560,10 +1572,10 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
fsp->desired_access = saved_access;
}
- if (ea_len && smb_action == FILE_WAS_CREATED) {
+ if (ea_len && (smb_action == FILE_WAS_CREATED)) {
status = set_ea(conn, fsp, fname, ea_list);
talloc_destroy(ctx);
- if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK)) {
+ if (!NT_STATUS_IS_OK(status)) {
close_file(fsp,False);
restore_case_semantics(conn, file_attributes);
return ERROR_NT(status);
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 1ae013d23a..a68b165cb0 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -710,6 +710,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
unsigned int max_data_bytes)
{
char *params = *pparams;
+ char *pdata = *ppdata;
int16 open_mode;
int16 open_attr;
BOOL oplock_request;
@@ -729,6 +730,8 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
int smb_action = 0;
BOOL bad_path = False;
files_struct *fsp;
+ TALLOC_CTX *ctx = NULL;
+ struct ea_list *ea_list = NULL;
NTSTATUS status;
/*
@@ -759,7 +762,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
return ERROR_NT(status);
}
- DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
+ DEBUG(3,("call_trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
fname,open_mode, open_attr, open_ofun, open_size));
/* XXXX we need to handle passed times, sattr and flags */
@@ -773,10 +776,38 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
}
+ /* Any data in this call is an EA list. */
+ if (total_data && !lp_ea_support(SNUM(conn))) {
+ return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);
+ }
+
+ if (total_data) {
+ if (total_data < 10) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+
+ if (IVAL(pdata,0) > total_data) {
+ DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
+ IVAL(pdata,0), (unsigned int)total_data));
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+
+ ctx = talloc_init("TRANS2_OPEN_SET_EA");
+ if (!ctx) {
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+ ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
+ if (!ea_list) {
+ talloc_destroy(ctx);
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+ }
+
fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,(uint32)open_attr,
oplock_request, &rmode,&smb_action);
if (!fsp) {
+ talloc_destroy(ctx);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
clear_cached_errors();
@@ -790,10 +821,20 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
mtime = sbuf.st_mtime;
inode = sbuf.st_ino;
if (fmode & aDIR) {
+ talloc_destroy(ctx);
close_file(fsp,False);
return(ERROR_DOS(ERRDOS,ERRnoaccess));
}
+ if (total_data && smb_action == FILE_WAS_CREATED) {
+ status = set_ea(conn, fsp, fname, ea_list);
+ talloc_destroy(ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ close_file(fsp,False);
+ return ERROR_NT(status);
+ }
+ }
+
/* Realloc the size of parameters and data we will return */
params = SMB_REALLOC(*pparams, 28);
if( params == NULL ) {
@@ -3670,7 +3711,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
status = set_ea(conn, fsp, fname, ea_list);
talloc_destroy(ctx);
- if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK)) {
+ if (!NT_STATUS_IS_OK(status)) {
return ERROR_NT(status);
}
break;
@@ -3853,13 +3894,15 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
status = set_delete_on_close_internal(fsp, delete_on_close, dosmode);
- if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
+ if (!NT_STATUS_IS_OK(status)) {
return ERROR_NT(status);
+ }
/* The set is across all open files on this dev/inode pair. */
status =set_delete_on_close_over_all(fsp, delete_on_close);
- if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
+ if (!NT_STATUS_IS_OK(status)) {
return ERROR_NT(status);
+ }
break;
}
@@ -4371,11 +4414,14 @@ static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf,
unsigned int max_data_bytes)
{
char *params = *pparams;
+ char *pdata = *ppdata;
pstring directory;
int ret = -1;
SMB_STRUCT_STAT sbuf;
BOOL bad_path = False;
NTSTATUS status = NT_STATUS_OK;
+ TALLOC_CTX *ctx = NULL;
+ struct ea_list *ea_list = NULL;
if (!CAN_WRITE(conn))
return ERROR_DOS(ERRSRV,ERRaccess);
@@ -4395,14 +4441,53 @@ static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf,
if (bad_path) {
return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
}
- if (check_name(directory,conn))
+
+ /* Any data in this call is an EA list. */
+ if (total_data && !lp_ea_support(SNUM(conn))) {
+ return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);
+ }
+
+ if (total_data) {
+ if (total_data < 10) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+
+ if (IVAL(pdata,0) > total_data) {
+ DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
+ IVAL(pdata,0), (unsigned int)total_data));
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+
+ ctx = talloc_init("TRANS2_MKDIR_SET_EA");
+ if (!ctx) {
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+ ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
+ if (!ea_list) {
+ talloc_destroy(ctx);
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+ }
+
+ if (check_name(directory,conn)) {
ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory,True));
+ }
if(ret < 0) {
+ talloc_destroy(ctx);
DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
}
+ /* Try and set any given EA. */
+ if (total_data) {
+ status = set_ea(conn, NULL, directory, ea_list);
+ talloc_destroy(ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ return ERROR_NT(status);
+ }
+ }
+
/* Realloc the parameter and data sizes */
params = SMB_REALLOC(*pparams,2);
if(params == NULL) {