mirror of
https://github.com/samba-team/samba.git
synced 2025-11-02 20:23:50 +03:00
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 commit is contained in:
committed by
Gerald (Jerry) Carter
parent
708ce7de30
commit
77125feaff
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)));
|
||||
|
||||
@@ -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"
|
||||
|
||||
470
source/libcli/ldap/ldap_controls.c
Normal file
470
source/libcli/ldap/ldap_controls.c
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user