1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-10 01:18:15 +03:00

r23724: Reduce access to the global inbuf a tiny bit. Add a struct smb_request

that contains some of the fields from the SMB header, removing the need
to access inbuf directly. This right now is used only in the open file
code & friends, and creating that header is only done when needed. This
needs more work, but it is a start.

Jeremy, I'm only checking this into 3_0, please review before I merge it
to _26.

Volker
This commit is contained in:
Volker Lendecke 2007-07-05 16:26:27 +00:00 committed by Gerald (Jerry) Carter
parent b35038fa4e
commit ca988f4e79
10 changed files with 208 additions and 110 deletions

View File

@ -682,6 +682,13 @@ struct current_user {
NT_USER_TOKEN *nt_user_token;
};
struct smb_request {
uint16 flags2;
uint16 smbpid;
uint16 mid;
uint16 vuid;
};
/* Defines for the sent_oplock_break field above. */
#define NO_BREAK_SENT 0
#define BREAK_TO_NONE_SENT 1

View File

@ -1291,7 +1291,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
driver_unix_convert(filepath,conn,NULL,&stat_buf);
status = open_file_ntcreate(conn, filepath, &stat_buf,
status = open_file_ntcreate(conn, NULL, filepath, &stat_buf,
FILE_GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
@ -1327,7 +1327,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
pstrcpy(filepath, new_file);
driver_unix_convert(filepath,conn,NULL,&stat_buf);
status = open_file_ntcreate(conn, filepath, &stat_buf,
status = open_file_ntcreate(conn, NULL, filepath, &stat_buf,
FILE_GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
@ -1460,7 +1460,7 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
goto error_exit;
}
status = open_file_ntcreate(conn, driverpath, &st,
status = open_file_ntcreate(conn, NULL, driverpath, &st,
FILE_GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
@ -4941,7 +4941,7 @@ static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
pstrcpy( file, s );
driver_unix_convert(file, conn, NULL, &st);
DEBUG(10,("deleting driverfile [%s]\n", s));
unlink_internals(conn, 0, file, False, False);
unlink_internals(conn, NULL, 0, file, False);
}
}
@ -4950,7 +4950,7 @@ static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
pstrcpy( file, s );
driver_unix_convert(file, conn, NULL, &st);
DEBUG(10,("deleting configfile [%s]\n", s));
unlink_internals(conn, 0, file, False, False);
unlink_internals(conn, NULL, 0, file, False);
}
}
@ -4959,7 +4959,7 @@ static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
pstrcpy( file, s );
driver_unix_convert(file, conn, NULL, &st);
DEBUG(10,("deleting datafile [%s]\n", s));
unlink_internals(conn, 0, file, False, False);
unlink_internals(conn, NULL, 0, file, False);
}
}
@ -4968,7 +4968,7 @@ static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
pstrcpy( file, s );
driver_unix_convert(file, conn, NULL, &st);
DEBUG(10,("deleting helpfile [%s]\n", s));
unlink_internals(conn, 0, file, False, False);
unlink_internals(conn, NULL, 0, file, False);
}
}
@ -4984,7 +4984,7 @@ static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
pstrcpy( file, p );
driver_unix_convert(file, conn, NULL, &st);
DEBUG(10,("deleting dependent file [%s]\n", file));
unlink_internals(conn, 0, file, False, False);
unlink_internals(conn, NULL, 0, file, False);
}
i++;

View File

