[PATCH] asn1_XXXX error check fixups.
Jeremy Allison
jra at samba.org
Tue Sep 23 13:47:34 MDT 2014
On Fri, Sep 19, 2014 at 04:01:56PM -0700, Jeremy Allison wrote:
> Here are more fixes to ensure we *always*
> check asn1_XXX() returns, as discovered
> at SNIA-SDC.
>
> Only two modules left to do:
>
> libcli/ldap/ldap_message.c
> source4/libcli/ldap/ldap_controls.c
>
> and then we'll have full coverage here.
> I'll try and get to those next week !
>
> Review and possibly push appreciated.
Finished version - completely protects
*all* uses of asn1_XXXX().
Review and push most appreciated !
Jeremy.
-------------- next part --------------
From 0c84df1ea4f2d94d7a65ea59cb64d067efebf245 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 19 Sep 2014 12:39:19 -0700
Subject: [PATCH 01/10] lib: util: asn1 fixes - check all returns.
Signed-off-by: Jeremy Allison <jra at samba.org>
---
lib/krb5_wrap/krb5_samba.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c
index 39926a6..5f0378b 100644
--- a/lib/krb5_wrap/krb5_samba.c
+++ b/lib/krb5_wrap/krb5_samba.c
@@ -296,23 +296,22 @@ bool unwrap_edata_ntstatus(TALLOC_CTX *mem_ctx,
return false;
}
- asn1_load(data, *edata);
- asn1_start_tag(data, ASN1_SEQUENCE(0));
- asn1_start_tag(data, ASN1_CONTEXT(1));
- asn1_read_Integer(data, &edata_type);
+ if (!asn1_load(data, *edata)) goto err;
+ if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto err;
+ if (!asn1_start_tag(data, ASN1_CONTEXT(1))) goto err;
+ if (!asn1_read_Integer(data, &edata_type)) goto err;
if (edata_type != KRB5_PADATA_PW_SALT) {
DEBUG(0,("edata is not of required type %d but of type %d\n",
KRB5_PADATA_PW_SALT, edata_type));
- asn1_free(data);
- return false;
+ goto err;
}
- asn1_start_tag(data, ASN1_CONTEXT(2));
- asn1_read_OctetString(data, talloc_tos(), &edata_contents);
- asn1_end_tag(data);
- asn1_end_tag(data);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, ASN1_CONTEXT(2))) goto err;
+ if (!asn1_read_OctetString(data, talloc_tos(), &edata_contents)) goto err;
+ if (!asn1_end_tag(data)) goto err;
+ if (!asn1_end_tag(data)) goto err;
+ if (!asn1_end_tag(data)) goto err;
asn1_free(data);
*edata_out = data_blob_talloc(mem_ctx, edata_contents.data, edata_contents.length);
@@ -320,6 +319,11 @@ bool unwrap_edata_ntstatus(TALLOC_CTX *mem_ctx,
data_blob_free(&edata_contents);
return true;
+
+ err:
+
+ asn1_free(data);
+ return false;
}
--
2.1.0.rc2.206.gedb03e5
From 5a9f218dd1727f828c82ec4fdfcbfb651c9a2126 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 19 Sep 2014 12:41:22 -0700
Subject: [PATCH 02/10] auth: gensec: asn1 fixes - check all returns.
Signed-off-by: Jeremy Allison <jra at samba.org>
---
auth/gensec/gensec_util.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/auth/gensec/gensec_util.c b/auth/gensec/gensec_util.c
index 568128a..b8e38b7 100644
--- a/auth/gensec/gensec_util.c
+++ b/auth/gensec/gensec_util.c
@@ -188,19 +188,20 @@ NTSTATUS gensec_packet_full_request(struct gensec_security *gensec_security,
*/
static bool gensec_gssapi_check_oid(const DATA_BLOB *blob, const char *oid)
{
- bool ret;
+ bool ret = false;
struct asn1_data *data = asn1_init(NULL);
if (!data) return false;
- asn1_load(data, *blob);
- asn1_start_tag(data, ASN1_APPLICATION(0));
- asn1_check_OID(data, oid);
+ if (!asn1_load(data, *blob)) goto err;
+ if (!asn1_start_tag(data, ASN1_APPLICATION(0))) goto err;
+ if (!asn1_check_OID(data, oid)) goto err;
ret = !data->has_error;
- asn1_free(data);
+ err:
+ asn1_free(data);
return ret;
}
--
2.1.0.rc2.206.gedb03e5
From 97371bf7401fa570e7dae8a4d242657392f5a799 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 19 Sep 2014 12:46:49 -0700
Subject: [PATCH 03/10] lib: util: asn1 tests. Check every asn1 return.
Signed-off-by: Jeremy Allison <jra at samba.org>
---
lib/util/tests/asn1_tests.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/lib/util/tests/asn1_tests.c b/lib/util/tests/asn1_tests.c
index 93ffbad..2c68cb4 100644
--- a/lib/util/tests/asn1_tests.c
+++ b/lib/util/tests/asn1_tests.c
@@ -321,6 +321,7 @@ static bool test_asn1_Integer(struct torture_context *tctx)
{
int i;
TALLOC_CTX *mem_ctx;
+ bool ret = false;
mem_ctx = talloc_new(tctx);
@@ -331,25 +332,28 @@ static bool test_asn1_Integer(struct torture_context *tctx)
data = asn1_init(mem_ctx);
if (!data) {
- return -1;
+ goto err;
}
- asn1_write_Integer(data, integer_tests[i].value);
+ if (!asn1_write_Integer(data, integer_tests[i].value)) goto err;
blob.data = data->data;
blob.length = data->length;
torture_assert_data_blob_equal(tctx, blob, integer_tests[i].blob, "asn1_write_Integer gave incorrect result");
- asn1_load(data, blob);
+ if (!asn1_load(data, blob)) goto err;
torture_assert(tctx, asn1_read_Integer(data, &val), "asn1_write_Integer output could not be read by asn1_read_Integer()");
torture_assert_int_equal(tctx, val, integer_tests[i].value,
"readback of asn1_write_Integer output by asn1_read_Integer() failed");
}
- talloc_free(mem_ctx);
+ ret = true;
- return true;
+ err:
+
+ talloc_free(mem_ctx);
+ return ret;
}
--
2.1.0.rc2.206.gedb03e5
From 3438f9b54ba2f042b68cf3568522b66e898e56b7 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 19 Sep 2014 13:42:39 -0700
Subject: [PATCH 04/10] libcli: auth: Ensure all asn1_XX returns are checked.
Signed-off-by: Jeremy Allison <jra at samba.org>
---
libcli/auth/spnego_parse.c | 214 ++++++++++++++++++++++++---------------------
1 file changed, 112 insertions(+), 102 deletions(-)
diff --git a/libcli/auth/spnego_parse.c b/libcli/auth/spnego_parse.c
index b1ca07d..d4c5bdc 100644
--- a/libcli/auth/spnego_parse.c
+++ b/libcli/auth/spnego_parse.c
@@ -29,12 +29,13 @@ static bool read_negTokenInit(struct asn1_data *asn1, TALLOC_CTX *mem_ctx,
{
ZERO_STRUCTP(token);
- asn1_start_tag(asn1, ASN1_CONTEXT(0));
- asn1_start_tag(asn1, ASN1_SEQUENCE(0));
+ if (!asn1_start_tag(asn1, ASN1_CONTEXT(0))) return false;
+ if (!asn1_start_tag(asn1, ASN1_SEQUENCE(0))) return false;
while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) {
int i;
uint8_t context;
+
if (!asn1_peek_uint8(asn1, &context)) {
asn1->has_error = true;
break;
@@ -45,8 +46,8 @@ static bool read_negTokenInit(struct asn1_data *asn1, TALLOC_CTX *mem_ctx,
case ASN1_CONTEXT(0): {
const char **mechTypes;
- asn1_start_tag(asn1, ASN1_CONTEXT(0));
- asn1_start_tag(asn1, ASN1_SEQUENCE(0));
+ if (!asn1_start_tag(asn1, ASN1_CONTEXT(0))) return false;
+ if (!asn1_start_tag(asn1, ASN1_SEQUENCE(0))) return false;
mechTypes = talloc(mem_ctx, const char *);
if (mechTypes == NULL) {
@@ -67,7 +68,7 @@ static bool read_negTokenInit(struct asn1_data *asn1, TALLOC_CTX *mem_ctx,
}
mechTypes = p;
- asn1_read_OID(asn1, mechTypes, &oid);
+ if (!asn1_read_OID(asn1, mechTypes, &oid)) return false;
mechTypes[i] = oid;
}
mechTypes[i] = NULL;
@@ -79,42 +80,42 @@ static bool read_negTokenInit(struct asn1_data *asn1, TALLOC_CTX *mem_ctx,
}
/* Read reqFlags */
case ASN1_CONTEXT(1):
- asn1_start_tag(asn1, ASN1_CONTEXT(1));
- asn1_read_BitString(asn1, mem_ctx, &token->reqFlags,
- &token->reqFlagsPadding);
- asn1_end_tag(asn1);
+ if (!asn1_start_tag(asn1, ASN1_CONTEXT(1))) return false;
+ if (!asn1_read_BitString(asn1, mem_ctx, &token->reqFlags,
+ &token->reqFlagsPadding)) return false;
+ if (!asn1_end_tag(asn1)) return false;
break;
/* Read mechToken */
case ASN1_CONTEXT(2):
- asn1_start_tag(asn1, ASN1_CONTEXT(2));
- asn1_read_OctetString(asn1, mem_ctx, &token->mechToken);
- asn1_end_tag(asn1);
+ if (!asn1_start_tag(asn1, ASN1_CONTEXT(2))) return false;
+ if (!asn1_read_OctetString(asn1, mem_ctx, &token->mechToken)) return false;
+ if (!asn1_end_tag(asn1)) return false;
break;
/* Read mecListMIC */
case ASN1_CONTEXT(3):
{
uint8_t type_peek;
- asn1_start_tag(asn1, ASN1_CONTEXT(3));
+ if (!asn1_start_tag(asn1, ASN1_CONTEXT(3))) return false;
if (!asn1_peek_uint8(asn1, &type_peek)) {
asn1->has_error = true;
break;
}
if (type_peek == ASN1_OCTET_STRING) {
- asn1_read_OctetString(asn1, mem_ctx,
- &token->mechListMIC);
+ if (!asn1_read_OctetString(asn1, mem_ctx,
+ &token->mechListMIC)) return false;
} else {
/* RFC 2478 says we have an Octet String here,
but W2k sends something different... */
char *mechListMIC;
- asn1_start_tag(asn1, ASN1_SEQUENCE(0));
- asn1_start_tag(asn1, ASN1_CONTEXT(0));
- asn1_read_GeneralString(asn1, mem_ctx, &mechListMIC);
- asn1_end_tag(asn1);
- asn1_end_tag(asn1);
+ if (!asn1_start_tag(asn1, ASN1_SEQUENCE(0))) return false;
+ if (!asn1_start_tag(asn1, ASN1_CONTEXT(0))) return false;
+ if (!asn1_read_GeneralString(asn1, mem_ctx, &mechListMIC)) return false;
+ if (!asn1_end_tag(asn1)) return false;
+ if (!asn1_end_tag(asn1)) return false;
token->targetPrincipal = mechListMIC;
}
- asn1_end_tag(asn1);
+ if (!asn1_end_tag(asn1)) return false;
break;
}
default:
@@ -123,50 +124,50 @@ static bool read_negTokenInit(struct asn1_data *asn1, TALLOC_CTX *mem_ctx,
}
}
- asn1_end_tag(asn1);
- asn1_end_tag(asn1);
+ if (!asn1_end_tag(asn1)) return false;
+ if (!asn1_end_tag(asn1)) return false;
return !asn1->has_error;
}
static bool write_negTokenInit(struct asn1_data *asn1, struct spnego_negTokenInit *token)
{
- asn1_push_tag(asn1, ASN1_CONTEXT(0));
- asn1_push_tag(asn1, ASN1_SEQUENCE(0));
+ if (!asn1_push_tag(asn1, ASN1_CONTEXT(0))) return false;
+ if (!asn1_push_tag(asn1, ASN1_SEQUENCE(0))) return false;
/* Write mechTypes */
if (token->mechTypes && *token->mechTypes) {
int i;
- asn1_push_tag(asn1, ASN1_CONTEXT(0));
- asn1_push_tag(asn1, ASN1_SEQUENCE(0));
+ if (!asn1_push_tag(asn1, ASN1_CONTEXT(0))) return false;
+ if (!asn1_push_tag(asn1, ASN1_SEQUENCE(0))) return false;
for (i = 0; token->mechTypes[i]; i++) {
- asn1_write_OID(asn1, token->mechTypes[i]);
+ if (!asn1_write_OID(asn1, token->mechTypes[i])) return false;
}
- asn1_pop_tag(asn1);
- asn1_pop_tag(asn1);
+ if (!asn1_pop_tag(asn1)) return false;
+ if (!asn1_pop_tag(asn1)) return false;
}
/* write reqFlags */
if (token->reqFlags.length > 0) {
- asn1_push_tag(asn1, ASN1_CONTEXT(1));
- asn1_write_BitString(asn1, token->reqFlags.data,
+ if (!asn1_push_tag(asn1, ASN1_CONTEXT(1))) return false;
+ if (!asn1_write_BitString(asn1, token->reqFlags.data,
token->reqFlags.length,
- token->reqFlagsPadding);
- asn1_pop_tag(asn1);
+ token->reqFlagsPadding)) return false;
+ if (!asn1_pop_tag(asn1)) return false;
}
/* write mechToken */
if (token->mechToken.data) {
- asn1_push_tag(asn1, ASN1_CONTEXT(2));
- asn1_write_OctetString(asn1, token->mechToken.data,
- token->mechToken.length);
- asn1_pop_tag(asn1);
+ if (!asn1_push_tag(asn1, ASN1_CONTEXT(2))) return false;
+ if (!asn1_write_OctetString(asn1, token->mechToken.data,
+ token->mechToken.length)) return false;
+ if (!asn1_pop_tag(asn1)) return false;
}
/* write mechListMIC */
if (token->mechListMIC.data) {
- asn1_push_tag(asn1, ASN1_CONTEXT(3));
+ if (!asn1_push_tag(asn1, ASN1_CONTEXT(3))) return false;
#if 0
/* This is what RFC 2478 says ... */
asn1_write_OctetString(asn1, token->mechListMIC.data,
@@ -174,20 +175,20 @@ static bool write_negTokenInit(struct asn1_data *asn1, struct spnego_negTokenIni
#else
/* ... but unfortunately this is what Windows
sends/expects */
- asn1_push_tag(asn1, ASN1_SEQUENCE(0));
- asn1_push_tag(asn1, ASN1_CONTEXT(0));
- asn1_push_tag(asn1, ASN1_GENERAL_STRING);
- asn1_write(asn1, token->mechListMIC.data,
- token->mechListMIC.length);
- asn1_pop_tag(asn1);
- asn1_pop_tag(asn1);
- asn1_pop_tag(asn1);
+ if (!asn1_push_tag(asn1, ASN1_SEQUENCE(0))) return false;
+ if (!asn1_push_tag(asn1, ASN1_CONTEXT(0))) return false;
+ if (!asn1_push_tag(asn1, ASN1_GENERAL_STRING)) return false;
+ if (!asn1_write(asn1, token->mechListMIC.data,
+ token->mechListMIC.length)) return false;
+ if (!asn1_pop_tag(asn1)) return false;
+ if (!asn1_pop_tag(asn1)) return false;
+ if (!asn1_pop_tag(asn1)) return false;
#endif
- asn1_pop_tag(asn1);
+ if (!asn1_pop_tag(asn1)) return false;
}
- asn1_pop_tag(asn1);
- asn1_pop_tag(asn1);
+ if (!asn1_pop_tag(asn1)) return false;
+ if (!asn1_pop_tag(asn1)) return false;
return !asn1->has_error;
}
@@ -197,8 +198,8 @@ static bool read_negTokenTarg(struct asn1_data *asn1, TALLOC_CTX *mem_ctx,
{
ZERO_STRUCTP(token);
- asn1_start_tag(asn1, ASN1_CONTEXT(1));
- asn1_start_tag(asn1, ASN1_SEQUENCE(0));
+ if (!asn1_start_tag(asn1, ASN1_CONTEXT(1))) return false;
+ if (!asn1_start_tag(asn1, ASN1_SEQUENCE(0))) return false;
while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) {
uint8_t context;
@@ -210,27 +211,27 @@ static bool read_negTokenTarg(struct asn1_data *asn1, TALLOC_CTX *mem_ctx,
switch (context) {
case ASN1_CONTEXT(0):
- asn1_start_tag(asn1, ASN1_CONTEXT(0));
- asn1_start_tag(asn1, ASN1_ENUMERATED);
- asn1_read_uint8(asn1, &token->negResult);
- asn1_end_tag(asn1);
- asn1_end_tag(asn1);
+ if (!asn1_start_tag(asn1, ASN1_CONTEXT(0))) return false;
+ if (!asn1_start_tag(asn1, ASN1_ENUMERATED)) return false;
+ if (!asn1_read_uint8(asn1, &token->negResult)) return false;
+ if (!asn1_end_tag(asn1)) return false;
+ if (!asn1_end_tag(asn1)) return false;
break;
case ASN1_CONTEXT(1):
- asn1_start_tag(asn1, ASN1_CONTEXT(1));
- asn1_read_OID(asn1, mem_ctx, &oid);
+ if (!asn1_start_tag(asn1, ASN1_CONTEXT(1))) return false;
+ if (!asn1_read_OID(asn1, mem_ctx, &oid)) return false;
token->supportedMech = oid;
- asn1_end_tag(asn1);
+ if (!asn1_end_tag(asn1)) return false;
break;
case ASN1_CONTEXT(2):
- asn1_start_tag(asn1, ASN1_CONTEXT(2));
- asn1_read_OctetString(asn1, mem_ctx, &token->responseToken);
- asn1_end_tag(asn1);
+ if (!asn1_start_tag(asn1, ASN1_CONTEXT(2))) return false;
+ if (!asn1_read_OctetString(asn1, mem_ctx, &token->responseToken)) return false;
+ if (!asn1_end_tag(asn1)) return false;
break;
case ASN1_CONTEXT(3):
- asn1_start_tag(asn1, ASN1_CONTEXT(3));
- asn1_read_OctetString(asn1, mem_ctx, &token->mechListMIC);
- asn1_end_tag(asn1);
+ if (!asn1_start_tag(asn1, ASN1_CONTEXT(3))) return false;
+ if (!asn1_read_OctetString(asn1, mem_ctx, &token->mechListMIC)) return false;
+ if (!asn1_end_tag(asn1)) return false;
break;
default:
asn1->has_error = true;
@@ -238,45 +239,45 @@ static bool read_negTokenTarg(struct asn1_data *asn1, TALLOC_CTX *mem_ctx,
}
}
- asn1_end_tag(asn1);
- asn1_end_tag(asn1);
+ if (!asn1_end_tag(asn1)) return false;
+ if (!asn1_end_tag(asn1)) return false;
return !asn1->has_error;
}
static bool write_negTokenTarg(struct asn1_data *asn1, struct spnego_negTokenTarg *token)
{
- asn1_push_tag(asn1, ASN1_CONTEXT(1));
- asn1_push_tag(asn1, ASN1_SEQUENCE(0));
+ if (!asn1_push_tag(asn1, ASN1_CONTEXT(1))) return false;
+ if (!asn1_push_tag(asn1, ASN1_SEQUENCE(0))) return false;
if (token->negResult != SPNEGO_NONE_RESULT) {
- asn1_push_tag(asn1, ASN1_CONTEXT(0));
- asn1_write_enumerated(asn1, token->negResult);
- asn1_pop_tag(asn1);
+ if (!asn1_push_tag(asn1, ASN1_CONTEXT(0))) return false;
+ if (!asn1_write_enumerated(asn1, token->negResult)) return false;
+ if (!asn1_pop_tag(asn1)) return false;
}
if (token->supportedMech) {
- asn1_push_tag(asn1, ASN1_CONTEXT(1));
- asn1_write_OID(asn1, token->supportedMech);
- asn1_pop_tag(asn1);
+ if (!asn1_push_tag(asn1, ASN1_CONTEXT(1))) return false;
+ if (!asn1_write_OID(asn1, token->supportedMech)) return false;
+ if (!asn1_pop_tag(asn1)) return false;
}
if (token->responseToken.data) {
- asn1_push_tag(asn1, ASN1_CONTEXT(2));
- asn1_write_OctetString(asn1, token->responseToken.data,
- token->responseToken.length);
- asn1_pop_tag(asn1);
+ if (!asn1_push_tag(asn1, ASN1_CONTEXT(2))) return false;
+ if (!asn1_write_OctetString(asn1, token->responseToken.data,
+ token->responseToken.length)) return false;
+ if (!asn1_pop_tag(asn1)) return false;
}
if (token->mechListMIC.data) {
- asn1_push_tag(asn1, ASN1_CONTEXT(3));
- asn1_write_OctetString(asn1, token->mechListMIC.data,
- token->mechListMIC.length);
- asn1_pop_tag(asn1);
+ if (!asn1_push_tag(asn1, ASN1_CONTEXT(3))) return false;
+ if (!asn1_write_OctetString(asn1, token->mechListMIC.data,
+ token->mechListMIC.length)) return false;
+ if (!asn1_pop_tag(asn1)) return false;
}
- asn1_pop_tag(asn1);
- asn1_pop_tag(asn1);
+ if (!asn1_pop_tag(asn1)) return false;
+ if (!asn1_pop_tag(asn1)) return false;
return !asn1->has_error;
}
@@ -298,19 +299,19 @@ ssize_t spnego_read_data(TALLOC_CTX *mem_ctx, DATA_BLOB data, struct spnego_data
return -1;
}
- asn1_load(asn1, data);
+ if (!asn1_load(asn1, data)) goto err;
if (!asn1_peek_uint8(asn1, &context)) {
asn1->has_error = true;
} else {
switch (context) {
case ASN1_APPLICATION(0):
- asn1_start_tag(asn1, ASN1_APPLICATION(0));
- asn1_check_OID(asn1, OID_SPNEGO);
+ if (!asn1_start_tag(asn1, ASN1_APPLICATION(0))) goto err;
+ if (!asn1_check_OID(asn1, OID_SPNEGO)) goto err;
if (read_negTokenInit(asn1, mem_ctx, &token->negTokenInit)) {
token->type = SPNEGO_NEG_TOKEN_INIT;
}
- asn1_end_tag(asn1);
+ if (!asn1_end_tag(asn1)) goto err;
break;
case ASN1_CONTEXT(1):
if (read_negTokenTarg(asn1, mem_ctx, &token->negTokenTarg)) {
@@ -324,6 +325,9 @@ ssize_t spnego_read_data(TALLOC_CTX *mem_ctx, DATA_BLOB data, struct spnego_data
}
if (!asn1->has_error) ret = asn1->ofs;
+
+ err:
+
asn1_free(asn1);
return ret;
@@ -340,10 +344,10 @@ ssize_t spnego_write_data(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct spnego_da
switch (spnego->type) {
case SPNEGO_NEG_TOKEN_INIT:
- asn1_push_tag(asn1, ASN1_APPLICATION(0));
- asn1_write_OID(asn1, OID_SPNEGO);
- write_negTokenInit(asn1, &spnego->negTokenInit);
- asn1_pop_tag(asn1);
+ if (!asn1_push_tag(asn1, ASN1_APPLICATION(0))) goto err;
+ if (!asn1_write_OID(asn1, OID_SPNEGO)) goto err;
+ if (!write_negTokenInit(asn1, &spnego->negTokenInit)) goto err;
+ if (!asn1_pop_tag(asn1)) goto err;
break;
case SPNEGO_NEG_TOKEN_TARG:
write_negTokenTarg(asn1, &spnego->negTokenTarg);
@@ -357,6 +361,9 @@ ssize_t spnego_write_data(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct spnego_da
*blob = data_blob_talloc(mem_ctx, asn1->data, asn1->length);
ret = asn1->ofs;
}
+
+ err:
+
asn1_free(asn1);
return ret;
@@ -398,6 +405,7 @@ bool spnego_write_mech_types(TALLOC_CTX *mem_ctx,
const char * const *mech_types,
DATA_BLOB *blob)
{
+ bool ret = false;
struct asn1_data *asn1 = asn1_init(mem_ctx);
if (asn1 == NULL) {
@@ -408,25 +416,27 @@ bool spnego_write_mech_types(TALLOC_CTX *mem_ctx,
if (mech_types && *mech_types) {
int i;
- asn1_push_tag(asn1, ASN1_SEQUENCE(0));
+ if (!asn1_push_tag(asn1, ASN1_SEQUENCE(0))) goto err;
for (i = 0; mech_types[i]; i++) {
- asn1_write_OID(asn1, mech_types[i]);
+ if (!asn1_write_OID(asn1, mech_types[i])) goto err;
}
- asn1_pop_tag(asn1);
+ if (!asn1_pop_tag(asn1)) goto err;
}
if (asn1->has_error) {
- asn1_free(asn1);
- return false;
+ goto err;
}
*blob = data_blob_talloc(mem_ctx, asn1->data, asn1->length);
if (blob->length != asn1->length) {
- asn1_free(asn1);
- return false;
+ goto err;
}
+ ret = true;
+
+ err:
+
asn1_free(asn1);
- return true;
+ return ret;
}
--
2.1.0.rc2.206.gedb03e5
From 12683680daa926e2d22bf12d9170f308d2dd0b86 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 19 Sep 2014 14:27:58 -0700
Subject: [PATCH 05/10] s3: libsmb: Ensure all asn1_XX returns are checked.
Signed-off-by: Jeremy Allison <jra at samba.org>
---
source3/libsmb/clispnego.c | 253 ++++++++++++++++++++++++---------------------
1 file changed, 137 insertions(+), 116 deletions(-)
diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c
index 9b4f8f9..ec8d1ee 100644
--- a/source3/libsmb/clispnego.c
+++ b/source3/libsmb/clispnego.c
@@ -37,53 +37,56 @@ DATA_BLOB spnego_gen_negTokenInit(TALLOC_CTX *ctx,
{
int i;
ASN1_DATA *data;
- DATA_BLOB ret;
+ DATA_BLOB ret = data_blob_null;
data = asn1_init(talloc_tos());
if (data == NULL) {
return data_blob_null;
}
- asn1_push_tag(data,ASN1_APPLICATION(0));
- asn1_write_OID(data,OID_SPNEGO);
- asn1_push_tag(data,ASN1_CONTEXT(0));
- asn1_push_tag(data,ASN1_SEQUENCE(0));
+ if (!asn1_push_tag(data,ASN1_APPLICATION(0))) goto err;
+ if (!asn1_write_OID(data,OID_SPNEGO)) goto err;
+ if (!asn1_push_tag(data,ASN1_CONTEXT(0))) goto err;
+ if (!asn1_push_tag(data,ASN1_SEQUENCE(0))) goto err;
- asn1_push_tag(data,ASN1_CONTEXT(0));
- asn1_push_tag(data,ASN1_SEQUENCE(0));
+ if (!asn1_push_tag(data,ASN1_CONTEXT(0))) goto err;
+ if (!asn1_push_tag(data,ASN1_SEQUENCE(0))) goto err;
for (i=0; OIDs[i]; i++) {
- asn1_write_OID(data,OIDs[i]);
+ if (!asn1_write_OID(data,OIDs[i])) goto err;
}
- asn1_pop_tag(data);
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
if (psecblob && psecblob->length && psecblob->data) {
- asn1_push_tag(data, ASN1_CONTEXT(2));
- asn1_write_OctetString(data,psecblob->data,
- psecblob->length);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_CONTEXT(2))) goto err;
+ if (!asn1_write_OctetString(data,psecblob->data,
+ psecblob->length)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
}
if (principal) {
- asn1_push_tag(data, ASN1_CONTEXT(3));
- asn1_push_tag(data, ASN1_SEQUENCE(0));
- asn1_push_tag(data, ASN1_CONTEXT(0));
- asn1_write_GeneralString(data,principal);
- asn1_pop_tag(data);
- asn1_pop_tag(data);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_CONTEXT(3))) goto err;
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
+ if (!asn1_push_tag(data, ASN1_CONTEXT(0))) goto err;
+ if (!asn1_write_GeneralString(data,principal)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
}
- asn1_pop_tag(data);
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) goto err;
+
+ ret = data_blob_talloc(ctx, data->data, data->length);
+
+ err:
if (data->has_error) {
DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data->ofs));
}
- ret = data_blob_talloc(ctx, data->data, data->length);
asn1_free(data);
return ret;
@@ -100,53 +103,53 @@ bool spnego_parse_negTokenInit(TALLOC_CTX *ctx,
DATA_BLOB *secblob)
{
int i;
- bool ret;
+ bool ret = false;
ASN1_DATA *data;
for (i = 0; i < ASN1_MAX_OIDS; i++) {
OIDs[i] = NULL;
}
+ if (principal) {
+ *principal = NULL;
+ }
+ if (secblob) {
+ *secblob = data_blob_null;
+ }
+
data = asn1_init(talloc_tos());
if (data == NULL) {
return false;
}
- asn1_load(data, blob);
+ if (!asn1_load(data, blob)) goto err;
- asn1_start_tag(data,ASN1_APPLICATION(0));
+ if (!asn1_start_tag(data,ASN1_APPLICATION(0))) goto err;
- asn1_check_OID(data,OID_SPNEGO);
+ if (!asn1_check_OID(data,OID_SPNEGO)) goto err;
/* negTokenInit [0] NegTokenInit */
- asn1_start_tag(data,ASN1_CONTEXT(0));
- asn1_start_tag(data,ASN1_SEQUENCE(0));
+ if (!asn1_start_tag(data,ASN1_CONTEXT(0))) goto err;
+ if (!asn1_start_tag(data,ASN1_SEQUENCE(0))) goto err;
/* mechTypes [0] MechTypeList OPTIONAL */
/* Not really optional, we depend on this to decide
* what mechanisms we have to work with. */
- asn1_start_tag(data,ASN1_CONTEXT(0));
- asn1_start_tag(data,ASN1_SEQUENCE(0));
+ if (!asn1_start_tag(data,ASN1_CONTEXT(0))) goto err;
+ if (!asn1_start_tag(data,ASN1_SEQUENCE(0))) goto err;
for (i=0; asn1_tag_remaining(data) > 0 && i < ASN1_MAX_OIDS-1; i++) {
if (!asn1_read_OID(data,ctx, &OIDs[i])) {
- break;
+ goto err;
}
if (data->has_error) {
- break;
+ goto err;
}
}
OIDs[i] = NULL;
- asn1_end_tag(data);
- asn1_end_tag(data);
-
- if (principal) {
- *principal = NULL;
- }
- if (secblob) {
- *secblob = data_blob_null;
- }
+ if (!asn1_end_tag(data)) goto err;
+ if (!asn1_end_tag(data)) goto err;
/*
Win7 + Live Sign-in Assistant attaches a mechToken
@@ -159,21 +162,24 @@ bool spnego_parse_negTokenInit(TALLOC_CTX *ctx,
uint8 flags;
/* reqFlags [1] ContextFlags OPTIONAL */
- asn1_start_tag(data, ASN1_CONTEXT(1));
- asn1_start_tag(data, ASN1_BIT_STRING);
+ if (!asn1_start_tag(data, ASN1_CONTEXT(1))) goto err;
+ if (!asn1_start_tag(data, ASN1_BIT_STRING)) goto err;
while (asn1_tag_remaining(data) > 0) {
- asn1_read_uint8(data, &flags);
+ if (!asn1_read_uint8(data, &flags)) goto err;
}
- asn1_end_tag(data);
- asn1_end_tag(data);
+ if (!asn1_end_tag(data)) goto err;
+ if (!asn1_end_tag(data)) goto err;
}
if (asn1_peek_tag(data, ASN1_CONTEXT(2))) {
DATA_BLOB sblob = data_blob_null;
/* mechToken [2] OCTET STRING OPTIONAL */
- asn1_start_tag(data, ASN1_CONTEXT(2));
- asn1_read_OctetString(data, ctx, &sblob);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, ASN1_CONTEXT(2))) goto err;
+ if (!asn1_read_OctetString(data, ctx, &sblob)) goto err;
+ if (!asn1_end_tag(data)) {
+ data_blob_free(&sblob);
+ goto err;
+ }
if (secblob) {
*secblob = sblob;
} else {
@@ -184,13 +190,13 @@ bool spnego_parse_negTokenInit(TALLOC_CTX *ctx,
if (asn1_peek_tag(data, ASN1_CONTEXT(3))) {
char *princ = NULL;
/* mechListMIC [3] OCTET STRING OPTIONAL */
- asn1_start_tag(data, ASN1_CONTEXT(3));
- asn1_start_tag(data, ASN1_SEQUENCE(0));
- asn1_start_tag(data, ASN1_CONTEXT(0));
- asn1_read_GeneralString(data, ctx, &princ);
- asn1_end_tag(data);
- asn1_end_tag(data);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, ASN1_CONTEXT(3))) goto err;
+ if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto err;
+ if (!asn1_start_tag(data, ASN1_CONTEXT(0))) goto err;
+ if (!asn1_read_GeneralString(data, ctx, &princ)) goto err;
+ if (!asn1_end_tag(data)) goto err;
+ if (!asn1_end_tag(data)) goto err;
+ if (!asn1_end_tag(data)) goto err;
if (principal) {
*principal = princ;
} else {
@@ -198,12 +204,15 @@ bool spnego_parse_negTokenInit(TALLOC_CTX *ctx,
}
}
- asn1_end_tag(data);
- asn1_end_tag(data);
+ if (!asn1_end_tag(data)) goto err;
+ if (!asn1_end_tag(data)) goto err;
- asn1_end_tag(data);
+ if (!asn1_end_tag(data)) goto err;
ret = !data->has_error;
+
+ err:
+
if (data->has_error) {
int j;
if (principal) {
@@ -227,25 +236,28 @@ bool spnego_parse_negTokenInit(TALLOC_CTX *ctx,
DATA_BLOB spnego_gen_krb5_wrap(TALLOC_CTX *ctx, const DATA_BLOB ticket, const uint8 tok_id[2])
{
ASN1_DATA *data;
- DATA_BLOB ret;
+ DATA_BLOB ret = data_blob_null;
data = asn1_init(talloc_tos());
if (data == NULL) {
return data_blob_null;
}
- asn1_push_tag(data, ASN1_APPLICATION(0));
- asn1_write_OID(data, OID_KERBEROS5);
+ if (!asn1_push_tag(data, ASN1_APPLICATION(0))) goto err;
+ if (!asn1_write_OID(data, OID_KERBEROS5)) goto err;
- asn1_write(data, tok_id, 2);
- asn1_write(data, ticket.data, ticket.length);
- asn1_pop_tag(data);
+ if (!asn1_write(data, tok_id, 2)) goto err;
+ if (!asn1_write(data, ticket.data, ticket.length)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
+
+ ret = data_blob_talloc(ctx, data->data, data->length);
+
+ err:
if (data->has_error) {
DEBUG(1,("Failed to build krb5 wrapper at offset %d\n", (int)data->ofs));
}
- ret = data_blob_talloc(ctx, data->data, data->length);
asn1_free(data);
return ret;
@@ -293,7 +305,7 @@ int spnego_gen_krb5_negTokenInit(TALLOC_CTX *ctx,
bool spnego_parse_challenge(TALLOC_CTX *ctx, const DATA_BLOB blob,
DATA_BLOB *chal1, DATA_BLOB *chal2)
{
- bool ret;
+ bool ret = false;
ASN1_DATA *data;
ZERO_STRUCTP(chal1);
@@ -304,34 +316,36 @@ bool spnego_parse_challenge(TALLOC_CTX *ctx, const DATA_BLOB blob,
return false;
}
- asn1_load(data, blob);
- asn1_start_tag(data,ASN1_CONTEXT(1));
- asn1_start_tag(data,ASN1_SEQUENCE(0));
+ if (!asn1_load(data, blob)) goto err;
+ if (!asn1_start_tag(data,ASN1_CONTEXT(1))) goto err;
+ if (!asn1_start_tag(data,ASN1_SEQUENCE(0))) goto err;
- asn1_start_tag(data,ASN1_CONTEXT(0));
- asn1_check_enumerated(data,1);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data,ASN1_CONTEXT(0))) goto err;
+ if (!asn1_check_enumerated(data,1)) goto err;
+ if (!asn1_end_tag(data)) goto err;
- asn1_start_tag(data,ASN1_CONTEXT(1));
- asn1_check_OID(data, OID_NTLMSSP);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data,ASN1_CONTEXT(1))) goto err;
+ if (!asn1_check_OID(data, OID_NTLMSSP)) goto err;
+ if (!asn1_end_tag(data)) goto err;
- asn1_start_tag(data,ASN1_CONTEXT(2));
- asn1_read_OctetString(data, ctx, chal1);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data,ASN1_CONTEXT(2))) goto err;
+ if (!asn1_read_OctetString(data, ctx, chal1)) goto err;
+ if (!asn1_end_tag(data)) goto err;
/* the second challenge is optional (XP doesn't send it) */
if (asn1_tag_remaining(data)) {
- asn1_start_tag(data,ASN1_CONTEXT(3));
- asn1_read_OctetString(data, ctx, chal2);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data,ASN1_CONTEXT(3))) goto err;
+ if (!asn1_read_OctetString(data, ctx, chal2)) goto err;
+ if (!asn1_end_tag(data)) goto err;
}
- asn1_end_tag(data);
- asn1_end_tag(data);
+ if (!asn1_end_tag(data)) goto err;
+ if (!asn1_end_tag(data)) goto err;
ret = !data->has_error;
+ err:
+
if (data->has_error) {
data_blob_free(chal1);
data_blob_free(chal2);
@@ -348,23 +362,25 @@ bool spnego_parse_challenge(TALLOC_CTX *ctx, const DATA_BLOB blob,
DATA_BLOB spnego_gen_auth(TALLOC_CTX *ctx, DATA_BLOB blob)
{
ASN1_DATA *data;
- DATA_BLOB ret;
+ DATA_BLOB ret = data_blob_null;
data = asn1_init(talloc_tos());
if (data == NULL) {
return data_blob_null;
}
- asn1_push_tag(data, ASN1_CONTEXT(1));
- asn1_push_tag(data, ASN1_SEQUENCE(0));
- asn1_push_tag(data, ASN1_CONTEXT(2));
- asn1_write_OctetString(data,blob.data,blob.length);
- asn1_pop_tag(data);
- asn1_pop_tag(data);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_CONTEXT(1))) goto err;
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
+ if (!asn1_push_tag(data, ASN1_CONTEXT(2))) goto err;
+ if (!asn1_write_OctetString(data,blob.data,blob.length)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
ret = data_blob_talloc(ctx, data->data, data->length);
+ err:
+
asn1_free(data);
return ret;
@@ -380,6 +396,7 @@ bool spnego_parse_auth_response(TALLOC_CTX *ctx,
{
ASN1_DATA *data;
uint8 negResult;
+ bool ret = false;
if (NT_STATUS_IS_OK(nt_status)) {
negResult = SPNEGO_ACCEPT_COMPLETED;
@@ -394,27 +411,28 @@ bool spnego_parse_auth_response(TALLOC_CTX *ctx,
return false;
}
- asn1_load(data, blob);
- asn1_start_tag(data, ASN1_CONTEXT(1));
- asn1_start_tag(data, ASN1_SEQUENCE(0));
- asn1_start_tag(data, ASN1_CONTEXT(0));
- asn1_check_enumerated(data, negResult);
- asn1_end_tag(data);
-
*auth = data_blob_null;
+ if (!asn1_load(data, blob)) goto err;
+ if (!asn1_start_tag(data, ASN1_CONTEXT(1))) goto err;
+ if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto err;
+ if (!asn1_start_tag(data, ASN1_CONTEXT(0))) goto err;
+ if (!asn1_check_enumerated(data, negResult)) goto err;
+ if (!asn1_end_tag(data)) goto err;
+
if (asn1_tag_remaining(data)) {
- asn1_start_tag(data,ASN1_CONTEXT(1));
- asn1_check_OID(data, mechOID);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data,ASN1_CONTEXT(1))) goto err;
+ if (!asn1_check_OID(data, mechOID)) goto err;
+ if (!asn1_end_tag(data)) goto err;
if (asn1_tag_remaining(data)) {
- asn1_start_tag(data,ASN1_CONTEXT(2));
- asn1_read_OctetString(data, ctx, auth);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data,ASN1_CONTEXT(2))) goto err;
+ if (!asn1_read_OctetString(data, ctx, auth)) goto err;
+ if (!asn1_end_tag(data)) goto err;
}
} else if (negResult == SPNEGO_ACCEPT_INCOMPLETE) {
data->has_error = 1;
+ goto err;
}
/* Binding against Win2K DC returns a duplicate of the responseToken in
@@ -423,25 +441,28 @@ bool spnego_parse_auth_response(TALLOC_CTX *ctx,
* which point we need to implement the integrity checking. */
if (asn1_tag_remaining(data)) {
DATA_BLOB mechList = data_blob_null;
- asn1_start_tag(data, ASN1_CONTEXT(3));
- asn1_read_OctetString(data, ctx, &mechList);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, ASN1_CONTEXT(3))) goto err;
+ if (!asn1_read_OctetString(data, ctx, &mechList)) goto err;
data_blob_free(&mechList);
+ if (!asn1_end_tag(data)) goto err;
DEBUG(5,("spnego_parse_auth_response received mechListMIC, "
"ignoring.\n"));
}
- asn1_end_tag(data);
- asn1_end_tag(data);
+ if (!asn1_end_tag(data)) goto err;
+ if (!asn1_end_tag(data)) goto err;
+
+ ret = !data->has_error;
+
+ err:
if (data->has_error) {
DEBUG(3,("spnego_parse_auth_response failed at %d\n", (int)data->ofs));
asn1_free(data);
data_blob_free(auth);
- return False;
+ return false;
}
asn1_free(data);
- return True;
+ return ret;
}
-
--
2.1.0.rc2.206.gedb03e5
From 03de51af3e99a9155a74146890bea6f6dce192e8 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 19 Sep 2014 15:10:46 -0700
Subject: [PATCH 06/10] s3: tldap: Ensure all asn1_XX returns are checked.
Signed-off-by: Jeremy Allison <jra at samba.org>
---
source3/lib/tldap.c | 315 ++++++++++++++++++++++++++++------------------------
1 file changed, 172 insertions(+), 143 deletions(-)
diff --git a/source3/lib/tldap.c b/source3/lib/tldap.c
index b15ee73..5d3773e 100644
--- a/source3/lib/tldap.c
+++ b/source3/lib/tldap.c
@@ -356,33 +356,33 @@ struct tldap_msg_state {
uint8_t *inbuf;
};
-static void tldap_push_controls(struct asn1_data *data,
+static bool tldap_push_controls(struct asn1_data *data,
struct tldap_control *sctrls,
int num_sctrls)
{
int i;
if ((sctrls == NULL) || (num_sctrls == 0)) {
- return;
+ return true;
}
- asn1_push_tag(data, ASN1_CONTEXT(0));
+ if (!asn1_push_tag(data, ASN1_CONTEXT(0))) return false;
for (i=0; i<num_sctrls; i++) {
struct tldap_control *c = &sctrls[i];
- asn1_push_tag(data, ASN1_SEQUENCE(0));
- asn1_write_OctetString(data, c->oid, strlen(c->oid));
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) return false;
+ if (!asn1_write_OctetString(data, c->oid, strlen(c->oid))) return false;
if (c->critical) {
- asn1_write_BOOLEAN(data, true);
+ if (!asn1_write_BOOLEAN(data, true)) return false;
}
if (c->value.data != NULL) {
- asn1_write_OctetString(data, c->value.data,
- c->value.length);
+ if (!asn1_write_OctetString(data, c->value.data,
+ c->value.length)) return false;
}
- asn1_pop_tag(data); /* ASN1_SEQUENCE(0) */
+ if (!asn1_pop_tag(data)) return false; /* ASN1_SEQUENCE(0) */
}
- asn1_pop_tag(data); /* ASN1_CONTEXT(0) */
+ return asn1_pop_tag(data); /* ASN1_CONTEXT(0) */
}
static void tldap_msg_sent(struct tevent_req *subreq);
@@ -415,9 +415,16 @@ static struct tevent_req *tldap_msg_send(TALLOC_CTX *mem_ctx,
return tevent_req_post(req, ev);
}
- tldap_push_controls(data, sctrls, num_sctrls);
+ if (!tldap_push_controls(data, sctrls, num_sctrls)) {
+ tevent_req_error(req, TLDAP_ENCODING_ERROR);
+ return tevent_req_post(req, ev);
+ }
+
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) {
+ tevent_req_error(req, TLDAP_ENCODING_ERROR);
+ return tevent_req_post(req, ev);
+ }
if (!asn1_blob(data, &blob)) {
tevent_req_error(req, TLDAP_ENCODING_ERROR);
@@ -719,17 +726,21 @@ static struct tevent_req *tldap_req_create(TALLOC_CTX *mem_ctx,
ZERO_STRUCTP(state);
state->out = asn1_init(state);
if (state->out == NULL) {
- TALLOC_FREE(req);
- return NULL;
+ goto err;
}
state->result = NULL;
state->id = tldap_next_msgid(ld);
- asn1_push_tag(state->out, ASN1_SEQUENCE(0));
- asn1_write_Integer(state->out, state->id);
+ if (!asn1_push_tag(state->out, ASN1_SEQUENCE(0))) goto err;
+ if (!asn1_write_Integer(state->out, state->id)) goto err;
*pstate = state;
return req;
+
+ err:
+
+ TALLOC_FREE(req);
+ return NULL;
}
static void tldap_save_msg(struct tldap_context *ld, struct tevent_req *req)
@@ -786,6 +797,7 @@ static bool tldap_decode_response(struct tldap_req_state *state)
ok &= asn1_read_OctetString_talloc(msg, data, &msg->res_matcheddn);
ok &= asn1_read_OctetString_talloc(msg, data,
&msg->res_diagnosticmessage);
+ if (!ok) return ok;
if (asn1_peek_tag(data, ASN1_CONTEXT(3))) {
ok &= asn1_start_tag(data, ASN1_CONTEXT(3));
ok &= asn1_read_OctetString_talloc(msg, data,
@@ -823,29 +835,26 @@ struct tevent_req *tldap_sasl_bind_send(TALLOC_CTX *mem_ctx,
dn = "";
}
- asn1_push_tag(state->out, TLDAP_REQ_BIND);
- asn1_write_Integer(state->out, ld->ld_version);
- asn1_write_OctetString(state->out, dn, strlen(dn));
+ if (!asn1_push_tag(state->out, TLDAP_REQ_BIND)) goto err;
+ if (!asn1_write_Integer(state->out, ld->ld_version)) goto err;
+ if (!asn1_write_OctetString(state->out, dn, strlen(dn))) goto err;
if (mechanism == NULL) {
- asn1_push_tag(state->out, ASN1_CONTEXT_SIMPLE(0));
- asn1_write(state->out, creds->data, creds->length);
- asn1_pop_tag(state->out);
+ if (!asn1_push_tag(state->out, ASN1_CONTEXT_SIMPLE(0))) goto err;
+ if (!asn1_write(state->out, creds->data, creds->length)) goto err;
+ if (!asn1_pop_tag(state->out)) goto err;
} else {
- asn1_push_tag(state->out, ASN1_CONTEXT(3));
- asn1_write_OctetString(state->out, mechanism,
- strlen(mechanism));
+ if (!asn1_push_tag(state->out, ASN1_CONTEXT(3))) goto err;
+ if (!asn1_write_OctetString(state->out, mechanism,
+ strlen(mechanism))) goto err;
if ((creds != NULL) && (creds->data != NULL)) {
- asn1_write_OctetString(state->out, creds->data,
- creds->length);
+ if (!asn1_write_OctetString(state->out, creds->data,
+ creds->length)) goto err;
}
- asn1_pop_tag(state->out);
+ if (!asn1_pop_tag(state->out)) goto err;
}
- if (!asn1_pop_tag(state->out)) {
- tevent_req_error(req, TLDAP_ENCODING_ERROR);
- return tevent_req_post(req, ev);
- }
+ if (!asn1_pop_tag(state->out)) goto err;
subreq = tldap_msg_send(state, ev, ld, state->id, state->out,
sctrls, num_sctrls);
@@ -854,6 +863,11 @@ struct tevent_req *tldap_sasl_bind_send(TALLOC_CTX *mem_ctx,
}
tevent_req_set_callback(subreq, tldap_sasl_bind_done, req);
return req;
+
+ err:
+
+ tevent_req_error(req, TLDAP_ENCODING_ERROR);
+ return tevent_req_post(req, ev);
}
static void tldap_sasl_bind_done(struct tevent_req *subreq)
@@ -1231,25 +1245,25 @@ static bool tldap_push_filter_int(struct tldap_context *ld,
switch (*s) {
case '&':
tldap_debug(ld, TLDAP_DEBUG_TRACE, "Filter op: AND\n");
- asn1_push_tag(data, TLDAP_FILTER_AND);
+ if (!asn1_push_tag(data, TLDAP_FILTER_AND)) return false;
s++;
break;
case '|':
tldap_debug(ld, TLDAP_DEBUG_TRACE, "Filter op: OR\n");
- asn1_push_tag(data, TLDAP_FILTER_OR);
+ if (!asn1_push_tag(data, TLDAP_FILTER_OR)) return false;
s++;
break;
case '!':
tldap_debug(ld, TLDAP_DEBUG_TRACE, "Filter op: NOT\n");
- asn1_push_tag(data, TLDAP_FILTER_NOT);
+ if (!asn1_push_tag(data, TLDAP_FILTER_NOT)) return false;
s++;
ret = tldap_push_filter_int(ld, data, &s);
if (!ret) {
return false;
}
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) return false;
goto done;
case '(':
@@ -1276,7 +1290,7 @@ static bool tldap_push_filter_int(struct tldap_context *ld,
if (*s == ')') {
/* RFC 4526: empty and/or */
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) return false;
goto done;
}
@@ -1288,7 +1302,7 @@ static bool tldap_push_filter_int(struct tldap_context *ld,
if (*s == ')') {
/* end of list, return */
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) return false;
break;
}
}
@@ -1341,19 +1355,19 @@ static bool tldap_push_filter_basic(struct tldap_context *ld,
switch (*e) {
case '<':
- asn1_push_tag(data, TLDAP_FILTER_LE);
+ if (!asn1_push_tag(data, TLDAP_FILTER_LE)) return false;
break;
case '>':
- asn1_push_tag(data, TLDAP_FILTER_GE);
+ if (!asn1_push_tag(data, TLDAP_FILTER_GE)) return false;
break;
case '~':
- asn1_push_tag(data, TLDAP_FILTER_APX);
+ if (!asn1_push_tag(data, TLDAP_FILTER_APX)) return false;
break;
case ':':
- asn1_push_tag(data, TLDAP_FILTER_EXT);
+ if (!asn1_push_tag(data, TLDAP_FILTER_EXT)) return false;
write_octect = false;
type = NULL;
@@ -1425,9 +1439,9 @@ static bool tldap_push_filter_basic(struct tldap_context *ld,
if (!ret) {
return false;
}
- asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1));
- asn1_write(data, rule, e - rule);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1))) return false;
+ if (!asn1_write(data, rule, e - rule)) return false;
+ if (!asn1_pop_tag(data)) return false;
}
/* check and add type */
@@ -1436,9 +1450,9 @@ static bool tldap_push_filter_basic(struct tldap_context *ld,
if (!ret) {
return false;
}
- asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(2));
- asn1_write(data, type, type_len);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(2))) return false;
+ if (!asn1_write(data, type, type_len)) return false;
+ if (!asn1_pop_tag(data)) return false;
}
uval = tldap_get_val(tmpctx, val, _s);
@@ -1451,13 +1465,13 @@ static bool tldap_push_filter_basic(struct tldap_context *ld,
return false;
}
- asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3));
- asn1_write(data, uval, uval_len);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3))) return false;
+ if (!asn1_write(data, uval, uval_len)) return false;
+ if (!asn1_pop_tag(data)) return false;
- asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4));
- asn1_write_uint8(data, dn?1:0);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4))) return false;
+ if (!asn1_write_uint8(data, dn?1:0)) return false;
+ if (!asn1_pop_tag(data)) return false;
break;
default:
@@ -1470,8 +1484,8 @@ static bool tldap_push_filter_basic(struct tldap_context *ld,
if (strncmp(val, "*)", 2) == 0) {
/* presence */
- asn1_push_tag(data, TLDAP_FILTER_PRES);
- asn1_write(data, s, e - s);
+ if (!asn1_push_tag(data, TLDAP_FILTER_PRES)) return false;
+ if (!asn1_write(data, s, e - s)) return false;
*_s = val + 1;
write_octect = false;
break;
@@ -1483,8 +1497,8 @@ static bool tldap_push_filter_basic(struct tldap_context *ld,
}
if (*star == '*') {
/* substring */
- asn1_push_tag(data, TLDAP_FILTER_SUB);
- asn1_write_OctetString(data, s, e - s);
+ if (!asn1_push_tag(data, TLDAP_FILTER_SUB)) return false;
+ if (!asn1_write_OctetString(data, s, e - s)) return false;
ret = tldap_push_filter_substring(ld, data, val, &s);
if (!ret) {
return false;
@@ -1495,7 +1509,7 @@ static bool tldap_push_filter_basic(struct tldap_context *ld,
}
/* if nothing else, then it is just equality */
- asn1_push_tag(data, TLDAP_FILTER_EQ);
+ if (!asn1_push_tag(data, TLDAP_FILTER_EQ)) return false;
write_octect = true;
break;
}
@@ -1511,15 +1525,14 @@ static bool tldap_push_filter_basic(struct tldap_context *ld,
return false;
}
- asn1_write_OctetString(data, s, e - s);
- asn1_write_OctetString(data, uval, uval_len);
+ if (!asn1_write_OctetString(data, s, e - s)) return false;
+ if (!asn1_write_OctetString(data, uval, uval_len)) return false;
}
if (data->has_error) {
return false;
}
- asn1_pop_tag(data);
- return true;
+ return asn1_pop_tag(data);
}
static bool tldap_push_filter_substring(struct tldap_context *ld,
@@ -1543,7 +1556,7 @@ static bool tldap_push_filter_substring(struct tldap_context *ld,
any [1] LDAPString,
final [2] LDAPString } }
*/
- asn1_push_tag(data, ASN1_SEQUENCE(0));
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) return false;
do {
ret = tldap_find_first_star(val, &star);
@@ -1588,21 +1601,21 @@ static bool tldap_push_filter_substring(struct tldap_context *ld,
switch (*star) {
case '*':
if (initial) {
- asn1_push_tag(data, TLDAP_SUB_INI);
+ if (!asn1_push_tag(data, TLDAP_SUB_INI)) return false;
initial = false;
} else {
- asn1_push_tag(data, TLDAP_SUB_ANY);
+ if (!asn1_push_tag(data, TLDAP_SUB_ANY)) return false;
}
break;
case ')':
- asn1_push_tag(data, TLDAP_SUB_FIN);
+ if (!asn1_push_tag(data, TLDAP_SUB_FIN)) return false;
break;
default:
/* ?? */
return false;
}
- asn1_write(data, chunk, chunk_len);
- asn1_pop_tag(data);
+ if (!asn1_write(data, chunk, chunk_len)) return false;
+ if (!asn1_pop_tag(data)) return false;
val = star + 1;
@@ -1611,8 +1624,7 @@ static bool tldap_push_filter_substring(struct tldap_context *ld,
*_s = star;
/* end of sequence */
- asn1_pop_tag(data);
- return true;
+ return asn1_pop_tag(data);
}
/* NOTE: although openldap libraries allow for spaces in some places, mosly
@@ -1665,24 +1677,24 @@ struct tevent_req *tldap_search_send(TALLOC_CTX *mem_ctx,
return NULL;
}
- asn1_push_tag(state->out, TLDAP_REQ_SEARCH);
- asn1_write_OctetString(state->out, base, strlen(base));
- asn1_write_enumerated(state->out, scope);
- asn1_write_enumerated(state->out, deref);
- asn1_write_Integer(state->out, sizelimit);
- asn1_write_Integer(state->out, timelimit);
- asn1_write_BOOLEAN(state->out, attrsonly);
+ if (!asn1_push_tag(state->out, TLDAP_REQ_SEARCH)) goto encoding_error;
+ if (!asn1_write_OctetString(state->out, base, strlen(base))) goto encoding_error;
+ if (!asn1_write_enumerated(state->out, scope)) goto encoding_error;
+ if (!asn1_write_enumerated(state->out, deref)) goto encoding_error;
+ if (!asn1_write_Integer(state->out, sizelimit)) goto encoding_error;
+ if (!asn1_write_Integer(state->out, timelimit)) goto encoding_error;
+ if (!asn1_write_BOOLEAN(state->out, attrsonly)) goto encoding_error;
if (!tldap_push_filter(ld, state->out, filter)) {
goto encoding_error;
}
- asn1_push_tag(state->out, ASN1_SEQUENCE(0));
+ if (!asn1_push_tag(state->out, ASN1_SEQUENCE(0))) goto encoding_error;
for (i=0; i<num_attrs; i++) {
- asn1_write_OctetString(state->out, attrs[i], strlen(attrs[i]));
+ if (!asn1_write_OctetString(state->out, attrs[i], strlen(attrs[i]))) goto encoding_error;
}
- asn1_pop_tag(state->out);
- asn1_pop_tag(state->out);
+ if (!asn1_pop_tag(state->out)) goto encoding_error;
+ if (!asn1_pop_tag(state->out)) goto encoding_error;
subreq = tldap_msg_send(state, ev, ld, state->id, state->out,
sctrls, num_sctrls);
@@ -1890,11 +1902,12 @@ static bool tldap_parse_search_entry(struct tldap_message *msg)
{
int num_attribs = 0;
- asn1_start_tag(msg->data, msg->type);
+ if (!asn1_start_tag(msg->data, msg->type)) return false;
/* dn */
- asn1_read_OctetString_talloc(msg, msg->data, &msg->dn);
+ if (!asn1_read_OctetString_talloc(msg, msg->data, &msg->dn)) return false;
+
if (msg->dn == NULL) {
return false;
}
@@ -1910,7 +1923,7 @@ static bool tldap_parse_search_entry(struct tldap_message *msg)
return false;
}
- asn1_start_tag(msg->data, ASN1_SEQUENCE(0));
+ if (!asn1_start_tag(msg->data, ASN1_SEQUENCE(0))) return false;
while (asn1_peek_tag(msg->data, ASN1_SEQUENCE(0))) {
struct tldap_attribute *attrib;
int num_values = 0;
@@ -1920,14 +1933,14 @@ static bool tldap_parse_search_entry(struct tldap_message *msg)
if (attrib->values == NULL) {
return false;
}
- asn1_start_tag(msg->data, ASN1_SEQUENCE(0));
- asn1_read_OctetString_talloc(msg->attribs, msg->data,
- &attrib->name);
- asn1_start_tag(msg->data, ASN1_SET);
+ if (!asn1_start_tag(msg->data, ASN1_SEQUENCE(0))) return false;
+ if (!asn1_read_OctetString_talloc(msg->attribs, msg->data,
+ &attrib->name)) return false;
+ if (!asn1_start_tag(msg->data, ASN1_SET)) return false;
while (asn1_peek_tag(msg->data, ASN1_OCTET_STRING)) {
- asn1_read_OctetString(msg->data, msg,
- &attrib->values[num_values]);
+ if (!asn1_read_OctetString(msg->data, msg,
+ &attrib->values[num_values])) return false;
attrib->values = talloc_realloc(
msg->attribs, attrib->values, DATA_BLOB,
@@ -1941,8 +1954,8 @@ static bool tldap_parse_search_entry(struct tldap_message *msg)
DATA_BLOB, num_values);
attrib->num_values = num_values;
- asn1_end_tag(msg->data); /* ASN1_SET */
- asn1_end_tag(msg->data); /* ASN1_SEQUENCE(0) */
+ if (!asn1_end_tag(msg->data)) return false; /* ASN1_SET */
+ if (!asn1_end_tag(msg->data)) return false; /* ASN1_SEQUENCE(0) */
msg->attribs = talloc_realloc(
msg, msg->attribs, struct tldap_attribute,
num_attribs + 2);
@@ -1953,11 +1966,7 @@ static bool tldap_parse_search_entry(struct tldap_message *msg)
}
msg->attribs = talloc_realloc(
msg, msg->attribs, struct tldap_attribute, num_attribs);
- asn1_end_tag(msg->data);
- if (msg->data->has_error) {
- return false;
- }
- return true;
+ return asn1_end_tag(msg->data);
}
bool tldap_entry_dn(struct tldap_message *msg, char **dn)
@@ -1987,6 +1996,7 @@ static bool tldap_decode_controls(struct tldap_req_state *state)
struct asn1_data *data = msg->data;
struct tldap_control *sctrls = NULL;
int num_controls = 0;
+ bool ret = false;
msg->res_sctrls = NULL;
@@ -1994,7 +2004,7 @@ static bool tldap_decode_controls(struct tldap_req_state *state)
return true;
}
- asn1_start_tag(data, ASN1_CONTEXT(0));
+ if (!asn1_start_tag(data, ASN1_CONTEXT(0))) goto out;
while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) {
struct tldap_control *c;
@@ -2003,39 +2013,43 @@ static bool tldap_decode_controls(struct tldap_req_state *state)
sctrls = talloc_realloc(msg, sctrls, struct tldap_control,
num_controls + 1);
if (sctrls == NULL) {
- return false;
+ goto out;
}
c = &sctrls[num_controls];
- asn1_start_tag(data, ASN1_SEQUENCE(0));
- asn1_read_OctetString_talloc(msg, data, &oid);
+ if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto out;
+ if (!asn1_read_OctetString_talloc(msg, data, &oid)) goto out;
if ((data->has_error) || (oid == NULL)) {
- return false;
+ goto out;
}
c->oid = oid;
if (asn1_peek_tag(data, ASN1_BOOLEAN)) {
- asn1_read_BOOLEAN(data, &c->critical);
+ if (!asn1_read_BOOLEAN(data, &c->critical)) goto out;
} else {
c->critical = false;
}
c->value = data_blob_null;
if (asn1_peek_tag(data, ASN1_OCTET_STRING) &&
!asn1_read_OctetString(data, msg, &c->value)) {
- return false;
+ goto out;
}
- asn1_end_tag(data); /* ASN1_SEQUENCE(0) */
+ if (!asn1_end_tag(data)) goto out; /* ASN1_SEQUENCE(0) */
num_controls += 1;
}
- asn1_end_tag(data); /* ASN1_CONTEXT(0) */
+ if (!asn1_end_tag(data)) goto out; /* ASN1_CONTEXT(0) */
- if (data->has_error) {
+ ret = true;
+
+ out:
+
+ if (ret == false) {
TALLOC_FREE(sctrls);
- return false;
+ } else {
+ msg->res_sctrls = sctrls;
}
- msg->res_sctrls = sctrls;
- return true;
+ return ret;
}
static void tldap_simple_done(struct tevent_req *subreq, int type)
@@ -2101,27 +2115,27 @@ struct tevent_req *tldap_add_send(TALLOC_CTX *mem_ctx,
return NULL;
}
- asn1_push_tag(state->out, TLDAP_REQ_ADD);
- asn1_write_OctetString(state->out, dn, strlen(dn));
- asn1_push_tag(state->out, ASN1_SEQUENCE(0));
+ if (!asn1_push_tag(state->out, TLDAP_REQ_ADD)) goto err;
+ if (!asn1_write_OctetString(state->out, dn, strlen(dn))) goto err;
+ if (!asn1_push_tag(state->out, ASN1_SEQUENCE(0))) goto err;
for (i=0; i<num_attributes; i++) {
struct tldap_mod *attrib = &attributes[i];
- asn1_push_tag(state->out, ASN1_SEQUENCE(0));
- asn1_write_OctetString(state->out, attrib->attribute,
- strlen(attrib->attribute));
- asn1_push_tag(state->out, ASN1_SET);
+ if (!asn1_push_tag(state->out, ASN1_SEQUENCE(0))) goto err;
+ if (!asn1_write_OctetString(state->out, attrib->attribute,
+ strlen(attrib->attribute))) goto err;
+ if (!asn1_push_tag(state->out, ASN1_SET)) goto err;
for (j=0; j<attrib->num_values; j++) {
- asn1_write_OctetString(state->out,
+ if (!asn1_write_OctetString(state->out,
attrib->values[j].data,
- attrib->values[j].length);
+ attrib->values[j].length)) goto err;
}
- asn1_pop_tag(state->out);
- asn1_pop_tag(state->out);
+ if (!asn1_pop_tag(state->out)) goto err;
+ if (!asn1_pop_tag(state->out)) goto err;
}
- asn1_pop_tag(state->out);
- asn1_pop_tag(state->out);
+ if (!asn1_pop_tag(state->out)) goto err;
+ if (!asn1_pop_tag(state->out)) goto err;
subreq = tldap_msg_send(state, ev, ld, state->id, state->out,
sctrls, num_sctrls);
@@ -2130,6 +2144,11 @@ struct tevent_req *tldap_add_send(TALLOC_CTX *mem_ctx,
}
tevent_req_set_callback(subreq, tldap_add_done, req);
return req;
+
+ err:
+
+ tevent_req_error(req, TLDAP_ENCODING_ERROR);
+ return tevent_req_post(req, ev);
}
static void tldap_add_done(struct tevent_req *subreq)
@@ -2198,30 +2217,30 @@ struct tevent_req *tldap_modify_send(TALLOC_CTX *mem_ctx,
return NULL;
}
- asn1_push_tag(state->out, TLDAP_REQ_MODIFY);
- asn1_write_OctetString(state->out, dn, strlen(dn));
- asn1_push_tag(state->out, ASN1_SEQUENCE(0));
+ if (!asn1_push_tag(state->out, TLDAP_REQ_MODIFY)) goto err;
+ if (!asn1_write_OctetString(state->out, dn, strlen(dn))) goto err;
+ if (!asn1_push_tag(state->out, ASN1_SEQUENCE(0))) goto err;
for (i=0; i<num_mods; i++) {
struct tldap_mod *mod = &mods[i];
- asn1_push_tag(state->out, ASN1_SEQUENCE(0));
- asn1_write_enumerated(state->out, mod->mod_op),
- asn1_push_tag(state->out, ASN1_SEQUENCE(0));
- asn1_write_OctetString(state->out, mod->attribute,
- strlen(mod->attribute));
- asn1_push_tag(state->out, ASN1_SET);
+ if (!asn1_push_tag(state->out, ASN1_SEQUENCE(0))) goto err;
+ if (!asn1_write_enumerated(state->out, mod->mod_op)) goto err;
+ if (!asn1_push_tag(state->out, ASN1_SEQUENCE(0))) goto err;
+ if (!asn1_write_OctetString(state->out, mod->attribute,
+ strlen(mod->attribute))) goto err;
+ if (!asn1_push_tag(state->out, ASN1_SET)) goto err;
for (j=0; j<mod->num_values; j++) {
- asn1_write_OctetString(state->out,
+ if (!asn1_write_OctetString(state->out,
mod->values[j].data,
- mod->values[j].length);
+ mod->values[j].length)) goto err;
}
- asn1_pop_tag(state->out);
- asn1_pop_tag(state->out);
- asn1_pop_tag(state->out);
+ if (!asn1_pop_tag(state->out)) goto err;
+ if (!asn1_pop_tag(state->out)) goto err;
+ if (!asn1_pop_tag(state->out)) goto err;
}
- asn1_pop_tag(state->out);
- asn1_pop_tag(state->out);
+ if (!asn1_pop_tag(state->out)) goto err;
+ if (!asn1_pop_tag(state->out)) goto err;
subreq = tldap_msg_send(state, ev, ld, state->id, state->out,
sctrls, num_sctrls);
@@ -2230,6 +2249,11 @@ struct tevent_req *tldap_modify_send(TALLOC_CTX *mem_ctx,
}
tevent_req_set_callback(subreq, tldap_modify_done, req);
return req;
+
+ err:
+
+ tevent_req_error(req, TLDAP_ENCODING_ERROR);
+ return tevent_req_post(req, ev);
}
static void tldap_modify_done(struct tevent_req *subreq)
@@ -2296,9 +2320,9 @@ struct tevent_req *tldap_delete_send(TALLOC_CTX *mem_ctx,
return NULL;
}
- asn1_push_tag(state->out, TLDAP_REQ_DELETE);
- asn1_write(state->out, dn, strlen(dn));
- asn1_pop_tag(state->out);
+ if (!asn1_push_tag(state->out, TLDAP_REQ_DELETE)) goto err;
+ if (!asn1_write(state->out, dn, strlen(dn))) goto err;
+ if (!asn1_pop_tag(state->out)) goto err;
subreq = tldap_msg_send(state, ev, ld, state->id, state->out,
sctrls, num_sctrls);
@@ -2307,6 +2331,11 @@ struct tevent_req *tldap_delete_send(TALLOC_CTX *mem_ctx,
}
tevent_req_set_callback(subreq, tldap_delete_done, req);
return req;
+
+ err:
+
+ tevent_req_error(req, TLDAP_ENCODING_ERROR);
+ return tevent_req_post(req, ev);
}
static void tldap_delete_done(struct tevent_req *subreq)
--
2.1.0.rc2.206.gedb03e5
From 1535111418e3b6bed035c32c2b66d742b91e9b88 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 19 Sep 2014 15:16:38 -0700
Subject: [PATCH 07/10] s4: auth: gensec: asn1 fixes - check all returns.
Signed-off-by: Jeremy Allison <jra at samba.org>
---
source4/auth/gensec/gensec_krb5.c | 41 +++++++++++++++++++++------------------
1 file changed, 22 insertions(+), 19 deletions(-)
diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c
index 237a263..c34c434 100644
--- a/source4/auth/gensec/gensec_krb5.c
+++ b/source4/auth/gensec/gensec_krb5.c
@@ -403,30 +403,31 @@ static NTSTATUS gensec_fake_gssapi_krb5_client_start(struct gensec_security *gen
static DATA_BLOB gensec_gssapi_gen_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *ticket, const uint8_t tok_id[2])
{
struct asn1_data *data;
- DATA_BLOB ret;
+ DATA_BLOB ret = data_blob_null;
data = asn1_init(mem_ctx);
if (!data || !ticket->data) {
- return data_blob(NULL,0);
+ return ret;
}
- asn1_push_tag(data, ASN1_APPLICATION(0));
- asn1_write_OID(data, GENSEC_OID_KERBEROS5);
+ if (!asn1_push_tag(data, ASN1_APPLICATION(0))) goto err;
+ if (!asn1_write_OID(data, GENSEC_OID_KERBEROS5)) goto err;
- asn1_write(data, tok_id, 2);
- asn1_write(data, ticket->data, ticket->length);
- asn1_pop_tag(data);
+ if (!asn1_write(data, tok_id, 2)) goto err;
+ if (!asn1_write(data, ticket->data, ticket->length)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
- if (data->has_error) {
- DEBUG(1,("Failed to build krb5 wrapper at offset %d\n", (int)data->ofs));
- asn1_free(data);
- return data_blob(NULL,0);
- }
ret = data_blob_talloc(mem_ctx, data->data, data->length);
asn1_free(data);
return ret;
+
+ err:
+
+ DEBUG(1,("Failed to build krb5 wrapper at offset %d\n", (int)data->ofs));
+ asn1_free(data);
+ return ret;
}
/*
@@ -434,7 +435,7 @@ static DATA_BLOB gensec_gssapi_gen_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLO
*/
static bool gensec_gssapi_parse_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, DATA_BLOB *ticket, uint8_t tok_id[2])
{
- bool ret;
+ bool ret = false;
struct asn1_data *data = asn1_init(mem_ctx);
int data_remaining;
@@ -442,25 +443,27 @@ static bool gensec_gssapi_parse_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *
return false;
}
- asn1_load(data, *blob);
- asn1_start_tag(data, ASN1_APPLICATION(0));
- asn1_check_OID(data, GENSEC_OID_KERBEROS5);
+ if (!asn1_load(data, *blob)) goto err;
+ if (!asn1_start_tag(data, ASN1_APPLICATION(0))) goto err;
+ if (!asn1_check_OID(data, GENSEC_OID_KERBEROS5)) goto err;
data_remaining = asn1_tag_remaining(data);
if (data_remaining < 3) {
data->has_error = true;
} else {
- asn1_read(data, tok_id, 2);
+ if (!asn1_read(data, tok_id, 2)) goto err;
data_remaining -= 2;
*ticket = data_blob_talloc(mem_ctx, NULL, data_remaining);
- asn1_read(data, ticket->data, ticket->length);
+ if (!asn1_read(data, ticket->data, ticket->length)) goto err;
}
- asn1_end_tag(data);
+ if (!asn1_end_tag(data)) goto err;
ret = !data->has_error;
+ err:
+
asn1_free(data);
return ret;
--
2.1.0.rc2.206.gedb03e5
From ec94f0aa48f63a7feb871dafe0d52960ab640b38 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 19 Sep 2014 15:21:06 -0700
Subject: [PATCH 08/10] s3: tldap_util: Ensure all asn1_XX returns are checked.
Signed-off-by: Jeremy Allison <jra at samba.org>
---
source3/lib/tldap_util.c | 43 +++++++++++++++++++++++--------------------
1 file changed, 23 insertions(+), 20 deletions(-)
diff --git a/source3/lib/tldap_util.c b/source3/lib/tldap_util.c
index 1ffb264..45bf19f 100644
--- a/source3/lib/tldap_util.c
+++ b/source3/lib/tldap_util.c
@@ -635,28 +635,23 @@ static struct tevent_req *tldap_ship_paged_search(
struct tldap_search_paged_state *state)
{
struct tldap_control *pgctrl;
- struct asn1_data *asn1;
+ struct asn1_data *asn1 = NULL;
asn1 = asn1_init(state);
if (asn1 == NULL) {
return NULL;
}
- asn1_push_tag(asn1, ASN1_SEQUENCE(0));
- asn1_write_Integer(asn1, state->page_size);
- asn1_write_OctetString(asn1, state->cookie.data, state->cookie.length);
- asn1_pop_tag(asn1);
- if (asn1->has_error) {
- TALLOC_FREE(asn1);
- return NULL;
- }
+ if (!asn1_push_tag(asn1, ASN1_SEQUENCE(0))) goto err;
+ if (!asn1_write_Integer(asn1, state->page_size)) goto err;
+ if (!asn1_write_OctetString(asn1, state->cookie.data, state->cookie.length)) goto err;
+ if (!asn1_pop_tag(asn1)) goto err;
state->asn1 = asn1;
pgctrl = &state->sctrls[state->num_sctrls-1];
pgctrl->oid = TLDAP_CONTROL_PAGEDRESULTS;
pgctrl->critical = true;
if (!asn1_blob(state->asn1, &pgctrl->value)) {
- TALLOC_FREE(asn1);
- return NULL;
+ goto err;
}
return tldap_search_send(mem_ctx, state->ev, state->ld, state->base,
state->scope, state->filter, state->attrs,
@@ -665,6 +660,11 @@ static struct tevent_req *tldap_ship_paged_search(
state->cctrls, state->num_cctrls,
state->timelimit, state->sizelimit,
state->deref);
+
+ err:
+
+ TALLOC_FREE(asn1);
+ return NULL;
}
static void tldap_search_paged_done(struct tevent_req *subreq);
@@ -737,7 +737,7 @@ static void tldap_search_paged_done(struct tevent_req *subreq)
subreq, struct tevent_req);
struct tldap_search_paged_state *state = tevent_req_data(
req, struct tldap_search_paged_state);
- struct asn1_data *asn1;
+ struct asn1_data *asn1 = NULL;
struct tldap_control *pgctrl;
int rc, size;
@@ -784,14 +784,11 @@ static void tldap_search_paged_done(struct tevent_req *subreq)
}
asn1_load_nocopy(asn1, pgctrl->value.data, pgctrl->value.length);
- asn1_start_tag(asn1, ASN1_SEQUENCE(0));
- asn1_read_Integer(asn1, &size);
- asn1_read_OctetString(asn1, state, &state->cookie);
- asn1_end_tag(asn1);
- if (asn1->has_error) {
- tevent_req_error(req, TLDAP_DECODING_ERROR);
- return;
- }
+ if (!asn1_start_tag(asn1, ASN1_SEQUENCE(0))) goto err;
+ if (!asn1_read_Integer(asn1, &size)) goto err;
+ if (!asn1_read_OctetString(asn1, state, &state->cookie)) goto err;
+ if (!asn1_end_tag(asn1)) goto err;
+
TALLOC_FREE(asn1);
if (state->cookie.length == 0) {
@@ -807,6 +804,12 @@ static void tldap_search_paged_done(struct tevent_req *subreq)
return;
}
tevent_req_set_callback(subreq, tldap_search_paged_done, req);
+
+ err:
+
+ TALLOC_FREE(asn1);
+ tevent_req_error(req, TLDAP_DECODING_ERROR);
+ return;
}
int tldap_search_paged_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
--
2.1.0.rc2.206.gedb03e5
From 5c8ddc4957a36a168d0089a1f4b07e988216c50b Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Mon, 22 Sep 2014 13:28:18 -0700
Subject: [PATCH 09/10] s4: libcli: ldap controls - Ensure all asn1_XX returns
are checked.
Signed-off-by: Jeremy Allison <jra at samba.org>
---
source4/libcli/ldap/ldap_controls.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c
index 17d96f6..1e67a01 100644
--- a/source4/libcli/ldap/ldap_controls.c
+++ b/source4/libcli/ldap/ldap_controls.c
@@ -1129,10 +1129,16 @@ static bool encode_openldap_dereference(void *mem_ctx, void *in, DATA_BLOB *out)
}
}
- asn1_pop_tag(data);
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) {
+ return false;
+ }
+ if (!asn1_pop_tag(data)) {
+ return false;
+ }
+ }
+ if (!asn1_pop_tag(data)) {
+ return false;
}
- asn1_pop_tag(data);
*out = data_blob_talloc(mem_ctx, data->data, data->length);
if (out->data == NULL) {
@@ -1181,8 +1187,12 @@ static bool decode_openldap_dereference(void *mem_ctx, DATA_BLOB in, void *_out)
return false;
}
- asn1_read_OctetString_talloc(r[i], data, &r[i]->source_attribute);
- asn1_read_OctetString_talloc(r[i], data, &r[i]->dereferenced_dn);
+ if (!asn1_read_OctetString_talloc(r[i], data, &r[i]->source_attribute)) {
+ return false;
+ }
+ if (!asn1_read_OctetString_talloc(r[i], data, &r[i]->dereferenced_dn)) {
+ return false;
+ }
if (asn1_peek_tag(data, ASN1_CONTEXT(0))) {
if (!asn1_start_tag(data, ASN1_CONTEXT(0))) {
return false;
--
2.1.0.rc2.206.gedb03e5
From f2e19113f886d1d9c252f8afcabd67107fd6a13c Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Mon, 22 Sep 2014 16:08:26 -0700
Subject: [PATCH 10/10] s4: libcli: ldap message - Ensure all asn1_XX returns
are checked.
Signed-off-by: Jeremy Allison <jra at samba.org>
---
libcli/ldap/ldap_message.c | 786 ++++++++++++++++++------------------
libcli/ldap/ldap_message.h | 2 +-
source4/libcli/ldap/ldap_controls.c | 8 +-
3 files changed, 401 insertions(+), 395 deletions(-)
diff --git a/libcli/ldap/ldap_message.c b/libcli/ldap/ldap_message.c
index 1c5542c..ba94f4c 100644
--- a/libcli/ldap/ldap_message.c
+++ b/libcli/ldap/ldap_message.c
@@ -229,31 +229,31 @@ static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree
switch (tree->operation) {
case LDB_OP_AND:
case LDB_OP_OR:
- asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1));
+ if (!asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1))) return false;
for (i=0; i<tree->u.list.num_elements; i++) {
if (!ldap_push_filter(data, tree->u.list.elements[i])) {
return false;
}
}
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) return false;
break;
case LDB_OP_NOT:
- asn1_push_tag(data, ASN1_CONTEXT(2));
+ if (!asn1_push_tag(data, ASN1_CONTEXT(2))) return false;
if (!ldap_push_filter(data, tree->u.isnot.child)) {
return false;
}
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) return false;
break;
case LDB_OP_EQUALITY:
/* equality test */
- asn1_push_tag(data, ASN1_CONTEXT(3));
- asn1_write_OctetString(data, tree->u.equality.attr,
- strlen(tree->u.equality.attr));
- asn1_write_OctetString(data, tree->u.equality.value.data,
- tree->u.equality.value.length);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_CONTEXT(3))) return false;
+ if (!asn1_write_OctetString(data, tree->u.equality.attr,
+ strlen(tree->u.equality.attr))) return false;
+ if (!asn1_write_OctetString(data, tree->u.equality.value.data,
+ tree->u.equality.value.length)) return false;
+ if (!asn1_pop_tag(data)) return false;
break;
case LDB_OP_SUBSTRING:
@@ -266,16 +266,16 @@ static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree
any [1] LDAPString,
final [2] LDAPString } }
*/
- asn1_push_tag(data, ASN1_CONTEXT(4));
- asn1_write_OctetString(data, tree->u.substring.attr, strlen(tree->u.substring.attr));
- asn1_push_tag(data, ASN1_SEQUENCE(0));
+ if (!asn1_push_tag(data, ASN1_CONTEXT(4))) return false;
+ if (!asn1_write_OctetString(data, tree->u.substring.attr, strlen(tree->u.substring.attr))) return false;
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) return false;
if (tree->u.substring.chunks && tree->u.substring.chunks[0]) {
i = 0;
if (!tree->u.substring.start_with_wildcard) {
- asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0));
- asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0))) return false;
+ if (!asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i])) return false;
+ if (!asn1_pop_tag(data)) return false;
i++;
}
while (tree->u.substring.chunks[i]) {
@@ -287,51 +287,51 @@ static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree
} else {
ctx = 1;
}
- asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(ctx));
- asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(ctx))) return false;
+ if (!asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i])) return false;
+ if (!asn1_pop_tag(data)) return false;
i++;
}
}
- asn1_pop_tag(data);
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) return false;
+ if (!asn1_pop_tag(data)) return false;
break;
case LDB_OP_GREATER:
/* greaterOrEqual test */
- asn1_push_tag(data, ASN1_CONTEXT(5));
- asn1_write_OctetString(data, tree->u.comparison.attr,
- strlen(tree->u.comparison.attr));
- asn1_write_OctetString(data, tree->u.comparison.value.data,
- tree->u.comparison.value.length);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_CONTEXT(5))) return false;
+ if (!asn1_write_OctetString(data, tree->u.comparison.attr,
+ strlen(tree->u.comparison.attr))) return false;
+ if (!asn1_write_OctetString(data, tree->u.comparison.value.data,
+ tree->u.comparison.value.length)) return false;
+ if (!asn1_pop_tag(data)) return false;
break;
case LDB_OP_LESS:
/* lessOrEqual test */
- asn1_push_tag(data, ASN1_CONTEXT(6));
- asn1_write_OctetString(data, tree->u.comparison.attr,
- strlen(tree->u.comparison.attr));
- asn1_write_OctetString(data, tree->u.comparison.value.data,
- tree->u.comparison.value.length);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_CONTEXT(6))) return false;
+ if (!asn1_write_OctetString(data, tree->u.comparison.attr,
+ strlen(tree->u.comparison.attr))) return false;
+ if (!asn1_write_OctetString(data, tree->u.comparison.value.data,
+ tree->u.comparison.value.length)) return false;
+ if (!asn1_pop_tag(data)) return false;
break;
case LDB_OP_PRESENT:
/* present test */
- asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7));
- asn1_write_LDAPString(data, tree->u.present.attr);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7))) return false;
+ if (!asn1_write_LDAPString(data, tree->u.present.attr)) return false;
+ if (!asn1_pop_tag(data)) return false;
return !data->has_error;
case LDB_OP_APPROX:
/* approx test */
- asn1_push_tag(data, ASN1_CONTEXT(8));
- asn1_write_OctetString(data, tree->u.comparison.attr,
- strlen(tree->u.comparison.attr));
- asn1_write_OctetString(data, tree->u.comparison.value.data,
- tree->u.comparison.value.length);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_CONTEXT(8))) return false;
+ if (!asn1_write_OctetString(data, tree->u.comparison.attr,
+ strlen(tree->u.comparison.attr))) return false;
+ if (!asn1_write_OctetString(data, tree->u.comparison.value.data,
+ tree->u.comparison.value.length)) return false;
+ if (!asn1_pop_tag(data)) return false;
break;
case LDB_OP_EXTENDED:
@@ -343,24 +343,24 @@ static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree
dnAttributes [4] BOOLEAN DEFAULT FALSE
}
*/
- asn1_push_tag(data, ASN1_CONTEXT(9));
+ if (!asn1_push_tag(data, ASN1_CONTEXT(9))) return false;
if (tree->u.extended.rule_id) {
- asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1));
- asn1_write_LDAPString(data, tree->u.extended.rule_id);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1))) return false;
+ if (!asn1_write_LDAPString(data, tree->u.extended.rule_id)) return false;
+ if (!asn1_pop_tag(data)) return false;
}
if (tree->u.extended.attr) {
- asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(2));
- asn1_write_LDAPString(data, tree->u.extended.attr);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(2))) return false;
+ if (!asn1_write_LDAPString(data, tree->u.extended.attr)) return false;
+ if (!asn1_pop_tag(data)) return false;
}
- asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3));
- asn1_write_DATA_BLOB_LDAPString(data, &tree->u.extended.value);
- asn1_pop_tag(data);
- asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4));
- asn1_write_uint8(data, tree->u.extended.dnAttributes);
- asn1_pop_tag(data);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3))) return false;
+ if (!asn1_write_DATA_BLOB_LDAPString(data, &tree->u.extended.value)) return false;
+ if (!asn1_pop_tag(data)) return false;
+ if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4))) return false;
+ if (!asn1_write_uint8(data, tree->u.extended.dnAttributes)) return false;
+ if (!asn1_pop_tag(data)) return false;
+ if (!asn1_pop_tag(data)) return false;
break;
default:
@@ -369,20 +369,21 @@ static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree
return !data->has_error;
}
-static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *result)
+static bool ldap_encode_response(struct asn1_data *data, struct ldap_Result *result)
{
- asn1_write_enumerated(data, result->resultcode);
- asn1_write_OctetString(data, result->dn,
- (result->dn) ? strlen(result->dn) : 0);
- asn1_write_OctetString(data, result->errormessage,
+ if (!asn1_write_enumerated(data, result->resultcode)) return false;
+ if (!asn1_write_OctetString(data, result->dn,
+ (result->dn) ? strlen(result->dn) : 0)) return false;
+ if (!asn1_write_OctetString(data, result->errormessage,
(result->errormessage) ?
- strlen(result->errormessage) : 0);
+ strlen(result->errormessage) : 0)) return false;
if (result->referral) {
- asn1_push_tag(data, ASN1_CONTEXT(3));
- asn1_write_OctetString(data, result->referral,
- strlen(result->referral));
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_CONTEXT(3))) return false;
+ if (!asn1_write_OctetString(data, result->referral,
+ strlen(result->referral))) return false;
+ if (!asn1_pop_tag(data)) return false;
}
+ return true;
}
_PUBLIC_ bool ldap_encode(struct ldap_message *msg,
@@ -394,286 +395,286 @@ _PUBLIC_ bool ldap_encode(struct ldap_message *msg,
if (!data) return false;
- asn1_push_tag(data, ASN1_SEQUENCE(0));
- asn1_write_Integer(data, msg->messageid);
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
+ if (!asn1_write_Integer(data, msg->messageid)) goto err;
switch (msg->type) {
case LDAP_TAG_BindRequest: {
struct ldap_BindRequest *r = &msg->r.BindRequest;
- asn1_push_tag(data, ASN1_APPLICATION(msg->type));
- asn1_write_Integer(data, r->version);
- asn1_write_OctetString(data, r->dn,
- (r->dn != NULL) ? strlen(r->dn) : 0);
+ if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
+ if (!asn1_write_Integer(data, r->version)) goto err;
+ if (!asn1_write_OctetString(data, r->dn,
+ (r->dn != NULL) ? strlen(r->dn) : 0)) goto err;
switch (r->mechanism) {
case LDAP_AUTH_MECH_SIMPLE:
/* context, primitive */
- asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0));
- asn1_write(data, r->creds.password,
- strlen(r->creds.password));
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0))) goto err;
+ if (!asn1_write(data, r->creds.password,
+ strlen(r->creds.password))) goto err;
+ if (!asn1_pop_tag(data)) goto err;
break;
case LDAP_AUTH_MECH_SASL:
/* context, constructed */
- asn1_push_tag(data, ASN1_CONTEXT(3));
- asn1_write_OctetString(data, r->creds.SASL.mechanism,
- strlen(r->creds.SASL.mechanism));
+ if (!asn1_push_tag(data, ASN1_CONTEXT(3))) goto err;
+ if (!asn1_write_OctetString(data, r->creds.SASL.mechanism,
+ strlen(r->creds.SASL.mechanism))) goto err;
if (r->creds.SASL.secblob) {
- asn1_write_OctetString(data, r->creds.SASL.secblob->data,
- r->creds.SASL.secblob->length);
+ if (!asn1_write_OctetString(data, r->creds.SASL.secblob->data,
+ r->creds.SASL.secblob->length)) goto err;
}
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) goto err;
break;
default:
- return false;
+ goto err;
}
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) goto err;
break;
}
case LDAP_TAG_BindResponse: {
struct ldap_BindResponse *r = &msg->r.BindResponse;
- asn1_push_tag(data, ASN1_APPLICATION(msg->type));
- ldap_encode_response(data, &r->response);
+ if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
+ if (!ldap_encode_response(data, &r->response)) goto err;
if (r->SASL.secblob) {
- asn1_write_ContextSimple(data, 7, r->SASL.secblob);
+ if (!asn1_write_ContextSimple(data, 7, r->SASL.secblob)) goto err;
}
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) goto err;
break;
}
case LDAP_TAG_UnbindRequest: {
/* struct ldap_UnbindRequest *r = &msg->r.UnbindRequest; */
- asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type));
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type))) goto err;
+ if (!asn1_pop_tag(data)) goto err;
break;
}
case LDAP_TAG_SearchRequest: {
struct ldap_SearchRequest *r = &msg->r.SearchRequest;
- asn1_push_tag(data, ASN1_APPLICATION(msg->type));
- asn1_write_OctetString(data, r->basedn, strlen(r->basedn));
- asn1_write_enumerated(data, r->scope);
- asn1_write_enumerated(data, r->deref);
- asn1_write_Integer(data, r->sizelimit);
- asn1_write_Integer(data, r->timelimit);
- asn1_write_BOOLEAN(data, r->attributesonly);
+ if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
+ if (!asn1_write_OctetString(data, r->basedn, strlen(r->basedn))) goto err;
+ if (!asn1_write_enumerated(data, r->scope)) goto err;
+ if (!asn1_write_enumerated(data, r->deref)) goto err;
+ if (!asn1_write_Integer(data, r->sizelimit)) goto err;
+ if (!asn1_write_Integer(data, r->timelimit)) goto err;
+ if (!asn1_write_BOOLEAN(data, r->attributesonly)) goto err;
if (!ldap_push_filter(data, r->tree)) {
- return false;
+ goto err;
}
- asn1_push_tag(data, ASN1_SEQUENCE(0));
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
for (i=0; i<r->num_attributes; i++) {
- asn1_write_OctetString(data, r->attributes[i],
- strlen(r->attributes[i]));
+ if (!asn1_write_OctetString(data, r->attributes[i],
+ strlen(r->attributes[i]))) goto err;
}
- asn1_pop_tag(data);
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
break;
}
case LDAP_TAG_SearchResultEntry: {
struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry;
- asn1_push_tag(data, ASN1_APPLICATION(msg->type));
- asn1_write_OctetString(data, r->dn, strlen(r->dn));
- asn1_push_tag(data, ASN1_SEQUENCE(0));
+ if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
+ if (!asn1_write_OctetString(data, r->dn, strlen(r->dn))) goto err;
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
for (i=0; i<r->num_attributes; i++) {
struct ldb_message_element *attr = &r->attributes[i];
- asn1_push_tag(data, ASN1_SEQUENCE(0));
- asn1_write_OctetString(data, attr->name,
- strlen(attr->name));
- asn1_push_tag(data, ASN1_SEQUENCE(1));
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
+ if (!asn1_write_OctetString(data, attr->name,
+ strlen(attr->name))) goto err;
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(1))) goto err;
for (j=0; j<attr->num_values; j++) {
- asn1_write_OctetString(data,
+ if (!asn1_write_OctetString(data,
attr->values[j].data,
- attr->values[j].length);
+ attr->values[j].length)) goto err;
}
- asn1_pop_tag(data);
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
}
- asn1_pop_tag(data);
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
break;
}
case LDAP_TAG_SearchResultDone: {
struct ldap_Result *r = &msg->r.SearchResultDone;
- asn1_push_tag(data, ASN1_APPLICATION(msg->type));
- ldap_encode_response(data, r);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
+ if (!ldap_encode_response(data, r)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
break;
}
case LDAP_TAG_ModifyRequest: {
struct ldap_ModifyRequest *r = &msg->r.ModifyRequest;
- asn1_push_tag(data, ASN1_APPLICATION(msg->type));
- asn1_write_OctetString(data, r->dn, strlen(r->dn));
- asn1_push_tag(data, ASN1_SEQUENCE(0));
+ if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
+ if (!asn1_write_OctetString(data, r->dn, strlen(r->dn))) goto err;
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
for (i=0; i<r->num_mods; i++) {
struct ldb_message_element *attrib = &r->mods[i].attrib;
- asn1_push_tag(data, ASN1_SEQUENCE(0));
- asn1_write_enumerated(data, r->mods[i].type);
- asn1_push_tag(data, ASN1_SEQUENCE(0));
- asn1_write_OctetString(data, attrib->name,
- strlen(attrib->name));
- asn1_push_tag(data, ASN1_SET);
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
+ if (!asn1_write_enumerated(data, r->mods[i].type)) goto err;
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
+ if (!asn1_write_OctetString(data, attrib->name,
+ strlen(attrib->name))) goto err;
+ if (!asn1_push_tag(data, ASN1_SET)) goto err;
for (j=0; j<attrib->num_values; j++) {
- asn1_write_OctetString(data,
+ if (!asn1_write_OctetString(data,
attrib->values[j].data,
- attrib->values[j].length);
+ attrib->values[j].length)) goto err;
}
- asn1_pop_tag(data);
- asn1_pop_tag(data);
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
}
- asn1_pop_tag(data);
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
break;
}
case LDAP_TAG_ModifyResponse: {
struct ldap_Result *r = &msg->r.ModifyResponse;
- asn1_push_tag(data, ASN1_APPLICATION(msg->type));
- ldap_encode_response(data, r);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
+ if (!ldap_encode_response(data, r)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
break;
}
case LDAP_TAG_AddRequest: {
struct ldap_AddRequest *r = &msg->r.AddRequest;
- asn1_push_tag(data, ASN1_APPLICATION(msg->type));
- asn1_write_OctetString(data, r->dn, strlen(r->dn));
- asn1_push_tag(data, ASN1_SEQUENCE(0));
+ if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
+ if (!asn1_write_OctetString(data, r->dn, strlen(r->dn))) goto err;
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
for (i=0; i<r->num_attributes; i++) {
struct ldb_message_element *attrib = &r->attributes[i];
- asn1_push_tag(data, ASN1_SEQUENCE(0));
- asn1_write_OctetString(data, attrib->name,
- strlen(attrib->name));
- asn1_push_tag(data, ASN1_SET);
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
+ if (!asn1_write_OctetString(data, attrib->name,
+ strlen(attrib->name))) goto err;
+ if (!asn1_push_tag(data, ASN1_SET)) goto err;
for (j=0; j<r->attributes[i].num_values; j++) {
- asn1_write_OctetString(data,
+ if (!asn1_write_OctetString(data,
attrib->values[j].data,
- attrib->values[j].length);
+ attrib->values[j].length)) goto err;
}
- asn1_pop_tag(data);
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
}
- asn1_pop_tag(data);
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
break;
}
case LDAP_TAG_AddResponse: {
struct ldap_Result *r = &msg->r.AddResponse;
- asn1_push_tag(data, ASN1_APPLICATION(msg->type));
- ldap_encode_response(data, r);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
+ if (!ldap_encode_response(data, r)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
break;
}
case LDAP_TAG_DelRequest: {
struct ldap_DelRequest *r = &msg->r.DelRequest;
- asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type));
- asn1_write(data, r->dn, strlen(r->dn));
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type))) goto err;
+ if (!asn1_write(data, r->dn, strlen(r->dn))) goto err;
+ if (!asn1_pop_tag(data)) goto err;
break;
}
case LDAP_TAG_DelResponse: {
struct ldap_Result *r = &msg->r.DelResponse;
- asn1_push_tag(data, ASN1_APPLICATION(msg->type));
- ldap_encode_response(data, r);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
+ if (!ldap_encode_response(data, r)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
break;
}
case LDAP_TAG_ModifyDNRequest: {
struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest;
- asn1_push_tag(data, ASN1_APPLICATION(msg->type));
- asn1_write_OctetString(data, r->dn, strlen(r->dn));
- asn1_write_OctetString(data, r->newrdn, strlen(r->newrdn));
- asn1_write_BOOLEAN(data, r->deleteolddn);
+ if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
+ if (!asn1_write_OctetString(data, r->dn, strlen(r->dn))) goto err;
+ if (!asn1_write_OctetString(data, r->newrdn, strlen(r->newrdn))) goto err;
+ if (!asn1_write_BOOLEAN(data, r->deleteolddn)) goto err;
if (r->newsuperior) {
- asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0));
- asn1_write(data, r->newsuperior,
- strlen(r->newsuperior));
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0))) goto err;
+ if (!asn1_write(data, r->newsuperior,
+ strlen(r->newsuperior))) goto err;
+ if (!asn1_pop_tag(data)) goto err;
}
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) goto err;
break;
}
case LDAP_TAG_ModifyDNResponse: {
struct ldap_Result *r = &msg->r.ModifyDNResponse;
- asn1_push_tag(data, ASN1_APPLICATION(msg->type));
- ldap_encode_response(data, r);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
+ if (!ldap_encode_response(data, r)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
break;
}
case LDAP_TAG_CompareRequest: {
struct ldap_CompareRequest *r = &msg->r.CompareRequest;
- asn1_push_tag(data, ASN1_APPLICATION(msg->type));
- asn1_write_OctetString(data, r->dn, strlen(r->dn));
- asn1_push_tag(data, ASN1_SEQUENCE(0));
- asn1_write_OctetString(data, r->attribute,
- strlen(r->attribute));
- asn1_write_OctetString(data, r->value.data,
- r->value.length);
- asn1_pop_tag(data);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
+ if (!asn1_write_OctetString(data, r->dn, strlen(r->dn))) goto err;
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
+ if (!asn1_write_OctetString(data, r->attribute,
+ strlen(r->attribute))) goto err;
+ if (!asn1_write_OctetString(data, r->value.data,
+ r->value.length)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
break;
}
case LDAP_TAG_CompareResponse: {
struct ldap_Result *r = &msg->r.ModifyDNResponse;
- asn1_push_tag(data, ASN1_APPLICATION(msg->type));
- ldap_encode_response(data, r);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
+ if (!ldap_encode_response(data, r)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
break;
}
case LDAP_TAG_AbandonRequest: {
struct ldap_AbandonRequest *r = &msg->r.AbandonRequest;
- asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type));
- asn1_write_implicit_Integer(data, r->messageid);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type))) goto err;
+ if (!asn1_write_implicit_Integer(data, r->messageid)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
break;
}
case LDAP_TAG_SearchResultReference: {
struct ldap_SearchResRef *r = &msg->r.SearchResultReference;
- asn1_push_tag(data, ASN1_APPLICATION(msg->type));
- asn1_write_OctetString(data, r->referral, strlen(r->referral));
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
+ if (!asn1_write_OctetString(data, r->referral, strlen(r->referral))) goto err;
+ if (!asn1_pop_tag(data)) goto err;
break;
}
case LDAP_TAG_ExtendedRequest: {
struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest;
- asn1_push_tag(data, ASN1_APPLICATION(msg->type));
- asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0));
- asn1_write(data, r->oid, strlen(r->oid));
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
+ if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0))) goto err;
+ if (!asn1_write(data, r->oid, strlen(r->oid))) goto err;
+ if (!asn1_pop_tag(data)) goto err;
if (r->value) {
- asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1));
- asn1_write(data, r->value->data, r->value->length);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1))) goto err;
+ if (!asn1_write(data, r->value->data, r->value->length)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
}
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) goto err;
break;
}
case LDAP_TAG_ExtendedResponse: {
struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse;
- asn1_push_tag(data, ASN1_APPLICATION(msg->type));
- ldap_encode_response(data, &r->response);
+ if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
+ if (!ldap_encode_response(data, &r->response)) goto err;
if (r->oid) {
- asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(10));
- asn1_write(data, r->oid, strlen(r->oid));
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(10))) goto err;
+ if (!asn1_write(data, r->oid, strlen(r->oid))) goto err;
+ if (!asn1_pop_tag(data)) goto err;
}
if (r->value) {
- asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(11));
- asn1_write(data, r->value->data, r->value->length);
- asn1_pop_tag(data);
+ if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(11))) goto err;
+ if (!asn1_write(data, r->value->data, r->value->length)) goto err;
+ if (!asn1_pop_tag(data)) goto err;
}
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) goto err;
break;
}
default:
- return false;
+ goto err;
}
if (msg->controls != NULL) {
- asn1_push_tag(data, ASN1_CONTEXT(0));
+ if (!asn1_push_tag(data, ASN1_CONTEXT(0))) goto err;
for (i = 0; msg->controls[i] != NULL; i++) {
if (!ldap_encode_control(mem_ctx, data,
@@ -681,23 +682,24 @@ _PUBLIC_ bool ldap_encode(struct ldap_message *msg,
msg->controls[i])) {
DEBUG(0,("Unable to encode control %s\n",
msg->controls[i]->oid));
- return false;
+ goto err;
}
}
- asn1_pop_tag(data);
+ if (!asn1_pop_tag(data)) goto err;
}
- asn1_pop_tag(data);
-
- if (data->has_error) {
- asn1_free(data);
- return false;
- }
+ if (!asn1_pop_tag(data)) goto err;
*result = data_blob_talloc(mem_ctx, data->data, data->length);
asn1_free(data);
+
return true;
+
+ err:
+
+ asn1_free(data);
+ return false;
}
static const char *blob2string_talloc(TALLOC_CTX *mem_ctx,
@@ -721,20 +723,21 @@ bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx,
return true;
}
-static void ldap_decode_response(TALLOC_CTX *mem_ctx,
+static bool ldap_decode_response(TALLOC_CTX *mem_ctx,
struct asn1_data *data,
struct ldap_Result *result)
{
- asn1_read_enumerated(data, &result->resultcode);
- asn1_read_OctetString_talloc(mem_ctx, data, &result->dn);
- asn1_read_OctetString_talloc(mem_ctx, data, &result->errormessage);
+ if (!asn1_read_enumerated(data, &result->resultcode)) return false;
+ if (!asn1_read_OctetString_talloc(mem_ctx, data, &result->dn)) return false;
+ if (!asn1_read_OctetString_talloc(mem_ctx, data, &result->errormessage)) return false;
if (asn1_peek_tag(data, ASN1_CONTEXT(3))) {
- asn1_start_tag(data, ASN1_CONTEXT(3));
- asn1_read_OctetString_talloc(mem_ctx, data, &result->referral);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, ASN1_CONTEXT(3))) return false;
+ if (!asn1_read_OctetString_talloc(mem_ctx, data, &result->referral)) return false;
+ if (!asn1_end_tag(data)) return false;
} else {
result->referral = NULL;
}
+ return true;
}
static struct ldb_val **ldap_decode_substring(TALLOC_CTX *mem_ctx, struct ldb_val **chunks, int chunk_num, char *value)
@@ -835,10 +838,10 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx,
const char *attrib;
DATA_BLOB value;
- asn1_start_tag(data, ASN1_CONTEXT(filter_tag));
- asn1_read_OctetString_talloc(mem_ctx, data, &attrib);
- asn1_read_OctetString(data, mem_ctx, &value);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) goto failed;
+ if (!asn1_read_OctetString_talloc(mem_ctx, data, &attrib)) goto failed;
+ if (!asn1_read_OctetString(data, mem_ctx, &value)) goto failed;
+ if (!asn1_end_tag(data)) goto failed;
if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) {
goto failed;
}
@@ -874,13 +877,13 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx,
}
while (asn1_tag_remaining(data)) {
- asn1_peek_uint8(data, &subs_tag);
+ if (!asn1_peek_uint8(data, &subs_tag)) goto failed;
subs_tag &= 0x1f; /* strip off the asn1 stuff */
if (subs_tag > 2) goto failed;
- asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(subs_tag));
- asn1_read_LDAPString(data, mem_ctx, &value);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(subs_tag))) goto failed;
+ if (!asn1_read_LDAPString(data, mem_ctx, &value)) goto failed;
+ if (!asn1_end_tag(data)) goto failed;
switch (subs_tag) {
case 0:
@@ -947,10 +950,10 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx,
const char *attrib;
DATA_BLOB value;
- asn1_start_tag(data, ASN1_CONTEXT(filter_tag));
- asn1_read_OctetString_talloc(mem_ctx, data, &attrib);
- asn1_read_OctetString(data, mem_ctx, &value);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) goto failed;
+ if (!asn1_read_OctetString_talloc(mem_ctx, data, &attrib)) goto failed;
+ if (!asn1_read_OctetString(data, mem_ctx, &value)) goto failed;
+ if (!asn1_end_tag(data)) goto failed;
if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) {
goto failed;
}
@@ -966,10 +969,10 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx,
const char *attrib;
DATA_BLOB value;
- asn1_start_tag(data, ASN1_CONTEXT(filter_tag));
- asn1_read_OctetString_talloc(mem_ctx, data, &attrib);
- asn1_read_OctetString(data, mem_ctx, &value);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) goto failed;
+ if (!asn1_read_OctetString_talloc(mem_ctx, data, &attrib)) goto failed;
+ if (!asn1_read_OctetString(data, mem_ctx, &value)) goto failed;
+ if (!asn1_end_tag(data)) goto failed;
if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) {
goto failed;
}
@@ -1004,10 +1007,10 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx,
const char *attrib;
DATA_BLOB value;
- asn1_start_tag(data, ASN1_CONTEXT(filter_tag));
- asn1_read_OctetString_talloc(mem_ctx, data, &attrib);
- asn1_read_OctetString(data, mem_ctx, &value);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) goto failed;
+ if (!asn1_read_OctetString_talloc(mem_ctx, data, &attrib)) goto failed;
+ if (!asn1_read_OctetString(data, mem_ctx, &value)) goto failed;
+ if (!asn1_end_tag(data)) goto failed;
if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) {
goto failed;
}
@@ -1030,18 +1033,18 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx,
we need to check we properly implement --SSS */
/* either oid or type must be defined */
if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { /* optional */
- asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1));
- asn1_read_LDAPString(data, ret, &oid);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1))) goto failed;
+ if (!asn1_read_LDAPString(data, ret, &oid)) goto failed;
+ if (!asn1_end_tag(data)) goto failed;
}
if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(2))) { /* optional */
- asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2));
- asn1_read_LDAPString(data, ret, &attr);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2))) goto failed;
+ if (!asn1_read_LDAPString(data, ret, &attr)) goto failed;
+ if (!asn1_end_tag(data)) goto failed;
}
- asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(3));
- asn1_read_LDAPString(data, ret, &value);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(3))) goto failed;
+ if (!asn1_read_LDAPString(data, ret, &value)) goto failed;
+ if (!asn1_end_tag(data)) goto failed;
/* dnAttributes is marked as BOOLEAN DEFAULT FALSE
it is not marked as OPTIONAL but openldap tools
do not set this unless it is to be set as TRUE
@@ -1049,9 +1052,9 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx,
seems that AD always requires the dnAttributes
boolean value to be set */
if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(4))) {
- asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(4));
- asn1_read_uint8(data, &dnAttributes);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(4))) goto failed;
+ if (!asn1_read_uint8(data, &dnAttributes)) goto failed;
+ if (!asn1_end_tag(data)) goto failed;
} else {
dnAttributes = 0;
}
@@ -1099,45 +1102,45 @@ failed:
}
/* Decode a single LDAP attribute, possibly containing multiple values */
-static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data,
+static bool ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data,
struct ldb_message_element *attrib)
{
- asn1_start_tag(data, ASN1_SEQUENCE(0));
- asn1_read_OctetString_talloc(mem_ctx, data, &attrib->name);
- asn1_start_tag(data, ASN1_SET);
+ if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) return false;
+ if (!asn1_read_OctetString_talloc(mem_ctx, data, &attrib->name)) return false;
+ if (!asn1_start_tag(data, ASN1_SET)) return false;
while (asn1_peek_tag(data, ASN1_OCTET_STRING)) {
DATA_BLOB blob;
- asn1_read_OctetString(data, mem_ctx, &blob);
+ if (!asn1_read_OctetString(data, mem_ctx, &blob)) return false;
add_value_to_attrib(mem_ctx, &blob, attrib);
}
- asn1_end_tag(data);
- asn1_end_tag(data);
-
+ if (!asn1_end_tag(data)) return false;
+ return asn1_end_tag(data);
}
/* Decode a set of LDAP attributes, as found in the dereference control */
-void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data,
+bool ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data,
struct ldb_message_element **attributes,
int *num_attributes)
{
while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) {
struct ldb_message_element attrib;
ZERO_STRUCT(attrib);
- ldap_decode_attrib(mem_ctx, data, &attrib);
+ if (!ldap_decode_attrib(mem_ctx, data, &attrib)) return false;
add_attrib_to_array_talloc(mem_ctx, &attrib,
attributes, num_attributes);
}
+ return true;
}
/* Decode a set of LDAP attributes, as found in a search entry */
-static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data,
+static bool ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data,
struct ldb_message_element **attributes,
int *num_attributes)
{
- asn1_start_tag(data, ASN1_SEQUENCE(0));
- ldap_decode_attribs_bare(mem_ctx, data,
- attributes, num_attributes);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) return false;
+ if (!ldap_decode_attribs_bare(mem_ctx, data,
+ attributes, num_attributes)) return false;
+ return asn1_end_tag(data);
}
/* This routine returns LDAP status codes */
@@ -1148,46 +1151,45 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data,
{
uint8_t tag;
- asn1_start_tag(data, ASN1_SEQUENCE(0));
- asn1_read_Integer(data, &msg->messageid);
+ if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto prot_err;
+ if (!asn1_read_Integer(data, &msg->messageid)) goto prot_err;
- if (!asn1_peek_uint8(data, &tag))
- return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
+ if (!asn1_peek_uint8(data, &tag)) goto prot_err;
switch(tag) {
case ASN1_APPLICATION(LDAP_TAG_BindRequest): {
struct ldap_BindRequest *r = &msg->r.BindRequest;
msg->type = LDAP_TAG_BindRequest;
- asn1_start_tag(data, tag);
- asn1_read_Integer(data, &r->version);
- asn1_read_OctetString_talloc(msg, data, &r->dn);
+ if (!asn1_start_tag(data, tag)) goto prot_err;
+ if (!asn1_read_Integer(data, &r->version)) goto prot_err;
+ if (!asn1_read_OctetString_talloc(msg, data, &r->dn)) goto prot_err;
if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(0))) {
int pwlen;
r->creds.password = "";
r->mechanism = LDAP_AUTH_MECH_SIMPLE;
- asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0));
+ if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0))) goto prot_err;
pwlen = asn1_tag_remaining(data);
if (pwlen == -1) {
- return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
+ goto prot_err;
}
if (pwlen != 0) {
char *pw = talloc_array(msg, char, pwlen+1);
if (!pw) {
return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
}
- asn1_read(data, pw, pwlen);
+ if (!asn1_read(data, pw, pwlen)) goto prot_err;
pw[pwlen] = '\0';
r->creds.password = pw;
}
- asn1_end_tag(data);
+ if (!asn1_end_tag(data)) goto prot_err;
} else if (asn1_peek_tag(data, ASN1_CONTEXT(3))){
- asn1_start_tag(data, ASN1_CONTEXT(3));
+ if (!asn1_start_tag(data, ASN1_CONTEXT(3))) goto prot_err;
r->mechanism = LDAP_AUTH_MECH_SASL;
- asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism);
+ if (!asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism)) goto prot_err;
if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { /* optional */
DATA_BLOB tmp_blob = data_blob(NULL, 0);
- asn1_read_OctetString(data, msg, &tmp_blob);
+ if (!asn1_read_OctetString(data, msg, &tmp_blob)) goto prot_err;
r->creds.SASL.secblob = talloc(msg, DATA_BLOB);
if (!r->creds.SASL.secblob) {
return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
@@ -1198,23 +1200,23 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data,
} else {
r->creds.SASL.secblob = NULL;
}
- asn1_end_tag(data);
+ if (!asn1_end_tag(data)) goto prot_err;
} else {
/* Neither Simple nor SASL bind */
- return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
+ goto prot_err;
}
- asn1_end_tag(data);
+ if (!asn1_end_tag(data)) goto prot_err;
break;
}
case ASN1_APPLICATION(LDAP_TAG_BindResponse): {
struct ldap_BindResponse *r = &msg->r.BindResponse;
msg->type = LDAP_TAG_BindResponse;
- asn1_start_tag(data, tag);
- ldap_decode_response(msg, data, &r->response);
+ if (!asn1_start_tag(data, tag)) goto prot_err;
+ if (!ldap_decode_response(msg, data, &r->response)) goto prot_err;
if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) {
DATA_BLOB tmp_blob = data_blob(NULL, 0);
- asn1_read_ContextSimple(data, 7, &tmp_blob);
+ if (!asn1_read_ContextSimple(data, 7, &tmp_blob)) goto prot_err;
r->SASL.secblob = talloc(msg, DATA_BLOB);
if (!r->SASL.secblob) {
return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
@@ -1225,14 +1227,14 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data,
} else {
r->SASL.secblob = NULL;
}
- asn1_end_tag(data);
+ if (!asn1_end_tag(data)) goto prot_err;
break;
}
case ASN1_APPLICATION_SIMPLE(LDAP_TAG_UnbindRequest): {
msg->type = LDAP_TAG_UnbindRequest;
- asn1_start_tag(data, tag);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, tag)) goto prot_err;
+ if (!asn1_end_tag(data)) goto prot_err;
break;
}
@@ -1241,41 +1243,41 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data,
int sizelimit, timelimit;
const char **attrs = NULL;
msg->type = LDAP_TAG_SearchRequest;
- asn1_start_tag(data, tag);
- asn1_read_OctetString_talloc(msg, data, &r->basedn);
- asn1_read_enumerated(data, (int *)(void *)&(r->scope));
- asn1_read_enumerated(data, (int *)(void *)&(r->deref));
- asn1_read_Integer(data, &sizelimit);
+ if (!asn1_start_tag(data, tag)) goto prot_err;
+ if (!asn1_read_OctetString_talloc(msg, data, &r->basedn)) goto prot_err;
+ if (!asn1_read_enumerated(data, (int *)(void *)&(r->scope))) goto prot_err;
+ if (!asn1_read_enumerated(data, (int *)(void *)&(r->deref))) goto prot_err;
+ if (!asn1_read_Integer(data, &sizelimit)) goto prot_err;
r->sizelimit = sizelimit;
- asn1_read_Integer(data, &timelimit);
+ if (!asn1_read_Integer(data, &timelimit)) goto prot_err;
r->timelimit = timelimit;
- asn1_read_BOOLEAN(data, &r->attributesonly);
+ if (!asn1_read_BOOLEAN(data, &r->attributesonly)) goto prot_err;
r->tree = ldap_decode_filter_tree(msg, data);
if (r->tree == NULL) {
- return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
+ goto prot_err;
}
- asn1_start_tag(data, ASN1_SEQUENCE(0));
+ if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto prot_err;
r->num_attributes = 0;
r->attributes = NULL;
- while (asn1_tag_remaining(data) > 0) {
+ while (asn1_tag_remaining(data) > 0) {
const char *attr;
if (!asn1_read_OctetString_talloc(msg, data,
&attr))
- return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
+ goto prot_err;
if (!add_string_to_array(msg, attr,
&attrs,
&r->num_attributes))
- return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
+ goto prot_err;
}
r->attributes = attrs;
- asn1_end_tag(data);
- asn1_end_tag(data);
+ if (!asn1_end_tag(data)) goto prot_err;
+ if (!asn1_end_tag(data)) goto prot_err;
break;
}
@@ -1284,38 +1286,38 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data,
msg->type = LDAP_TAG_SearchResultEntry;
r->attributes = NULL;
r->num_attributes = 0;
- asn1_start_tag(data, tag);
- asn1_read_OctetString_talloc(msg, data, &r->dn);
- ldap_decode_attribs(msg, data, &r->attributes,
- &r->num_attributes);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, tag)) goto prot_err;
+ if (!asn1_read_OctetString_talloc(msg, data, &r->dn)) goto prot_err;
+ if (!ldap_decode_attribs(msg, data, &r->attributes,
+ &r->num_attributes)) goto prot_err;
+ if (!asn1_end_tag(data)) goto prot_err;
break;
}
case ASN1_APPLICATION(LDAP_TAG_SearchResultDone): {
struct ldap_Result *r = &msg->r.SearchResultDone;
msg->type = LDAP_TAG_SearchResultDone;
- asn1_start_tag(data, tag);
- ldap_decode_response(msg, data, r);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, tag)) goto prot_err;
+ if (!ldap_decode_response(msg, data, r)) goto prot_err;
+ if (!asn1_end_tag(data)) goto prot_err;
break;
}
case ASN1_APPLICATION(LDAP_TAG_SearchResultReference): {
struct ldap_SearchResRef *r = &msg->r.SearchResultReference;
msg->type = LDAP_TAG_SearchResultReference;
- asn1_start_tag(data, tag);
- asn1_read_OctetString_talloc(msg, data, &r->referral);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, tag)) goto prot_err;
+ if (!asn1_read_OctetString_talloc(msg, data, &r->referral)) goto prot_err;
+ if (!asn1_end_tag(data)) goto prot_err;
break;
}
case ASN1_APPLICATION(LDAP_TAG_ModifyRequest): {
struct ldap_ModifyRequest *r = &msg->r.ModifyRequest;
msg->type = LDAP_TAG_ModifyRequest;
- asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest));
- asn1_read_OctetString_talloc(msg, data, &r->dn);
- asn1_start_tag(data, ASN1_SEQUENCE(0));
+ if (!asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest))) goto prot_err;
+ if (!asn1_read_OctetString_talloc(msg, data, &r->dn)) goto prot_err;
+ if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto prot_err;
r->num_mods = 0;
r->mods = NULL;
@@ -1324,52 +1326,52 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data,
struct ldap_mod mod;
int v;
ZERO_STRUCT(mod);
- asn1_start_tag(data, ASN1_SEQUENCE(0));
- asn1_read_enumerated(data, &v);
+ if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto prot_err;
+ if (!asn1_read_enumerated(data, &v)) goto prot_err;
mod.type = v;
- ldap_decode_attrib(msg, data, &mod.attrib);
- asn1_end_tag(data);
+ if (!ldap_decode_attrib(msg, data, &mod.attrib)) goto prot_err;
+ if (!asn1_end_tag(data)) goto prot_err;
if (!add_mod_to_array_talloc(msg, &mod,
&r->mods, &r->num_mods)) {
return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
}
}
- asn1_end_tag(data);
- asn1_end_tag(data);
+ if (!asn1_end_tag(data)) goto prot_err;
+ if (!asn1_end_tag(data)) goto prot_err;
break;
}
case ASN1_APPLICATION(LDAP_TAG_ModifyResponse): {
struct ldap_Result *r = &msg->r.ModifyResponse;
msg->type = LDAP_TAG_ModifyResponse;
- asn1_start_tag(data, tag);
- ldap_decode_response(msg, data, r);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, tag)) goto prot_err;
+ if (!ldap_decode_response(msg, data, r)) goto prot_err;
+ if (!asn1_end_tag(data)) goto prot_err;
break;
}
case ASN1_APPLICATION(LDAP_TAG_AddRequest): {
struct ldap_AddRequest *r = &msg->r.AddRequest;
msg->type = LDAP_TAG_AddRequest;
- asn1_start_tag(data, tag);
- asn1_read_OctetString_talloc(msg, data, &r->dn);
+ if (!asn1_start_tag(data, tag)) goto prot_err;
+ if (!asn1_read_OctetString_talloc(msg, data, &r->dn)) goto prot_err;
r->attributes = NULL;
r->num_attributes = 0;
- ldap_decode_attribs(msg, data, &r->attributes,
- &r->num_attributes);
+ if (!ldap_decode_attribs(msg, data, &r->attributes,
+ &r->num_attributes)) goto prot_err;
- asn1_end_tag(data);
+ if (!asn1_end_tag(data)) goto prot_err;
break;
}
case ASN1_APPLICATION(LDAP_TAG_AddResponse): {
struct ldap_Result *r = &msg->r.AddResponse;
msg->type = LDAP_TAG_AddResponse;
- asn1_start_tag(data, tag);
- ldap_decode_response(msg, data, r);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, tag)) goto prot_err;
+ if (!ldap_decode_response(msg, data, r)) goto prot_err;
+ if (!asn1_end_tag(data)) goto prot_err;
break;
}
@@ -1378,102 +1380,102 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data,
int len;
char *dn;
msg->type = LDAP_TAG_DelRequest;
- asn1_start_tag(data,
- ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest));
+ if (!asn1_start_tag(data,
+ ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest))) goto prot_err;
len = asn1_tag_remaining(data);
if (len == -1) {
- return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
+ goto prot_err;
}
dn = talloc_array(msg, char, len+1);
if (dn == NULL)
break;
- asn1_read(data, dn, len);
+ if (!asn1_read(data, dn, len)) goto prot_err;
dn[len] = '\0';
r->dn = dn;
- asn1_end_tag(data);
+ if (!asn1_end_tag(data)) goto prot_err;
break;
}
case ASN1_APPLICATION(LDAP_TAG_DelResponse): {
struct ldap_Result *r = &msg->r.DelResponse;
msg->type = LDAP_TAG_DelResponse;
- asn1_start_tag(data, tag);
- ldap_decode_response(msg, data, r);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, tag)) goto prot_err;
+ if (!ldap_decode_response(msg, data, r)) goto prot_err;
+ if (!asn1_end_tag(data)) goto prot_err;
break;
}
case ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest): {
struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest;
msg->type = LDAP_TAG_ModifyDNRequest;
- asn1_start_tag(data,
- ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest));
- asn1_read_OctetString_talloc(msg, data, &r->dn);
- asn1_read_OctetString_talloc(msg, data, &r->newrdn);
- asn1_read_BOOLEAN(data, &r->deleteolddn);
+ if (!asn1_start_tag(data,
+ ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest))) goto prot_err;
+ if (!asn1_read_OctetString_talloc(msg, data, &r->dn)) goto prot_err;
+ if (!asn1_read_OctetString_talloc(msg, data, &r->newrdn)) goto prot_err;
+ if (!asn1_read_BOOLEAN(data, &r->deleteolddn)) goto prot_err;
r->newsuperior = NULL;
if (asn1_tag_remaining(data) > 0) {
int len;
char *newsup;
- asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0));
+ if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0))) goto prot_err;
len = asn1_tag_remaining(data);
if (len == -1) {
- return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
+ goto prot_err;
}
newsup = talloc_array(msg, char, len+1);
if (newsup == NULL) {
return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
}
- asn1_read(data, newsup, len);
+ if (!asn1_read(data, newsup, len)) goto prot_err;
newsup[len] = '\0';
r->newsuperior = newsup;
- asn1_end_tag(data);
+ if (!asn1_end_tag(data)) goto prot_err;
}
- asn1_end_tag(data);
+ if (!asn1_end_tag(data)) goto prot_err;
break;
}
case ASN1_APPLICATION(LDAP_TAG_ModifyDNResponse): {
struct ldap_Result *r = &msg->r.ModifyDNResponse;
msg->type = LDAP_TAG_ModifyDNResponse;
- asn1_start_tag(data, tag);
- ldap_decode_response(msg, data, r);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, tag)) goto prot_err;
+ if (!ldap_decode_response(msg, data, r)) goto prot_err;
+ if (!asn1_end_tag(data)) goto prot_err;
break;
}
case ASN1_APPLICATION(LDAP_TAG_CompareRequest): {
struct ldap_CompareRequest *r = &msg->r.CompareRequest;
msg->type = LDAP_TAG_CompareRequest;
- asn1_start_tag(data,
- ASN1_APPLICATION(LDAP_TAG_CompareRequest));
- asn1_read_OctetString_talloc(msg, data, &r->dn);
- asn1_start_tag(data, ASN1_SEQUENCE(0));
- asn1_read_OctetString_talloc(msg, data, &r->attribute);
- asn1_read_OctetString(data, msg, &r->value);
+ if (!asn1_start_tag(data,
+ ASN1_APPLICATION(LDAP_TAG_CompareRequest))) goto prot_err;
+ if (!asn1_read_OctetString_talloc(msg, data, &r->dn)) goto prot_err;
+ if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto prot_err;
+ if (!asn1_read_OctetString_talloc(msg, data, &r->attribute)) goto prot_err;
+ if (!asn1_read_OctetString(data, msg, &r->value)) goto prot_err;
if (r->value.data) {
talloc_steal(msg, r->value.data);
}
- asn1_end_tag(data);
- asn1_end_tag(data);
+ if (!asn1_end_tag(data)) goto prot_err;
+ if (!asn1_end_tag(data)) goto prot_err;
break;
}
case ASN1_APPLICATION(LDAP_TAG_CompareResponse): {
struct ldap_Result *r = &msg->r.CompareResponse;
msg->type = LDAP_TAG_CompareResponse;
- asn1_start_tag(data, tag);
- ldap_decode_response(msg, data, r);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, tag)) goto prot_err;
+ if (!ldap_decode_response(msg, data, r)) goto prot_err;
+ if (!asn1_end_tag(data)) goto prot_err;
break;
}
case ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest): {
struct ldap_AbandonRequest *r = &msg->r.AbandonRequest;
msg->type = LDAP_TAG_AbandonRequest;
- asn1_start_tag(data, tag);
- asn1_read_implicit_Integer(data, &r->messageid);
- asn1_end_tag(data);
+ if (!asn1_start_tag(data, tag)) goto prot_err;
+ if (!asn1_read_implicit_Integer(data, &r->messageid)) goto prot_err;
+ if (!asn1_end_tag(data)) goto prot_err;
break;
}
@@ -1482,9 +1484,9 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data,
DATA_BLOB tmp_blob = data_blob(NULL, 0);
msg->type = LDAP_TAG_ExtendedRequest;
- asn1_start_tag(data,tag);
+ if (!asn1_start_tag(data,tag)) goto prot_err;
if (!asn1_read_ContextSimple(data, 0, &tmp_blob)) {
- return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
+ goto prot_err;
}
r->oid = blob2string_talloc(msg, tmp_blob);
data_blob_free(&tmp_blob);
@@ -1493,7 +1495,7 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data,
}
if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) {
- asn1_read_ContextSimple(data, 1, &tmp_blob);
+ if (!asn1_read_ContextSimple(data, 1, &tmp_blob)) goto prot_err;
r->value = talloc(msg, DATA_BLOB);
if (!r->value) {
return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
@@ -1504,7 +1506,7 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data,
r->value = NULL;
}
- asn1_end_tag(data);
+ if (!asn1_end_tag(data)) goto prot_err;
break;
}
@@ -1513,11 +1515,11 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data,
DATA_BLOB tmp_blob = data_blob(NULL, 0);
msg->type = LDAP_TAG_ExtendedResponse;
- asn1_start_tag(data, tag);
- ldap_decode_response(msg, data, &r->response);
+ if (!asn1_start_tag(data, tag)) goto prot_err;
+ if (!ldap_decode_response(msg, data, &r->response)) goto prot_err;
if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(10))) {
- asn1_read_ContextSimple(data, 1, &tmp_blob);
+ if (!asn1_read_ContextSimple(data, 1, &tmp_blob)) goto prot_err;
r->oid = blob2string_talloc(msg, tmp_blob);
data_blob_free(&tmp_blob);
if (!r->oid) {
@@ -1528,7 +1530,7 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data,
}
if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(11))) {
- asn1_read_ContextSimple(data, 1, &tmp_blob);
+ if (!asn1_read_ContextSimple(data, 1, &tmp_blob)) goto prot_err;
r->value = talloc(msg, DATA_BLOB);
if (!r->value) {
return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
@@ -1539,11 +1541,11 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data,
r->value = NULL;
}
- asn1_end_tag(data);
+ if (!asn1_end_tag(data)) goto prot_err;
break;
}
- default:
- return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
+ default:
+ goto prot_err;
}
msg->controls = NULL;
@@ -1554,7 +1556,7 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data,
struct ldb_control **ctrl = NULL;
bool *decoded = NULL;
- asn1_start_tag(data, ASN1_CONTEXT(0));
+ if (!asn1_start_tag(data, ASN1_CONTEXT(0))) goto prot_err;
while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) {
DATA_BLOB value;
@@ -1576,9 +1578,9 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data,
}
if (!ldap_decode_control_wrapper(ctrl[i], data, ctrl[i], &value)) {
- return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
+ goto prot_err;
}
-
+
if (!ldap_decode_control_value(ctrl[i], value,
control_handlers,
ctrl[i])) {
@@ -1603,14 +1605,18 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data,
msg->controls = ctrl;
msg->controls_decoded = decoded;
- asn1_end_tag(data);
+ if (!asn1_end_tag(data)) goto prot_err;
}
- asn1_end_tag(data);
+ if (!asn1_end_tag(data)) goto prot_err;
if ((data->has_error) || (data->nesting != NULL)) {
return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
}
return NT_STATUS_OK;
+
+ prot_err:
+
+ return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
}
diff --git a/libcli/ldap/ldap_message.h b/libcli/ldap/ldap_message.h
index eb7e620..4385fe6 100644
--- a/libcli/ldap/ldap_message.h
+++ b/libcli/ldap/ldap_message.h
@@ -228,7 +228,7 @@ bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx,
struct asn1_data *data,
const char **result);
-void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data,
+bool ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data,
struct ldb_message_element **attributes,
int *num_attributes);
diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c
index 1e67a01..f910acb 100644
--- a/source4/libcli/ldap/ldap_controls.c
+++ b/source4/libcli/ldap/ldap_controls.c
@@ -1197,10 +1197,10 @@ static bool decode_openldap_dereference(void *mem_ctx, DATA_BLOB in, void *_out)
if (!asn1_start_tag(data, ASN1_CONTEXT(0))) {
return false;
}
-
- ldap_decode_attribs_bare(r, data, &r[i]->attributes,
- &r[i]->num_attributes);
-
+ if (!ldap_decode_attribs_bare(r, data, &r[i]->attributes,
+ &r[i]->num_attributes)) {
+ return false;
+ }
if (!asn1_end_tag(data)) {
return false;
}
--
2.1.0.rc2.206.gedb03e5
More information about the samba-technical
mailing list