r23030: finally fixed up our asn1 code to use better memory allocation. This
authorAndrew Tridgell <tridge@samba.org>
Mon, 21 May 2007 06:12:06 +0000 (06:12 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:52:42 +0000 (14:52 -0500)
should allow us to fix some long standing memory leaks.
(This used to be commit 3db49c2ec9968221c1361785b94061046ecd159d)

source4/auth/gensec/spnego.c
source4/auth/gensec/spnego_parse.c
source4/auth/kerberos/gssapi_parse.c
source4/ldap_server/ldap_server.c
source4/libcli/cldap/cldap.c
source4/libcli/cldap/cldap.h
source4/libcli/ldap/ldap.c
source4/libcli/ldap/ldap_client.c
source4/libcli/ldap/ldap_controls.c
source4/libcli/util/asn1.c
source4/librpc/ndr/ndr_drsuapi.c

index 79dc0ea6e743da0c458b3e53d460b1aa2db61b42..5c9a518cdd12688f08181036a5f79cceab75240a 100644 (file)
@@ -711,7 +711,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA
                NTSTATUS nt_status;
                if (in.length) {
 
-                       len = spnego_read_data(in, &spnego);
+                       len = spnego_read_data(gensec_security, in, &spnego);
                        if (len == -1) {
                                return gensec_spnego_server_try_fallback(gensec_security, spnego_state, 
                                                                         out_mem_ctx, in, out);
@@ -769,7 +769,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA
                        return nt_status;
                }
                
-               len = spnego_read_data(in, &spnego);
+               len = spnego_read_data(gensec_security, in, &spnego);
                
                if (len == -1) {
                        DEBUG(1, ("Invalid SPNEGO request:\n"));
@@ -834,7 +834,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA
                        return NT_STATUS_INVALID_PARAMETER;
                }
                
-               len = spnego_read_data(in, &spnego);
+               len = spnego_read_data(gensec_security, in, &spnego);
                
                if (len == -1) {
                        DEBUG(1, ("Invalid SPNEGO request:\n"));
@@ -880,7 +880,7 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA
                        return NT_STATUS_INVALID_PARAMETER;
                }
                
-               len = spnego_read_data(in, &spnego);
+               len = spnego_read_data(gensec_security, in, &spnego);
                
                if (len == -1) {
                        DEBUG(1, ("Invalid SPNEGO request:\n"));
index 66e24bdbe5adb5c821215cf8243c198962a546c7..c768d1e8470635660c3c188acee190f99bc575f2 100644 (file)
@@ -26,7 +26,8 @@
 #include "auth/gensec/gensec.h"
 #include "libcli/util/asn_1.h"
 
-static BOOL read_negTokenInit(struct asn1_data *asn1, struct spnego_negTokenInit *token)
+static BOOL read_negTokenInit(struct asn1_data *asn1, TALLOC_CTX *mem_ctx,
+                             struct spnego_negTokenInit *token)
 {
        ZERO_STRUCTP(token);
 
@@ -53,11 +54,7 @@ static BOOL read_negTokenInit(struct asn1_data *asn1, struct spnego_negTokenInit
                                token->mechTypes = talloc_realloc(NULL, 
                                                                  token->mechTypes, 
                                                                  const char *, i+2);
-                               asn1_read_OID(asn1, token->mechTypes + i);
-                               if (token->mechTypes[i]) {
-                                       talloc_steal(token->mechTypes, 
-                                                    token->mechTypes[i]);
-                               }
+                               asn1_read_OID(asn1, token->mechTypes, token->mechTypes + i);
                        }
                        token->mechTypes[i] = NULL;
                        
@@ -74,7 +71,7 @@ static BOOL read_negTokenInit(struct asn1_data *asn1, struct spnego_negTokenInit
                 /* Read mechToken */
                case ASN1_CONTEXT(2):
                        asn1_start_tag(asn1, ASN1_CONTEXT(2));
-                       asn1_read_OctetString(asn1, &token->mechToken);
+                       asn1_read_OctetString(asn1, mem_ctx, &token->mechToken);
                        asn1_end_tag(asn1);
                        break;
                /* Read mecListMIC */
@@ -87,7 +84,7 @@ static BOOL read_negTokenInit(struct asn1_data *asn1, struct spnego_negTokenInit
                                break;
                        }
                        if (type_peek == ASN1_OCTET_STRING) {
-                               asn1_read_OctetString(asn1,
+                               asn1_read_OctetString(asn1, mem_ctx, 
                                                      &token->mechListMIC);
                        } else {
                                /* RFC 2478 says we have an Octet String here,
@@ -95,7 +92,7 @@ static BOOL read_negTokenInit(struct asn1_data *asn1, struct spnego_negTokenInit
                                char *mechListMIC;
                                asn1_push_tag(asn1, ASN1_SEQUENCE(0));
                                asn1_push_tag(asn1, ASN1_CONTEXT(0));
-                               asn1_read_GeneralString(asn1, &mechListMIC);
+                               asn1_read_GeneralString(asn1, mem_ctx, &mechListMIC);
                                asn1_pop_tag(asn1);
                                asn1_pop_tag(asn1);
 
@@ -179,7 +176,8 @@ static BOOL write_negTokenInit(struct asn1_data *asn1, struct spnego_negTokenIni
        return !asn1->has_error;
 }
 
-static BOOL read_negTokenTarg(struct asn1_data *asn1, struct spnego_negTokenTarg *token)
+static BOOL read_negTokenTarg(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, 
+                             struct spnego_negTokenTarg *token)
 {
        ZERO_STRUCTP(token);
 
@@ -203,17 +201,17 @@ static BOOL read_negTokenTarg(struct asn1_data *asn1, struct spnego_negTokenTarg
                        break;
                case ASN1_CONTEXT(1):
                        asn1_start_tag(asn1, ASN1_CONTEXT(1));
-                       asn1_read_OID(asn1, &token->supportedMech);
+                       asn1_read_OID(asn1, mem_ctx, &token->supportedMech);
                        asn1_end_tag(asn1);
                        break;
                case ASN1_CONTEXT(2):
                        asn1_start_tag(asn1, ASN1_CONTEXT(2));
-                       asn1_read_OctetString(asn1, &token->responseToken);
+                       asn1_read_OctetString(asn1, mem_ctx, &token->responseToken);
                        asn1_end_tag(asn1);
                        break;
                case ASN1_CONTEXT(3):
                        asn1_start_tag(asn1, ASN1_CONTEXT(3));
-                       asn1_read_OctetString(asn1, &token->mechListMIC);
+                       asn1_read_OctetString(asn1, mem_ctx, &token->mechListMIC);
                        asn1_end_tag(asn1);
                        break;
                default:
@@ -265,77 +263,74 @@ static BOOL write_negTokenTarg(struct asn1_data *asn1, struct spnego_negTokenTar
        return !asn1->has_error;
 }
 
-ssize_t spnego_read_data(DATA_BLOB data, struct spnego_data *token)
+ssize_t spnego_read_data(TALLOC_CTX *mem_ctx, DATA_BLOB data, struct spnego_data *token)
 {
-       struct asn1_data asn1;
+       struct asn1_data *asn1 = asn1_init(mem_ctx);
        ssize_t ret = -1;
        uint8_t context;
 
        ZERO_STRUCTP(token);
-       ZERO_STRUCT(asn1);
 
        if (data.length == 0) {
                return ret;
        }
 
-       asn1_load(&asn1, data);
+       asn1_load(asn1, data);
 
-       if (!asn1_peek_uint8(&asn1, &context)) {
-               asn1.has_error = True;
+       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, GENSEC_OID_SPNEGO);
-                       if (read_negTokenInit(&asn1, &token->negTokenInit)) {
+                       asn1_start_tag(asn1, ASN1_APPLICATION(0));
+                       asn1_check_OID(asn1, GENSEC_OID_SPNEGO);
+                       if (read_negTokenInit(asn1, mem_ctx, &token->negTokenInit)) {
                                token->type = SPNEGO_NEG_TOKEN_INIT;
                        }
-                       asn1_end_tag(&asn1);
+                       asn1_end_tag(asn1);
                        break;
                case ASN1_CONTEXT(1):
-                       if (read_negTokenTarg(&asn1, &token->negTokenTarg)) {
+                       if (read_negTokenTarg(asn1, mem_ctx, &token->negTokenTarg)) {
                                token->type = SPNEGO_NEG_TOKEN_TARG;
                        }
                        break;
                default:
-                       asn1.has_error = True;
+                       asn1->has_error = True;
                        break;
                }
        }
 
-       if (!asn1.has_error) ret = asn1.ofs;
-       asn1_free(&asn1);
+       if (!asn1->has_error) ret = asn1->ofs;
+       asn1_free(asn1);
 
        return ret;
 }
 
 ssize_t spnego_write_data(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct spnego_data *spnego)
 {
-       struct asn1_data asn1;
+       struct asn1_data *asn1 = asn1_init(mem_ctx);
        ssize_t ret = -1;
 
-       ZERO_STRUCT(asn1);
-
        switch (spnego->type) {
        case SPNEGO_NEG_TOKEN_INIT:
-               asn1_push_tag(&asn1, ASN1_APPLICATION(0));
-               asn1_write_OID(&asn1, GENSEC_OID_SPNEGO);
-               write_negTokenInit(&asn1, &spnego->negTokenInit);
-               asn1_pop_tag(&asn1);
+               asn1_push_tag(asn1, ASN1_APPLICATION(0));
+               asn1_write_OID(asn1, GENSEC_OID_SPNEGO);
+               write_negTokenInit(asn1, &spnego->negTokenInit);
+               asn1_pop_tag(asn1);
                break;
        case SPNEGO_NEG_TOKEN_TARG:
-               write_negTokenTarg(&asn1, &spnego->negTokenTarg);
+               write_negTokenTarg(asn1, &spnego->negTokenTarg);
                break;
        default:
-               asn1.has_error = True;
+               asn1->has_error = True;
                break;
        }
 
-       if (!asn1.has_error) {
-               *blob = data_blob_talloc(mem_ctx, asn1.data, asn1.length);
-               ret = asn1.ofs;
+       if (!asn1->has_error) {
+               *blob = data_blob_talloc(mem_ctx, asn1->data, asn1->length);
+               ret = asn1->ofs;
        }
-       asn1_free(&asn1);
+       asn1_free(asn1);
 
        return ret;
 }
index cc9565a040b357c69d385aa88075b788289f5074..86a9e9554aabc3b4d4bbfe57e86c499c3d43a600 100644 (file)
 */
 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;
+       struct asn1_data *data = asn1_init(mem_ctx);
        DATA_BLOB ret;
 
-       if (!ticket->data) {
+       if (!data || !ticket->data) {
                return data_blob(NULL,0);
        }
 
-       ZERO_STRUCT(data);
+       asn1_push_tag(data, ASN1_APPLICATION(0));
+       asn1_write_OID(data, GENSEC_OID_KERBEROS5);
 
-       asn1_push_tag(&data, ASN1_APPLICATION(0));
-       asn1_write_OID(&data, GENSEC_OID_KERBEROS5);
+       asn1_write(data, tok_id, 2);
+       asn1_write(data, ticket->data, ticket->length);
+       asn1_pop_tag(data);
 
-       asn1_write(&data, tok_id, 2);
-       asn1_write(&data, ticket->data, ticket->length);
-       asn1_pop_tag(&data);
-
-       if (data.has_error) {
-               DEBUG(1,("Failed to build krb5 wrapper at offset %d\n", (int)data.ofs));
-               asn1_free(&data);
+       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);
+       ret = data_blob_talloc(mem_ctx, data->data, data->length);
+       asn1_free(data);
 
        return ret;
 }
@@ -65,29 +63,29 @@ DATA_BLOB gensec_gssapi_gen_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *tick
 BOOL gensec_gssapi_parse_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, DATA_BLOB *ticket, uint8_t tok_id[2])
 {
        BOOL ret;
-       struct asn1_data data;
+       struct asn1_data *data = asn1_init(mem_ctx);
        int data_remaining;
 
-       asn1_load(&data, *blob);
-       asn1_start_tag(&data, ASN1_APPLICATION(0));
-       asn1_check_OID(&data, GENSEC_OID_KERBEROS5);
+       asn1_load(data, *blob);
+       asn1_start_tag(data, ASN1_APPLICATION(0));
+       asn1_check_OID(data, GENSEC_OID_KERBEROS5);
 
-       data_remaining = asn1_tag_remaining(&data);
+       data_remaining = asn1_tag_remaining(data);
 
        if (data_remaining < 3) {
-               data.has_error = True;
+               data->has_error = True;
        } else {
-               asn1_read(&data, tok_id, 2);
+               asn1_read(data, tok_id, 2);
                data_remaining -= 2;
                *ticket = data_blob_talloc(mem_ctx, NULL, data_remaining);
-               asn1_read(&data, ticket->data, ticket->length);
+               asn1_read(data, ticket->data, ticket->length);
        }
 
-       asn1_end_tag(&data);
+       asn1_end_tag(data);
 
-       ret = !data.has_error;
+       ret = !data->has_error;
 
-       asn1_free(&data);
+       asn1_free(data);
 
        return ret;
 }
@@ -99,15 +97,15 @@ BOOL gensec_gssapi_parse_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, D
 BOOL gensec_gssapi_check_oid(const DATA_BLOB *blob, const char *oid)
 {
        BOOL ret;
-       struct asn1_data data;
+       struct asn1_data *data = asn1_init(NULL);
 
-       asn1_load(&data, *blob);
-       asn1_start_tag(&data, ASN1_APPLICATION(0));
-       asn1_check_OID(&data, oid);
+       asn1_load(data, *blob);
+       asn1_start_tag(data, ASN1_APPLICATION(0));
+       asn1_check_OID(data, oid);
 
-       ret = !data.has_error;
+       ret = !data->has_error;
 
-       asn1_free(&data);
+       asn1_free(data);
 
        return ret;
 }
index 738215cda524b95927366bcee24289ea981bd265..9aefbed48564d7b971c3bafcf2f9de39d4da3720 100644 (file)
@@ -134,26 +134,26 @@ static NTSTATUS ldapsrv_decode(void *private, DATA_BLOB blob)
        NTSTATUS status;
        struct ldapsrv_connection *conn = talloc_get_type(private, 
                                                          struct ldapsrv_connection);
-       struct asn1_data asn1;
+       struct asn1_data *asn1 = asn1_init(conn);
        struct ldap_message *msg = talloc(conn, struct ldap_message);
 
        if (msg == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       if (!asn1_load(&asn1, blob)) {
+       if (!asn1_load(asn1, blob)) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       status = ldap_decode(&asn1, msg);
+       status = ldap_decode(asn1, msg);
        if (!NT_STATUS_IS_OK(status)) {
-               asn1_free(&asn1);
+               asn1_free(asn1);
                return status;
        }
 
        data_blob_free(&blob);
        ldapsrv_process_message(conn, msg);
-       asn1_free(&asn1);
+       asn1_free(asn1);
        return NT_STATUS_OK;
 }
 
index c68a037552f16dd283b268fa04d862753752e457..e92abe4d47af359738515adc06f2244f6191be69 100644 (file)
@@ -66,7 +66,7 @@ static void cldap_socket_recv(struct cldap_socket *cldap)
        struct socket_address *src;
        DATA_BLOB blob;
        size_t nread, dsize;
-       struct asn1_data asn1;
+       struct asn1_data *asn1 = asn1_init(tmp_ctx);
        struct ldap_message *ldap_msg;
        struct cldap_request *req;
 
@@ -93,12 +93,12 @@ static void cldap_socket_recv(struct cldap_socket *cldap)
        DEBUG(2,("Received cldap packet of length %d from %s:%d\n", 
                 (int)blob.length, src->addr, src->port));
 
-       if (!asn1_load(&asn1, blob)) {
+       if (!asn1_load(asn1, blob)) {
                DEBUG(2,("Failed to setup for asn.1 decode\n"));
                talloc_free(tmp_ctx);
                return;
        }
-       talloc_steal(tmp_ctx, asn1.data);
+       talloc_steal(tmp_ctx, asn1->data);
 
        ldap_msg = talloc(tmp_ctx, struct ldap_message);
        if (ldap_msg == NULL) {
@@ -107,7 +107,7 @@ static void cldap_socket_recv(struct cldap_socket *cldap)
        }
 
        /* this initial decode is used to find the message id */
-       status = ldap_decode(&asn1, ldap_msg);
+       status = ldap_decode(asn1, ldap_msg);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(2,("Failed to decode ldap message: %s\n", nt_errstr(status)));
                talloc_free(tmp_ctx);
@@ -128,8 +128,8 @@ static void cldap_socket_recv(struct cldap_socket *cldap)
        }
 
        req->asn1 = asn1;
-       talloc_steal(req, asn1.data);
-       req->asn1.ofs = 0;
+       talloc_steal(req, asn1->data);
+       req->asn1->ofs = 0;
 
        req->state = CLDAP_REQUEST_DONE;
        talloc_free(req->te);
@@ -456,7 +456,7 @@ NTSTATUS cldap_search_recv(struct cldap_request *req,
        ldap_msg = talloc(mem_ctx, struct ldap_message);
        NT_STATUS_HAVE_NO_MEMORY(ldap_msg);
 
-       status = ldap_decode(&req->asn1, ldap_msg);
+       status = ldap_decode(req->asn1, ldap_msg);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(2,("Failed to decode cldap search reply: %s\n", nt_errstr(status)));
                talloc_free(req);
@@ -472,7 +472,7 @@ NTSTATUS cldap_search_recv(struct cldap_request *req,
                *io->out.response = ldap_msg->r.SearchResultEntry;
 
                /* decode the 2nd part */
-               status = ldap_decode(&req->asn1, ldap_msg);
+               status = ldap_decode(req->asn1, ldap_msg);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(2,("Failed to decode cldap search result entry: %s\n", nt_errstr(status)));
                        talloc_free(req);
index 928cf1f3e4efd39b78e69bcdb1f328777c6c67dd..4b4be0d316dd50a4dc94888cac115bbbb2006e0e 100644 (file)
@@ -59,7 +59,7 @@ struct cldap_request {
        DATA_BLOB encoded;
 
        /* the reply data */
-       struct asn1_data asn1;
+       struct asn1_data *asn1;
 
        /* information on what to do on completion */
        struct {
index 1e308d584783cfdafe7df66a12d119d2dba3d7e7..70ba9335dbfb3a78aae72268aa3519d66f0106d3 100644 (file)
@@ -190,55 +190,54 @@ static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *res
 
 BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx)
 {
-       struct asn1_data data;
+       struct asn1_data *data = asn1_init(mem_ctx);
        int i, j;
 
-       ZERO_STRUCT(data);
-       asn1_push_tag(&data, ASN1_SEQUENCE(0));
-       asn1_write_Integer(&data, msg->messageid);
+       asn1_push_tag(data, ASN1_SEQUENCE(0));
+       asn1_write_Integer(data, msg->messageid);
 
        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,
+               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);
 
                switch (r->mechanism) {
                case LDAP_AUTH_MECH_SIMPLE:
                        /* context, primitive */
-                       asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(0));
-                       asn1_write(&data, r->creds.password,
+                       asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0));
+                       asn1_write(data, r->creds.password,
                                   strlen(r->creds.password));
-                       asn1_pop_tag(&data);
+                       asn1_pop_tag(data);
                        break;
                case LDAP_AUTH_MECH_SASL:
                        /* context, constructed */
-                       asn1_push_tag(&data, ASN1_CONTEXT(3));
-                       asn1_write_OctetString(&data, r->creds.SASL.mechanism,
+                       asn1_push_tag(data, ASN1_CONTEXT(3));
+                       asn1_write_OctetString(data, r->creds.SASL.mechanism,
                                               strlen(r->creds.SASL.mechanism));
                        if (r->creds.SASL.secblob) {
-                               asn1_write_OctetString(&data, r->creds.SASL.secblob->data,
+                               asn1_write_OctetString(data, r->creds.SASL.secblob->data,
                                                       r->creds.SASL.secblob->length);
                        }
-                       asn1_pop_tag(&data);
+                       asn1_pop_tag(data);
                        break;
                default:
                        return False;
                }
 
-               asn1_pop_tag(&data);
+               asn1_pop_tag(data);
                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);
+               asn1_push_tag(data, ASN1_APPLICATION(msg->type));
+               ldap_encode_response(data, &r->response);
                if (r->SASL.secblob) {
-                       asn1_write_ContextSimple(&data, 7, r->SASL.secblob);
+                       asn1_write_ContextSimple(data, 7, r->SASL.secblob);
                }
-               asn1_pop_tag(&data);
+               asn1_pop_tag(data);
                break;
        }
        case LDAP_TAG_UnbindRequest: {
@@ -247,223 +246,223 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct
        }
        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 (!ldap_push_filter(&data, r->tree)) {
+               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 (!ldap_push_filter(data, r->tree)) {
                        return False;
                }
 
-               asn1_push_tag(&data, ASN1_SEQUENCE(0));
+               asn1_push_tag(data, ASN1_SEQUENCE(0));
                for (i=0; i<r->num_attributes; i++) {
-                       asn1_write_OctetString(&data, r->attributes[i],
+                       asn1_write_OctetString(data, r->attributes[i],
                                               strlen(r->attributes[i]));
                }
-               asn1_pop_tag(&data);
-               asn1_pop_tag(&data);
+               asn1_pop_tag(data);
+               asn1_pop_tag(data);
                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));
+               asn1_push_tag(data, ASN1_APPLICATION(msg->type));
+               asn1_write_OctetString(data, r->dn, strlen(r->dn));
+               asn1_push_tag(data, ASN1_SEQUENCE(0));
                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,
+                       asn1_push_tag(data, ASN1_SEQUENCE(0));
+                       asn1_write_OctetString(data, attr->name,
                                               strlen(attr->name));
-                       asn1_push_tag(&data, ASN1_SEQUENCE(1));
+                       asn1_push_tag(data, ASN1_SEQUENCE(1));
                        for (j=0; j<attr->num_values; j++) {
-                               asn1_write_OctetString(&data,
+                               asn1_write_OctetString(data,
                                                       attr->values[j].data,
                                                       attr->values[j].length);
                        }
-                       asn1_pop_tag(&data);
-                       asn1_pop_tag(&data);
+                       asn1_pop_tag(data);
+                       asn1_pop_tag(data);
                }
-               asn1_pop_tag(&data);
-               asn1_pop_tag(&data);
+               asn1_pop_tag(data);
+               asn1_pop_tag(data);
                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);
+               asn1_push_tag(data, ASN1_APPLICATION(msg->type));
+               ldap_encode_response(data, r);
+               asn1_pop_tag(data);
                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));
+               asn1_push_tag(data, ASN1_APPLICATION(msg->type));
+               asn1_write_OctetString(data, r->dn, strlen(r->dn));
+               asn1_push_tag(data, ASN1_SEQUENCE(0));
 
                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,
+                       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);
+                       asn1_push_tag(data, ASN1_SET);
                        for (j=0; j<attrib->num_values; j++) {
-                               asn1_write_OctetString(&data,
+                               asn1_write_OctetString(data,
                                                       attrib->values[j].data,
                                                       attrib->values[j].length);
        
                        }
-                       asn1_pop_tag(&data);
-                       asn1_pop_tag(&data);
-                       asn1_pop_tag(&data);
+                       asn1_pop_tag(data);
+                       asn1_pop_tag(data);
+                       asn1_pop_tag(data);
                }
                
-               asn1_pop_tag(&data);
-               asn1_pop_tag(&data);
+               asn1_pop_tag(data);
+               asn1_pop_tag(data);
                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);
+               asn1_push_tag(data, ASN1_APPLICATION(msg->type));
+               ldap_encode_response(data, r);
+               asn1_pop_tag(data);
                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));
+               asn1_push_tag(data, ASN1_APPLICATION(msg->type));
+               asn1_write_OctetString(data, r->dn, strlen(r->dn));
+               asn1_push_tag(data, ASN1_SEQUENCE(0));
 
                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,
+                       asn1_push_tag(data, ASN1_SEQUENCE(0));
+                       asn1_write_OctetString(data, attrib->name,
                                               strlen(attrib->name));
-                       asn1_push_tag(&data, ASN1_SET);
+                       asn1_push_tag(data, ASN1_SET);
                        for (j=0; j<r->attributes[i].num_values; j++) {
-                               asn1_write_OctetString(&data,
+                               asn1_write_OctetString(data,
                                                       attrib->values[j].data,
                                                       attrib->values[j].length);
                        }
-                       asn1_pop_tag(&data);
-                       asn1_pop_tag(&data);
+                       asn1_pop_tag(data);
+                       asn1_pop_tag(data);
                }
-               asn1_pop_tag(&data);
-               asn1_pop_tag(&data);
+               asn1_pop_tag(data);
+               asn1_pop_tag(data);
                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);
