summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/smbd/nttrans.c10
-rw-r--r--source3/smbd/open.c13
-rw-r--r--source3/smbd/trans2.c21
3 files changed, 27 insertions, 17 deletions
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index e2a2543e30..5d19d496fd 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -1652,11 +1652,11 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
fsp1 = open_file_ntcreate(conn,oldname,&sbuf1,
FILE_READ_DATA, /* Read-only. */
- 0, /* No sharing. */
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
FILE_OPEN,
0, /* No create options. */
FILE_ATTRIBUTE_NORMAL,
- INTERNAL_OPEN_ONLY,
+ NO_OPLOCK,
&info);
if (!fsp1) {
@@ -1669,12 +1669,12 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
}
fsp2 = open_file_ntcreate(conn,newname,&sbuf2,
- FILE_WRITE_DATA, /* Read-only. */
- 0, /* No sharing. */
+ FILE_WRITE_DATA, /* Write-only. */
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
FILE_CREATE,
0, /* No create options. */
fattr,
- INTERNAL_OPEN_ONLY,
+ NO_OPLOCK,
&info);
if (!fsp2) {
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index f1d1b776dd..5b615f01e2 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -599,7 +599,7 @@ static BOOL is_delete_request(files_struct *fsp) {
}
/*
- * 1) No files open at all: Grant whatever the client wants.
+ * 1) No files open at all or internal open: Grant whatever the client wants.
*
* 2) Exclusive (or batch) oplock around: If the requested access is a delete
* request, break if the oplock around is a batch oplock. If it's another
@@ -608,7 +608,10 @@ static BOOL is_delete_request(files_struct *fsp) {
* 3) Only level2 around: Grant level2 and do nothing else.
*/
-static BOOL delay_for_oplocks(struct share_mode_lock *lck, files_struct *fsp, int pass_number)
+static BOOL delay_for_oplocks(struct share_mode_lock *lck,
+ files_struct *fsp,
+ int pass_number,
+ BOOL internal_only_open)
{
int i;
struct share_mode_entry *exclusive = NULL;
@@ -616,7 +619,7 @@ static BOOL delay_for_oplocks(struct share_mode_lock *lck, files_struct *fsp, in
BOOL delay_it = False;
BOOL have_level2 = False;
- if (is_stat_open(fsp->access_mask)) {
+ if (internal_only_open || is_stat_open(fsp->access_mask)) {
fsp->oplock_type = NO_OPLOCK;
return False;
}
@@ -1367,7 +1370,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
}
/* First pass - send break only on batch oplocks. */
- if (delay_for_oplocks(lck, fsp, 1)) {
+ if (delay_for_oplocks(lck, fsp, 1, internal_only_open)) {
schedule_defer_open(lck, request_time);
TALLOC_FREE(lck);
return NULL;
@@ -1380,7 +1383,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
if (NT_STATUS_IS_OK(status)) {
/* We might be going to allow this open. Check oplock status again. */
/* Second pass - send break for both batch or exclusive oplocks. */
- if (delay_for_oplocks(lck, fsp, 2)) {
+ if (delay_for_oplocks(lck, fsp, 2, internal_only_open)) {
schedule_defer_open(lck, request_time);
TALLOC_FREE(lck);
return NULL;
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index ad78c51fdf..a033833d00 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -4020,15 +4020,19 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
new_fsp = open_file_ntcreate(conn, fname, &sbuf,
FILE_WRITE_DATA,
- FILE_SHARE_READ|FILE_SHARE_WRITE,
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
FILE_OPEN,
0,
FILE_ATTRIBUTE_NORMAL,
- INTERNAL_OPEN_ONLY,
+ NO_OPLOCK,
NULL);
if (new_fsp == NULL) {
- return(UNIXERROR(ERRDOS,ERRbadpath));
+ if (open_was_deferred(SVAL(inbuf,smb_mid))) {
+ /* We have re-scheduled this call. */
+ return -1;
+ }
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
}
ret = vfs_allocate_file_space(new_fsp, allocation_size);
if (SMB_VFS_FSTAT(new_fsp,new_fsp->fh->fd,&new_sbuf) != 0) {
@@ -4561,7 +4565,6 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
POSIX_LOCK,
&my_lock_ctx);
- /* TODO: Deal with rescheduling blocking lock fail here... */
if (lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) {
/*
* A blocking lock was requested. Package up
@@ -4660,15 +4663,19 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
new_fsp = open_file_ntcreate(conn, fname, &sbuf,
FILE_WRITE_DATA,
- FILE_SHARE_READ|FILE_SHARE_WRITE,
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
FILE_OPEN,
0,
FILE_ATTRIBUTE_NORMAL,
- INTERNAL_OPEN_ONLY,
+ NO_OPLOCK,
NULL);
if (new_fsp == NULL) {
- return(UNIXERROR(ERRDOS,ERRbadpath));
+ if (open_was_deferred(SVAL(inbuf,smb_mid))) {
+ /* We have re-scheduled this call. */
+ return -1;
+ }
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
}
ret = vfs_set_filelen(new_fsp, size);
close_file(new_fsp,NORMAL_CLOSE);