From f110f2d63fc931deb7fa44fbfee7235a5cb2cf56 Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Tue, 15 May 2012 11:15:38 -0700 Subject: s4-ldap: handle VERIFY_NAME control encoding/decoding --- source4/libcli/ldap/ldap_controls.c | 96 +++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index c8e562317a..17d96f6f9d 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -426,6 +426,101 @@ static bool decode_asq_control(void *mem_ctx, DATA_BLOB in, void *_out) return true; } +static bool decode_verify_name_request(void *mem_ctx, DATA_BLOB in, void *_out) +{ + void **out = (void **)_out; + DATA_BLOB name; + struct asn1_data *data = asn1_init(mem_ctx); + struct ldb_verify_name_control *lvnc; + int len; + + if (!data) return false; + + if (!asn1_load(data, in)) { + return false; + } + + lvnc = talloc(mem_ctx, struct ldb_verify_name_control); + if (!lvnc) { + return false; + } + + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { + return false; + } + + if (!asn1_read_Integer(data, &(lvnc->flags))) { + return false; + } + + if (!asn1_read_OctetString(data, mem_ctx, &name)) { + return false; + } + + if (name.length) { + len = utf16_len_n(name.data, name.length); + convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, + name.data, len, + (void **)&lvnc->gc, &lvnc->gc_len); + + if (!(lvnc->gc)) { + return false; + } + } else { + lvnc->gc_len = 0; + lvnc->gc = NULL; + } + + if (!asn1_end_tag(data)) { + return false; + } + + *out = lvnc; + return true; +} + +static bool encode_verify_name_request(void *mem_ctx, void *in, DATA_BLOB *out) +{ + struct ldb_verify_name_control *lvnc = talloc_get_type(in, struct ldb_verify_name_control); + struct asn1_data *data = asn1_init(mem_ctx); + DATA_BLOB gc_utf16; + + if (!data) return false; + + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { + return false; + } + + if (!asn1_write_Integer(data, lvnc->flags)) { + return false; + } + + if (lvnc->gc_len) { + convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, + lvnc->gc, lvnc->gc_len, + (void **)&gc_utf16.data, &gc_utf16.length); + if (!asn1_write_OctetString(data, gc_utf16.data, gc_utf16.length)) { + return false; + } + } else { + if (!asn1_write_OctetString(data, NULL, 0)) { + return false; + } + } + + if (!asn1_pop_tag(data)) { + return false; + } + + *out = data_blob_talloc(mem_ctx, data->data, data->length); + if (out->data == NULL) { + return false; + } + talloc_free(data); + + return true; +} + static bool decode_vlv_request(void *mem_ctx, DATA_BLOB in, void *_out) { void **out = (void **)_out; @@ -1158,6 +1253,7 @@ static const struct ldap_control_handler ldap_known_controls[] = { { LDB_CONTROL_RODC_DCPROMO_OID, decode_flag_request, encode_flag_request }, { LDB_CONTROL_RELAX_OID, decode_flag_request, encode_flag_request }, { DSDB_OPENLDAP_DEREFERENCE_CONTROL, decode_openldap_dereference, encode_openldap_dereference }, + { LDB_CONTROL_VERIFY_NAME_OID, decode_verify_name_request, encode_verify_name_request }, /* the following are internal only, with a network representation */ -- cgit