+               asn1_push_tag(data, ASN1_APPLICATION(msg->type));
+               ldap_encode_response(data, r);
+               asn1_pop_tag(data);
                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);
+               asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type));
+               asn1_write(data, r->dn, strlen(r->dn));
+               asn1_pop_tag(data);
                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);
+               asn1_push_tag(data, ASN1_APPLICATION(msg->type));
+               ldap_encode_response(data, r);
+               asn1_pop_tag(data);
                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);
+               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 (r->newsuperior) {
-                       asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(0));
-                       asn1_write(&data, r->newsuperior,
+                       asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0));
+                       asn1_write(data, r->newsuperior,
                                   strlen(r->newsuperior));
-                       asn1_pop_tag(&data);
+                       asn1_pop_tag(data);
                }
-               asn1_pop_tag(&data);
+               asn1_pop_tag(data);
                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);
+               asn1_push_tag(data, ASN1_APPLICATION(msg->type));
+               ldap_encode_response(data, r);
+               asn1_pop_tag(data);
                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,
+               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,
+               asn1_write_OctetString(data, r->value.data,
                                       r->value.length);
-               asn1_pop_tag(&data);
-               asn1_pop_tag(&data);
+               asn1_pop_tag(data);
+               asn1_pop_tag(data);
                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);
