summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2005-01-23 00:51:20 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:09:07 -0500
commit8eb0963c95bde4a8226f5d02ee0d8b478cf2dcc4 (patch)
treec46970635b936853a56142f9288ba4d3c32080aa
parent8c504b22f096cbaa37e943a6497dc76f069f40de (diff)
downloadsamba-8eb0963c95bde4a8226f5d02ee0d8b478cf2dcc4.tar.gz
samba-8eb0963c95bde4a8226f5d02ee0d8b478cf2dcc4.tar.bz2
samba-8eb0963c95bde4a8226f5d02ee0d8b478cf2dcc4.zip
r4935: fixed a bug where "c->status = xxx_handler(x);" could write to c after
it is freed. The problem is that the handler might complete the request, and called the c->async.fn() async handler. That handler might free the request handle. (This used to be commit c4faceadc74e0849f6197ccbec9952f6c94f6176)
-rw-r--r--source4/libcli/composite/connect.c16
-rw-r--r--source4/libcli/composite/loadfile.c11
-rw-r--r--source4/libcli/composite/savefile.c10
3 files changed, 22 insertions, 15 deletions
diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c
index 2663c789e4..67123a3af5 100644
--- a/source4/libcli/composite/connect.c
+++ b/source4/libcli/composite/connect.c
@@ -277,29 +277,31 @@ static NTSTATUS connect_resolve(struct smbcli_composite *c,
static void state_handler(struct smbcli_composite *c)
{
struct connect_state *state = talloc_get_type(c->private, struct connect_state);
+ NTSTATUS status;
switch (state->stage) {
case CONNECT_RESOLVE:
- c->status = connect_resolve(c, state->io);
+ status = connect_resolve(c, state->io);
break;
case CONNECT_SOCKET:
- c->status = connect_socket(c, state->io);
+ status = connect_socket(c, state->io);
break;
case CONNECT_SESSION_REQUEST:
- c->status = connect_session_request(c, state->io);
+ status = connect_session_request(c, state->io);
break;
case CONNECT_NEGPROT:
- c->status = connect_negprot(c, state->io);
+ status = connect_negprot(c, state->io);
break;
case CONNECT_SESSION_SETUP:
- c->status = connect_session_setup(c, state->io);
+ status = connect_session_setup(c, state->io);
break;
case CONNECT_TCON:
- c->status = connect_tcon(c, state->io);
+ status = connect_tcon(c, state->io);
break;
}
- if (!NT_STATUS_IS_OK(c->status)) {
+ if (!NT_STATUS_IS_OK(status)) {
+ c->status = status;
c->state = SMBCLI_REQUEST_ERROR;
if (c->async.fn) {
c->async.fn(c);
diff --git a/source4/libcli/composite/loadfile.c b/source4/libcli/composite/loadfile.c
index b95f43149e..37327ca62e 100644
--- a/source4/libcli/composite/loadfile.c
+++ b/source4/libcli/composite/loadfile.c
@@ -185,24 +185,26 @@ static void loadfile_handler(struct smbcli_request *req)
{
struct smbcli_composite *c = req->async.private;
struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state);
+ NTSTATUS status;
/* when this handler is called, the stage indicates what
call has just finished */
switch (state->stage) {
case LOADFILE_OPEN:
- c->status = loadfile_open(c, state->io);
+ status = loadfile_open(c, state->io);
break;
case LOADFILE_READ:
- c->status = loadfile_read(c, state->io);
+ status = loadfile_read(c, state->io);
break;
case LOADFILE_CLOSE:
- c->status = loadfile_close(c, state->io);
+ status = loadfile_close(c, state->io);
break;
}
- if (!NT_STATUS_IS_OK(c->status)) {
+ if (!NT_STATUS_IS_OK(status)) {
+ c->status = status;
c->state = SMBCLI_REQUEST_ERROR;
if (c->async.fn) {
c->async.fn(c);
@@ -291,3 +293,4 @@ NTSTATUS smb_composite_loadfile(struct smbcli_tree *tree,
struct smbcli_composite *c = smb_composite_loadfile_send(tree, io);
return smb_composite_loadfile_recv(c, mem_ctx);
}
+
diff --git a/source4/libcli/composite/savefile.c b/source4/libcli/composite/savefile.c
index 29d26c7eba..c87ea178f9 100644
--- a/source4/libcli/composite/savefile.c
+++ b/source4/libcli/composite/savefile.c
@@ -186,24 +186,26 @@ static void savefile_handler(struct smbcli_request *req)
{
struct smbcli_composite *c = req->async.private;
struct savefile_state *state = talloc_get_type(c->private, struct savefile_state);
+ NTSTATUS status;
/* when this handler is called, the stage indicates what
call has just finished */
switch (state->stage) {
case SAVEFILE_OPEN:
- c->status = savefile_open(c, state->io);
+ status = savefile_open(c, state->io);
break;
case SAVEFILE_WRITE:
- c->status = savefile_write(c, state->io);
+ status = savefile_write(c, state->io);
break;
case SAVEFILE_CLOSE:
- c->status = savefile_close(c, state->io);
+ status = savefile_close(c, state->io);
break;
}
- if (!NT_STATUS_IS_OK(c->status)) {
+ if (!NT_STATUS_IS_OK(status)) {
+ c->status = status;
c->state = SMBCLI_REQUEST_ERROR;
if (c->async.fn) {
c->async.fn(c);