1
0
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:
Simo Sorce
2006-01-06 04:01:23 +00:00
committed by Gerald (Jerry) Carter
parent 708ce7de30
commit 77125feaff
53 changed files with 1870 additions and 100 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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"

View File

@@ -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)));

View File

@@ -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"

View 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;
}

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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"
/*