+               asn1_push_tag(data, ASN1_APPLICATION(msg->type));
+               ldap_encode_response(data, r);
+               asn1_pop_tag(data);
                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);
+               asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type));
+               asn1_write_implicit_Integer(data, r->messageid);
+               asn1_pop_tag(data);
                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);
+               asn1_push_tag(data, ASN1_APPLICATION(msg->type));
+               asn1_write_OctetString(data, r->referral, strlen(r->referral));
+               asn1_pop_tag(data);
                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);
+               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 (r->value) {
-                       asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(1));
-                       asn1_write(&data, r->value->data, r->value->length);
-                       asn1_pop_tag(&data);
+                       asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1));
+                       asn1_write(data, r->value->data, r->value->length);
+                       asn1_pop_tag(data);
                }
-               asn1_pop_tag(&data);
+               asn1_pop_tag(data);
                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);
+               asn1_push_tag(data, ASN1_APPLICATION(msg->type));
+               ldap_encode_response(data, &r->response);
                if (r->oid) {
-                       asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(10));
-                       asn1_write(&data, r->oid, strlen(r->oid));
-                       asn1_pop_tag(&data);
+                       asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(10));
+                       asn1_write(data, r->oid, strlen(r->oid));
+                       asn1_pop_tag(data);
                }
                if (r->value) {
-                       asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(11));
-                       asn1_write(&data, r->value->data, r->value->length);
-                       asn1_pop_tag(&data);
+                       asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(11));
+                       asn1_write(data, r->value->data, r->value->length);
+                       asn1_pop_tag(data);
                }
