From 223359fb71cab6319e7b8679605b0e15470ad7ec Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 26 Jan 2024 14:19:12 +0100 Subject: [PATCH] s3:tldap: simplify read_ldap_more() by using asn1_peek_full_tag() An LDAP pdu is at least 7 bytes long, so we read at least 7 bytes, then it's easy to use asn1_peek_full_tag() in order to find out the whole length of the pdu on one go. As a side effect it's now possible that wireshark can reassemble the fragments in a socket_wrapper generated pcap file. Signed-off-by: Stefan Metzmacher --- source3/lib/tldap.c | 54 ++++++++++++++------------------------------- 1 file changed, 17 insertions(+), 37 deletions(-) diff --git a/source3/lib/tldap.c b/source3/lib/tldap.c index e008b04e5e6b..99f7788c298e 100644 --- a/source3/lib/tldap.c +++ b/source3/lib/tldap.c @@ -298,7 +298,6 @@ void *tldap_context_getattr(struct tldap_context *ld, const char *name) struct read_ldap_state { uint8_t *buf; - bool done; }; static ssize_t read_ldap_more(uint8_t *buf, size_t buflen, void *private_data); @@ -315,9 +314,8 @@ static struct tevent_req *read_ldap_send(TALLOC_CTX *mem_ctx, if (req == NULL) { return NULL; } - state->done = false; - subreq = tstream_read_packet_send(state, ev, conn, 2, read_ldap_more, + subreq = tstream_read_packet_send(state, ev, conn, 7, read_ldap_more, state); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); @@ -328,48 +326,30 @@ static struct tevent_req *read_ldap_send(TALLOC_CTX *mem_ctx, static ssize_t read_ldap_more(uint8_t *buf, size_t buflen, void *private_data) { - struct read_ldap_state *state = talloc_get_type_abort( - private_data, struct read_ldap_state); - size_t len; - int i, lensize; - - if (state->done) { - /* We've been here, we're done */ - return 0; - } + const DATA_BLOB blob = data_blob_const(buf, buflen); + size_t pdu_len = 0; + int ret; - /* - * From ldap.h: LDAP_TAG_MESSAGE is 0x30 - */ - if (buf[0] != 0x30) { + if (buflen < 7) { + /* + * We need at least 6 bytes to workout the length + * of the pdu. + * + * And we have asked for 7 because the that's + * the size of the smallest possible LDAP pdu. + */ return -1; } - len = buf[1]; - if ((len & 0x80) == 0) { - state->done = true; - return len; - } - - lensize = (len & 0x7f); - len = 0; - - if (buflen == 2) { - /* Please get us the full length */ - return lensize; - } - if (buflen > 2 + lensize) { - state->done = true; + ret = asn1_peek_full_tag(blob, ASN1_SEQUENCE(0), &pdu_len); + if (ret == 0) { return 0; } - if (buflen != 2 + lensize) { - return -1; + if (ret == EAGAIN) { + return pdu_len - buflen; } - for (i=0; i