r4935: fixed a bug where "c->status = xxx_handler(x);" could write to c after
authorAndrew Tridgell <tridge@samba.org>
Sun, 23 Jan 2005 00:51:20 +0000 (00:51 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:09:07 +0000 (13:09 -0500)
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)

source4/libcli/composite/connect.c
source4/libcli/composite/loadfile.c
source4/libcli/composite/savefile.c

index 2663c789e497bbb513d20f746d7dcb672fe6c94e..67123a3af566dd292ca4cc8b6bad21822723e2c9 100644 (file)
@@ -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);
index b95f43149e7caf5b8b5bfa593df1fbe26213ccad..37327ca62e37b7ac29b0e405f0d602c9217e0145 100644 (file)
@@ -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);
 }
+
index 29d26c7eba4134d6e523d10bd8d1d58c9e0a2327..c87ea178f9db3fba4401e055362d94f4033c820d 100644 (file)
@@ -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);