-               asn1_pop_tag(&data);
+               asn1_pop_tag(data);
                break;
        }
        default:
@@ -471,26 +470,26 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct
        }
 
        if (msg->controls != NULL) {
-               asn1_push_tag(&data, ASN1_CONTEXT(0));
+               asn1_push_tag(data, ASN1_CONTEXT(0));
                
                for (i = 0; msg->controls[i] != NULL; i++) {
-                       if (!ldap_encode_control(mem_ctx, &data, msg->controls[i])) {
+                       if (!ldap_encode_control(mem_ctx, data, msg->controls[i])) {
                                return False;
                        }
                }
 
-               asn1_pop_tag(&data);
+               asn1_pop_tag(data);
        }
 
-       asn1_pop_tag(&data);
+       asn1_pop_tag(data);
 
-       if (data.has_error) {
-               asn1_free(&data);
+       if (data->has_error) {
+               asn1_free(data);
                return False;
        }
 
-       *result = data_blob_talloc(mem_ctx, data.data, data.length);
-       asn1_free(&data);
+       *result = data_blob_talloc(mem_ctx, data->data, data->length);
+       asn1_free(data);
        return True;
 }
 
@@ -508,7 +507,7 @@ static BOOL asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx,
                                         const char **result)
 {
        DATA_BLOB string;
-       if (!asn1_read_OctetString(data, &string))
+       if (!asn1_read_OctetString(data, mem_ctx, &string))
                return False;
        *result = blob2string_talloc(mem_ctx, string);
        data_blob_free(&string);
@@ -631,7 +630,7 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx,
 
                asn1_start_tag(data, ASN1_CONTEXT(filter_tag));
                asn1_read_OctetString_talloc(mem_ctx, data, &attrib);
-               asn1_read_OctetString(data, &value);
+               asn1_read_OctetString(data, mem_ctx, &value);
                asn1_end_tag(data);
                if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) {
                        goto failed;
@@ -653,7 +652,7 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx,
                if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) {
                        goto failed;
                }
-               if (!asn1_read_OctetString(data, &attr)) {
+               if (!asn1_read_OctetString(data, mem_ctx, &attr)) {
                        goto failed;
                }
 
@@ -673,7 +672,7 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx,
                        if (subs_tag > 2) goto failed;
 
                        asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(subs_tag));
-                       asn1_read_LDAPString(data, &value);
+                       asn1_read_LDAPString(data, mem_ctx, &value);
                        asn1_end_tag(data);
 
                        switch (subs_tag) {
@@ -743,7 +742,7 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx,
 
                asn1_start_tag(data, ASN1_CONTEXT(filter_tag));
                asn1_read_OctetString_talloc(mem_ctx, data, &attrib);
-               asn1_read_OctetString(data, &value);
+               asn1_read_OctetString(data, mem_ctx, &value);
                asn1_end_tag(data);
                if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) {
                        goto failed;
@@ -762,7 +761,7 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx,
 
                asn1_start_tag(data, ASN1_CONTEXT(filter_tag));
                asn1_read_OctetString_talloc(mem_ctx, data, &attrib);
-               asn1_read_OctetString(data, &value);
+               asn1_read_OctetString(data, mem_ctx, &value);
                asn1_end_tag(data);
                if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) {
                        goto failed;
@@ -781,7 +780,7 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx,
                if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(filter_tag))) {
                        goto failed;
                }
-               if (!asn1_read_LDAPString(data, &attr)) {
+               if (!asn1_read_LDAPString(data, ret, &attr)) {
                        goto failed;
                }
 
@@ -800,7 +799,7 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx,
 
                asn1_start_tag(data, ASN1_CONTEXT(filter_tag));
                asn1_read_OctetString_talloc(mem_ctx, data, &attrib);
-               asn1_read_OctetString(data, &value);
+               asn1_read_OctetString(data, mem_ctx, &value);
                asn1_end_tag(data);
                if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) {
                        goto failed;
@@ -825,16 +824,16 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx,
                /* 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, &oid);
+                       asn1_read_LDAPString(data, ret, &oid);
                        asn1_end_tag(data);
                }
                if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(2))) {      /* optional  */
                        asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2));
-                       asn1_read_LDAPString(data, &attr);
+                       asn1_read_LDAPString(data, ret, &attr);
                        asn1_end_tag(data);
                }
                asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(3));
-               asn1_read_LDAPString(data, &value);
+               asn1_read_LDAPString(data, ret, &value);
                asn1_end_tag(data);
                /* dnAttributes is marked as BOOLEAN DEFAULT FALSE
                   it is not marked as OPTIONAL but openldap tools
@@ -902,7 +901,7 @@ static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data,
        asn1_start_tag(data, ASN1_SET);
        while (asn1_peek_tag(data, ASN1_OCTET_STRING)) {
                DATA_BLOB blob;
-               asn1_read_OctetString(data, &blob);
+               asn1_read_OctetString(data, mem_ctx, &blob);
                add_value_to_attrib(mem_ctx, &blob, attrib);
        }
        asn1_end_tag(data);
@@ -970,7 +969,7 @@ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg)
                        asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism);
                        if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { /* optional */
                                DATA_BLOB tmp_blob = data_blob(NULL, 0);
-                               asn1_read_OctetString(data, &tmp_blob);
+                               asn1_read_OctetString(data, msg, &tmp_blob);
                                r->creds.SASL.secblob = talloc(msg, DATA_BLOB);
                                if (!r->creds.SASL.secblob) {
                                        return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
@@ -1228,7 +1227,7 @@ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg)
                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, &r->value);
+               asn1_read_OctetString(data, msg, &r->value);
                if (r->value.data) {
                        talloc_steal(msg, r->value.data);
                }
index c819122dd2344c87d85f150e5568ffbd6ad675bb..5e4eddee927ccf247318c76f62b0ba4a45d44eed 100644 (file)
@@ -169,31 +169,30 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message
 */
 static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob)
 {
-       int ret;
        NTSTATUS status;
-       struct asn1_data asn1;
        struct ldap_connection *conn = talloc_get_type(private_data, 
                                                       struct ldap_connection);
        struct ldap_message *msg = talloc(conn, struct ldap_message);
+       struct asn1_data *asn1 = asn1_init(conn);
 
        if (msg == NULL) {
                return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
        }
 
-       if (!asn1_load(&asn1, blob)) {
+       if (!asn1_load(asn1, blob)) {
                return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
        }
        
-       status = ldap_decode(&asn1, msg);
+       status = ldap_decode(asn1, msg);
        if (!NT_STATUS_IS_OK(status)) {
-               asn1_free(&asn1);
+               asn1_free(asn1);
                return status;
        }
 
        ldap_match_message(conn, msg);
 
        data_blob_free(&blob);
-       asn1_free(&asn1);
+       asn1_free(asn1);
        return NT_STATUS_OK;
 }
 
index bbb0cb1aa575411b123d082668f02f89a97406b1..180e6eeb62b6c25b980edd3cbaba535f10d5e39f 100644 (file)
@@ -34,10 +34,10 @@ struct control_handler {
 static BOOL decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void **out)
 {
        DATA_BLOB attr;
-       struct asn1_data data;
+       struct asn1_data *data = asn1_init(mem_ctx);
        struct ldb_sort_resp_control *lsrc;
 
-       if (!asn1_load(&data, in)) {
+       if (!asn1_load(data, in)) {
                return False;
        }
 
@@ -46,17 +46,17 @@ static BOOL decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void **out)
                return False;
        }
 
-       if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) {
+       if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
                return False;
        }
 
-       if (!asn1_read_enumerated(&data, &(lsrc->result))) {
+       if (!asn1_read_enumerated(data, &(lsrc->result))) {
                return False;
        }
 
        lsrc->attr_desc = NULL;
-       if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) {
-               if (!asn1_read_OctetString(&data, &attr)) {
+       if (asn1_peek_tag(data, ASN1_OCTET_STRING)) {
+               if (!asn1_read_OctetString(data, mem_ctx, &attr)) {
                        return False;
                }
                lsrc->attr_desc = talloc_strndup(lsrc, (const char *)attr.data, attr.length);
@@ -65,7 +65,7 @@ static BOOL decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void **out)
                }
        }
 
-       if (!asn1_end_tag(&data)) {
+       if (!asn1_end_tag(data)) {
                return False;
        }
 
@@ -78,21 +78,21 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out)
 {
        DATA_BLOB attr;
        DATA_BLOB rule;
-       struct asn1_data data;
+       struct asn1_data *data = asn1_init(mem_ctx);
        struct ldb_server_sort_control **lssc;
        int num;
 
-       if (!asn1_load(&data, in)) {
+       if (!asn1_load(data, in)) {
                return False;
        }
 
-       if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) {
+       if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
                return False;
        }
 
        lssc = NULL;
 
-       for (num = 0; asn1_peek_tag(&data, ASN1_SEQUENCE(0)); num++) {
+       for (num = 0; asn1_peek_tag(data, ASN1_SEQUENCE(0)); num++) {
                lssc = talloc_realloc(mem_ctx, lssc, struct ldb_server_sort_control *, num + 2);
                if (!lssc) {
                        return False;
@@ -102,11 +102,11 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out)
                        return False;
                }
 
-               if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) {
+               if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
                        return False;
                }
 
-               if (!asn1_read_OctetString(&data, &attr)) {
+               if (!asn1_read_OctetString(data, mem_ctx, &attr)) {
                        return False;
                }
 
@@ -115,8 +115,8 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out)
                        return False;
                }
        
