summaryrefslogtreecommitdiff
path: root/source4/libcli
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2006-01-06 04:01:23 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:49:47 -0500
commitc908d0b2aa111659e57a73efb8c33c413965c846 (patch)
tree8446f4dbff222ced9466f70c8f0ef42d87f5cda6 /source4/libcli
parente011ab7e1d9d624b4fd926dc3f15df2ab5f756e6 (diff)
downloadsamba-c908d0b2aa111659e57a73efb8c33c413965c846.tar.gz
samba-c908d0b2aa111659e57a73efb8c33c413965c846.tar.bz2
samba-c908d0b2aa111659e57a73efb8c33c413965c846.zip
r12733: Merge ldap/ldb controls into main tree
There's still lot of work to do but the patch is stable enough to be pushed into the main samba4 tree. Simo. (This used to be commit 77125feaff252cab44d26593093a9c211c846ce8)
Diffstat (limited to 'source4/libcli')
-rw-r--r--source4/libcli/cldap/cldap.c2
-rw-r--r--source4/libcli/ldap/config.mk3
-rw-r--r--source4/libcli/ldap/ldap.c39
-rw-r--r--source4/libcli/ldap/ldap.h7
-rw-r--r--source4/libcli/ldap/ldap_bind.c5
-rw-r--r--source4/libcli/ldap/ldap_client.c1
-rw-r--r--source4/libcli/ldap/ldap_controls.c470
-rw-r--r--source4/libcli/ldap/ldap_ildap.c14
-rw-r--r--source4/libcli/ldap/ldap_msg.c3
-rw-r--r--source4/libcli/ldap/ldap_ndr.c1
10 files changed, 518 insertions, 27 deletions
diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c
index d406b50baf..a6710cf32c 100644
--- a/source4/libcli/cldap/cldap.c
+++ b/source4/libcli/cldap/cldap.c
@@ -319,7 +319,6 @@ struct cldap_request *cldap_search_send(struct cldap_socket *cldap,
if (msg == NULL) goto failed;
msg->messageid = req->message_id;
msg->type = LDAP_TAG_SearchRequest;
- msg->num_controls = 0;
msg->controls = NULL;
search = &msg->r.SearchRequest;
@@ -380,7 +379,6 @@ NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io)
msg = talloc(req, struct ldap_message);
if (msg == NULL) goto failed;
msg->messageid = io->messageid;
- msg->num_controls = 0;
msg->controls = NULL;
if (io->response) {
diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk
index 912cb133bf..59d2d1ea30 100644
--- a/source4/libcli/ldap/config.mk
+++ b/source4/libcli/ldap/config.mk
@@ -7,7 +7,8 @@ OBJ_FILES = ldap.o \
ldap_bind.o \
ldap_msg.o \
ldap_ndr.o \
- ldap_ildap.o
+ ldap_ildap.o \
+ ldap_controls.o
REQUIRED_SUBSYSTEMS = LIBCLI_UTILS LIBEVENTS GENSEC SOCKET NDR_SAMR LIBTLS \
LIBPACKET
# End SUBSYSTEM LIBCLI_LDAP
diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c
index c699820cea..d021fc3bd6 100644
--- a/source4/libcli/ldap/ldap.c
+++ b/source4/libcli/ldap/ldap.c
@@ -455,6 +455,18 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct
return False;
}
+ if (msg->controls != NULL) {
+ 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])) {
+ return False;
+ }
+ }
+
+ asn1_pop_tag(&data);
+ }
+
asn1_pop_tag(&data);
if (data.has_error) {
@@ -1243,42 +1255,35 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg)
return False;
}
- msg->num_controls = 0;
msg->controls = NULL;
if (asn1_peek_tag(data, ASN1_CONTEXT(0))) {
int i;
- struct ldap_Control *ctrl = NULL;
+ struct ldap_Control **ctrl = NULL;
asn1_start_tag(data, ASN1_CONTEXT(0));
for (i=0; asn1_peek_tag(data, ASN1_SEQUENCE(0)); i++) {
asn1_start_tag(data, ASN1_SEQUENCE(0));
- ctrl = talloc_realloc(msg, ctrl, struct ldap_Control, i+1);
+ ctrl = talloc_realloc(msg, ctrl, struct ldap_Control *, i+2);
if (!ctrl) {
return False;
}
- ctrl[i].oid = NULL;
- ctrl[i].critical = False;
- ctrl[i].value = data_blob(NULL, 0);
- asn1_read_OctetString_talloc(ctrl, data, &ctrl[i].oid);
-
- if (asn1_peek_tag(data, ASN1_BOOLEAN)) {
- asn1_read_BOOLEAN(data, &ctrl[i].critical);
+ ctrl[i] = talloc(ctrl, struct ldap_Control);
+ if (!ctrl[i]) {
+ return False;
}
- if (asn1_peek_tag(data, ASN1_OCTET_STRING)) {
- asn1_read_OctetString(data, &ctrl[i].value);
- if (ctrl[i].value.data) {
- talloc_steal(msg, ctrl[i].value.data);
- }
+ if (!ldap_decode_control(ctrl, data, ctrl[i])) {
+ return False;
}
- asn1_end_tag(data);
}
- msg->num_controls = i;
+
+ ctrl[i] = NULL;
+
msg->controls = ctrl;
asn1_end_tag(data);
diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h
index b6e69ff8e6..5283553f13 100644
--- a/source4/libcli/ldap/ldap.h
+++ b/source4/libcli/ldap/ldap.h
@@ -243,15 +243,14 @@ union ldap_Request {
struct ldap_Control {
const char *oid;
BOOL critical;
- DATA_BLOB value;
+ void *value;
};
struct ldap_message {
- uint32_t messageid;
+ int messageid;
enum ldap_request_tag type;
union ldap_Request r;
- int num_controls;
- struct ldap_Control *controls;
+ struct ldap_Control **controls;
};
#include "libcli/ldap/ldap_proto.h"
diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c
index 6b1c321d49..1f6ef77631 100644
--- a/source4/libcli/ldap/ldap_bind.c
+++ b/source4/libcli/ldap/ldap_bind.c
@@ -23,6 +23,7 @@
*/
#include "includes.h"
+#include "libcli/ldap/ldap.h"
#include "libcli/ldap/ldap_client.h"
#include "auth/auth.h"
@@ -41,6 +42,7 @@ static struct ldap_message *new_ldap_simple_bind_msg(struct ldap_connection *con
res->r.BindRequest.dn = talloc_strdup(res, dn);
res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SIMPLE;
res->r.BindRequest.creds.password = talloc_strdup(res, pw);
+ res->controls = NULL;
return res;
}
@@ -128,6 +130,7 @@ static struct ldap_message *new_ldap_sasl_bind_msg(struct ldap_connection *conn,
res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SASL;
res->r.BindRequest.creds.SASL.mechanism = talloc_strdup(res, sasl_mechanism);
res->r.BindRequest.creds.SASL.secblob = *secblob;
+ res->controls = NULL;
return res;
}
@@ -186,7 +189,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr
}
status = ildap_search(conn, "", LDAP_SEARCH_SCOPE_BASE, "", supported_sasl_mech_attrs,
- False, &sasl_mechs_msgs);
+ False, NULL, NULL, &sasl_mechs_msgs);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: %s\n",
nt_errstr(status)));
diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c
index 9b1a4ef9d5..9103e939e7 100644
--- a/source4/libcli/ldap/ldap_client.c
+++ b/source4/libcli/ldap/ldap_client.c
@@ -28,6 +28,7 @@
#include "dlinklist.h"
#include "lib/events/events.h"
#include "lib/socket/socket.h"
+#include "libcli/ldap/ldap.h"
#include "libcli/ldap/ldap_client.h"
#include "libcli/composite/composite.h"
#include "lib/stream/packet.h"
diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c
new file mode 100644
index 0000000000..55e7a94aa7
--- /dev/null
+++ b/source4/libcli/ldap/ldap_controls.c
@@ -0,0 +1,470 @@
+/*
+ Unix SMB/CIFS mplementation.
+ LDAP protocol helper functions for SAMBA
+
+ Copyright (C) Simo Sorce 2005
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "includes.h"
+#include "system/iconv.h"
+#include "libcli/util/asn_1.h"
+#include "libcli/ldap/ldap.h"
+#include "lib/ldb/include/ldb.h"
+
+struct control_handler {
+ const char *oid;
+ BOOL (*decode)(void *mem_ctx, DATA_BLOB in, void **out);
+ BOOL (*encode)(void *mem_ctx, void *in, DATA_BLOB *out);
+};
+
+static BOOL decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void **out)
+{
+ DATA_BLOB attr;
+ struct asn1_data data;
+ struct ldb_sort_resp_control *lsrc;
+
+ if (!asn1_load(&data, in)) {
+ return False;
+ }
+
+ lsrc = talloc(mem_ctx, struct ldb_sort_resp_control);
+ if (!lsrc) {
+ return False;
+ }
+
+ if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) {
+ return False;
+ }
+
+ 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)) {
+ return False;
+ }
+ lsrc->attr_desc = talloc_strndup(lsrc, attr.data, attr.length);
+ if (!lsrc->attr_desc) {
+ return False;
+ }
+ }
+
+ if (!asn1_end_tag(&data)) {
+ return False;
+ }
+
+ *out = lsrc;
+
+ return True;
+}
+
+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 ldb_server_sort_control **lssc;
+ int num;
+
+ if (!asn1_load(&data, in)) {
+ return False;
+ }
+
+ if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) {
+ return False;
+ }
+
+ lssc = NULL;
+
+ 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;
+ }
+ lssc[num] = talloc(lssc, struct ldb_server_sort_control);
+ if (!lssc[num]) {
+ return False;
+ }
+
+ if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) {
+ return False;
+ }
+
+ if (!asn1_read_OctetString(&data, &attr)) {
+ return False;
+ }
+
+ lssc[num]->attributeName = talloc_strndup(lssc[num], attr.data, attr.length);
+ if (!lssc [num]->attributeName) {
+ return False;
+ }
+
+ if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) {
+ if (!asn1_read_OctetString(&data, &rule)) {
+ return False;
+ }
+ lssc[num]->orderingRule = talloc_strndup(lssc[num], rule.data, rule.length);
+ if (!lssc[num]->orderingRule) {
+ return False;
+ }
+ }
+
+ if (asn1_peek_tag(&data, ASN1_BOOLEAN)) {
+ if (!asn1_read_BOOLEAN(&data, &(lssc[num]->reverse))) {
+ return False;
+ }
+ }
+
+ if (!asn1_end_tag(&data)) {
+ return False;
+ }
+ }
+
+ lssc[num] = NULL;
+
+ if (!asn1_end_tag(&data)) {
+ return False;
+ }
+
+ *out = lssc;
+
+ return True;
+}
+
+static BOOL decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out)
+{
+ struct asn1_data data;
+ struct ldb_extended_dn_control *ledc;
+
+ if (!asn1_load(&data, in)) {
+ return False;
+ }
+
+ ledc = talloc(mem_ctx, struct ldb_extended_dn_control);
+ if (!ledc) {
+ return False;
+ }
+
+ if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) {
+ return False;
+ }
+
+ if (!asn1_read_Integer(&data, &(ledc->type))) {
+ return False;
+ }
+
+ if (!asn1_end_tag(&data)) {
+ return False;
+ }
+
+ *out = ledc;
+
+ return True;
+}
+
+static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out)
+{
+ DATA_BLOB cookie;
+ struct asn1_data data;
+ struct ldb_paged_control *lprc;
+
+ if (!asn1_load(&data, in)) {
+ return False;
+ }
+
+ lprc = talloc(mem_ctx, struct ldb_paged_control);
+ if (!lprc) {
+ return False;
+ }
+
+ if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) {
+ return False;
+ }
+
+ if (!asn1_read_Integer(&data, &(lprc->size))) {
+ return False;
+ }
+
+ if (!asn1_read_OctetString(&data, &cookie)) {
+ return False;
+ }
+ lprc->cookie_len = cookie.length;
+ if (lprc->cookie_len) {
+ lprc->cookie = talloc_memdup(lprc, cookie.data, cookie.length);
+
+ if (!(lprc->cookie)) {
+ return False;
+ }
+ } else {
+ lprc->cookie = NULL;
+ }
+
+ if (!asn1_end_tag(&data)) {
+ return False;
+ }
+
+ *out = lprc;
+
+ return True;
+}
+
+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);
+
+ if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) {
+ return False;
+ }
+
+ 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))) {
+ 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;
+ }
+
+ return True;
+}
+
+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;
+ int num;
+
+ ZERO_STRUCT(data);
+
+ if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) {
+ return False;
+ }
+
+ for (num = 0; lssc[num]; num++) {
+ if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) {
+ return False;
+ }
+
+ 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))) {
+ return False;
+ }
+ }
+
+ if (lssc[num]->reverse) {
+ if (!asn1_write_BOOLEAN(&data, lssc[num]->reverse)) {
+ return False;
+ }
+ }
+
+ if (!asn1_pop_tag(&data)) {
+ 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;
+ }
+
+ return True;
+}
+
+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);
+
+ if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) {
+ return False;
+ }
+
+ if (!asn1_write_Integer(&data, ledc->type)) {
+ 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;
+ }
+
+ return True;
+}
+
+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;
+
+ ZERO_STRUCT(data);
+
+ if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) {
+ return False;
+ }
+
+ if (!asn1_write_Integer(&data, lprc->size)) {
+ return False;
+ }
+
+ if (!asn1_write_OctetString(&data, lprc->cookie, lprc->cookie_len)) {
+ 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;
+ }
+
+ 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 },
+ { "1.2.840.113556.1.4.473", decode_server_sort_request, encode_server_sort_request },
+ { "1.2.840.113556.1.4.474", decode_server_sort_response, encode_server_sort_response },
+ { NULL, NULL, NULL }
+};
+
+BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Control *ctrl)
+{
+ int i;
+ DATA_BLOB oid;
+ DATA_BLOB value;
+
+ if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
+ return False;
+ }
+
+ if (!asn1_read_OctetString(data, &oid)) {
+ return False;
+ }
+ ctrl->oid = talloc_strndup(mem_ctx, (char *)oid.data, oid.length);
+ if (!(ctrl->oid)) {
+ return False;
+ }
+
+ if (asn1_peek_tag(data, ASN1_BOOLEAN)) {
+ if (!asn1_read_BOOLEAN(data, &(ctrl->critical))) {
+ return False;
+ }
+ } else {
+ ctrl->critical = False;
+ }
+
+ ctrl->value = NULL;
+
+ for (i = 0; ldap_known_controls[i].oid != NULL; i++) {
+ if (strcmp(ldap_known_controls[i].oid, ctrl->oid) == 0) {
+
+ if (!asn1_read_OctetString(data, &value)) {
+ return False;
+ }
+ if (!ldap_known_controls[i].decode(mem_ctx, value, &(ctrl->value))) {
+ return False;
+ }
+ break;
+ }
+ }
+ if (ldap_known_controls[i].oid == NULL) {
+ return False;
+ }
+
+ if (!asn1_end_tag(data)) {
+ return False;
+ }
+
+ return True;
+}
+
+BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Control *ctrl)
+{
+ DATA_BLOB value;
+ int i;
+
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
+ return False;
+ }
+
+ if (!asn1_write_OctetString(data, ctrl->oid, strlen(ctrl->oid))) {
+ return False;
+ }
+
+ if (ctrl->critical) {
+ if (!asn1_write_BOOLEAN(data, ctrl->critical)) {
+ return False;
+ }
+ }
+
+ for (i = 0; ldap_known_controls[i].oid != NULL; i++) {
+ if (strcmp(ldap_known_controls[i].oid, ctrl->oid) == 0) {
+ if (!ldap_known_controls[i].encode(mem_ctx, ctrl->value, &value)) {
+ return False;
+ }
+ break;
+ }
+ }
+ if (ldap_known_controls[i].oid == NULL) {
+ return False;
+ }
+
+ if (value.length != 0) {
+ if (!asn1_write_OctetString(data, value.data, value.length)) {
+ return False;
+ }
+ }
+
+ if (!asn1_pop_tag(data)) {
+ return False;
+ }
+
+ return True;
+}
diff --git a/source4/libcli/ldap/ldap_ildap.c b/source4/libcli/ldap/ldap_ildap.c
index f29685a67c..a5227ec37f 100644
--- a/source4/libcli/ldap/ldap_ildap.c
+++ b/source4/libcli/ldap/ldap_ildap.c
@@ -22,6 +22,7 @@
*/
#include "includes.h"
+#include "libcli/ldap/ldap.h"
#include "libcli/ldap/ldap_client.h"
/*
@@ -156,6 +157,8 @@ int ildap_count_entries(struct ldap_connection *conn, struct ldap_message **res)
NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn,
int scope, struct ldb_parse_tree *tree,
const char * const *attrs, BOOL attributesonly,
+ struct ldap_Control **control_req,
+ struct ldap_Control ***control_res,
struct ldap_message ***results)
{
struct ldap_message *msg;
@@ -163,6 +166,8 @@ NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn,
NTSTATUS status;
struct ldap_request *req;
+ if (control_res)
+ *control_res = NULL;
*results = NULL;
msg = new_ldap_message(conn);
@@ -180,6 +185,7 @@ NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn,
msg->r.SearchRequest.tree = tree;
msg->r.SearchRequest.num_attributes = n;
msg->r.SearchRequest.attributes = discard_const(attrs);
+ msg->controls = control_req;
req = ldap_request_send(conn, msg);
talloc_steal(msg, req);
@@ -191,6 +197,9 @@ NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn,
if (res->type == LDAP_TAG_SearchResultDone) {
status = ldap_check_response(conn, &res->r.GeneralResult);
+ if (control_res) {
+ *control_res = talloc_steal(conn, res->controls);
+ }
break;
}
@@ -219,12 +228,15 @@ NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn,
NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn,
int scope, const char *expression,
const char * const *attrs, BOOL attributesonly,
+ struct ldap_Control **control_req,
+ struct ldap_Control ***control_res,
struct ldap_message ***results)
{
struct ldb_parse_tree *tree = ldb_parse_tree(conn, expression);
NTSTATUS status;
status = ildap_search_bytree(conn, basedn, scope, tree, attrs,
- attributesonly, results);
+ attributesonly, control_req,
+ control_res, results);
talloc_free(tree);
return status;
}
diff --git a/source4/libcli/ldap/ldap_msg.c b/source4/libcli/ldap/ldap_msg.c
index c77d9eb356..d74aa500ca 100644
--- a/source4/libcli/ldap/ldap_msg.c
+++ b/source4/libcli/ldap/ldap_msg.c
@@ -23,12 +23,13 @@
*/
#include "includes.h"
+#include "libcli/ldap/ldap.h"
#include "libcli/ldap/ldap_client.h"
struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx)
{
- return talloc(mem_ctx, struct ldap_message);
+ return talloc_zero(mem_ctx, struct ldap_message);
}
diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c
index 1d5e4ccf20..0cccdbe971 100644
--- a/source4/libcli/ldap/ldap_ndr.c
+++ b/source4/libcli/ldap/ldap_ndr.c
@@ -23,6 +23,7 @@
#include "includes.h"
#include "libcli/ldap/ldap.h"
+#include "librpc/gen_ndr/ndr_security.h"
#include "librpc/gen_ndr/ndr_misc.h"
/*