From 31454d2e8b70f7aca87099dba25abe790781c7a7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 29 Sep 2006 04:45:15 +0000 Subject: r18989: Fixes found by these two LDAP testsuites: - http://www.ee.oulu.fi/research/ouspg/protos/testing/c06/ldapv3/ - http://gleg.net/protover_ldap_sample.shtml Also fixes found by a subsequent audit of the code for similar issues. (This used to be commit 441a4f6262459dabfefd9bb12622ada9c007a60c) --- source4/ldap_server/ldap_backend.c | 4 ++++ source4/libcli/ldap/ldap.c | 25 +++++++++++++++++++++---- source4/libcli/util/asn1.c | 23 ++++++++++++++++++++++- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/source4/ldap_server/ldap_backend.c b/source4/ldap_server/ldap_backend.c index e8e3e293b7..3cd1f1c58a 100644 --- a/source4/ldap_server/ldap_backend.c +++ b/source4/ldap_server/ldap_backend.c @@ -220,6 +220,10 @@ static NTSTATUS ldapsrv_SearchRequest(struct ldapsrv_call *call) scope = LDB_SCOPE_SUBTREE; success_limit = 0; break; + default: + result = LDAP_PROTOCOL_ERROR; + errstr = "Invalid scope"; + break; } if (req->num_attributes >= 1) { diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 6a0b86f78b..5a7174b41d 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -949,8 +949,14 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) r->mechanism = LDAP_AUTH_MECH_SIMPLE; asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); pwlen = asn1_tag_remaining(data); + if (pwlen == -1) { + return False; + } if (pwlen != 0) { char *pw = talloc_size(msg, pwlen+1); + if (!pw) { + return False; + } asn1_read(data, pw, pwlen); pw[pwlen] = '\0'; r->creds.password = pw; @@ -974,6 +980,9 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) r->creds.SASL.secblob = NULL; } asn1_end_tag(data); + } else { + /* Neither Simple nor SASL bind */ + return False; } asn1_end_tag(data); break; @@ -1096,8 +1105,9 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) ldap_decode_attrib(msg, data, &mod.attrib); asn1_end_tag(data); if (!add_mod_to_array_talloc(msg, &mod, - &r->mods, &r->num_mods)) - break; + &r->mods, &r->num_mods)) { + return False; + } } asn1_end_tag(data); @@ -1146,6 +1156,9 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_start_tag(data, ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); len = asn1_tag_remaining(data); + if (len == -1) { + return False; + } dn = talloc_size(msg, len+1); if (dn == NULL) break; @@ -1179,9 +1192,13 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) char *newsup; asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); len = asn1_tag_remaining(data); + if (len == -1) { + return False; + } newsup = talloc_size(msg, len+1); - if (newsup == NULL) - break; + if (newsup == NULL) { + return False; + } asn1_read(data, newsup, len); newsup[len] = '\0'; r->newsuperior = newsup; diff --git a/source4/libcli/util/asn1.c b/source4/libcli/util/asn1.c index db3f7823fa..01c869dc17 100644 --- a/source4/libcli/util/asn1.c +++ b/source4/libcli/util/asn1.c @@ -396,6 +396,9 @@ BOOL asn1_start_tag(struct asn1_data *data, uint8_t tag) nesting->start = data->ofs; nesting->next = data->nesting; data->nesting = nesting; + if (asn1_tag_remaining(data) == -1) { + return False; + } return !data->has_error; } @@ -426,11 +429,21 @@ BOOL asn1_end_tag(struct asn1_data *data) /* work out how many bytes are left in this nested tag */ int asn1_tag_remaining(struct asn1_data *data) { + int remaining; + if (data->has_error) { + return -1; + } + if (!data->nesting) { data->has_error = True; return -1; } - return data->nesting->taglen - (data->ofs - data->nesting->start); + remaining = data->nesting->taglen - (data->ofs - data->nesting->start); + if (remaining > (data->length - data->ofs)) { + data->has_error = True; + return -1; + } + return remaining; } /* read an object ID from a ASN1 buffer */ @@ -518,6 +531,10 @@ BOOL asn1_read_OctetString(struct asn1_data *data, DATA_BLOB *blob) return False; } *blob = data_blob(NULL, len+1); + if (!blob->data) { + data->has_error = True; + return False; + } asn1_read(data, blob->data, len); asn1_end_tag(data); blob->length--; @@ -542,6 +559,10 @@ BOOL asn1_read_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blo return False; } *blob = data_blob(NULL, len); + if (!blob->data) { + data->has_error = True; + return False; + } asn1_read(data, blob->data, len); asn1_end_tag(data); return !data->has_error; -- cgit