-               if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) {
-                       if (!asn1_read_OctetString(&data, &rule)) {
+               if (asn1_peek_tag(data, ASN1_OCTET_STRING)) {
+                       if (!asn1_read_OctetString(data, mem_ctx, &rule)) {
                                return False;
                        }
                        lssc[num]->orderingRule = talloc_strndup(lssc[num], (const char *)rule.data, rule.length);
@@ -125,15 +125,15 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out)
                        }
                }
 
-               if (asn1_peek_tag(&data, ASN1_BOOLEAN)) {
+               if (asn1_peek_tag(data, ASN1_BOOLEAN)) {
                        BOOL reverse;
-                       if (!asn1_read_BOOLEAN(&data, &reverse)) {
+                       if (!asn1_read_BOOLEAN(data, &reverse)) {
                        return False;
                        }
                        lssc[num]->reverse = reverse;
                }
        
-               if (!asn1_end_tag(&data)) {
+               if (!asn1_end_tag(data)) {
                        return False;
                }
        }
@@ -142,7 +142,7 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out)
                lssc[num] = NULL;
        }
 
-       if (!asn1_end_tag(&data)) {
+       if (!asn1_end_tag(data)) {
                return False;
        }
 
@@ -153,10 +153,10 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out)
 
 static BOOL decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out)
 {
-       struct asn1_data data;
+       struct asn1_data *data = asn1_init(mem_ctx);
        struct ldb_extended_dn_control *ledc;
 
-       if (!asn1_load(&data, in)) {
+       if (!asn1_load(data, in)) {
                return False;
        }
 
@@ -165,15 +165,15 @@ static BOOL decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out)
                return False;
        }
 
-       if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) {
+       if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
                return False;
        }
 
-       if (!asn1_read_Integer(&data, &(ledc->type))) {
+       if (!asn1_read_Integer(data, &(ledc->type))) {
                return False;
        }
        
-       if (!asn1_end_tag(&data)) {
+       if (!asn1_end_tag(data)) {
                return False;
        }
 
@@ -184,10 +184,10 @@ static BOOL decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out)
 
 static BOOL decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out)
 {
-       struct asn1_data data;
+       struct asn1_data *data = asn1_init(mem_ctx);
        struct ldb_sd_flags_control *lsdfc;
 
-       if (!asn1_load(&data, in)) {
+       if (!asn1_load(data, in)) {
                return False;
        }
 
@@ -196,15 +196,15 @@ static BOOL decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out)
                return False;
        }
 
-       if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) {
+       if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
                return False;
        }
 
