diff options
author | Andrew Tridgell <tridge@samba.org> | 2010-09-15 14:24:51 +1000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2010-09-15 15:39:36 +1000 |
commit | 5a0bb2234e86c6718c9dbfd7a087ab7c1b7f6bb4 (patch) | |
tree | 10860f43eab9d2f23636ece55ee04ae7ce6402d9 /libcli | |
parent | ea223baabc599415bf8da14a53cb77632343bc82 (diff) | |
download | samba-5a0bb2234e86c6718c9dbfd7a087ab7c1b7f6bb4.tar.gz |
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>
Diffstat (limited to 'libcli')
-rw-r--r-- | libcli/cldap/cldap.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/libcli/cldap/cldap.c b/libcli/cldap/cldap.c index 33a1bd65715..f5585c2b730 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; } /* |