summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/ipc.c26
-rw-r--r--source3/smbd/open.c28
-rw-r--r--source3/smbd/pipes.c42
-rw-r--r--source3/smbd/reply.c188
-rw-r--r--source3/smbd/server.c46
5 files changed, 186 insertions, 144 deletions
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index d18b5debe0..f20c851297 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -211,14 +211,14 @@ struct dcerpc_cmd_state {
size_t max_read;
};
-static void api_dcerpc_cmd_write_done(struct async_req *subreq);
-static void api_dcerpc_cmd_read_done(struct async_req *subreq);
+static void api_dcerpc_cmd_write_done(struct tevent_req *subreq);
+static void api_dcerpc_cmd_read_done(struct tevent_req *subreq);
static void api_dcerpc_cmd(connection_struct *conn, struct smb_request *req,
files_struct *fsp, uint8_t *data, size_t length,
size_t max_read)
{
- struct async_req *subreq;
+ struct tevent_req *subreq;
struct dcerpc_cmd_state *state;
if (!fsp_is_np(fsp)) {
@@ -254,14 +254,14 @@ static void api_dcerpc_cmd(connection_struct *conn, struct smb_request *req,
reply_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
- subreq->async.fn = api_dcerpc_cmd_write_done;
- subreq->async.priv = talloc_move(conn, &req);
+ tevent_req_set_callback(subreq, api_dcerpc_cmd_write_done,
+ talloc_move(conn, &req));
}
-static void api_dcerpc_cmd_write_done(struct async_req *subreq)
+static void api_dcerpc_cmd_write_done(struct tevent_req *subreq)
{
- struct smb_request *req = talloc_get_type_abort(
- subreq->async.priv, struct smb_request);
+ struct smb_request *req = tevent_req_callback_data(
+ subreq, struct smb_request);
struct dcerpc_cmd_state *state = talloc_get_type_abort(
req->async_priv, struct dcerpc_cmd_state);
NTSTATUS status;
@@ -290,9 +290,7 @@ static void api_dcerpc_cmd_write_done(struct async_req *subreq)
reply_nterror(req, NT_STATUS_NO_MEMORY);
goto send;
}
-
- subreq->async.fn = api_dcerpc_cmd_read_done;
- subreq->async.priv = req;
+ tevent_req_set_callback(subreq, api_dcerpc_cmd_read_done, req);
return;
send:
@@ -305,10 +303,10 @@ static void api_dcerpc_cmd_write_done(struct async_req *subreq)
TALLOC_FREE(req);
}
-static void api_dcerpc_cmd_read_done(struct async_req *subreq)
+static void api_dcerpc_cmd_read_done(struct tevent_req *subreq)
{
- struct smb_request *req = talloc_get_type_abort(
- subreq->async.priv, struct smb_request);
+ struct smb_request *req = tevent_req_callback_data(
+ subreq, struct smb_request);
struct dcerpc_cmd_state *state = talloc_get_type_abort(
req->async_priv, struct dcerpc_cmd_state);
NTSTATUS status;
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index c8cc2e64a3..d529b009d5 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -454,8 +454,26 @@ static NTSTATUS open_file(files_struct *fsp,
&access_granted);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+ /*
+ * On NT_STATUS_ACCESS_DENIED, access_granted
+ * contains the denied bits.
+ */
+
+ if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
+ (access_granted & FILE_WRITE_ATTRIBUTES) &&
+ (lp_map_readonly(SNUM(conn)) ||
+ lp_map_archive(SNUM(conn)) ||
+ lp_map_hidden(SNUM(conn)) ||
+ lp_map_system(SNUM(conn)))) {
+ access_granted &= ~FILE_WRITE_ATTRIBUTES;
+
+ DEBUG(10,("open_file: overrode FILE_WRITE_ATTRIBUTES "
+ "on file %s\n",
+ path ));
+ }
+
if ((access_mask & DELETE_ACCESS) &&
- (access_granted == DELETE_ACCESS) &&
+ (access_granted & DELETE_ACCESS) &&
can_delete_file_in_directory(conn, path)) {
/* Were we trying to do a stat open
* for delete and didn't get DELETE
@@ -465,10 +483,14 @@ static NTSTATUS open_file(files_struct *fsp,
* http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
* for details. */
- DEBUG(10,("open_file: overrode ACCESS_DENIED "
+ access_granted &= ~DELETE_ACCESS;
+
+ DEBUG(10,("open_file: overrode DELETE_ACCESS "
"on file %s\n",
path ));
- } else {
+ }
+
+ if (access_granted != 0) {
DEBUG(10, ("open_file: Access denied on "
"file %s\n",
path));
diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c
index 6fd4031f3d..2686cf41d9 100644
--- a/source3/smbd/pipes.c
+++ b/source3/smbd/pipes.c
@@ -148,14 +148,14 @@ struct pipe_write_state {
size_t numtowrite;
};
-static void pipe_write_done(struct async_req *subreq);
+static void pipe_write_done(struct tevent_req *subreq);
void reply_pipe_write(struct smb_request *req)
{
files_struct *fsp = file_fsp(req, SVAL(req->vwv+0, 0));
const uint8_t *data;
struct pipe_write_state *state;
- struct async_req *subreq;
+ struct tevent_req *subreq;
if (!fsp_is_np(fsp)) {
reply_doserror(req, ERRDOS, ERRbadfid);
@@ -188,14 +188,14 @@ void reply_pipe_write(struct smb_request *req)
reply_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
- subreq->async.fn = pipe_write_done;
- subreq->async.priv = talloc_move(req->conn, &req);
+ tevent_req_set_callback(subreq, pipe_write_done,
+ talloc_move(req->conn, &req));
}
-static void pipe_write_done(struct async_req *subreq)
+static void pipe_write_done(struct tevent_req *subreq)
{
- struct smb_request *req = talloc_get_type_abort(
- subreq->async.priv, struct smb_request);
+ struct smb_request *req = tevent_req_callback_data(
+ subreq, struct smb_request);
struct pipe_write_state *state = talloc_get_type_abort(
req->async_priv, struct pipe_write_state);
NTSTATUS status;
@@ -235,7 +235,7 @@ struct pipe_write_andx_state {
size_t numtowrite;
};
-static void pipe_write_andx_done(struct async_req *subreq);
+static void pipe_write_andx_done(struct tevent_req *subreq);
void reply_pipe_write_and_X(struct smb_request *req)
{
@@ -243,7 +243,7 @@ void reply_pipe_write_and_X(struct smb_request *req)
int smb_doff = SVAL(req->vwv+11, 0);
uint8_t *data;
struct pipe_write_andx_state *state;
- struct async_req *subreq;
+ struct tevent_req *subreq;
if (!fsp_is_np(fsp)) {
reply_doserror(req, ERRDOS, ERRbadfid);
@@ -297,14 +297,14 @@ void reply_pipe_write_and_X(struct smb_request *req)
reply_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
- subreq->async.fn = pipe_write_andx_done;
- subreq->async.priv = talloc_move(req->conn, &req);
+ tevent_req_set_callback(subreq, pipe_write_andx_done,
+ talloc_move(req->conn, &req));
}
-static void pipe_write_andx_done(struct async_req *subreq)
+static void pipe_write_andx_done(struct tevent_req *subreq)
{
- struct smb_request *req = talloc_get_type_abort(
- subreq->async.priv, struct smb_request);
+ struct smb_request *req = tevent_req_callback_data(
+ subreq, struct smb_request);
struct pipe_write_andx_state *state = talloc_get_type_abort(
req->async_priv, struct pipe_write_andx_state);
NTSTATUS status;
@@ -340,14 +340,14 @@ struct pipe_read_andx_state {
int smb_maxcnt;
};
-static void pipe_read_andx_done(struct async_req *subreq);
+static void pipe_read_andx_done(struct tevent_req *subreq);
void reply_pipe_read_and_X(struct smb_request *req)
{
files_struct *fsp = file_fsp(req, SVAL(req->vwv+0, 0));
uint8_t *data;
struct pipe_read_andx_state *state;
- struct async_req *subreq;
+ struct tevent_req *subreq;
/* we don't use the offset given to use for pipe reads. This
is deliberate, instead we always return the next lump of
@@ -392,14 +392,14 @@ void reply_pipe_read_and_X(struct smb_request *req)
reply_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
- subreq->async.fn = pipe_read_andx_done;
- subreq->async.priv = talloc_move(req->conn, &req);
+ tevent_req_set_callback(subreq, pipe_read_andx_done,
+ talloc_move(req->conn, &req));
}
-static void pipe_read_andx_done(struct async_req *subreq)
+static void pipe_read_andx_done(struct tevent_req *subreq)
{
- struct smb_request *req = talloc_get_type_abort(
- subreq->async.priv, struct smb_request);
+ struct smb_request *req = tevent_req_callback_data(
+ subreq, struct smb_request);
struct pipe_read_andx_state *state = talloc_get_type_abort(
req->async_priv, struct pipe_read_andx_state);
NTSTATUS status;
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 22e4c1aad7..8b560bd8ca 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -72,11 +72,16 @@ static NTSTATUS check_path_syntax_internal(char *path,
}
}
- if (!stream_started && *s == ':') {
+ if (!posix_path && !stream_started && *s == ':') {
if (*p_last_component_contains_wcard) {
return NT_STATUS_OBJECT_NAME_INVALID;
}
- /* stream names allow more characters than file names */
+ /* Stream names allow more characters than file names.
+ We're overloading posix_path here to allow a wider
+ range of characters. If stream_started is true this
+ is still a Windows path even if posix_path is true.
+ JRA.
+ */
stream_started = true;
start_of_name_component = false;
posix_path = true;
@@ -2859,6 +2864,7 @@ void reply_readbraw(struct smb_request *req)
size_t nread = 0;
SMB_OFF_T startpos;
files_struct *fsp;
+ struct lock_struct lock;
SMB_STRUCT_STAT st;
SMB_OFF_T size = 0;
@@ -2959,10 +2965,11 @@ void reply_readbraw(struct smb_request *req)
/* ensure we don't overrun the packet size */
maxcount = MIN(65535,maxcount);
- if (is_locked(fsp,(uint32)req->smbpid,
- (uint64_t)maxcount,
- (uint64_t)startpos,
- READ_LOCK)) {
+ init_strict_lock_struct(fsp, (uint32)req->smbpid,
+ (uint64_t)startpos, (uint64_t)maxcount, READ_LOCK,
+ &lock);
+
+ if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
reply_readbraw_error();
END_PROFILE(SMBreadbraw);
return;
@@ -2993,7 +3000,11 @@ void reply_readbraw(struct smb_request *req)
send_file_readbraw(conn, req, fsp, startpos, nread, mincount);
DEBUG(5,("reply_readbraw finished\n"));
+
+ SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+
END_PROFILE(SMBreadbraw);
+ return;
}
#undef DBGC_CLASS
@@ -3121,6 +3132,7 @@ void reply_read(struct smb_request *req)
SMB_OFF_T startpos;
int outsize = 0;
files_struct *fsp;
+ struct lock_struct lock;
START_PROFILE(SMBread);
@@ -3162,8 +3174,11 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
data = smb_buf(req->outbuf) + 3;
- if (is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtoread,
- (uint64_t)startpos, READ_LOCK)) {
+ init_strict_lock_struct(fsp, (uint32)req->smbpid,
+ (uint64_t)startpos, (uint64_t)numtoread, READ_LOCK,
+ &lock);
+
+ if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
reply_doserror(req, ERRDOS,ERRlock);
END_PROFILE(SMBread);
return;
@@ -3174,8 +3189,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
if (nread < 0) {
reply_unixerror(req, ERRDOS,ERRnoaccess);
- END_PROFILE(SMBread);
- return;
+ goto strict_unlock;
}
srv_set_message((char *)req->outbuf, 5, nread+3, False);
@@ -3188,6 +3202,9 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
fsp->fnum, (int)numtoread, (int)nread ) );
+strict_unlock:
+ SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+
END_PROFILE(SMBread);
return;
}
@@ -3387,6 +3404,7 @@ void reply_read_and_X(struct smb_request *req)
files_struct *fsp;
SMB_OFF_T startpos;
size_t smb_maxcnt;
+ struct lock_struct lock;
bool big_readX = False;
#if 0
size_t smb_mincnt = SVAL(req->vwv+6, 0);
@@ -3474,8 +3492,11 @@ void reply_read_and_X(struct smb_request *req)
}
- if (is_locked(fsp, (uint32)req->smbpid, (uint64_t)smb_maxcnt,
- (uint64_t)startpos, READ_LOCK)) {
+ init_strict_lock_struct(fsp, (uint32)req->smbpid,
+ (uint64_t)startpos, (uint64_t)smb_maxcnt, READ_LOCK,
+ &lock);
+
+ if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
END_PROFILE(SMBreadX);
reply_doserror(req, ERRDOS, ERRlock);
return;
@@ -3483,12 +3504,14 @@ void reply_read_and_X(struct smb_request *req)
if (!big_readX &&
schedule_aio_read_and_X(conn, req, fsp, startpos, smb_maxcnt)) {
- END_PROFILE(SMBreadX);
- return;
+ goto strict_unlock;
}
send_file_readX(conn, req, fsp, startpos, smb_maxcnt);
+strict_unlock:
+ SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+
END_PROFILE(SMBreadX);
return;
}
@@ -3523,6 +3546,7 @@ void reply_writebraw(struct smb_request *req)
char *data=NULL;
bool write_through;
files_struct *fsp;
+ struct lock_struct lock;
NTSTATUS status;
START_PROFILE(SMBwritebraw);
@@ -3584,8 +3608,11 @@ void reply_writebraw(struct smb_request *req)
return;
}
- if (is_locked(fsp,(uint32)req->smbpid,(uint64_t)tcount,
- (uint64_t)startpos, WRITE_LOCK)) {
+ init_strict_lock_struct(fsp, (uint32)req->smbpid,
+ (uint64_t)startpos, (uint64_t)tcount, WRITE_LOCK,
+ &lock);
+
+ if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
reply_doserror(req, ERRDOS, ERRlock);
error_to_writebrawerr(req);
END_PROFILE(SMBwritebraw);
@@ -3604,8 +3631,7 @@ void reply_writebraw(struct smb_request *req)
if (nwritten < (ssize_t)numtowrite) {
reply_unixerror(req, ERRHRD, ERRdiskfull);
error_to_writebrawerr(req);
- END_PROFILE(SMBwritebraw);
- return;
+ goto strict_unlock;
}
total_written = nwritten;
@@ -3615,8 +3641,7 @@ void reply_writebraw(struct smb_request *req)
if (!buf) {
reply_doserror(req, ERRDOS, ERRnomem);
error_to_writebrawerr(req);
- END_PROFILE(SMBwritebraw);
- return;
+ goto strict_unlock;
}
/* Return a SMBwritebraw message to the redirector to tell
@@ -3674,8 +3699,7 @@ void reply_writebraw(struct smb_request *req)
TALLOC_FREE(buf);
reply_unixerror(req, ERRHRD, ERRdiskfull);
error_to_writebrawerr(req);
- END_PROFILE(SMBwritebraw);
- return;
+ goto strict_unlock;
}
if (nwritten < (ssize_t)numtowrite) {
@@ -3697,8 +3721,7 @@ void reply_writebraw(struct smb_request *req)
fsp->fsp_name, nt_errstr(status) ));
reply_nterror(req, status);
error_to_writebrawerr(req);
- END_PROFILE(SMBwritebraw);
- return;
+ goto strict_unlock;
}
DEBUG(3,("reply_writebraw: secondart write fnum=%d start=%.0f num=%d "
@@ -3706,6 +3729,8 @@ void reply_writebraw(struct smb_request *req)
fsp->fnum, (double)startpos, (int)numtowrite,
(int)total_written));
+ SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+
/* We won't return a status if write through is not selected - this
* follows what WfWg does */
END_PROFILE(SMBwritebraw);
@@ -3726,6 +3751,12 @@ void reply_writebraw(struct smb_request *req)
TALLOC_FREE(req->outbuf);
}
return;
+
+strict_unlock:
+ SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+
+ END_PROFILE(SMBwritebraw);
+ return;
}
#undef DBGC_CLASS
@@ -3744,6 +3775,7 @@ void reply_writeunlock(struct smb_request *req)
const char *data;
NTSTATUS status = NT_STATUS_OK;
files_struct *fsp;
+ struct lock_struct lock;
START_PROFILE(SMBwriteunlock);
@@ -3770,12 +3802,16 @@ void reply_writeunlock(struct smb_request *req)
startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
data = (const char *)req->buf + 3;
- if (numtowrite
- && is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite,
- (uint64_t)startpos, WRITE_LOCK)) {
- reply_doserror(req, ERRDOS, ERRlock);
- END_PROFILE(SMBwriteunlock);
- return;
+ if (numtowrite) {
+ init_strict_lock_struct(fsp, (uint32)req->smbpid,
+ (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
+ &lock);
+
+ if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
+ reply_doserror(req, ERRDOS, ERRlock);
+ END_PROFILE(SMBwriteunlock);
+ return;
+ }
}
/* The special X/Open SMB protocol handling of
@@ -3792,14 +3828,12 @@ void reply_writeunlock(struct smb_request *req)
DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n",
fsp->fsp_name, nt_errstr(status) ));
reply_nterror(req, status);
- END_PROFILE(SMBwriteunlock);
- return;
+ goto strict_unlock;
}
if(((nwritten < numtowrite) && (numtowrite != 0))||(nwritten < 0)) {
reply_unixerror(req, ERRHRD, ERRdiskfull);
- END_PROFILE(SMBwriteunlock);
- return;
+ goto strict_unlock;
}
if (numtowrite) {
@@ -3812,8 +3846,7 @@ void reply_writeunlock(struct smb_request *req)
if (NT_STATUS_V(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBwriteunlock);
- return;
+ goto strict_unlock;
}
}
@@ -3824,6 +3857,11 @@ void reply_writeunlock(struct smb_request *req)
DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n",
fsp->fnum, (int)numtowrite, (int)nwritten));
+strict_unlock:
+ if (numtowrite) {
+ SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+ }
+
END_PROFILE(SMBwriteunlock);
return;
}
@@ -3843,6 +3881,7 @@ void reply_write(struct smb_request *req)
SMB_OFF_T startpos;
const char *data;
files_struct *fsp;
+ struct lock_struct lock;
NTSTATUS status;
START_PROFILE(SMBwrite);
@@ -3877,8 +3916,11 @@ void reply_write(struct smb_request *req)
startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
data = (const char *)req->buf + 3;
- if (is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite,
- (uint64_t)startpos, WRITE_LOCK)) {
+ init_strict_lock_struct(fsp, (uint32)req->smbpid,
+ (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
+ &lock);
+
+ if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
reply_doserror(req, ERRDOS, ERRlock);
END_PROFILE(SMBwrite);
return;
@@ -3897,14 +3939,12 @@ void reply_write(struct smb_request *req)
nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos);
if (nwritten < 0) {
reply_nterror(req, NT_STATUS_DISK_FULL);
- END_PROFILE(SMBwrite);
- return;
+ goto strict_unlock;
}
nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos);
if (nwritten < 0) {
reply_nterror(req, NT_STATUS_DISK_FULL);
- END_PROFILE(SMBwrite);
- return;
+ goto strict_unlock;
}
trigger_write_time_update_immediate(fsp);
} else {
@@ -3916,14 +3956,12 @@ void reply_write(struct smb_request *req)
DEBUG(5,("reply_write: sync_file for %s returned %s\n",
fsp->fsp_name, nt_errstr(status) ));
reply_nterror(req, status);
- END_PROFILE(SMBwrite);
- return;
+ goto strict_unlock;
}
if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
reply_unixerror(req, ERRHRD, ERRdiskfull);
- END_PROFILE(SMBwrite);
- return;
+ goto strict_unlock;
}
reply_outbuf(req, 1, 0);
@@ -3937,6 +3975,9 @@ void reply_write(struct smb_request *req)
DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten));
+strict_unlock:
+ SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+
END_PROFILE(SMBwrite);
return;
}
@@ -4034,6 +4075,7 @@ void reply_write_and_X(struct smb_request *req)
{
connection_struct *conn = req->conn;
files_struct *fsp;
+ struct lock_struct lock;
SMB_OFF_T startpos;
size_t numtowrite;
bool write_through;
@@ -4136,9 +4178,11 @@ void reply_write_and_X(struct smb_request *req)
#endif /* LARGE_SMB_OFF_T */
}
- if (is_locked(fsp,(uint32)req->smbpid,
- (uint64_t)numtowrite,
- (uint64_t)startpos, WRITE_LOCK)) {
+ init_strict_lock_struct(fsp, (uint32)req->smbpid,
+ (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
+ &lock);
+
+ if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
reply_doserror(req, ERRDOS, ERRlock);
END_PROFILE(SMBwriteX);
return;
@@ -4156,8 +4200,7 @@ void reply_write_and_X(struct smb_request *req)
if ((req->unread_bytes == 0) &&
schedule_aio_write_and_X(conn, req, fsp, data, startpos,
numtowrite)) {
- END_PROFILE(SMBwriteX);
- return;
+ goto strict_unlock;
}
nwritten = write_file(req,fsp,data,startpos,numtowrite);
@@ -4165,8 +4208,7 @@ void reply_write_and_X(struct smb_request *req)
if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
reply_unixerror(req, ERRHRD, ERRdiskfull);
- END_PROFILE(SMBwriteX);
- return;
+ goto strict_unlock;
}
reply_outbuf(req, 6, 0);
@@ -4186,13 +4228,20 @@ void reply_write_and_X(struct smb_request *req)
DEBUG(5,("reply_write_and_X: sync_file for %s returned %s\n",
fsp->fsp_name, nt_errstr(status) ));
reply_nterror(req, status);
- END_PROFILE(SMBwriteX);
- return;
+ goto strict_unlock;
}
+ SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+
END_PROFILE(SMBwriteX);
chain_reply(req);
return;
+
+strict_unlock:
+ SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+
+ END_PROFILE(SMBwriteX);
+ return;
}
/****************************************************************************
@@ -4432,6 +4481,7 @@ void reply_writeclose(struct smb_request *req)
const char *data;
struct timespec mtime;
files_struct *fsp;
+ struct lock_struct lock;
START_PROFILE(SMBwriteclose);
@@ -4458,12 +4508,16 @@ void reply_writeclose(struct smb_request *req)
mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+4));
data = (const char *)req->buf + 1;
- if (numtowrite
- && is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite,
- (uint64_t)startpos, WRITE_LOCK)) {
- reply_doserror(req, ERRDOS,ERRlock);
- END_PROFILE(SMBwriteclose);
- return;
+ if (numtowrite) {
+ init_strict_lock_struct(fsp, (uint32)req->smbpid,
+ (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
+ &lock);
+
+ if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
+ reply_doserror(req, ERRDOS,ERRlock);
+ END_PROFILE(SMBwriteclose);
+ return;
+ }
}
nwritten = write_file(req,fsp,data,startpos,numtowrite);
@@ -4487,19 +4541,23 @@ void reply_writeclose(struct smb_request *req)
if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
reply_doserror(req, ERRHRD, ERRdiskfull);
- END_PROFILE(SMBwriteclose);
- return;
+ goto strict_unlock;
}
if(!NT_STATUS_IS_OK(close_status)) {
reply_nterror(req, close_status);
- END_PROFILE(SMBwriteclose);
- return;
+ goto strict_unlock;
}
reply_outbuf(req, 1, 0);
SSVAL(req->outbuf,smb_vwv0,nwritten);
+
+strict_unlock:
+ if (numtowrite) {
+ SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+ }
+
END_PROFILE(SMBwriteclose);
return;
}
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 538e04938e..d27f98281b 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -654,52 +654,16 @@ static void smbd_parent_loop(struct smbd_parent_context *parent)
{
/* now accept incoming connections - forking a new process
for each incoming connection */
- DEBUG(2,("waiting for a connection\n"));
+ DEBUG(2,("waiting for connections\n"));
while (1) {
- struct timeval now, idle_timeout;
- fd_set r_fds, w_fds;
- int maxfd = 0;
- int num;
+ int ret;
TALLOC_CTX *frame = talloc_stackframe();
- if (run_events(smbd_event_context(), 0, NULL, NULL)) {
- TALLOC_FREE(frame);
- continue;
- }
-
- idle_timeout = timeval_zero();
-
- FD_ZERO(&w_fds);
- FD_ZERO(&r_fds);
- GetTimeOfDay(&now);
-
- event_add_to_select_args(smbd_event_context(), &now,
- &r_fds, &w_fds, &idle_timeout,
- &maxfd);
-
- num = sys_select(maxfd+1,&r_fds,&w_fds,NULL,
- timeval_is_zero(&idle_timeout) ?
- NULL : &idle_timeout);
-
- /* check if we need to reload services */
- check_reload(time(NULL));
-
- if (run_events(smbd_event_context(), num, &r_fds, &w_fds)) {
- TALLOC_FREE(frame);
- continue;
+ ret = tevent_loop_once(smbd_event_context());
+ if (ret != 0) {
+ exit_server_cleanly("tevent_loop_once() error");
}
- /* socket error */
- if (num < 0)
- exit_server_cleanly("socket error");
-
- /* If the idle timeout fired and we don't have any connected
- * users, exit gracefully. We should be running under a process
- * controller that will restart us if necessry.
- */
- if (num == 0 && count_all_current_connections() == 0) {
- exit_server_cleanly("idle timeout");
- }
TALLOC_FREE(frame);
} /* end while 1 */