@ -2089,11 +2089,11 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, struct srvsvc_NetGetFileSecur
goto error_exit;
}
nt_status = open_file_stat(conn, r->in.file, &st, &fsp);
nt_status = open_file_stat(conn, NULL, r->in.file, &st, &fsp);
if (!NT_STATUS_IS_OK(nt_status)) {
/* Perhaps it is a directory */
if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
nt_status = open_directory(conn, r->in.file, &st,
nt_status = open_directory(conn, NULL, r->in.file, &st,
READ_CONTROL_ACCESS,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
@ -2194,12 +2194,12 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, struct srvsvc_NetSetFileSecur
}
nt_status = open_file_stat(conn, r->in.file, &st, &fsp);
nt_status = open_file_stat(conn, NULL, r->in.file, &st, &fsp);
if (!NT_STATUS_IS_OK(nt_status)) {
/* Perhaps it is a directory */
if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
nt_status = open_directory(conn, r->in.file, &st,
nt_status = open_directory(conn, NULL, r->in.file, &st,
FILE_READ_ATTRIBUTES,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,

View File

@ -879,7 +879,7 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S
/* Pseudo-open the file (note - no fd's created). */
if(S_ISDIR(pst->st_mode)) {
status = open_directory(conn, name, pst,
status = open_directory(conn, NULL, name, pst,
READ_CONTROL_ACCESS,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
@ -887,7 +887,7 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S
FILE_ATTRIBUTE_DIRECTORY,
NULL, &fsp);
} else {
status = open_file_stat(conn, name, pst, &fsp);
status = open_file_stat(conn, NULL, name, pst, &fsp);
}
if (!NT_STATUS_IS_OK(status)) {
@ -943,7 +943,7 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_
if(S_ISDIR(pst->st_mode)) {
return True;
} else {
status = open_file_ntcreate(conn, name, pst,
status = open_file_ntcreate(conn, NULL, name, pst,
FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,

View File

@ -505,6 +505,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
struct timespec m_timespec;
BOOL extended_oplock_granted = False;
NTSTATUS status;
struct smb_request req;
START_PROFILE(SMBntcreateX);
@ -520,6 +521,8 @@ int reply_ntcreate_and_X(connection_struct *conn,
(unsigned int)create_options,
(unsigned int)root_dir_fid ));
init_smb_request(&req, (uint8 *)inbuf);
/*
* If it's an IPC, use the pipe handler.
*/
@ -726,7 +729,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
}
oplock_request = 0;
status = open_directory(conn, fname, &sbuf,
status = open_directory(conn, &req, fname, &sbuf,
access_mask,
share_access,
create_disposition,
@ -764,7 +767,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
* before issuing an oplock break request to
* our client. JRA. */
status = open_file_ntcreate(conn,fname,&sbuf,
status = open_file_ntcreate(conn, &req, fname, &sbuf,
access_mask,
share_access,
create_disposition,
@ -807,7 +810,8 @@ int reply_ntcreate_and_X(connection_struct *conn,
}
oplock_request = 0;
status = open_directory(conn, fname, &sbuf,
status = open_directory(conn, &req, fname,
&sbuf,
access_mask,
share_access,
create_disposition,
@ -1199,6 +1203,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
char *pdata = NULL;
NTSTATUS status;
size_t param_len;
struct smb_request req;
DEBUG(5,("call_nt_transact_create\n"));
@ -1227,6 +1232,8 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
init_smb_request(&req, (uint8 *)inbuf);
flags = IVAL(params,0);
access_mask = IVAL(params,8);
file_attributes = IVAL(params,20);
@ -1389,16 +1396,6 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
}
}
#if 0
/* We need to support SeSecurityPrivilege for this. */
if ((access_mask & SEC_RIGHT_SYSTEM_SECURITY)) &&
!user_has_privileges(current_user.nt_user_token,
&se_security)) {
restore_case_semantics(conn, file_attributes);
return ERROR_NT(NT_STATUS_PRIVILEGE_NOT_HELD);
}
#endif
if (ea_len) {
pdata = data + sd_len;
@ -1430,7 +1427,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
*/
oplock_request = 0;
status = open_directory(conn, fname, &sbuf,
status = open_directory(conn, &req, fname, &sbuf,
access_mask,
share_access,
create_disposition,
@ -1448,7 +1445,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
* Ordinary file case.
*/
status = open_file_ntcreate(conn,fname,&sbuf,
status = open_file_ntcreate(conn,&req,fname,&sbuf,
access_mask,
share_access,
create_disposition,
@ -1471,7 +1468,8 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
}
oplock_request = 0;
status = open_directory(conn, fname, &sbuf,
status = open_directory(conn, &req, fname,
&sbuf,
access_mask,
share_access,
create_disposition,
@ -1691,7 +1689,9 @@ int reply_ntcancel(connection_struct *conn,
Copy a file.
****************************************************************************/
static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *newname, uint32 attrs)
static NTSTATUS copy_internals(connection_struct *conn,
struct smb_request *req,
char *oldname, char *newname, uint32 attrs)
{
SMB_STRUCT_STAT sbuf1, sbuf2;
pstring last_component_oldname;
@ -1757,7 +1757,7 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
DEBUG(10,("copy_internals: doing file copy %s to %s\n", oldname, newname));
status = open_file_ntcreate(conn,oldname,&sbuf1,
status = open_file_ntcreate(conn, req, oldname, &sbuf1,
FILE_READ_DATA, /* Read-only. */
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
FILE_OPEN,
@ -1770,7 +1770,7 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
return status;
}
status = open_file_ntcreate(conn,newname,&sbuf2,
status = open_file_ntcreate(conn, req, newname, &sbuf2,
FILE_WRITE_DATA, /* Read-only. */
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
FILE_CREATE,
@ -1834,9 +1834,12 @@ int reply_ntrename(connection_struct *conn,
BOOL dest_has_wcard = False;
uint32 attrs = SVAL(inbuf,smb_vwv0);
uint16 rename_type = SVAL(inbuf,smb_vwv1);
struct smb_request req;
START_PROFILE(SMBntrename);
init_smb_request(&req, (uint8 *)inbuf);
p = smb_buf(inbuf) + 1;
p += srvstr_get_path_wcard(inbuf, oldname, p, sizeof(oldname), 0, STR_TERMINATE, &status, &src_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
@ -1884,7 +1887,9 @@ int reply_ntrename(connection_struct *conn,
switch(rename_type) {
case RENAME_FLAG_RENAME:
status = rename_internals(conn, oldname, newname, attrs, False, src_has_wcard, dest_has_wcard);
status = rename_internals(conn, &req, oldname, newname,
attrs, False, src_has_wcard,
dest_has_wcard);
break;
case RENAME_FLAG_HARD_LINK:
if (src_has_wcard || dest_has_wcard) {
@ -1899,7 +1904,8 @@ int reply_ntrename(connection_struct *conn,
/* No wildcards. */
status = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
} else {
status = copy_internals(conn, oldname, newname, attrs);
status = copy_internals(conn, &req, oldname,
newname, attrs);
}
break;
case RENAME_FLAG_MOVE_CLUSTER_INFORMATION:
@ -2036,6 +2042,9 @@ static int call_nt_transact_rename(connection_struct *conn, char *inbuf, char *o
BOOL replace_if_exists = False;
BOOL dest_has_wcard = False;
NTSTATUS status;
struct smb_request req;
init_smb_request(&req, (uint8 *)inbuf);
if(parameter_count < 5) {
return ERROR_DOS(ERRDOS,ERRbadfunc);
@ -2050,7 +2059,7 @@ static int call_nt_transact_rename(connection_struct *conn, char *inbuf, char *o
return ERROR_NT(status);
}
status = rename_internals(conn, fsp->fsp_name,
status = rename_internals(conn, &req, fsp->fsp_name,
new_name, 0, replace_if_exists, False, dest_has_wcard);
if (!NT_STATUS_IS_OK(status)) {

View File

@ -25,7 +25,6 @@
extern struct generic_mapping file_generic_mapping;
extern struct current_user current_user;
extern userdom_struct current_user_info;
extern uint16 global_smbpid;
extern BOOL global_client_failed_oplock_break;
struct deferred_open_record {
@ -201,6 +200,7 @@ static void change_dir_owner_to_parent(connection_struct *conn,
static NTSTATUS open_file(files_struct *fsp,
connection_struct *conn,
struct smb_request *req,
const char *parent_dir,
const char *name,
const char *path,
@ -359,8 +359,8 @@ static NTSTATUS open_file(files_struct *fsp,
fsp->mode = psbuf->st_mode;
fsp->file_id = file_id_sbuf(psbuf);
fsp->vuid = current_user.vuid;
fsp->file_pid = global_smbpid;
fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
fsp->file_pid = req ? req->smbpid : 0;
fsp->can_lock = True;
fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
if (!CAN_WRITE(conn)) {
@ -871,6 +871,8 @@ static BOOL open_match_attributes(connection_struct *conn,
static files_struct *fcb_or_dos_open(connection_struct *conn,
const char *fname,
struct file_id id,
uint16 file_pid,
uint16 vuid,
uint32 access_mask,
uint32 share_access,
uint32 create_options)
@ -893,8 +895,8 @@ static files_struct *fcb_or_dos_open(connection_struct *conn,
(unsigned int)fsp->access_mask ));
if (fsp->fh->fd != -1 &&
fsp->vuid == current_user.vuid &&
fsp->file_pid == global_smbpid &&
fsp->vuid == vuid &&
fsp->file_pid == file_pid &&
(fsp->fh->private_options & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS |
NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) &&
(fsp->access_mask & FILE_WRITE_DATA) &&
@ -1103,6 +1105,7 @@ static void schedule_defer_open(struct share_mode_lock *lck, struct timeval requ
****************************************************************************/
NTSTATUS open_file_ntcreate(connection_struct *conn,
struct smb_request *req,
const char *fname,
SMB_STRUCT_STAT *psbuf,
uint32 access_mask, /* access bits (FILE_READ_DATA etc.) */
@ -1129,7 +1132,6 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
int info;
uint32 existing_dos_attributes = 0;
struct pending_message_list *pml = NULL;
uint16 mid = get_current_mid();
struct timeval request_time = timeval_zero();
struct share_mode_lock *lck = NULL;
uint32 open_access_mask = access_mask;
@ -1179,7 +1181,17 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
create_disposition, create_options, unx_mode,
oplock_request));
if ((pml = get_open_deferred_message(mid)) != NULL) {
if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
DEBUG(0, ("No smb request but not an internal only open!\n"));
return NT_STATUS_INTERNAL_ERROR;
}
/*
* Only non-internal opens can be deferred at all
*/
if ((req != NULL)
&& ((pml = get_open_deferred_message(req->mid)) != NULL)) {
struct deferred_open_record *state =
(struct deferred_open_record *)pml->private_data.data;
@ -1194,12 +1206,12 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
if (lck == NULL) {
DEBUG(0, ("could not get share mode lock\n"));
} else {
del_deferred_open_entry(lck, mid);
del_deferred_open_entry(lck, req->mid);
TALLOC_FREE(lck);
}
/* Ensure we don't reprocess this message. */
remove_deferred_open_smb_message(mid);
remove_deferred_open_smb_message(req->mid);
}
status = check_name(conn, fname);
@ -1477,9 +1489,19 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
files_struct *fsp_dup;
if (req == NULL) {
DEBUG(0, ("DOS open without an SMB "
"request!\n"));
TALLOC_FREE(lck);
file_free(fsp);
return NT_STATUS_INTERNAL_ERROR;
}
/* Use the client requested access mask here,
* not the one we open with. */
fsp_dup = fcb_or_dos_open(conn, fname, id,
req->smbpid,
req->vuid,
access_mask,
share_access,
create_options);
@ -1601,7 +1623,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
* open_file strips any O_TRUNC flags itself.
*/
fsp_open = open_file(fsp, conn, parent_dir, newname, fname, psbuf,
fsp_open = open_file(fsp, conn, req, parent_dir, newname, fname, psbuf,
flags|flags2, unx_mode, access_mask,
open_access_mask);
@ -1862,7 +1884,9 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
/* If this is a successful open, we must remove any deferred open
* records. */
del_deferred_open_entry(lck, mid);
if (req != NULL) {
del_deferred_open_entry(lck, req->mid);
}
TALLOC_FREE(lck);
conn->num_files_open++;
@ -1892,8 +1916,8 @@ NTSTATUS open_file_fchmod(connection_struct *conn, const char *fname,
/* note! we must use a non-zero desired access or we don't get
a real file descriptor. Oh what a twisted web we weave. */
status = open_file(fsp, conn, NULL, NULL, fname, psbuf, O_WRONLY, 0,
FILE_WRITE_DATA, FILE_WRITE_DATA);
status = open_file(fsp, conn, NULL, NULL, NULL, fname, psbuf, O_WRONLY,
0, FILE_WRITE_DATA, FILE_WRITE_DATA);
/*
* This is not a user visible file open.
@ -2005,6 +2029,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
****************************************************************************/
NTSTATUS open_directory(connection_struct *conn,
struct smb_request *req,
const char *fname,
SMB_STRUCT_STAT *psbuf,
uint32 access_mask,
@ -2121,8 +2146,8 @@ NTSTATUS open_directory(connection_struct *conn,
fsp->mode = psbuf->st_mode;
fsp->file_id = file_id_sbuf(psbuf);
fsp->vuid = current_user.vuid;
fsp->file_pid = global_smbpid;
fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
fsp->file_pid = req ? req->smbpid : 0;
fsp->can_lock = False;
fsp->can_read = False;
fsp->can_write = False;
@ -2200,7 +2225,7 @@ NTSTATUS create_directory(connection_struct *conn, const char *directory)
SET_STAT_INVALID(sbuf);
status = open_directory(conn, directory, &sbuf,
status = open_directory(conn, NULL, directory, &sbuf,
FILE_READ_ATTRIBUTES, /* Just a stat open */
FILE_SHARE_NONE, /* Ignored for stat opens */
FILE_CREATE,
@ -2220,8 +2245,9 @@ NTSTATUS create_directory(connection_struct *conn, const char *directory)
Open a pseudo-file (no locking checks - a 'stat' open).
****************************************************************************/
NTSTATUS open_file_stat(connection_struct *conn, const char *fname,
SMB_STRUCT_STAT *psbuf, files_struct **result)
NTSTATUS open_file_stat(connection_struct *conn, struct smb_request *req,
const char *fname, SMB_STRUCT_STAT *psbuf,
files_struct **result)
{
files_struct *fsp = NULL;
NTSTATUS status;
@ -2248,8 +2274,8 @@ NTSTATUS open_file_stat(connection_struct *conn, const char *fname,
fsp->mode = psbuf->st_mode;
fsp->file_id = file_id_sbuf(psbuf);
fsp->vuid = current_user.vuid;
fsp->file_pid = global_smbpid;
fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
fsp->file_pid = req ? req->smbpid : 0;
fsp->can_lock = False;
fsp->can_read = False;
fsp->can_write = False;

View File

@ -3195,13 +3195,14 @@ static NTSTATUS append_parent_acl(files_struct *fsp,
parent_name);
status = open_directory(fsp->conn,
NULL,
parent_name,
&sbuf,
FILE_READ_ATTRIBUTES, /* Just a stat open */
FILE_SHARE_NONE, /* Ignored for stat opens */
FILE_OPEN,
0,
0,
INTERNAL_OPEN_ONLY,
&info,
&parent_fsp);

View File

@ -57,6 +57,18 @@ uint16 get_current_mid(void)
return SVAL(InBuffer,smb_mid);
}
/*
* Initialize a struct smb_request from an inbuf
*/
void init_smb_request(struct smb_request *req, const uint8 *inbuf)
{
req->flags2 = SVAL(inbuf, smb_flg2);
req->smbpid = SVAL(inbuf, smb_pid);
req->mid = SVAL(inbuf, smb_mid);
req->vuid = SVAL(inbuf, smb_uid);
}
/****************************************************************************
structure to hold a linked list of queued messages.
for processing.

View File

@ -1263,7 +1263,11 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
uint32 create_disposition;
uint32 create_options = 0;
NTSTATUS status;
struct smb_request req;
START_PROFILE(SMBopen);
init_smb_request(&req, (uint8 *)inbuf);
deny_mode = SVAL(inbuf,smb_vwv0);
@ -1300,7 +1304,7 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRbadaccess));
}
status = open_file_ntcreate(conn,fname,&sbuf,
status = open_file_ntcreate(conn, &req, fname, &sbuf,
access_mask,
share_mode,
create_disposition,
@ -1383,9 +1387,12 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
uint32 share_mode;
uint32 create_disposition;
uint32 create_options = 0;
struct smb_request req;
START_PROFILE(SMBopenX);
init_smb_request(&req, (uint8 *)inbuf);
/* If it's an IPC, pass off the pipe handler. */
if (IS_IPC(conn)) {
if (lp_nt_pipe_support()) {
@ -1434,7 +1441,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRbadaccess));
}
status = open_file_ntcreate(conn,fname,&sbuf,
status = open_file_ntcreate(conn, &req, fname, &sbuf,
access_mask,
share_mode,
create_disposition,
@ -1576,8 +1583,11 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
uint32 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
uint32 create_disposition;
uint32 create_options = 0;
struct smb_request req;
START_PROFILE(SMBcreate);
init_smb_request(&req, (uint8 *)inbuf);
com = SVAL(inbuf,smb_com);
@ -1623,7 +1633,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
}
/* Open file using ntcreate. */
status = open_file_ntcreate(conn,fname,&sbuf,
status = open_file_ntcreate(conn, &req, fname, &sbuf,
access_mask,
share_mode,
create_disposition,
@ -1678,9 +1688,12 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
char *p, *s;
NTSTATUS status;
unsigned int namelen;
struct smb_request req;
START_PROFILE(SMBctemp);
init_smb_request(&req, (uint8 *)inbuf);
srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBctemp);
@ -1722,7 +1735,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
SMB_VFS_STAT(conn,fname,&sbuf);
/* We should fail if file does not exist. */
status = open_file_ntcreate(conn,fname,&sbuf,
status = open_file_ntcreate(conn, &req, fname, &sbuf,
FILE_GENERIC_READ | FILE_GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
@ -1813,8 +1826,8 @@ static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp,
* unlink a file with all relevant access checks
*******************************************************************/
static NTSTATUS do_unlink(connection_struct *conn, char *fname,
uint32 dirtype, BOOL can_defer)
static NTSTATUS do_unlink(connection_struct *conn, struct smb_request *req,
char *fname, uint32 dirtype)
{
SMB_STRUCT_STAT sbuf;
uint32 fattr;
@ -1906,13 +1919,13 @@ static NTSTATUS do_unlink(connection_struct *conn, char *fname,
/* On open checks the open itself will check the share mode, so
don't do it here as we'll get it wrong. */
status = open_file_ntcreate(conn, fname, &sbuf,
status = open_file_ntcreate(conn, req, fname, &sbuf,
DELETE_ACCESS,
FILE_SHARE_NONE,
FILE_OPEN,
0,
FILE_ATTRIBUTE_NORMAL,
can_defer ? 0 : INTERNAL_OPEN_ONLY,
req != NULL ? 0 : INTERNAL_OPEN_ONLY,
NULL, &fsp);
if (!NT_STATUS_IS_OK(status)) {
@ -1935,8 +1948,8 @@ static NTSTATUS do_unlink(connection_struct *conn, char *fname,
code.
****************************************************************************/
NTSTATUS unlink_internals(connection_struct *conn, uint32 dirtype,
char *name, BOOL has_wild, BOOL can_defer)
NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
uint32 dirtype, char *name, BOOL has_wild)
{
pstring directory;
pstring mask;
@ -1986,7 +1999,7 @@ NTSTATUS unlink_internals(connection_struct *conn, uint32 dirtype,
return status;
}
status = do_unlink(conn,directory,dirtype,can_defer);
status = do_unlink(conn, req, directory, dirtype);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@ -2050,7 +2063,7 @@ NTSTATUS unlink_internals(connection_struct *conn, uint32 dirtype,
return status;
}
status = do_unlink(conn, fname, dirtype, can_defer);
status = do_unlink(conn, req, fname, dirtype);
if (!NT_STATUS_IS_OK(status)) {
continue;
}
@ -2081,9 +2094,12 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
uint32 dirtype;
NTSTATUS status;
BOOL path_contains_wcard = False;
struct smb_request req;
START_PROFILE(SMBunlink);
init_smb_request(&req, (uint8 *)inbuf);
dirtype = SVAL(inbuf,smb_vwv0);
srvstr_get_path_wcard(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), 0, STR_TERMINATE, &status, &path_contains_wcard);
@ -2103,8 +2119,8 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
DEBUG(3,("reply_unlink : %s\n",name));
status = unlink_internals(conn, dirtype, name, path_contains_wcard,
True);
status = unlink_internals(conn, &req, dirtype, name,
path_contains_wcard);
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
@ -4467,7 +4483,7 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, pstrin
code.
****************************************************************************/
NTSTATUS rename_internals(connection_struct *conn,
NTSTATUS rename_internals(connection_struct *conn, struct smb_request *req,
pstring name,
pstring newname,
uint32 attrs,
@ -4578,12 +4594,12 @@ NTSTATUS rename_internals(connection_struct *conn,
SMB_VFS_STAT(conn, directory, &sbuf1);
status = S_ISDIR(sbuf1.st_mode) ?
open_directory(conn, directory, &sbuf1,
open_directory(conn, req, directory, &sbuf1,
DELETE_ACCESS,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN, 0, 0, NULL,
&fsp)
: open_file_ntcreate(conn, directory, &sbuf1,
: open_file_ntcreate(conn, req, directory, &sbuf1,
DELETE_ACCESS,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN, 0, 0, 0, NULL,
@ -4674,12 +4690,12 @@ NTSTATUS rename_internals(connection_struct *conn,
SMB_VFS_STAT(conn, fname, &sbuf1);
status = S_ISDIR(sbuf1.st_mode) ?
open_directory(conn, fname, &sbuf1,
open_directory(conn, req, fname, &sbuf1,
DELETE_ACCESS,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN, 0, 0, NULL,
&fsp)
: open_file_ntcreate(conn, fname, &sbuf1,
: open_file_ntcreate(conn, req, fname, &sbuf1,
DELETE_ACCESS,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN, 0, 0, 0, NULL,
@ -4733,9 +4749,12 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
NTSTATUS status;
BOOL src_has_wcard = False;
BOOL dest_has_wcard = False;
struct smb_request req;
START_PROFILE(SMBmv);
init_smb_request(&req, (uint8 *)inbuf);
p = smb_buf(inbuf) + 1;
p += srvstr_get_path_wcard(inbuf, name, p, sizeof(name), 0, STR_TERMINATE, &status, &src_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
@ -4769,7 +4788,8 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
status = rename_internals(conn, name, newname, attrs, False, src_has_wcard, dest_has_wcard);
status = rename_internals(conn, &req, name, newname, attrs, False,
src_has_wcard, dest_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBmv);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
@ -4833,7 +4853,7 @@ NTSTATUS copy_file(connection_struct *conn,
}
}
status = open_file_ntcreate(conn,src,&src_sbuf,
status = open_file_ntcreate(conn, NULL, src, &src_sbuf,
FILE_GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
@ -4851,7 +4871,7 @@ NTSTATUS copy_file(connection_struct *conn,
ZERO_STRUCTP(&sbuf2);
}
status = open_file_ntcreate(conn,dest,&sbuf2,
status = open_file_ntcreate(conn, NULL, dest, &sbuf2,
FILE_GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
new_create_disposition,

View File

@ -740,9 +740,12 @@ int send_trans2_replies(const char *inbuf,
Reply to a TRANSACT2_OPEN.
****************************************************************************/
static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
char **pparams, int total_params, char **ppdata, int total_data,
unsigned int max_data_bytes)
static int call_trans2open(connection_struct *conn,
struct smb_request *req,
char *inbuf, char *outbuf, int bufsize,
char **pparams, int total_params,
char **ppdata, int total_data,
unsigned int max_data_bytes)
{
char *params = *pparams;
char *pdata = *ppdata;
@ -859,7 +862,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
status = open_file_ntcreate(conn,fname,&sbuf,
status = open_file_ntcreate(conn, req, fname, &sbuf,
access_mask,
share_mode,
create_disposition,
@ -4299,6 +4302,7 @@ static NTSTATUS smb_set_file_dosmode(connection_struct *conn,
****************************************************************************/
static NTSTATUS smb_set_file_size(connection_struct *conn,
struct smb_request *req,
files_struct *fsp,
const char *fname,
SMB_STRUCT_STAT *psbuf,
@ -4328,7 +4332,7 @@ static NTSTATUS smb_set_file_size(connection_struct *conn,
return NT_STATUS_OK;
}
status = open_file_ntcreate(conn, fname, psbuf,
status = open_file_ntcreate(conn, req, fname, psbuf,
FILE_WRITE_DATA,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
FILE_OPEN,
@ -4603,6 +4607,7 @@ static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
****************************************************************************/
static NTSTATUS smb_file_rename_information(connection_struct *conn,
struct smb_request *req,
char *inbuf,
char *outbuf,
const char *pdata,
@ -4664,7 +4669,8 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
} else {
DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
fname, newname ));
status = rename_internals(conn, fname, base_name, 0, overwrite, False, dest_has_wcard);
status = rename_internals(conn, req, fname, base_name, 0,
overwrite, False, dest_has_wcard);
}
return status;
@ -4955,6 +4961,7 @@ static NTSTATUS smb_set_file_basic_info(connection_struct *conn,
****************************************************************************/
static NTSTATUS smb_set_file_allocation_info(connection_struct *conn,
struct smb_request *req,
const char *pdata,
int total_data,
files_struct *fsp,
@ -5007,7 +5014,7 @@ static NTSTATUS smb_set_file_allocation_info(connection_struct *conn,
/* Pathname or stat or directory file. */
status = open_file_ntcreate(conn, fname, psbuf,
status = open_file_ntcreate(conn, req, fname, psbuf,
FILE_WRITE_DATA,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
FILE_OPEN,
@ -5035,6 +5042,7 @@ static NTSTATUS smb_set_file_allocation_info(connection_struct *conn,
****************************************************************************/
static NTSTATUS smb_set_file_end_of_file_info(connection_struct *conn,
struct smb_request *req,
const char *pdata,
int total_data,
files_struct *fsp,
@ -5059,7 +5067,7 @@ static NTSTATUS smb_set_file_end_of_file_info(connection_struct *conn,
DEBUG(10,("smb_set_file_end_of_file_info: Set end of file info for "
"file %s to %.0f\n", fname, (double)size ));
return smb_set_file_size(conn,
return smb_set_file_size(conn, req,
fsp,
fname,
psbuf,
@ -5155,6 +5163,7 @@ static NTSTATUS smb_unix_mknod(connection_struct *conn,
****************************************************************************/
static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
struct smb_request *req,
const char *pdata,
int total_data,
files_struct *fsp,
@ -5306,7 +5315,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
/* Deal with any size changes. */
status = smb_set_file_size(conn,
status = smb_set_file_size(conn, req,
fsp,
fname,
psbuf,
@ -5329,6 +5338,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
****************************************************************************/
static NTSTATUS smb_set_file_unix_info2(connection_struct *conn,
struct smb_request *req,
const char *pdata,
int total_data,
files_struct *fsp,
@ -5346,7 +5356,7 @@ static NTSTATUS smb_set_file_unix_info2(connection_struct *conn,
/* Start by setting all the fields that are common between UNIX_BASIC
* and UNIX_INFO2.
*/
status = smb_set_file_unix_basic(conn, pdata, total_data,
status = smb_set_file_unix_basic(conn, req, pdata, total_data,
fsp, fname, psbuf);
if (!NT_STATUS_IS_OK(status)) {
return status;
@ -5390,6 +5400,7 @@ static NTSTATUS smb_set_file_unix_info2(connection_struct *conn,
****************************************************************************/
static NTSTATUS smb_posix_mkdir(connection_struct *conn,
struct smb_request *req,
char **ppdata,
int total_data,
const char *fname,
@ -5422,7 +5433,7 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn,
DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
fname, (unsigned int)unixmode ));
status = open_directory(conn,
status = open_directory(conn, req,
fname,
psbuf,
FILE_READ_ATTRIBUTES, /* Just a stat open */
@ -5484,6 +5495,7 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn,
****************************************************************************/
static NTSTATUS smb_posix_open(connection_struct *conn,
struct smb_request *req,
char **ppdata,
int total_data,
const char *fname,
@ -5519,7 +5531,7 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
wire_open_mode = IVAL(pdata,4);
if (wire_open_mode == (SMB_O_CREAT|SMB_O_DIRECTORY)) {
return smb_posix_mkdir(conn,
return smb_posix_mkdir(conn, req,
ppdata,
total_data,
fname,
@ -5587,7 +5599,7 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
(unsigned int)wire_open_mode,
(unsigned int)unixmode ));
status = open_file_ntcreate(conn,
status = open_file_ntcreate(conn, req,
fname,
psbuf,
access_mask,
@ -5671,6 +5683,7 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
****************************************************************************/
static NTSTATUS smb_posix_unlink(connection_struct *conn,
struct smb_request *req,
const char *pdata,
int total_data,
const char *fname,
@ -5701,7 +5714,7 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn,
fname));
if (VALID_STAT_OF_DIR(*psbuf)) {
status = open_directory(conn,
status = open_directory(conn, req,
fname,
psbuf,
DELETE_ACCESS,
@ -5714,7 +5727,7 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn,
} else {
char del = 1;
status = open_file_ntcreate(conn,
status = open_file_ntcreate(conn, req,
fname,
psbuf,
DELETE_ACCESS,
@ -5752,7 +5765,10 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn,
Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
****************************************************************************/
static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
static int call_trans2setfilepathinfo(connection_struct *conn,
struct smb_request *req,
char *inbuf, char *outbuf, int length,
int bufsize,
unsigned int tran_call,
char **pparams, int total_params, char **ppdata, int total_data,
unsigned int max_data_bytes)
@ -5933,7 +5949,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
case SMB_FILE_ALLOCATION_INFORMATION:
case SMB_SET_FILE_ALLOCATION_INFO:
{
status = smb_set_file_allocation_info(conn,
status = smb_set_file_allocation_info(conn, req,
pdata,
total_data,
fsp,
@ -5945,7 +5961,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
case SMB_FILE_END_OF_FILE_INFORMATION:
case SMB_SET_FILE_END_OF_FILE_INFO:
{
status = smb_set_file_end_of_file_info(conn,
status = smb_set_file_end_of_file_info(conn, req,
pdata,
total_data,
fsp,
@ -6004,7 +6020,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
case SMB_SET_FILE_UNIX_BASIC:
{
status = smb_set_file_unix_basic(conn,
status = smb_set_file_unix_basic(conn, req,
pdata,
total_data,
fsp,
@ -6015,7 +6031,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
case SMB_SET_FILE_UNIX_INFO2:
{
status = smb_set_file_unix_info2(conn,
status = smb_set_file_unix_info2(conn, req,
pdata,
total_data,
fsp,
@ -6055,7 +6071,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
case SMB_FILE_RENAME_INFORMATION:
{
status = smb_file_rename_information(conn,
status = smb_file_rename_information(conn, req,
inbuf,
outbuf,
pdata,
@ -6099,7 +6115,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
return ERROR_NT(NT_STATUS_INVALID_LEVEL);
}
status = smb_posix_open(conn,
status = smb_posix_open(conn, req,
ppdata,
total_data,
fname,
@ -6115,7 +6131,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
return ERROR_NT(NT_STATUS_INVALID_LEVEL);
}
status = smb_posix_unlink(conn,
status = smb_posix_unlink(conn, req,
pdata,
total_data,
fname,
@ -6451,9 +6467,9 @@ int reply_findnclose(connection_struct *conn,
return(outsize);
}
int handle_trans2(connection_struct *conn,
struct trans_state *state,
char *inbuf, char *outbuf, int size, int bufsize)
static int handle_trans2(connection_struct *conn, struct smb_request *req,
struct trans_state *state,
char *inbuf, char *outbuf, int size, int bufsize)
{
int outsize;
@ -6467,7 +6483,7 @@ int handle_trans2(connection_struct *conn,
{
START_PROFILE(Trans2_open);
outsize = call_trans2open(
conn, inbuf, outbuf, bufsize,
conn, req, inbuf, outbuf, bufsize,
&state->param, state->total_param,
&state->data, state->total_data,
state->max_data_return);
@ -6541,7 +6557,7 @@ int handle_trans2(connection_struct *conn,
{
START_PROFILE(Trans2_setpathinfo);
outsize = call_trans2setfilepathinfo(
conn, inbuf, outbuf, size, bufsize, state->call,
conn, req, inbuf, outbuf, size, bufsize, state->call,
&state->param, state->total_param,
&state->data, state->total_data,
state->max_data_return);
@ -6749,7 +6765,10 @@ int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf,
if ((state->received_param == state->total_param) &&
(state->received_data == state->total_data)) {
outsize = handle_trans2(conn, state, inbuf, outbuf,
struct smb_request req;
init_smb_request(&req, (uint8 *)inbuf);
outsize = handle_trans2(conn, &req, state, inbuf, outbuf,
size, bufsize);
SAFE_FREE(state->data);
SAFE_FREE(state->param);
@ -6788,6 +6807,7 @@ int reply_transs2(connection_struct *conn,
int outsize = 0;
unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
struct trans_state *state;
struct smb_request req;
START_PROFILE(SMBtranss2);
@ -6873,7 +6893,10 @@ int reply_transs2(connection_struct *conn,
*/
SCVAL(outbuf,smb_com,SMBtrans2);
outsize = handle_trans2(conn, state, inbuf, outbuf, size, bufsize);
init_smb_request(&req, (uint8 *)inbuf);
outsize = handle_trans2(conn, &req, state, inbuf, outbuf, size,
bufsize);
DLIST_REMOVE(conn->pending_trans, state);
SAFE_FREE(state->data);