summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libcli/ldap/ldap_controls.c96
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 */