diff options
Diffstat (limited to 'source4/libcli/ldap')
-rw-r--r-- | source4/libcli/ldap/ldap.c | 26 | ||||
-rw-r--r-- | source4/libcli/ldap/ldap_client.c | 2 | ||||
-rw-r--r-- | source4/libcli/ldap/ldap_controls.c | 115 | ||||
-rw-r--r-- | source4/libcli/ldap/ldap_ndr.c | 1 |
4 files changed, 134 insertions, 10 deletions
diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 87c89daf9f..7a65cc5c27 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -504,9 +504,9 @@ static const char *blob2string_talloc(TALLOC_CTX *mem_ctx, return result; } -static bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, - struct asn1_data *data, - const char **result) +bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, + struct asn1_data *data, + const char **result) { DATA_BLOB string; if (!asn1_read_OctetString(data, mem_ctx, &string)) @@ -894,7 +894,7 @@ failed: return NULL; } - +/* Decode a single LDAP attribute, possibly containing multiple values */ static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, struct ldb_message_element *attrib) { @@ -911,11 +911,11 @@ static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, } -static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldb_message_element **attributes, - int *num_attributes) +/* Decode a set of LDAP attributes, as found in the dereference control */ +void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data, + struct ldb_message_element **attributes, + int *num_attributes) { - asn1_start_tag(data, ASN1_SEQUENCE(0)); while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { struct ldb_message_element attrib; ZERO_STRUCT(attrib); @@ -923,6 +923,16 @@ static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, add_attrib_to_array_talloc(mem_ctx, &attrib, attributes, num_attributes); } +} + +/* Decode a set of LDAP attributes, as found in a search entry */ +void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, + struct ldb_message_element **attributes, + int *num_attributes) +{ + asn1_start_tag(data, ASN1_SEQUENCE(0)); + ldap_decode_attribs_bare(mem_ctx, data, + attributes, num_attributes); asn1_end_tag(data); } diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 7f43e16c95..082f6fa3e4 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -358,7 +358,7 @@ _PUBLIC_ struct composite_context *ldap_connect_send(struct ldap_connection *con } ctx = socket_connect_send(conn->sock, NULL, unix_addr, - 0, lp_resolve_context(conn->lp_ctx), conn->event.event_ctx); + 0, conn->event.event_ctx); ctx->async.fn = ldap_connect_recv_unix_conn; ctx->async.private_data = state; return result; diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 930d97c40d..109837c2bf 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -24,6 +24,7 @@ #include "libcli/ldap/ldap.h" #include "lib/ldb/include/ldb.h" #include "libcli/ldap/ldap_proto.h" +#include "dsdb/samdb/samdb.h" struct control_handler { const char *oid; @@ -1087,6 +1088,119 @@ static bool encode_vlv_response(void *mem_ctx, void *in, DATA_BLOB *out) return true; } +static bool encode_openldap_dereference(void *mem_ctx, void *in, DATA_BLOB *out) +{ + struct dsdb_openldap_dereference_control *control = talloc_get_type(in, struct dsdb_openldap_dereference_control); + int i,j; + struct asn1_data *data = asn1_init(mem_ctx); + + if (!data) return false; + + if (!control) return false; + + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { + return false; + } + + for (i=0; control->dereference && control->dereference[i]; i++) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { + return false; + } + if (!asn1_write_OctetString(data, control->dereference[i]->source_attribute, strlen(control->dereference[i]->source_attribute))) { + return false; + } + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { + return false; + } + for (j=0; control->dereference && control->dereference[i]->dereference_attribute[j]; j++) { + if (!asn1_write_OctetString(data, control->dereference[i]->dereference_attribute[j], + strlen(control->dereference[i]->dereference_attribute[j]))) { + return false; + } + } + + asn1_pop_tag(data); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + + *out = data_blob_talloc(mem_ctx, data->data, data->length); + if (out->data == NULL) { + return false; + } + talloc_free(data); + return true; +} + +static bool decode_openldap_dereference(void *mem_ctx, DATA_BLOB in, void **out) +{ + struct asn1_data *data = asn1_init(mem_ctx); + struct dsdb_openldap_dereference_result_control *control; + struct dsdb_openldap_dereference_result **r = NULL; + int i = 0; + if (!data) return false; + + control = talloc(mem_ctx, struct dsdb_openldap_dereference_result_control); + if (!control) return false; + + if (!asn1_load(data, in)) { + return false; + } + + control = talloc(mem_ctx, struct dsdb_openldap_dereference_result_control); + if (!control) { + return false; + } + + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { + return false; + } + + while (asn1_tag_remaining(data) > 0) { + r = talloc_realloc(control, r, struct dsdb_openldap_dereference_result *, i + 2); + if (!r) { + return false; + } + r[i] = talloc_zero(r, struct dsdb_openldap_dereference_result); + if (!r[i]) { + return false; + } + + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { + return false; + } + + asn1_read_OctetString_talloc(r[i], data, &r[i]->source_attribute); + asn1_read_OctetString_talloc(r[i], data, &r[i]->dereferenced_dn); + if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { + if (!asn1_start_tag(data, ASN1_CONTEXT(0))) { + return false; + } + + ldap_decode_attribs_bare(r, data, &r[i]->attributes, + &r[i]->num_attributes); + + if (!asn1_end_tag(data)) { + return false; + } + } + if (!asn1_end_tag(data)) { + return false; + } + i++; + r[i] = NULL; + } + + if (!asn1_end_tag(data)) { + return false; + } + + control->attributes = r; + *out = control; + + return true; +} + struct control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.319", decode_paged_results_request, encode_paged_results_request }, { "1.2.840.113556.1.4.529", decode_extended_dn_request, encode_extended_dn_request }, @@ -1107,6 +1221,7 @@ struct control_handler ldap_known_controls[] = { { "1.3.6.1.4.1.7165.4.3.2", NULL, NULL }, /* DSDB_EXTENDED_REPLICATED_OBJECTS_OID is internal only, and has no network representation */ { "1.3.6.1.4.1.7165.4.4.1", NULL, NULL }, + { DSDB_OPENLDAP_DEREFERENCE_CONTROL, decode_openldap_dereference, encode_openldap_dereference}, { NULL, NULL, NULL } }; diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index 5e938ea148..f0a11ba41f 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -21,7 +21,6 @@ */ #include "includes.h" -#include "lib/events/events.h" #include "libcli/ldap/ldap.h" #include "librpc/gen_ndr/ndr_security.h" #include "librpc/gen_ndr/ndr_misc.h" |