diff options
author | Matthieu Patou <mat@matws.net> | 2012-05-15 11:15:38 -0700 |
---|---|---|
committer | Matthieu Patou <mat@matws.net> | 2012-06-22 23:22:02 -0700 |
commit | f110f2d63fc931deb7fa44fbfee7235a5cb2cf56 (patch) | |
tree | 0e5943c7f739de3f300f0f61aa5bc8e95abfdc7b /source4 | |
parent | 9ebb081ccec0587736920e85a9de624e079836e5 (diff) | |
download | samba-f110f2d63fc931deb7fa44fbfee7235a5cb2cf56.tar.gz samba-f110f2d63fc931deb7fa44fbfee7235a5cb2cf56.tar.bz2 samba-f110f2d63fc931deb7fa44fbfee7235a5cb2cf56.zip |
s4-ldap: handle VERIFY_NAME control encoding/decoding
Diffstat (limited to 'source4')
-rw-r--r-- | source4/libcli/ldap/ldap_controls.c | 96 |
1 files changed, 96 insertions, 0 deletions
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 */ |