summaryrefslogtreecommitdiff
path: root/source3/smbd/open.c
diff options
context:
space:
mode:
authorVolker Lendecke <vlendec@samba.org>2007-07-05 16:26:27 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:23:48 -0500
commit0bc56a2e5ffd0e65e4770e10c80d9fec02950b36 (patch)
treee1d8ede295e811121e252e80c3313697246df29b /source3/smbd/open.c
parent4ce65137d927a1f464dcd8f3e5b7b13c71adda27 (diff)
downloadsamba-0bc56a2e5ffd0e65e4770e10c80d9fec02950b36.tar.gz
samba-0bc56a2e5ffd0e65e4770e10c80d9fec02950b36.tar.bz2
samba-0bc56a2e5ffd0e65e4770e10c80d9fec02950b36.zip
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 used to be commit ca988f4e79e977160d82e86486972afd15d4acf5)
Diffstat (limited to 'source3/smbd/open.c')
-rw-r--r--source3/smbd/open.c66
1 files changed, 46 insertions, 20 deletions
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 41fbce9889..62a4fe0807 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -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;