-       if (!asn1_read_Integer(&data, &(lsdfc->secinfo_flags))) {
+       if (!asn1_read_Integer(data, &(lsdfc->secinfo_flags))) {
                return False;
        }
 
-       if (!asn1_end_tag(&data)) {
+       if (!asn1_end_tag(data)) {
                return False;
        }
 
@@ -215,10 +215,10 @@ static BOOL decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out)
 
 static BOOL decode_search_options_request(void *mem_ctx, DATA_BLOB in, void **out)
 {
-       struct asn1_data data;
+       struct asn1_data *data = asn1_init(mem_ctx);
        struct ldb_search_options_control *lsoc;
 
-       if (!asn1_load(&data, in)) {
+       if (!asn1_load(data, in)) {
                return False;
        }
 
@@ -227,15 +227,15 @@ static BOOL decode_search_options_request(void *mem_ctx, DATA_BLOB in, void **ou
                return False;
        }
 
-       if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) {
+       if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
                return False;
        }
 
-       if (!asn1_read_Integer(&data, &(lsoc->search_options))) {
+       if (!asn1_read_Integer(data, &(lsoc->search_options))) {
                return False;
        }
 
-       if (!asn1_end_tag(&data)) {
+       if (!asn1_end_tag(data)) {
                return False;
        }
 
@@ -247,10 +247,10 @@ static BOOL decode_search_options_request(void *mem_ctx, DATA_BLOB in, void **ou
 static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out)
 {
        DATA_BLOB cookie;
-       struct asn1_data data;
+       struct asn1_data *data = asn1_init(mem_ctx);
        struct ldb_paged_control *lprc;
 
-       if (!asn1_load(&data, in)) {
+       if (!asn1_load(data, in)) {
                return False;
        }
 
@@ -259,15 +259,15 @@ static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out
                return False;
        }
 
-       if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) {
+       if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
                return False;
        }
 
-       if (!asn1_read_Integer(&data, &(lprc->size))) {
+       if (!asn1_read_Integer(data, &(lprc->size))) {
                return False;
        }
        
-       if (!asn1_read_OctetString(&data, &cookie)) {
+       if (!asn1_read_OctetString(data, mem_ctx, &cookie)) {
                return False;
        }
        lprc->cookie_len = cookie.length;
@@ -281,7 +281,7 @@ static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out
                lprc->cookie = NULL;
        }
 
-       if (!asn1_end_tag(&data)) {
+       if (!asn1_end_tag(data)) {
                return False;
        }
 
@@ -293,10 +293,10 @@ static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out
 static BOOL decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out)
 {
        DATA_BLOB cookie;
-       struct asn1_data data;
+       struct asn1_data *data = asn1_init(mem_ctx);
        struct ldb_dirsync_control *ldc;
 
-       if (!asn1_load(&data, in)) {
+       if (!asn1_load(data, in)) {
                return False;
        }
 
@@ -305,19 +305,19 @@ static BOOL decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out)
                return False;
        }
 
-       if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) {
+       if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
                return False;
        }
 
-       if (!asn1_read_Integer(&data, &(ldc->flags))) {
+       if (!asn1_read_Integer(data, &(ldc->flags))) {
                return False;
        }
        
-       if (!asn1_read_Integer(&data, &(ldc->max_attributes))) {
+       if (!asn1_read_Integer(data, &(ldc->max_attributes))) {
                return False;
        }
        
-       if (!asn1_read_OctetString(&data, &cookie)) {
+       if (!asn1_read_OctetString(data, mem_ctx, &cookie)) {
                return False;
        }
        ldc->cookie_len = cookie.length;
@@ -331,7 +331,7 @@ static BOOL decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out)
                ldc->cookie = NULL;
        }
 
-       if (!asn1_end_tag(&data)) {
+       if (!asn1_end_tag(data)) {
                return False;
        }
 
@@ -346,10 +346,10 @@ static BOOL decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out)
 static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out)
 {
        DATA_BLOB source_attribute;
-       struct asn1_data data;
+       struct asn1_data *data = asn1_init(mem_ctx);
        struct ldb_asq_control *lac;
 
-       if (!asn1_load(&data, in)) {
+       if (!asn1_load(data, in)) {
                return False;
        }
 
@@ -358,13 +358,13 @@ static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out)
                return False;
        }
 
-       if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) {
+       if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
                return False;
        }
 
-       if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) {
+       if (asn1_peek_tag(data, ASN1_OCTET_STRING)) {
 
-               if (!asn1_read_OctetString(&data, &source_attribute)) {
+               if (!asn1_read_OctetString(data, mem_ctx, &source_attribute)) {
                        return False;
                }
                lac->src_attr_len = source_attribute.length;
@@ -380,9 +380,9 @@ static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out)
 
                lac->request = 1;
 
-       } else if (asn1_peek_tag(&data, ASN1_ENUMERATED)) {
+       } else if (asn1_peek_tag(data, ASN1_ENUMERATED)) {
 
-               if (!asn1_read_enumerated(&data, &(lac->result))) {
+               if (!asn1_read_enumerated(data, &(lac->result))) {
                        return False;
                }
 
@@ -392,7 +392,7 @@ static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out)
                return False;
        }
 
-       if (!asn1_end_tag(&data)) {
+       if (!asn1_end_tag(data)) {
                return False;
        }
 
@@ -449,10 +449,10 @@ static BOOL decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void **out)
 static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out)
 {
        DATA_BLOB assertion_value, context_id;
-       struct asn1_data data;
+       struct asn1_data *data = asn1_init(mem_ctx);
        struct ldb_vlv_req_control *lvrc;
 
-       if (!asn1_load(&data, in)) {
+       if (!asn1_load(data, in)) {
                return False;
        }
 
@@ -461,43 +461,43 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out)
                return False;
        }
 
-       if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) {
+       if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
                return False;
        }
 
-       if (!asn1_read_Integer(&data, &(lvrc->beforeCount))) {
+       if (!asn1_read_Integer(data, &(lvrc->beforeCount))) {
                return False;
        }
        
-       if (!asn1_read_Integer(&data, &(lvrc->afterCount))) {
+       if (!asn1_read_Integer(data, &(lvrc->afterCount))) {
                return False;
        }
 
-       if (asn1_peek_tag(&data, ASN1_CONTEXT(0))) {
+       if (asn1_peek_tag(data, ASN1_CONTEXT(0))) {
 
                lvrc->type = 0;
                
-               if (!asn1_start_tag(&data, ASN1_CONTEXT(0))) {
+               if (!asn1_start_tag(data, ASN1_CONTEXT(0))) {
                        return False;
                }
 
-               if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) {
+               if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
                        return False;
                }
 
-               if (!asn1_read_Integer(&data, &(lvrc->match.byOffset.offset))) {
+               if (!asn1_read_Integer(data, &(lvrc->match.byOffset.offset))) {
                        return False;
                }
 
-               if (!asn1_read_Integer(&data, &(lvrc->match.byOffset.contentCount))) {
+               if (!asn1_read_Integer(data, &(lvrc->match.byOffset.contentCount))) {
                        return False;
                }
 
-               if (!asn1_end_tag(&data)) { /*SEQUENCE*/
+               if (!asn1_end_tag(data)) { /*SEQUENCE*/
                        return False;
                }
 
-               if (!asn1_end_tag(&data)) { /*CONTEXT*/
+               if (!asn1_end_tag(data)) { /*CONTEXT*/
                        return False;
                }
 
@@ -505,11 +505,11 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out)
 
                lvrc->type = 1;
 
-               if (!asn1_start_tag(&data, ASN1_CONTEXT(1))) {
+               if (!asn1_start_tag(data, ASN1_CONTEXT(1))) {
                        return False;
                }
 
-               if (!asn1_read_OctetString(&data, &assertion_value)) {
+               if (!asn1_read_OctetString(data, mem_ctx, &assertion_value)) {
                        return False;
                }
                lvrc->match.gtOrEq.value_len = assertion_value.length;
@@ -523,13 +523,13 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out)
                        lvrc->match.gtOrEq.value = NULL;
                }
 
-               if (!asn1_end_tag(&data)) { /*CONTEXT*/
+               if (!asn1_end_tag(data)) { /*CONTEXT*/
                        return False;
                }
        }
 
-       if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) {
-               if (!asn1_read_OctetString(&data, &context_id)) {
+       if (asn1_peek_tag(data, ASN1_OCTET_STRING)) {
+               if (!asn1_read_OctetString(data, mem_ctx, &context_id)) {
                        return False;
                }
                lvrc->ctxid_len = context_id.length;
@@ -547,7 +547,7 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out)
                lvrc->ctxid_len = 0;
        }
 
-       if (!asn1_end_tag(&data)) {
+       if (!asn1_end_tag(data)) {
                return False;
        }
 
@@ -559,10 +559,10 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out)
 static BOOL decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out)
 {
        DATA_BLOB context_id;
-       struct asn1_data data;
+       struct asn1_data *data = asn1_init(mem_ctx);
        struct ldb_vlv_resp_control *lvrc;
 
-       if (!asn1_load(&data, in)) {
+       if (!asn1_load(data, in)) {
                return False;
        }
 
@@ -571,24 +571,24 @@ static BOOL decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out)
                return False;
        }
 
-       if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) {
+       if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
                return False;
        }
 
-       if (!asn1_read_Integer(&data, &(lvrc->targetPosition))) {
+       if (!asn1_read_Integer(data, &(lvrc->targetPosition))) {
                return False;
        }
        
-       if (!asn1_read_Integer(&data, &(lvrc->contentCount))) {
+       if (!asn1_read_Integer(data, &(lvrc->contentCount))) {
                return False;
        }
        
-       if (!asn1_read_enumerated(&data, &(lvrc->vlv_result))) {
+       if (!asn1_read_enumerated(data, &(lvrc->vlv_result))) {
                return False;
        }
 
-       if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) {
-               if (!asn1_read_OctetString(&data, &context_id)) {
+       if (asn1_peek_tag(data, ASN1_OCTET_STRING)) {
+               if (!asn1_read_OctetString(data, mem_ctx, &context_id)) {
                        return False;
                }
                lvrc->contextId = talloc_strndup(lvrc, (const char *)context_id.data, context_id.length);
@@ -601,7 +601,7 @@ static BOOL decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out)
                lvrc->ctxid_len = 0;
        }
 
-       if (!asn1_end_tag(&data)) {
+       if (!asn1_end_tag(data)) {
                return False;
        }
 
@@ -613,32 +613,31 @@ static BOOL decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out)
 static BOOL encode_server_sort_response(void *mem_ctx, void *in, DATA_BLOB *out)
 {
        struct ldb_sort_resp_control *lsrc = talloc_get_type(in, struct ldb_sort_resp_control);
-       struct asn1_data data;
-
-       ZERO_STRUCT(data);
+       struct asn1_data *data = asn1_init(mem_ctx);
 
-       if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) {
+       if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
                return False;
        }
 
-       if (!asn1_write_enumerated(&data, lsrc->result)) {
+       if (!asn1_write_enumerated(data, lsrc->result)) {
                return False;
        }
 
        if (lsrc->attr_desc) {
-               if (!asn1_write_OctetString(&data, lsrc->attr_desc, strlen(lsrc->attr_desc))) {
+               if (!asn1_write_OctetString(data, lsrc->attr_desc, strlen(lsrc->attr_desc))) {
                        return False;
                }
        }
 
-       if (!asn1_pop_tag(&data)) {
+       if (!asn1_pop_tag(data)) {
                return False;
        }
 
-       *out = data_blob_talloc(mem_ctx, data.data, data.length);
+       *out = data_blob_talloc(mem_ctx, data->data, data->length);
        if (out->data == NULL) {
                return False;
        }
+       talloc_free(data);
 
        return True;
 }
@@ -646,49 +645,48 @@ static BOOL encode_server_sort_response(void *mem_ctx, void *in, DATA_BLOB *out)
 static BOOL encode_server_sort_request(void *mem_ctx, void *in, DATA_BLOB *out)
 {
        struct ldb_server_sort_control **lssc = talloc_get_type(in, struct ldb_server_sort_control *);
-       struct asn1_data data;
+       struct asn1_data *data = asn1_init(mem_ctx);
        int num;
 
-       ZERO_STRUCT(data);
-
-       if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) {
+       if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
                return False;
        }
 
        for (num = 0; lssc[num]; num++) {
-               if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) {
+               if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
                        return False;
                }
                
-               if (!asn1_write_OctetString(&data, lssc[num]->attributeName, strlen(lssc[num]->attributeName))) {
+               if (!asn1_write_OctetString(data, lssc[num]->attributeName, strlen(lssc[num]->attributeName))) {
                        return False;
                }
 
                if (lssc[num]->orderingRule) {
-                       if (!asn1_write_OctetString(&data, lssc[num]->orderingRule, strlen(lssc[num]->orderingRule))) {
+                       if (!asn1_write_OctetString(data, lssc[num]->orderingRule, strlen(lssc[num]->orderingRule))) {
                                return False;
                        }
                }
 
                if (lssc[num]->reverse) {
-                       if (!asn1_write_BOOLEAN(&data, lssc[num]->reverse)) {
+                       if (!asn1_write_BOOLEAN(data, lssc[num]->reverse)) {
                                return False;
                        }
                }
 
-               if (!asn1_pop_tag(&data)) {
+               if (!asn1_pop_tag(data)) {
                        return False;
                }
        }
 
-       if (!asn1_pop_tag(&data)) {
+       if (!asn1_pop_tag(data)) {
                return False;
        }
 
-       *out = data_blob_talloc(mem_ctx, data.data, data.length);
+       *out = data_blob_talloc(mem_ctx, data->data, data->length);
        if (out->data == NULL) {
                return False;
        }
+       talloc_free(data);
 
        return True;
 }
@@ -696,26 +694,25 @@ static BOOL encode_server_sort_request(void *mem_ctx, void *in, DATA_BLOB *out)
 static BOOL encode_extended_dn_request(void *mem_ctx, void *in, DATA_BLOB *out)
 {
        struct ldb_extended_dn_control *ledc = talloc_get_type(in, struct ldb_extended_dn_control);
-       struct asn1_data data;
-
-       ZERO_STRUCT(data);
+       struct asn1_data *data = asn1_init(mem_ctx);
 
-       if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) {
+       if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
                return False;
        }
 
-       if (!asn1_write_Integer(&data, ledc->type)) {
+       if (!asn1_write_Integer(data, ledc->type)) {
                return False;
        }
 
-       if (!asn1_pop_tag(&data)) {
+       if (!asn1_pop_tag(data)) {
                return False;
        }
 
-       *out = data_blob_talloc(mem_ctx, data.data, data.length);
+       *out = data_blob_talloc(mem_ctx, data->data, data->length);
        if (out->data == NULL) {
                return False;
        }
+       talloc_free(data);
 
        return True;
 }
@@ -723,26 +720,25 @@ static BOOL encode_extended_dn_request(void *mem_ctx, void *in, DATA_BLOB *out)
 static BOOL encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out)
 {
        struct ldb_sd_flags_control *lsdfc = talloc_get_type(in, struct ldb_sd_flags_control);
-       struct asn1_data data;
+       struct asn1_data *data = asn1_init(mem_ctx);
 
-       ZERO_STRUCT(data);
-
-       if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) {
+       if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
                return False;
        }
 
-       if (!asn1_write_Integer(&data, lsdfc->secinfo_flags)) {
+       if (!asn1_write_Integer(data, lsdfc->secinfo_flags)) {
                return False;
        }
 
-       if (!asn1_pop_tag(&data)) {
+       if (!asn1_pop_tag(data)) {
                return False;
        }
 
-       *out = data_blob_talloc(mem_ctx, data.data, data.length);
+       *out = data_blob_talloc(mem_ctx, data->data, data->length);
        if (out->data == NULL) {
                return False;
        }
+       talloc_free(data);
 
        return True;
 }
@@ -750,26 +746,25 @@ static BOOL encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out)
 static BOOL encode_search_options_request(void *mem_ctx, void *in, DATA_BLOB *out)
 {
        struct ldb_search_options_control *lsoc = talloc_get_type(in, struct ldb_search_options_control);
-       struct asn1_data data;
+       struct asn1_data *data = asn1_init(mem_ctx);
 
-       ZERO_STRUCT(data);
-
-       if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) {
+       if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
                return False;
        }
 
-       if (!asn1_write_Integer(&data, lsoc->search_options)) {
+       if (!asn1_write_Integer(data, lsoc->search_options)) {
                return False;
        }
 
-       if (!asn1_pop_tag(&data)) {
+       if (!asn1_pop_tag(data)) {
                return False;
        }
 
-       *out = data_blob_talloc(mem_ctx, data.data, data.length);
+       *out = data_blob_talloc(mem_ctx, data->data, data->length);
        if (out->data == NULL) {
                return False;
        }
+       talloc_free(data);
 
        return True;
 }
@@ -777,30 +772,29 @@ static BOOL encode_search_options_request(void *mem_ctx, void *in, DATA_BLOB *ou
 static BOOL encode_paged_results_request(void *mem_ctx, void *in, DATA_BLOB *out)
 {
        struct ldb_paged_control *lprc = talloc_get_type(in, struct ldb_paged_control);
-       struct asn1_data data;
+       struct asn1_data *data = asn1_init(mem_ctx);
 
-       ZERO_STRUCT(data);
-
-       if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) {
+       if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
                return False;
        }
 
-       if (!asn1_write_Integer(&data, lprc->size)) {
+       if (!asn1_write_Integer(data, lprc->size)) {
                return False;
        }
 
-       if (!asn1_write_OctetString(&data, lprc->cookie, lprc->cookie_len)) {
+       if (!asn1_write_OctetString(data, lprc->cookie, lprc->cookie_len)) {
                return False;
        }       
 
-       if (!asn1_pop_tag(&data)) {
+       if (!asn1_pop_tag(data)) {
                return False;
        }
 
-       *out = data_blob_talloc(mem_ctx, data.data, data.length);
+       *out = data_blob_talloc(mem_ctx, data->data, data->length);
        if (out->data == NULL) {
                return False;
        }
+       talloc_free(data);
 
        return True;
 }
@@ -811,33 +805,32 @@ static BOOL encode_paged_results_request(void *mem_ctx, void *in, DATA_BLOB *out
 static BOOL encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out)
 {
        struct ldb_asq_control *lac = talloc_get_type(in, struct ldb_asq_control);
-       struct asn1_data data;
+       struct asn1_data *data = asn1_init(mem_ctx);
 
-       ZERO_STRUCT(data);
-
-       if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) {
+       if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
                return False;
        }
 
        if (lac->request) {
 
-               if (!asn1_write_OctetString(&data, lac->source_attribute, lac->src_attr_len)) {
+               if (!asn1_write_OctetString(data, lac->source_attribute, lac->src_attr_len)) {
                        return False;
                }
        } else {
-               if (!asn1_write_enumerated(&data, lac->result)) {
+               if (!asn1_write_enumerated(data, lac->result)) {
                        return False;
                }
        }
 
-       if (!asn1_pop_tag(&data)) {
+       if (!asn1_pop_tag(data)) {
                return False;
        }
 
-       *out = data_blob_talloc(mem_ctx, data.data, data.length);
+       *out = data_blob_talloc(mem_ctx, data->data, data->length);
        if (out->data == NULL) {
                return False;
        }
+       talloc_free(data);
 
        return True;
 }
@@ -845,34 +838,33 @@ static BOOL encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out)
 static BOOL encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out)
 {
        struct ldb_dirsync_control *ldc = talloc_get_type(in, struct ldb_dirsync_control);
-       struct asn1_data data;
+       struct asn1_data *data = asn1_init(mem_ctx);
 
-       ZERO_STRUCT(data);
-
-       if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) {
+       if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
                return False;
        }
 
-       if (!asn1_write_Integer(&data, ldc->flags)) {
+       if (!asn1_write_Integer(data, ldc->flags)) {
                return False;
        }
 
-       if (!asn1_write_Integer(&data, ldc->max_attributes)) {
+       if (!asn1_write_Integer(data, ldc->max_attributes)) {
                return False;
        }
 
-       if (!asn1_write_OctetString(&data, ldc->cookie, ldc->cookie_len)) {
+       if (!asn1_write_OctetString(data, ldc->cookie, ldc->cookie_len)) {
                return False;
        }       
 
-       if (!asn1_pop_tag(&data)) {
+       if (!asn1_pop_tag(data)) {
                return False;
        }
 
-       *out = data_blob_talloc(mem_ctx, data.data, data.length);
+       *out = data_blob_talloc(mem_ctx, data->data, data->length);
        if (out->data == NULL) {
                return False;
        }
+       talloc_free(data);
 
        return True;
 }
@@ -930,74 +922,73 @@ static BOOL encode_manageDSAIT_request(void *mem_ctx, void *in, DATA_BLOB *out)
 static BOOL encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out)
 {
        struct ldb_vlv_req_control *lvrc = talloc_get_type(in, struct ldb_vlv_req_control);
-       struct asn1_data data;
+       struct asn1_data *data = asn1_init(mem_ctx);
 
-       ZERO_STRUCT(data);
-
-       if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) {
+       if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
                return False;
        }
 
-       if (!asn1_write_Integer(&data, lvrc->beforeCount)) {
+       if (!asn1_write_Integer(data, lvrc->beforeCount)) {
                return False;
        }
 
-       if (!asn1_write_Integer(&data, lvrc->afterCount)) {
+       if (!asn1_write_Integer(data, lvrc->afterCount)) {
                return False;
        }
 
        if (lvrc->type == 0) {
-               if (!asn1_push_tag(&data, ASN1_CONTEXT(0))) {
+               if (!asn1_push_tag(data, ASN1_CONTEXT(0))) {
                        return False;
                }
                
-               if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) {
+               if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
                        return False;
                }
                
-               if (!asn1_write_Integer(&data, lvrc->match.byOffset.offset)) {
+               if (!asn1_write_Integer(data, lvrc->match.byOffset.offset)) {
                        return False;
                }
 
-               if (!asn1_write_Integer(&data, lvrc->match.byOffset.contentCount)) {
+               if (!asn1_write_Integer(data, lvrc->match.byOffset.contentCount)) {
                        return False;
                }
 
-               if (!asn1_pop_tag(&data)) { /*SEQUENCE*/
+               if (!asn1_pop_tag(data)) { /*SEQUENCE*/
                        return False;
                }
 
-               if (!asn1_pop_tag(&data)) { /*CONTEXT*/
+               if (!asn1_pop_tag(data)) { /*CONTEXT*/
                        return False;
                }
        } else {
-               if (!asn1_push_tag(&data, ASN1_CONTEXT(1))) {
+               if (!asn1_push_tag(data, ASN1_CONTEXT(1))) {
                        return False;
                }
                
-               if (!asn1_write_OctetString(&data, lvrc->match.gtOrEq.value, lvrc->match.gtOrEq.value_len)) {
+               if (!asn1_write_OctetString(data, lvrc->match.gtOrEq.value, lvrc->match.gtOrEq.value_len)) {
                        return False;
                }
 
-               if (!asn1_pop_tag(&data)) { /*CONTEXT*/
+               if (!asn1_pop_tag(data)) { /*CONTEXT*/
                        return False;
                }
        }
 
        if (lvrc->ctxid_len) {
-               if (!asn1_write_OctetString(&data, lvrc->contextId, lvrc->ctxid_len)) {
+               if (!asn1_write_OctetString(data, lvrc->contextId, lvrc->ctxid_len)) {
                        return False;
                }
        }
 
-       if (!asn1_pop_tag(&data)) {
+       if (!asn1_pop_tag(data)) {
                return False;
        }
 
-       *out = data_blob_talloc(mem_ctx, data.data, data.length);
+       *out = data_blob_talloc(mem_ctx, data->data, data->length);
        if (out->data == NULL) {
                return False;
        }
+       talloc_free(data);
 
        return True;
 }
@@ -1005,40 +996,39 @@ static BOOL encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out)
 static BOOL encode_vlv_response(void *mem_ctx, void *in, DATA_BLOB *out)
 {
        struct ldb_vlv_resp_control *lvrc = talloc_get_type(in, struct ldb_vlv_resp_control);
-       struct asn1_data data;
+       struct asn1_data *data = asn1_init(mem_ctx);
 
-       ZERO_STRUCT(data);
-
-       if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) {
+       if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
                return False;
        }
 
-       if (!asn1_write_Integer(&data, lvrc->targetPosition)) {
+       if (!asn1_write_Integer(data, lvrc->targetPosition)) {
                return False;
        }
 
-       if (!asn1_write_Integer(&data, lvrc->contentCount)) {
+       if (!asn1_write_Integer(data, lvrc->contentCount)) {
                return False;
        }
 
-       if (!asn1_write_enumerated(&data, lvrc->vlv_result)) {
+       if (!asn1_write_enumerated(data, lvrc->vlv_result)) {
                return False;
        }
 
        if (lvrc->ctxid_len) {
-               if (!asn1_write_OctetString(&data, lvrc->contextId, lvrc->ctxid_len)) {
+               if (!asn1_write_OctetString(data, lvrc->contextId, lvrc->ctxid_len)) {
                        return False;
                }
        }
 
-       if (!asn1_pop_tag(&data)) {
+       if (!asn1_pop_tag(data)) {
                return False;
        }
 
-       *out = data_blob_talloc(mem_ctx, data.data, data.length);
+       *out = data_blob_talloc(mem_ctx, data->data, data->length);
        if (out->data == NULL) {
                return False;
        }
+       talloc_free(data);
 
        return True;
 }
@@ -1093,7 +1083,7 @@ BOOL ldap_decode_control_wrapper(void *mem_ctx, struct asn1_data *data, struct l
                return False;
        }
 
-       if (!asn1_read_OctetString(data, &oid)) {
+       if (!asn1_read_OctetString(data, mem_ctx, &oid)) {
                return False;
        }
        ctrl->oid = talloc_strndup(mem_ctx, (char *)oid.data, oid.length);
@@ -1117,7 +1107,7 @@ BOOL ldap_decode_control_wrapper(void *mem_ctx, struct asn1_data *data, struct l
                goto end_tag;
        }
 
-       if (!asn1_read_OctetString(data, value)) {
+       if (!asn1_read_OctetString(data, mem_ctx, value)) {
                return False;
        }
 
index e64ffdf86c6c8155aa059233ca6f681da639074f..d02f6be9c776b2eaaac96c29968e7bb86251af31 100644 (file)
 #include "includes.h"
 #include "libcli/util/asn_1.h"
 
+/* allocate an asn1 structure */
+struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx)
+{
+       return talloc_zero(NULL, struct asn1_data);
+}
+
 /* free an asn1 structure */
 void asn1_free(struct asn1_data *data)
 {
-       talloc_free(data->data);
-       ZERO_STRUCTP(data);
-       data->has_error = True;
+       talloc_free(data);
 }
 
 /* write to the ASN1 buffer, advancing the buffer pointer */
@@ -35,7 +39,7 @@ BOOL asn1_write(struct asn1_data *data, const void *p, int len)
        if (data->has_error) return False;
        if (data->length < data->ofs+len) {
                uint8_t *newp;
-               newp = talloc_realloc(NULL, data->data, uint8_t, data->ofs+len);
+               newp = talloc_realloc(data, data->data, uint8_t, data->ofs+len);
                if (!newp) {
                        asn1_free(data);
                        data->has_error = True;
@@ -61,7 +65,7 @@ BOOL asn1_push_tag(struct asn1_data *data, uint8_t tag)
        struct nesting *nesting;
 
        asn1_write_uint8(data, tag);
-       nesting = talloc(NULL, struct nesting);
+       nesting = talloc(data, struct nesting);
        if (!nesting) {
                data->has_error = True;
                return False;
@@ -341,7 +345,7 @@ BOOL asn1_check_BOOLEAN(struct asn1_data *data, BOOL v)
 BOOL asn1_load(struct asn1_data *data, DATA_BLOB blob)
 {
        ZERO_STRUCTP(data);
-       data->data = talloc_memdup(NULL, blob.data, blob.length);
+       data->data = talloc_memdup(data, blob.data, blob.length);
        if (!data->data) {
                data->has_error = True;
                return False;
@@ -417,7 +421,7 @@ BOOL asn1_start_tag(struct asn1_data *data, uint8_t tag)
                data->has_error = True;
                return False;
        }
-       nesting = talloc(NULL, struct nesting);
+       nesting = talloc(data, struct nesting);
        if (!nesting) {
                data->has_error = True;
                return False;
@@ -494,7 +498,7 @@ int asn1_tag_remaining(struct asn1_data *data)
 }
 
 /* read an object ID from a data blob */
-BOOL ber_read_OID_String(DATA_BLOB blob, const char **OID)
+BOOL ber_read_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, const char **OID)
 {
        int i;
        uint8_t *b;
@@ -505,7 +509,7 @@ BOOL ber_read_OID_String(DATA_BLOB blob, const char **OID)
 
        b = blob.data;
 
-       tmp_oid = talloc_asprintf(NULL, "%u",  b[0]/40);
+       tmp_oid = talloc_asprintf(mem_ctx, "%u",  b[0]/40);
        if (!tmp_oid) goto nomem;
        tmp_oid = talloc_asprintf_append(tmp_oid, ".%u",  b[0]%40);
        if (!tmp_oid) goto nomem;
@@ -532,7 +536,7 @@ nomem:
 }
 
 /* read an object ID from a ASN1 buffer */
-BOOL asn1_read_OID(struct asn1_data *data, const char **OID)
+BOOL asn1_read_OID(struct asn1_data *data, TALLOC_CTX *mem_ctx, const char **OID)
 {
        DATA_BLOB blob;
        int len;
@@ -558,7 +562,7 @@ BOOL asn1_read_OID(struct asn1_data *data, const char **OID)
                return False;
        }
 
-       if (!ber_read_OID_String(blob, OID)) {
+       if (!ber_read_OID_String(mem_ctx, blob, OID)) {
                data->has_error = True;
                data_blob_free(&blob);
                return False;
@@ -573,9 +577,10 @@ BOOL asn1_check_OID(struct asn1_data *data, const char *OID)
 {
        const char *id;
 
-       if (!asn1_read_OID(data, &id)) return False;
+       if (!asn1_read_OID(data, data, &id)) return False;
 
        if (strcmp(id, OID) != 0) {
+               talloc_free(discard_const(id));
                data->has_error = True;
                return False;
        }
@@ -584,7 +589,7 @@ BOOL asn1_check_OID(struct asn1_data *data, const char *OID)
 }
 
 /* read a LDAPString from a ASN1 buffer */
-BOOL asn1_read_LDAPString(struct asn1_data *data, char **s)
+BOOL asn1_read_LDAPString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s)
 {
        int len;
        len = asn1_tag_remaining(data);
@@ -592,7 +597,7 @@ BOOL asn1_read_LDAPString(struct asn1_data *data, char **s)
                data->has_error = True;
                return False;
        }
-       *s = talloc_size(NULL, len+1);
+       *s = talloc_size(mem_ctx, len+1);
        if (! *s) {
                data->has_error = True;
                return False;
@@ -604,16 +609,16 @@ BOOL asn1_read_LDAPString(struct asn1_data *data, char **s)
 
 
 /* read a GeneralString from a ASN1 buffer */
-BOOL asn1_read_GeneralString(struct asn1_data *data, char **s)
+BOOL asn1_read_GeneralString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s)
 {
        if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return False;
-       if (!asn1_read_LDAPString(data, s)) return False;
+       if (!asn1_read_LDAPString(data, mem_ctx, s)) return False;
        return asn1_end_tag(data);
 }
 
 
 /* read a octet string blob */
-BOOL asn1_read_OctetString(struct asn1_data *data, DATA_BLOB *blob)
+BOOL asn1_read_OctetString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob)
 {
        int len;
        ZERO_STRUCTP(blob);
@@ -623,7 +628,7 @@ BOOL asn1_read_OctetString(struct asn1_data *data, DATA_BLOB *blob)
                data->has_error = True;
                return False;
        }
-       *blob = data_blob(NULL, len+1);
+       *blob = data_blob_talloc(mem_ctx, NULL, len+1);
        if (!blob->data) {
                data->has_error = True;
                return False;
@@ -727,19 +732,21 @@ BOOL asn1_write_enumerated(struct asn1_data *data, uint8_t v)
 */
 NTSTATUS asn1_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size)
 {
-       struct asn1_data asn1;
+       struct asn1_data *asn1 = asn1_init(NULL);
        int size;
 
-       ZERO_STRUCT(asn1);
-       asn1.data = blob.data;
-       asn1.length = blob.length;
-       asn1_start_tag(&asn1, tag);
-       if (asn1.has_error) {
-               talloc_free(asn1.nesting);
+       NT_STATUS_HAVE_NO_MEMORY(asn1);
+
+       asn1->data = blob.data;
+       asn1->length = blob.length;
+       asn1_start_tag(asn1, tag);
+       if (asn1->has_error) {
+               talloc_free(asn1);
                return STATUS_MORE_ENTRIES;
        }
-       size = asn1_tag_remaining(&asn1) + asn1.ofs;
-       talloc_free(asn1.nesting);
+       size = asn1_tag_remaining(asn1) + asn1->ofs;
+
+       talloc_free(asn1);
 
        if (size > blob.length) {
                return STATUS_MORE_ENTRIES;
index f8f84f8c702b13ab9fce4851a6955d015fc1d1ac..ac6e4f9c18600e39d42fd0906c9008b0f0dfd65d 100644 (file)
@@ -144,7 +144,7 @@ NTSTATUS ndr_pull_drsuapi_DsReplicaOID(struct ndr_pull *ndr, int ndr_flags, stru
                                _oid = data_blob_hex_string(ndr, &_oid_array);
                                NT_STATUS_HAVE_NO_MEMORY(_oid);
                        } else {
-                               _OID_PULL_CHECK(ber_read_OID_String(_oid_array, &_oid));
+                               _OID_PULL_CHECK(ber_read_OID_String(r->oid, _oid_array, &_oid));
                        }
                        data_blob_free(&_oid_array);
                        talloc_steal(r->oid, _oid);