summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2010-09-15 14:24:51 +1000
committerAndrew Tridgell <tridge@samba.org>2010-09-15 15:39:36 +1000
commit5a0bb2234e86c6718c9dbfd7a087ab7c1b7f6bb4 (patch)
tree10860f43eab9d2f23636ece55ee04ae7ce6402d9
parentea223baabc599415bf8da14a53cb77632343bc82 (diff)
downloadsamba-5a0bb2234e86c6718c9dbfd7a087ab7c1b7f6bb4.tar.gz
samba-5a0bb2234e86c6718c9dbfd7a087ab7c1b7f6bb4.tar.bz2
samba-5a0bb2234e86c6718c9dbfd7a087ab7c1b7f6bb4.zip
cldap: prevent crashes when freeing cldap socket
As a callback may destroy the cldap socket we need to ensure we don't reference the cldap structure after the callback Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org>
-rw-r--r--libcli/cldap/cldap.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/libcli/cldap/cldap.c b/libcli/cldap/cldap.c
index 33a1bd6571..f5585c2b73 100644
--- a/libcli/cldap/cldap.c
+++ b/libcli/cldap/cldap.c
@@ -167,7 +167,7 @@ static void cldap_recvfrom_stop(struct cldap_socket *c)
c->recv_subreq = NULL;
}
-static void cldap_socket_recv_dgram(struct cldap_socket *c,
+static bool cldap_socket_recv_dgram(struct cldap_socket *c,
struct cldap_incoming *in);
static void cldap_recvfrom_done(struct tevent_req *subreq)
@@ -176,6 +176,7 @@ static void cldap_recvfrom_done(struct tevent_req *subreq)
struct cldap_socket);
struct cldap_incoming *in = NULL;
ssize_t ret;
+ bool setup_done;
c->recv_subreq = NULL;
@@ -199,10 +200,10 @@ static void cldap_recvfrom_done(struct tevent_req *subreq)
}
/* this function should free or steal 'in' */
- cldap_socket_recv_dgram(c, in);
+ setup_done = cldap_socket_recv_dgram(c, in);
in = NULL;
- if (!cldap_recvfrom_setup(c)) {
+ if (!setup_done && !cldap_recvfrom_setup(c)) {
goto nomem;
}
@@ -218,7 +219,7 @@ nomem:
/*
handle recv events on a cldap socket
*/
-static void cldap_socket_recv_dgram(struct cldap_socket *c,
+static bool cldap_socket_recv_dgram(struct cldap_socket *c,
struct cldap_incoming *in)
{
DATA_BLOB blob;
@@ -262,7 +263,7 @@ static void cldap_socket_recv_dgram(struct cldap_socket *c,
/* this function should free or steal 'in' */
c->incoming.handler(c, c->incoming.private_data, in);
- return;
+ return false;
}
search = talloc_get_type(p, struct cldap_search_state);
@@ -270,8 +271,15 @@ static void cldap_socket_recv_dgram(struct cldap_socket *c,
search->response.asn1 = asn1;
search->response.asn1->ofs = 0;
+ DLIST_REMOVE(c->searches.list, search);
+
+ if (!cldap_recvfrom_setup(c)) {
+ goto nomem;
+ }
+
tevent_req_done(search->req);
- goto done;
+ talloc_free(in);
+ return true;
nomem:
in->recv_errno = ENOMEM;
@@ -289,6 +297,7 @@ nterror:
tevent_req_nterror(c->searches.list->req, status);
done:
talloc_free(in);
+ return false;
}
/*