summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/ldap_server/ldap_backend.c4
-rw-r--r--source4/libcli/ldap/ldap.c25
-rw-r--r--source4/libcli/util/asn1.c23
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;