From fa8d37adae70a5f479262b722e47aa7fc21aaf5c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 12 Aug 2004 04:55:59 +0000 Subject: r1756: merge volkers ldap client lib to samba4 for simo to start with the ldap server code it's not compiled in yet... metze (This used to be commit 48939adca1332ff90f9287311c0e9ff3e2e5917a) --- source4/libcli/ldap/config.m4 | 1 + source4/libcli/ldap/config.mk | 6 + source4/libcli/ldap/ldap.c | 1989 +++++++++++++++++++++++++++++++++++++++++ source4/libcli/ldap/ldap.h | 246 +++++ 4 files changed, 2242 insertions(+) create mode 100644 source4/libcli/ldap/config.m4 create mode 100644 source4/libcli/ldap/config.mk create mode 100644 source4/libcli/ldap/ldap.c create mode 100644 source4/libcli/ldap/ldap.h (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.m4 b/source4/libcli/ldap/config.m4 new file mode 100644 index 0000000000..01f78279bf --- /dev/null +++ b/source4/libcli/ldap/config.m4 @@ -0,0 +1 @@ +SMB_SUBSYSTEM_MK(LIBCLI_LDAP,libcli/ldap/config.mk) diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk new file mode 100644 index 0000000000..397cfe0b72 --- /dev/null +++ b/source4/libcli/ldap/config.mk @@ -0,0 +1,6 @@ +################################# +# Start SUBSYSTEM LIBCLI_LDAP +[SUBSYSTEM::LIBCLI_LDAP] +ADD_OBJ_FILES = libcli/ldap/ldap.o +# End SUBSYSTEM LIBCLI_LDAP +################################# diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c new file mode 100644 index 0000000000..38fff7e357 --- /dev/null +++ b/source4/libcli/ldap/ldap.c @@ -0,0 +1,1989 @@ +/* + Unix SMB/CIFS mplementation. + LDAP protocol helper functions for SAMBA + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Volker Lendecke 2004 + + 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 "smb_ldap.h" + +/**************************************************************************** + * + * LDAP filter parser -- main routine is ldb_parse_filter + * + * Shamelessly stolen and adapted from Samba 4. + * + ***************************************************************************/ + +/* Hmm. A blob might be more appropriate here :-) */ + +struct ldb_val { + unsigned int length; + void *data; +}; + +enum ldb_parse_op {LDB_OP_SIMPLE, LDB_OP_AND, LDB_OP_OR, LDB_OP_NOT}; + +struct ldb_parse_tree { + enum ldb_parse_op operation; + union { + struct { + char *attr; + struct ldb_val value; + } simple; + struct { + unsigned int num_elements; + struct ldb_parse_tree **elements; + } list; + struct { + struct ldb_parse_tree *child; + } not; + } u; +}; + +#define LDB_ALL_SEP "()&|=!" + +/* + return next token element. Caller frees +*/ +static char *ldb_parse_lex(TALLOC_CTX *mem_ctx, const char **s, + const char *sep) +{ + const char *p = *s; + char *ret; + + while (isspace(*p)) { + p++; + } + *s = p; + + if (*p == 0) { + return NULL; + } + + if (strchr(sep, *p)) { + (*s) = p+1; + ret = talloc_strndup(mem_ctx, p, 1); + if (!ret) { + errno = ENOMEM; + } + return ret; + } + + while (*p && (isalnum(*p) || !strchr(sep, *p))) { + p++; + } + + if (p == *s) { + return NULL; + } + + ret = talloc_strndup(mem_ctx, *s, p - *s); + if (!ret) { + errno = ENOMEM; + } + + *s = p; + + return ret; +} + + +/* + find a matching close brace in a string +*/ +static const char *match_brace(const char *s) +{ + unsigned int count = 0; + while (*s && (count != 0 || *s != ')')) { + if (*s == '(') { + count++; + } + if (*s == ')') { + count--; + } + s++; + } + if (! *s) { + return NULL; + } + return s; +} + +static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, + const char **s); + +/* + ::= +*/ +static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *mem_ctx, + const char *s) +{ + char *eq, *val, *l; + struct ldb_parse_tree *ret; + + l = ldb_parse_lex(mem_ctx, &s, LDB_ALL_SEP); + if (!l) { + return NULL; + } + + if (strchr("()&|=", *l)) + return NULL; + + eq = ldb_parse_lex(mem_ctx, &s, LDB_ALL_SEP); + if (!eq || strcmp(eq, "=") != 0) + return NULL; + + val = ldb_parse_lex(mem_ctx, &s, ")"); + if (val && strchr("()&|", *val)) + return NULL; + + ret = talloc(mem_ctx, sizeof(*ret)); + if (!ret) { + errno = ENOMEM; + return NULL; + } + + ret->operation = LDB_OP_SIMPLE; + ret->u.simple.attr = l; + ret->u.simple.value.data = val; + ret->u.simple.value.length = val?strlen(val):0; + + return ret; +} + + +/* + parse a filterlist + ::= '&' + ::= '|' + ::= | +*/ +static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *mem_ctx, + enum ldb_parse_op op, + const char *s) +{ + struct ldb_parse_tree *ret, *next; + + ret = talloc(mem_ctx, sizeof(*ret)); + + if (!ret) { + errno = ENOMEM; + return NULL; + } + + ret->operation = op; + ret->u.list.num_elements = 1; + ret->u.list.elements = talloc(mem_ctx, sizeof(*ret->u.list.elements)); + if (!ret->u.list.elements) { + errno = ENOMEM; + return NULL; + } + + ret->u.list.elements[0] = ldb_parse_filter(mem_ctx, &s); + if (!ret->u.list.elements[0]) { + return NULL; + } + + while (isspace(*s)) s++; + + while (*s && (next = ldb_parse_filter(mem_ctx, &s))) { + struct ldb_parse_tree **e; + e = talloc_realloc(mem_ctx, ret->u.list.elements, + sizeof(struct ldb_parse_tree) * + (ret->u.list.num_elements+1)); + if (!e) { + errno = ENOMEM; + return NULL; + } + ret->u.list.elements = e; + ret->u.list.elements[ret->u.list.num_elements] = next; + ret->u.list.num_elements++; + while (isspace(*s)) s++; + } + + return ret; +} + + +/* + ::= '!' +*/ +static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *mem_ctx, const char *s) +{ + struct ldb_parse_tree *ret; + + ret = talloc(mem_ctx, sizeof(*ret)); + if (!ret) { + errno = ENOMEM; + return NULL; + } + + ret->operation = LDB_OP_NOT; + ret->u.not.child = ldb_parse_filter(mem_ctx, &s); + if (!ret->u.not.child) + return NULL; + + return ret; +} + +/* + parse a filtercomp + ::= | | | +*/ +static struct ldb_parse_tree *ldb_parse_filtercomp(TALLOC_CTX *mem_ctx, + const char *s) +{ + while (isspace(*s)) s++; + + switch (*s) { + case '&': + return ldb_parse_filterlist(mem_ctx, LDB_OP_AND, s+1); + + case '|': + return ldb_parse_filterlist(mem_ctx, LDB_OP_OR, s+1); + + case '!': + return ldb_parse_not(mem_ctx, s+1); + + case '(': + case ')': + return NULL; + } + + return ldb_parse_simple(mem_ctx, s); +} + + +/* + ::= '(' ')' +*/ +static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, + const char **s) +{ + char *l, *s2; + const char *p, *p2; + struct ldb_parse_tree *ret; + + l = ldb_parse_lex(mem_ctx, s, LDB_ALL_SEP); + if (!l) { + return NULL; + } + + if (strcmp(l, "(") != 0) { + return NULL; + } + + p = match_brace(*s); + if (!p) { + return NULL; + } + p2 = p + 1; + + s2 = talloc_strndup(mem_ctx, *s, p - *s); + if (!s2) { + errno = ENOMEM; + return NULL; + } + + ret = ldb_parse_filtercomp(mem_ctx, s2); + + *s = p2; + + return ret; +} + +/* + main parser entry point. Takes a search string and returns a parse tree + + expression ::= | +*/ +static struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s) +{ + while (isspace(*s)) s++; + + if (*s == '(') { + return ldb_parse_filter(mem_ctx, &s); + } + + return ldb_parse_simple(mem_ctx, s); +} + +static BOOL ldap_push_filter(ASN1_DATA *data, struct ldb_parse_tree *tree) +{ + switch (tree->operation) { + case LDB_OP_SIMPLE: { + if ((tree->u.simple.value.length == 1) && + (((char *)(tree->u.simple.value.data))[0] == '*')) { + /* Just a presence test */ + asn1_push_tag(data, 0x87); + asn1_write(data, tree->u.simple.attr, + strlen(tree->u.simple.attr)); + asn1_pop_tag(data); + return !data->has_error; + } + + /* Equality is all we currently do... */ + asn1_push_tag(data, 0xa3); + asn1_write_OctetString(data, tree->u.simple.attr, + strlen(tree->u.simple.attr)); + asn1_write_OctetString(data, tree->u.simple.value.data, + tree->u.simple.value.length); + asn1_pop_tag(data); + break; + } + + case LDB_OP_AND: { + int i; + + asn1_push_tag(data, 0xa0); + for (i=0; iu.list.num_elements; i++) { + ldap_push_filter(data, tree->u.list.elements[i]); + } + asn1_pop_tag(data); + break; + } + + case LDB_OP_OR: { + int i; + + asn1_push_tag(data, 0xa1); + for (i=0; iu.list.num_elements; i++) { + ldap_push_filter(data, tree->u.list.elements[i]); + } + asn1_pop_tag(data); + break; + } + default: + return False; + } + return !data->has_error; +} + +/**************************************************************************** + * + * LDIF parser + * + * Shamelessly stolen and adapted from Samba 4. + * + ***************************************************************************/ + +/* + pull a ldif chunk, which is defined as a piece of data ending in \n\n or EOF + this routine removes any RFC2849 continuations and comments + + caller frees +*/ +static char *next_chunk(TALLOC_CTX *mem_ctx, + int (*fgetc_fn)(void *), void *private_data) +{ + size_t alloc_size=0, chunk_size = 0; + char *chunk = NULL; + int c; + int in_comment = 0; + + while ((c = fgetc_fn(private_data)) != EOF) { + if (chunk_size+1 >= alloc_size) { + char *c2; + alloc_size += 1024; + c2 = talloc_realloc(mem_ctx, chunk, alloc_size); + if (!c2) { + errno = ENOMEM; + return NULL; + } + chunk = c2; + } + + if (in_comment) { + if (c == '\n') { + in_comment = 0; + } + continue; + } + + /* handle continuation lines - see RFC2849 */ + if (c == ' ' && chunk_size > 1 && + chunk[chunk_size-1] == '\n') { + chunk_size--; + continue; + } + + /* chunks are terminated by a double line-feed */ + if (c == '\n' && chunk_size > 0 && + chunk[chunk_size-1] == '\n') { + chunk[chunk_size-1] = 0; + return chunk; + } + + if (c == '#' && + (chunk_size == 0 || chunk[chunk_size-1] == '\n')) { + in_comment = 1; + continue; + } + + /* ignore leading blank lines */ + if (chunk_size == 0 && c == '\n') { + continue; + } + + chunk[chunk_size++] = c; + } + + if (chunk) { + chunk[chunk_size] = 0; + } + + return chunk; +} + +/* simple ldif attribute parser */ +static int next_attr(char **s, const char **attr, struct ldb_val *value) +{ + char *p; + int base64_encoded = 0; + + if (strncmp(*s, "-\n", 2) == 0) { + value->length = 0; + *attr = "-"; + *s += 2; + return 0; + } + + p = strchr(*s, ':'); + if (!p) { + return -1; + } + + *p++ = 0; + + if (*p == ':') { + base64_encoded = 1; + p++; + } + + *attr = *s; + + while (isspace(*p)) { + p++; + } + + value->data = p; + + p = strchr(p, '\n'); + + if (!p) { + value->length = strlen((char *)value->data); + *s = ((char *)value->data) + value->length; + } else { + value->length = p - (char *)value->data; + *s = p+1; + *p = 0; + } + + if (base64_encoded) { + DATA_BLOB blob = base64_decode_data_blob(value->data); + memcpy(value->data, blob.data, blob.length); + value->length = blob.length; + ((char *)value->data)[value->length] = '\0'; + } + + return 0; +} + +static BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, + struct ldap_attribute *attrib) +{ + attrib->values = talloc_realloc(mem_ctx, attrib->values, + sizeof(*attrib->values) * + (attrib->num_values+1)); + if (attrib->values == NULL) + return False; + + attrib->values[attrib->num_values] = + data_blob_talloc(mem_ctx, value->data, value->length); + attrib->num_values += 1; + return True; +} + +static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) +{ + struct ldap_AddRequest *r = &msg->r.AddRequest; + const char *attr_name; + struct ldb_val value; + + r->num_attributes = 0; + r->attributes = NULL; + + while (next_attr(chunk, &attr_name, &value) == 0) { + int i; + struct ldap_attribute *attrib = NULL; + + for (i=0; inum_attributes; i++) { + if (strequal(r->attributes[i].name, attr_name)) { + attrib = &r->attributes[i]; + break; + } + } + + if (attrib == NULL) { + r->attributes = talloc_realloc(msg->mem_ctx, + r->attributes, + sizeof(*r->attributes) * + (r->num_attributes+1)); + if (r->attributes == NULL) + return False; + + attrib = &(r->attributes[r->num_attributes]); + r->num_attributes += 1; + ZERO_STRUCTP(attrib); + attrib->name = talloc_strdup(msg->mem_ctx, + attr_name); + } + + if (!add_value_to_attrib(msg->mem_ctx, &value, attrib)) + return False; + } + return True; +} + +static BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, + struct ldap_mod *mod, + struct ldap_mod **mods, + int *num_mods) +{ + *mods = talloc_realloc(mem_ctx, *mods, + sizeof(**mods) * ((*num_mods)+1)); + + if (*mods == NULL) + return False; + + (*mods)[*num_mods] = *mod; + *num_mods += 1; + return True; +} + +static BOOL fill_mods(struct ldap_message *msg, char **chunk) +{ + struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; + const char *attr_name; + struct ldb_val value; + + r->num_mods = 0; + r->mods = NULL; + + while (next_attr(chunk, &attr_name, &value) == 0) { + + struct ldap_mod mod; + mod.type = LDAP_MODIFY_NONE; + + mod.attrib.name = talloc_strdup(msg->mem_ctx, value.data); + + if (strequal(attr_name, "add")) + mod.type = LDAP_MOD_ADD; + + if (strequal(attr_name, "delete")) + mod.type = LDAP_MOD_DELETE; + + if (strequal(attr_name, "replace")) + mod.type = LDAP_MOD_REPLACE; + + if (mod.type == LDAP_MODIFY_NONE) { + DEBUG(2, ("ldif modification type %s unsupported\n", + attr_name)); + return False; + } + + mod.attrib.num_values = 0; + mod.attrib.values = NULL; + + while (next_attr(chunk, &attr_name, &value) == 0) { + if (strequal(attr_name, "-")) + break; + if (!strequal(attr_name, mod.attrib.name)) { + DEBUG(3, ("attrib name %s does not " + "match %s\n", attr_name, + mod.attrib.name)); + return False; + } + if (!add_value_to_attrib(msg->mem_ctx, &value, + &mod.attrib)) { + DEBUG(3, ("Could not add value\n")); + return False; + } + } + + if (!add_mod_to_array_talloc(msg->mem_ctx, &mod, &r->mods, + &r->num_mods)) + return False; + } + + return True; +} + +/* + read from a LDIF source, creating a ldap_message +*/ +static struct ldap_message *ldif_read(int (*fgetc_fn)(void *), + void *private_data) +{ + struct ldap_message *msg; + const char *attr=NULL; + const char *dn; + char *chunk=NULL, *s; + struct ldb_val value; + + value.data = NULL; + + msg = new_ldap_message(); + if (msg == NULL) + return NULL; + + chunk = next_chunk(msg->mem_ctx, fgetc_fn, private_data); + if (!chunk) { + goto failed; + } + + s = chunk; + + if (next_attr(&s, &attr, &value) != 0) { + goto failed; + } + + /* first line must be a dn */ + if (!strequal(attr, "dn")) { + DEBUG(5, ("Error: First line of ldif must be a dn not '%s'\n", + attr)); + goto failed; + } + + dn = talloc_strdup(msg->mem_ctx, value.data); + + if (next_attr(&s, &attr, &value) != 0) { + goto failed; + } + + if (!strequal(attr, "changetype")) { + DEBUG(5, ("Error: Second line of ldif must be a changetype " + "not '%s'\n", attr)); + goto failed; + } + + if (strequal(value.data, "delete")) { + msg->type = LDAP_TAG_DelRequest; + msg->r.DelRequest.dn = dn; + return msg; + } + + if (strequal(value.data, "add")) { + msg->type = LDAP_TAG_AddRequest; + + msg->r.AddRequest.dn = dn; + + if (!fill_add_attributes(msg, &s)) + goto failed; + + return msg; + } + + if (strequal(value.data, "modify")) { + msg->type = LDAP_TAG_ModifyRequest; + + msg->r.ModifyRequest.dn = dn; + + if (!fill_mods(msg, &s)) + goto failed; + + return msg; + } + + DEBUG(3, ("changetype %s not supported\n", (char *)value.data)); + +failed: + destroy_ldap_message(msg); + return NULL; +} + +/* + a wrapper around ldif_read() for reading from const char* +*/ +struct ldif_read_string_state { + const char *s; +}; + +static int fgetc_string(void *private_data) +{ + struct ldif_read_string_state *state = private_data; + if (state->s[0] != 0) { + return *state->s++; + } + return EOF; +} + +struct ldap_message *ldap_ldif2msg(const char *s) +{ + struct ldif_read_string_state state; + state.s = s; + return ldif_read(fgetc_string, &state); +} + +static void ldap_encode_response(enum ldap_request_tag tag, + struct ldap_Result *result, + ASN1_DATA *data) +{ + asn1_push_tag(data, ASN1_APPLICATION(tag)); + asn1_write_enumerated(data, result->resultcode); + asn1_write_OctetString(data, result->dn, + (result->dn) ? strlen(result->dn) : 0); + asn1_write_OctetString(data, result->errormessage, + (result->errormessage) ? + strlen(result->errormessage) : 0); + if (result->referral != NULL) + asn1_write_OctetString(data, result->referral, + strlen(result->referral)); + asn1_pop_tag(data); +} + +BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) +{ + ASN1_DATA data; + int i, j; + + ZERO_STRUCT(data); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_write_Integer(&data, msg->messageid); + + switch (msg->type) { + case LDAP_TAG_BindRequest: { + struct ldap_BindRequest *r = &msg->r.BindRequest; + asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_BindRequest)); + asn1_write_Integer(&data, r->version); + asn1_write_OctetString(&data, r->dn, + (r->dn != NULL) ? strlen(r->dn) : 0); + + switch (r->mechanism) { + case LDAP_AUTH_MECH_SIMPLE: + /* context, primitive */ + asn1_push_tag(&data, r->mechanism | 0x80); + asn1_write(&data, r->creds.password, + strlen(r->creds.password)); + asn1_pop_tag(&data); + break; + case LDAP_AUTH_MECH_SASL: + /* context, constructed */ + asn1_push_tag(&data, r->mechanism | 0xa0); + asn1_write_OctetString(&data, r->creds.SASL.mechanism, + strlen(r->creds.SASL.mechanism)); + asn1_write_OctetString(&data, r->creds.SASL.creds.data, + r->creds.SASL.creds.length); + asn1_pop_tag(&data); + break; + default: + return False; + } + + asn1_pop_tag(&data); + asn1_pop_tag(&data); + break; + } + case LDAP_TAG_BindResponse: { + struct ldap_BindResponse *r = &msg->r.BindResponse; + ldap_encode_response(msg->type, &r->response, &data); + break; + } + case LDAP_TAG_UnbindRequest: { +/* struct ldap_UnbindRequest *r = &msg->r.UnbindRequest; */ + break; + } + case LDAP_TAG_SearchRequest: { + struct ldap_SearchRequest *r = &msg->r.SearchRequest; + asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_SearchRequest)); + asn1_write_OctetString(&data, r->basedn, strlen(r->basedn)); + asn1_write_enumerated(&data, r->scope); + asn1_write_enumerated(&data, r->deref); + asn1_write_Integer(&data, r->sizelimit); + asn1_write_Integer(&data, r->timelimit); + asn1_write_BOOLEAN2(&data, r->attributesonly); + + { + TALLOC_CTX *mem_ctx = talloc_init("ldb_parse_tree"); + struct ldb_parse_tree *tree; + + if (mem_ctx == NULL) + return False; + + tree = ldb_parse_tree(mem_ctx, r->filter); + + if (tree == NULL) + return False; + + ldap_push_filter(&data, tree); + + talloc_destroy(mem_ctx); + } + + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + for (i=0; inum_attributes; i++) { + asn1_write_OctetString(&data, r->attributes[i], + strlen(r->attributes[i])); + } + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + break; + } + case LDAP_TAG_SearchResultEntry: { + struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; + asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_SearchResultEntry)); + asn1_write_OctetString(&data, r->dn, strlen(r->dn)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + for (i=0; inum_attributes; i++) { + struct ldap_attribute *attr = &r->attributes[i]; + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(&data, attr->name, + strlen(attr->name)); + asn1_push_tag(&data, ASN1_SEQUENCE(1)); + for (j=0; jnum_values; j++) { + asn1_write_OctetString(&data, + attr->values[j].data, + attr->values[j].length); + } + asn1_pop_tag(&data); + asn1_pop_tag(&data); + } + asn1_pop_tag(&data); + asn1_pop_tag(&data); + break; + } + case LDAP_TAG_SearchResultDone: { + struct ldap_SearchResultDone *r = &msg->r.SearchResultDone; + ldap_encode_response(msg->type, r, &data); + break; + } + case LDAP_TAG_ModifyRequest: { + struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; + asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest)); + asn1_write_OctetString(&data, r->dn, strlen(r->dn)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + + for (i=0; inum_mods; i++) { + struct ldap_attribute *attrib = &r->mods[i].attrib; + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_write_enumerated(&data, r->mods[i].type); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(&data, attrib->name, + strlen(attrib->name)); + asn1_push_tag(&data, ASN1_SET); + for (j=0; jnum_values; j++) { + asn1_write_OctetString(&data, + attrib->values[j].data, + attrib->values[j].length); + + } + asn1_pop_tag(&data); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + } + + asn1_pop_tag(&data); + asn1_pop_tag(&data); + break; + } + case LDAP_TAG_ModifyResponse: { + struct ldap_Result *r = &msg->r.ModifyResponse; + ldap_encode_response(msg->type, r, &data); + break; + } + case LDAP_TAG_AddRequest: { + struct ldap_AddRequest *r = &msg->r.AddRequest; + asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_AddRequest)); + asn1_write_OctetString(&data, r->dn, strlen(r->dn)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + + for (i=0; inum_attributes; i++) { + struct ldap_attribute *attrib = &r->attributes[i]; + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(&data, attrib->name, + strlen(attrib->name)); + asn1_push_tag(&data, ASN1_SET); + for (j=0; jattributes[i].num_values; j++) { + asn1_write_OctetString(&data, + attrib->values[j].data, + attrib->values[j].length); + } + asn1_pop_tag(&data); + asn1_pop_tag(&data); + } + asn1_pop_tag(&data); + asn1_pop_tag(&data); + break; + } + case LDAP_TAG_AddResponse: { + struct ldap_Result *r = &msg->r.AddResponse; + ldap_encode_response(msg->type, r, &data); + break; + } + case LDAP_TAG_DelRequest: { + struct ldap_DelRequest *r = &msg->r.DelRequest; + asn1_push_tag(&data, + ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); + asn1_write(&data, r->dn, strlen(r->dn)); + asn1_pop_tag(&data); + break; + } + case LDAP_TAG_DelResponse: { + struct ldap_Result *r = &msg->r.DelResponse; + ldap_encode_response(msg->type, r, &data); + break; + } + case LDAP_TAG_ModifyDNRequest: { + struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; + asn1_push_tag(&data, + ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest)); + asn1_write_OctetString(&data, r->dn, strlen(r->dn)); + asn1_write_OctetString(&data, r->newrdn, strlen(r->newrdn)); + asn1_write_BOOLEAN2(&data, r->deleteolddn); + if (r->newsuperior != NULL) { + asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(&data, r->newsuperior, + strlen(r->newsuperior)); + asn1_pop_tag(&data); + } + asn1_pop_tag(&data); + break; + } + case LDAP_TAG_ModifyDNResponse: { +/* struct ldap_Result *r = &msg->r.ModifyDNResponse; */ + break; + } + case LDAP_TAG_CompareRequest: { + struct ldap_CompareRequest *r = &msg->r.CompareRequest; + asn1_push_tag(&data, + ASN1_APPLICATION(LDAP_TAG_CompareRequest)); + asn1_write_OctetString(&data, r->dn, strlen(r->dn)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(&data, r->attribute, + strlen(r->attribute)); + asn1_write_OctetString(&data, r->value, + strlen(r->value)); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + break; + } + case LDAP_TAG_CompareResponse: { +/* struct ldap_Result *r = &msg->r.CompareResponse; */ + break; + } + case LDAP_TAG_AbandonRequest: { + struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; + asn1_push_tag(&data, + ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest)); + asn1_write_Integer(&data, r->messageid); + asn1_pop_tag(&data); + break; + } + case LDAP_TAG_SearchResultReference: { +/* struct ldap_SearchResRef *r = &msg->r.SearchResultReference; */ + break; + } + case LDAP_TAG_ExtendedRequest: { + struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; + asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_ExtendedRequest)); + asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(&data, r->oid, strlen(r->oid)); + asn1_pop_tag(&data); + asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(1)); + asn1_write(&data, r->value.data, r->value.length); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + break; + } + case LDAP_TAG_ExtendedResponse: { + struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; + ldap_encode_response(msg->type, &r->response, &data); + break; + } + default: + return False; + } + + asn1_pop_tag(&data); + *result = data_blob(data.data, data.length); + asn1_free(&data); + return True; +} + +static const char *blob2string_talloc(TALLOC_CTX *mem_ctx, + DATA_BLOB blob) +{ + char *result = talloc(mem_ctx, blob.length+1); + memcpy(result, blob.data, blob.length); + result[blob.length] = '\0'; + return result; +} + +static BOOL asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, + ASN1_DATA *data, + const char **result) +{ + DATA_BLOB string; + if (!asn1_read_OctetString(data, &string)) + return False; + *result = blob2string_talloc(mem_ctx, string); + data_blob_free(&string); + return True; +} + +static void ldap_decode_response(TALLOC_CTX *mem_ctx, + ASN1_DATA *data, + enum ldap_request_tag tag, + struct ldap_Result *result) +{ + asn1_start_tag(data, ASN1_APPLICATION(tag)); + asn1_read_enumerated(data, &result->resultcode); + asn1_read_OctetString_talloc(mem_ctx, data, &result->dn); + asn1_read_OctetString_talloc(mem_ctx, data, &result->errormessage); + if (asn1_peek_tag(data, ASN1_OCTET_STRING)) + asn1_read_OctetString_talloc(mem_ctx, data, &result->referral); + else + result->referral = NULL; + asn1_end_tag(data); +} + +static BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, + const struct ldap_attribute *attrib, + struct ldap_attribute **attribs, + int *num_attribs) +{ + *attribs = talloc_realloc(mem_ctx, *attribs, + sizeof(**attribs) * (*num_attribs+1)); + + if (*attribs == NULL) + return False; + + (*attribs)[*num_attribs] = *attrib; + *num_attribs += 1; + return True; +} + +static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, ASN1_DATA *data, + char **filter) +{ + uint8 filter_tag, tag_desc; + + if (!asn1_peek_uint8(data, &filter_tag)) + return False; + + tag_desc = filter_tag; + filter_tag &= 0x1f; /* strip off the asn1 stuff */ + tag_desc &= 0xe0; + + switch(filter_tag) { + case 0: { + /* AND of one or more filters */ + if (tag_desc != 0xa0) /* context compount */ + return False; + + asn1_start_tag(data, ASN1_CONTEXT(0)); + + *filter = talloc_strdup(mem_ctx, "(&"); + if (*filter == NULL) + return False; + + while (asn1_tag_remaining(data) > 0) { + char *subfilter; + if (!ldap_decode_filter(mem_ctx, data, &subfilter)) + return False; + *filter = talloc_asprintf(mem_ctx, "%s%s", *filter, + subfilter); + if (*filter == NULL) + return False; + } + asn1_end_tag(data); + + *filter = talloc_asprintf(mem_ctx, "%s)", *filter); + break; + } + case 1: { + /* OR of one or more filters */ + if (tag_desc != 0xa0) /* context compount */ + return False; + + asn1_start_tag(data, ASN1_CONTEXT(1)); + + *filter = talloc_strdup(mem_ctx, "(|"); + if (*filter == NULL) + return False; + + while (asn1_tag_remaining(data) > 0) { + char *subfilter; + if (!ldap_decode_filter(mem_ctx, data, &subfilter)) + return False; + *filter = talloc_asprintf(mem_ctx, "%s%s", *filter, + subfilter); + if (*filter == NULL) + return False; + } + + asn1_end_tag(data); + + *filter = talloc_asprintf(mem_ctx, "%s)", *filter); + break; + } + case 3: { + /* equalityMatch */ + const char *attrib, *value; + if (tag_desc != 0xa0) /* context compound */ + return False; + asn1_start_tag(data, ASN1_CONTEXT(3)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString_talloc(mem_ctx, data, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value == NULL)) + return False; + *filter = talloc_asprintf(mem_ctx, "(%s=%s)", attrib, value); + break; + } + case 7: { + /* Normal presence, "attribute=*" */ + int attr_len; + char *attr_name; + if (tag_desc != 0x80) /* context simple */ + return False; + if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(7))) + return False; + attr_len = asn1_tag_remaining(data); + attr_name = malloc(attr_len+1); + if (attr_name == NULL) + return False; + asn1_read(data, attr_name, attr_len); + attr_name[attr_len] = '\0'; + *filter = talloc_asprintf(mem_ctx, "(%s=*)", attr_name); + SAFE_FREE(attr_name); + asn1_end_tag(data); + break; + } + default: + return False; + } + if (*filter == NULL) + return False; + return True; +} + +static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, ASN1_DATA *data, + struct ldap_attribute *attrib) +{ + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib->name); + asn1_start_tag(data, ASN1_SET); + while (asn1_peek_tag(data, ASN1_OCTET_STRING)) { + DATA_BLOB blob; + struct ldb_val value; + asn1_read_OctetString(data, &blob); + value.data = blob.data; + value.length = blob.length; + add_value_to_attrib(mem_ctx, &value, attrib); + data_blob_free(&blob); + } + asn1_end_tag(data); + asn1_end_tag(data); + +} + +static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, ASN1_DATA *data, + struct ldap_attribute **attributes, + int *num_attributes) +{ + asn1_start_tag(data, ASN1_SEQUENCE(0)); + while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { + struct ldap_attribute attrib; + ZERO_STRUCT(attrib); + ldap_decode_attrib(mem_ctx, data, &attrib); + add_attrib_to_array_talloc(mem_ctx, &attrib, + attributes, num_attributes); + } + asn1_end_tag(data); +} + +BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) +{ + uint8 tag; + + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_Integer(data, &msg->messageid); + + if (!asn1_peek_uint8(data, &tag)) + return False; + + switch(tag) { + + case ASN1_APPLICATION(LDAP_TAG_BindRequest): { + struct ldap_BindRequest *r = &msg->r.BindRequest; + msg->type = LDAP_TAG_BindRequest; + asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_BindRequest)); + asn1_read_Integer(data, &r->version); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); + if (asn1_peek_tag(data, 0x80)) { + int pwlen; + r->creds.password = ""; + /* Mechanism 0 (SIMPLE) */ + asn1_start_tag(data, 0x80); + pwlen = asn1_tag_remaining(data); + if (pwlen != 0) { + char *pw = talloc(msg->mem_ctx, pwlen+1); + asn1_read(data, pw, pwlen); + pw[pwlen] = '\0'; + r->creds.password = pw; + } + asn1_end_tag(data); + } + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_BindResponse): { + struct ldap_BindResponse *r = &msg->r.BindResponse; + msg->type = LDAP_TAG_BindResponse; + ldap_decode_response(msg->mem_ctx, + data, LDAP_TAG_BindResponse, + &r->response); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_UnbindRequest): { + msg->type = LDAP_TAG_UnbindRequest; + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchRequest): { + struct ldap_SearchRequest *r = &msg->r.SearchRequest; + msg->type = LDAP_TAG_SearchRequest; + asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_SearchRequest)); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->basedn); + asn1_read_enumerated(data, (int *)&(r->scope)); + asn1_read_enumerated(data, (int *)&(r->deref)); + asn1_read_Integer(data, &r->sizelimit); + asn1_read_Integer(data, &r->timelimit); + asn1_read_BOOLEAN2(data, &r->attributesonly); + + /* Maybe create a TALLOC_CTX for the filter? This can waste + * quite a bit of memory recursing down. */ + ldap_decode_filter(msg->mem_ctx, data, &r->filter); + + asn1_start_tag(data, ASN1_SEQUENCE(0)); + + r->num_attributes = 0; + r->attributes = NULL; + + while (asn1_tag_remaining(data) > 0) { + const char *attr; + if (!asn1_read_OctetString_talloc(msg->mem_ctx, data, + &attr)) + return False; + if (!add_string_to_array(msg->mem_ctx, attr, + &r->attributes, + &r->num_attributes)) + return False; + } + + asn1_end_tag(data); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchResultEntry): { + struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; + msg->type = LDAP_TAG_SearchResultEntry; + r->attributes = NULL; + r->num_attributes = 0; + asn1_start_tag(data, + ASN1_APPLICATION(LDAP_TAG_SearchResultEntry)); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); + ldap_decode_attribs(msg->mem_ctx, data, &r->attributes, + &r->num_attributes); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchResultDone): { + struct ldap_SearchResultDone *r = &msg->r.SearchResultDone; + msg->type = LDAP_TAG_SearchResultDone; + ldap_decode_response(msg->mem_ctx, data, + LDAP_TAG_SearchResultDone, r); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchResultReference): { +/* struct ldap_SearchResRef *r = &msg->r.SearchResultReference; */ + msg->type = LDAP_TAG_SearchResultReference; + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyRequest): { + struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; + msg->type = LDAP_TAG_ModifyRequest; + asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest)); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); + asn1_start_tag(data, ASN1_SEQUENCE(0)); + + r->num_mods = 0; + r->mods = NULL; + + while (asn1_tag_remaining(data) > 0) { + struct ldap_mod mod; + ZERO_STRUCT(mod); + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_enumerated(data, &mod.type); + ldap_decode_attrib(msg->mem_ctx, data, &mod.attrib); + asn1_end_tag(data); + if (!add_mod_to_array_talloc(msg->mem_ctx, &mod, + &r->mods, &r->num_mods)) + break; + } + + asn1_end_tag(data); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyResponse): { + struct ldap_ModifyResponse *r = &msg->r.ModifyResponse; + msg->type = LDAP_TAG_ModifyResponse; + ldap_decode_response(msg->mem_ctx, data, + LDAP_TAG_ModifyResponse, r); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_AddRequest): { + struct ldap_AddRequest *r = &msg->r.AddRequest; + msg->type = LDAP_TAG_AddRequest; + asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_AddRequest)); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); + + r->attributes = NULL; + r->num_attributes = 0; + ldap_decode_attribs(msg->mem_ctx, data, &r->attributes, + &r->num_attributes); + + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_AddResponse): { + struct ldap_AddResponse *r = &msg->r.AddResponse; + msg->type = LDAP_TAG_AddResponse; + ldap_decode_response(msg->mem_ctx, data, + LDAP_TAG_AddResponse, r); + break; + } + + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest): { + struct ldap_DelRequest *r = &msg->r.DelRequest; + int len; + char *dn; + msg->type = LDAP_TAG_DelRequest; + asn1_start_tag(data, + ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); + len = asn1_tag_remaining(data); + dn = talloc(msg->mem_ctx, len+1); + if (dn == NULL) + break; + asn1_read(data, dn, len); + dn[len] = '\0'; + r->dn = dn; + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_DelResponse): { + struct ldap_DelResponse *r = &msg->r.DelResponse; + msg->type = LDAP_TAG_DelResponse; + ldap_decode_response(msg->mem_ctx, data, + LDAP_TAG_DelResponse, r); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest): { +/* struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; */ + msg->type = LDAP_TAG_ModifyDNRequest; + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyDNResponse): { + struct ldap_ModifyDNResponse *r = &msg->r.ModifyDNResponse; + msg->type = LDAP_TAG_ModifyDNResponse; + ldap_decode_response(msg->mem_ctx, data, + LDAP_TAG_ModifyDNResponse, r); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_CompareRequest): { +/* struct ldap_CompareRequest *r = &msg->r.CompareRequest; */ + msg->type = LDAP_TAG_CompareRequest; + break; + } + + case ASN1_APPLICATION(LDAP_TAG_CompareResponse): { + struct ldap_CompareResponse *r = &msg->r.CompareResponse; + msg->type = LDAP_TAG_CompareResponse; + ldap_decode_response(msg->mem_ctx, data, + LDAP_TAG_CompareResponse, r); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_AbandonRequest): { +/* struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; */ + msg->type = LDAP_TAG_AbandonRequest; + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ExtendedRequest): { +/* struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; */ + msg->type = LDAP_TAG_ExtendedRequest; + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ExtendedResponse): { + struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; + msg->type = LDAP_TAG_ExtendedResponse; + ldap_decode_response(msg->mem_ctx, data, + LDAP_TAG_ExtendedResponse, &r->response); + /* I have to come across an operation that actually sends + * something back to really see what's going on. The currently + * needed pwdchange does not send anything back. */ + r->name = NULL; + r->value.data = NULL; + r->value.length = 0; + break; + } + + } + + asn1_end_tag(data); + return ((!data->has_error) && (data->nesting == NULL)); +} + +BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, + char **host, uint16 *port, BOOL *ldaps) +{ + int tmp_port = 0; + fstring protocol; + fstring tmp_host; + const char *p = url; + + /* skip leading "URL:" (if any) */ + if ( strnequal( p, "URL:", 4 ) ) { + p += 4; + } + + /* Paranoia check */ + SMB_ASSERT(sizeof(protocol)>10 && sizeof(tmp_host)>254); + + sscanf(p, "%10[^:]://%254[^:/]:%d", protocol, tmp_host, &tmp_port); + + if (strequal(protocol, "ldap")) { + *port = 389; + *ldaps = False; + } else if (strequal(protocol, "ldaps")) { + *port = 636; + *ldaps = True; + } else { + DEBUG(0, ("unrecognised protocol (%s)!\n", protocol)); + return False; + } + + if (tmp_port != 0) + *port = tmp_port; + + *host = talloc_strdup(mem_ctx, tmp_host); + + return (*host != NULL); +} + +struct ldap_connection *new_ldap_connection(void) +{ + TALLOC_CTX *mem_ctx = talloc_init("ldap_connection"); + struct ldap_connection *result; + + if (mem_ctx == NULL) + return NULL; + + result = talloc(mem_ctx, sizeof(*result)); + + if (result == NULL) + return NULL; + + result->mem_ctx = mem_ctx; + result->next_msgid = 1; + result->outstanding = NULL; + result->searchid = 0; + result->search_entries = NULL; + return result; +} + +BOOL ldap_connect(struct ldap_connection *conn, const char *url) +{ + struct hostent *hp; + struct in_addr ip; + + if (!ldap_parse_basic_url(conn->mem_ctx, url, &conn->host, + &conn->port, &conn->ldaps)) + return False; + + hp = sys_gethostbyname(conn->host); + + if ((hp == NULL) || (hp->h_addr == NULL)) + return False; + + putip((char *)&ip, (char *)hp->h_addr); + + conn->sock = open_socket_out(SOCK_STREAM, &ip, conn->port, 10000); + + return (conn->sock >= 0); +} + +BOOL ldap_set_simple_creds(struct ldap_connection *conn, + const char *dn, const char *password) +{ + conn->auth_dn = talloc_strdup(conn->mem_ctx, dn); + conn->simple_pw = talloc_strdup(conn->mem_ctx, password); + + return ((conn->auth_dn != NULL) && (conn->simple_pw != NULL)); +} + +struct ldap_message *new_ldap_message(void) +{ + TALLOC_CTX *mem_ctx = talloc_init("ldap_message"); + struct ldap_message *result; + + if (mem_ctx == NULL) + return NULL; + + result = talloc(mem_ctx, sizeof(*result)); + + if (result == NULL) + return NULL; + + result->mem_ctx = mem_ctx; + return result; +} + +void destroy_ldap_message(struct ldap_message *msg) +{ + if (msg != NULL) + talloc_destroy(msg->mem_ctx); +} + +BOOL ldap_send_msg(struct ldap_connection *conn, struct ldap_message *msg, + const struct timeval *endtime) +{ + DATA_BLOB request; + BOOL result; + struct ldap_queue_entry *entry; + + msg->messageid = conn->next_msgid++; + + if (!ldap_encode(msg, &request)) + return False; + + result = (write_data_until(conn->sock, request.data, request.length, + endtime) == request.length); + + data_blob_free(&request); + + if (!result) + return result; + + /* abandon and unbind don't expect results */ + + if ((msg->type == LDAP_TAG_AbandonRequest) || + (msg->type == LDAP_TAG_UnbindRequest)) + return True; + + entry = malloc(sizeof(*entry)); + + if (entry == NULL) + return False; + + entry->msgid = msg->messageid; + entry->msg = NULL; + DLIST_ADD(conn->outstanding, entry); + + return True; +} + +BOOL ldap_receive_msg(struct ldap_connection *conn, struct ldap_message *msg, + const struct timeval *endtime) +{ + struct asn1_data data; + BOOL result; + + if (!asn1_read_sequence_until(conn->sock, &data, endtime)) + return False; + + result = ldap_decode(&data, msg); + + asn1_free(&data); + return result; +} + +static struct ldap_message *recv_from_queue(struct ldap_connection *conn, + int msgid) +{ + struct ldap_queue_entry *e; + + for (e = conn->outstanding; e != NULL; e = e->next) { + + if (e->msgid == msgid) { + struct ldap_message *result = e->msg; + DLIST_REMOVE(conn->outstanding, e); + SAFE_FREE(e); + return result; + } + } + + return NULL; +} + +static void add_search_entry(struct ldap_connection *conn, + struct ldap_message *msg) +{ + struct ldap_queue_entry *e = malloc(sizeof *e); + struct ldap_queue_entry *tmp; + + if (e == NULL) + return; + + e->msg = msg; + DLIST_ADD_END(conn->search_entries, e, tmp); + return; +} + +static void fill_outstanding_request(struct ldap_connection *conn, + struct ldap_message *msg) +{ + struct ldap_queue_entry *e; + + for (e = conn->outstanding; e != NULL; e = e->next) { + if (e->msgid == msg->messageid) { + e->msg = msg; + return; + } + } + + /* This reply has not been expected, destroy the incoming msg */ + destroy_ldap_message(msg); + return; +} + +struct ldap_message *ldap_receive(struct ldap_connection *conn, int msgid, + const struct timeval *endtime) +{ + struct ldap_message *result = recv_from_queue(conn, msgid); + + if (result != NULL) + return result; + + while (True) { + struct asn1_data data; + result = new_ldap_message(); + BOOL res; + + if (!asn1_read_sequence_until(conn->sock, &data, endtime)) + return NULL; + + res = ldap_decode(&data, result); + asn1_free(&data); + + if (!res) + return NULL; + + if (result->messageid == msgid) + return result; + + if (result->type == LDAP_TAG_SearchResultEntry) { + add_search_entry(conn, result); + } else { + fill_outstanding_request(conn, result); + } + } + + return NULL; +} + +struct ldap_message *ldap_transaction(struct ldap_connection *conn, + struct ldap_message *request) +{ + if (!ldap_send_msg(conn, request, NULL)) + return False; + + return ldap_receive(conn, request->messageid, NULL); +} + +BOOL ldap_setup_connection(struct ldap_connection *conn, + const char *url) +{ + struct ldap_message *msg = new_ldap_message(); + struct ldap_message *response; + BOOL result; + + if (msg == NULL) + return False; + + if (!ldap_connect(conn, url)) { + destroy_ldap_message(msg); + return False; + } + + msg->messageid = conn->next_msgid++; + msg->type = LDAP_TAG_BindRequest; + msg->r.BindRequest.version = 3; + msg->r.BindRequest.dn = conn->auth_dn; + msg->r.BindRequest.mechanism = LDAP_AUTH_MECH_SIMPLE; + msg->r.BindRequest.creds.password = conn->simple_pw; + + if ((response = ldap_transaction(conn, msg)) == NULL) + return False; + + result = (response->r.BindResponse.response.resultcode == 0); + + destroy_ldap_message(msg); + destroy_ldap_message(response); + return result; +} + +static BOOL ldap_abandon_message(struct ldap_connection *conn, int msgid, + const struct timeval *endtime) +{ + struct ldap_message *msg = new_ldap_message(); + BOOL result; + + if (msg == NULL) + return False; + + msg->type = LDAP_TAG_AbandonRequest; + msg->r.AbandonRequest.messageid = msgid; + + result = ldap_send_msg(conn, msg, endtime); + destroy_ldap_message(msg); + return result; +} + +struct ldap_message *new_ldap_search_message(const char *base, + enum ldap_scope scope, + char *filter, + int num_attributes, + const char **attributes) +{ + struct ldap_message *res = new_ldap_message(); + + if (res == NULL) + return NULL; + + res->type = LDAP_TAG_SearchRequest; + res->r.SearchRequest.basedn = base; + res->r.SearchRequest.scope = scope; + res->r.SearchRequest.deref = LDAP_DEREFERENCE_NEVER; + res->r.SearchRequest.timelimit = 0; + res->r.SearchRequest.sizelimit = 0; + res->r.SearchRequest.attributesonly = False; + res->r.SearchRequest.filter = filter; + res->r.SearchRequest.num_attributes = num_attributes; + res->r.SearchRequest.attributes = attributes; + return res; +} + +struct ldap_message *new_ldap_simple_bind_msg(const char *dn, const char *pw) +{ + struct ldap_message *res = new_ldap_message(); + + if (res == NULL) + return NULL; + + res->type = LDAP_TAG_BindRequest; + res->r.BindRequest.version = 3; + res->r.BindRequest.dn = talloc_strdup(res->mem_ctx, dn); + res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SIMPLE; + res->r.BindRequest.creds.password = talloc_strdup(res->mem_ctx, pw); + return res; +} + +BOOL ldap_setsearchent(struct ldap_connection *conn, struct ldap_message *msg, + const struct timeval *endtime) +{ + if ((conn->searchid != 0) && + (!ldap_abandon_message(conn, conn->searchid, endtime))) + return False; + + conn->searchid = conn->next_msgid; + return ldap_send_msg(conn, msg, endtime); +} + +struct ldap_message *ldap_getsearchent(struct ldap_connection *conn, + const struct timeval *endtime) +{ + struct ldap_message *result; + + if (conn->search_entries != NULL) { + struct ldap_queue_entry *e = conn->search_entries; + + result = e->msg; + DLIST_REMOVE(conn->search_entries, e); + SAFE_FREE(e); + return result; + } + + result = ldap_receive(conn, conn->searchid, endtime); + + if (result->type == LDAP_TAG_SearchResultEntry) + return result; + + if (result->type == LDAP_TAG_SearchResultDone) { + /* TODO: Handle Paged Results */ + destroy_ldap_message(result); + return NULL; + } + + /* TODO: Handle Search References here */ + return NULL; +} + +void ldap_endsearchent(struct ldap_connection *conn, + const struct timeval *endtime) +{ + struct ldap_queue_entry *e; + + e = conn->search_entries; + + while (e != NULL) { + struct ldap_queue_entry *next = e->next; + DLIST_REMOVE(conn->search_entries, e); + SAFE_FREE(e); + e = next; + } +} + +struct ldap_message *ldap_searchone(struct ldap_connection *conn, + struct ldap_message *msg, + const struct timeval *endtime) +{ + struct ldap_message *res1, *res2 = NULL; + if (!ldap_setsearchent(conn, msg, endtime)) + return NULL; + + res1 = ldap_getsearchent(conn, endtime); + + if (res1 != NULL) + res2 = ldap_getsearchent(conn, endtime); + + ldap_endsearchent(conn, endtime); + + if (res1 == NULL) + return NULL; + + if (res2 != NULL) { + /* More than one entry */ + destroy_ldap_message(res1); + destroy_ldap_message(res2); + return NULL; + } + + return res1; +} + +BOOL ldap_find_single_value(struct ldap_message *msg, const char *attr, + DATA_BLOB *value) +{ + int i; + struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; + + if (msg->type != LDAP_TAG_SearchResultEntry) + return False; + + for (i=0; inum_attributes; i++) { + if (strequal(attr, r->attributes[i].name)) { + if (r->attributes[i].num_values != 1) + return False; + + *value = r->attributes[i].values[0]; + return True; + } + } + return False; +} + +BOOL ldap_find_single_string(struct ldap_message *msg, const char *attr, + TALLOC_CTX *mem_ctx, char **value) +{ + DATA_BLOB blob; + + if (!ldap_find_single_value(msg, attr, &blob)) + return False; + + *value = talloc(mem_ctx, blob.length+1); + + if (*value == NULL) + return False; + + memcpy(*value, blob.data, blob.length); + (*value)[blob.length] = '\0'; + return True; +} + +BOOL ldap_find_single_int(struct ldap_message *msg, const char *attr, + int *value) +{ + DATA_BLOB blob; + char *val; + int errno_save; + BOOL res; + + if (!ldap_find_single_value(msg, attr, &blob)) + return False; + + val = malloc(blob.length+1); + if (val == NULL) + return False; + + memcpy(val, blob.data, blob.length); + val[blob.length] = '\0'; + + errno_save = errno; + errno = 0; + + *value = strtol(val, NULL, 10); + + res = (errno == 0); + + free(val); + errno = errno_save; + + return res; +} + +int ldap_error(struct ldap_connection *conn) +{ + return 0; +} + +NTSTATUS ldap2nterror(int ldaperror) +{ + return NT_STATUS_OK; +} diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h new file mode 100644 index 0000000000..96c1b82ca3 --- /dev/null +++ b/source4/libcli/ldap/ldap.h @@ -0,0 +1,246 @@ +/* + Unix SMB/CIFS Implementation. + LDAP protocol helper functions for SAMBA + Copyright (C) Volker Lendecke 2004 + + 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. + +*/ + +#ifndef _SMB_LDAP_H +#define _SMB_LDAP_H + +enum ldap_request_tag { + LDAP_TAG_BindRequest = 0, + LDAP_TAG_BindResponse = 1, + LDAP_TAG_UnbindRequest = 2, + LDAP_TAG_SearchRequest = 3, + LDAP_TAG_SearchResultEntry = 4, + LDAP_TAG_SearchResultDone = 5, + LDAP_TAG_ModifyRequest = 6, + LDAP_TAG_ModifyResponse = 7, + LDAP_TAG_AddRequest = 8, + LDAP_TAG_AddResponse = 9, + LDAP_TAG_DelRequest = 10, + LDAP_TAG_DelResponse = 11, + LDAP_TAG_ModifyDNRequest = 12, + LDAP_TAG_ModifyDNResponse = 13, + LDAP_TAG_CompareRequest = 14, + LDAP_TAG_CompareResponse = 15, + LDAP_TAG_AbandonRequest = 16, + LDAP_TAG_SearchResultReference = 19, + LDAP_TAG_ExtendedRequest = 23, + LDAP_TAG_ExtendedResponse = 24 +}; + +enum ldap_auth_mechanism { + LDAP_AUTH_MECH_SIMPLE = 0, + LDAP_AUTH_MECH_SASL = 3 +}; + +struct ldap_Result { + int resultcode; + const char *dn; + const char *errormessage; + const char *referral; +}; + +struct ldap_attribute { + const char *name; + int num_values; + DATA_BLOB *values; +}; + +struct ldap_BindRequest { + int version; + const char *dn; + enum ldap_auth_mechanism mechanism; + union { + const char *password; + struct { + const char *mechanism; + DATA_BLOB creds; + } SASL; + } creds; +}; + +struct ldap_BindResponse { + struct ldap_Result response; + union { + DATA_BLOB credentials; + } SASL_Credentials; +}; + +struct ldap_UnbindRequest { +}; + +enum ldap_scope { + LDAP_SEARCH_SCOPE_BASE = 0, + LDAP_SEARCH_SCOPE_SINGLE = 1, + LDAP_SEARCH_SCOPE_SUB = 2 +}; + +enum ldap_deref { + LDAP_DEREFERENCE_NEVER = 0, + LDAP_DEREFERENCE_IN_SEARCHING = 1, + LDAP_DEREFERENCE_FINDING_BASE = 2, + LDAP_DEREFERENCE_ALWAYS +}; + +struct ldap_SearchRequest { + const char *basedn; + enum ldap_scope scope; + enum ldap_deref deref; + uint32 timelimit; + uint32 sizelimit; + BOOL attributesonly; + char *filter; + int num_attributes; + const char **attributes; +}; + +struct ldap_SearchResEntry { + const char *dn; + int num_attributes; + struct ldap_attribute *attributes; +}; + +struct ldap_SearchResRef { + int num_referrals; + const char **referrals; +}; + +enum ldap_modify_type { + LDAP_MODIFY_NONE = -1, + LDAP_MODIFY_ADD = 0, + LDAP_MODIFY_DELETE = 1, + LDAP_MODIFY_REPLACE = 2 +}; + +struct ldap_mod { + enum ldap_modify_type type; + struct ldap_attribute attrib; +}; + +struct ldap_ModifyRequest { + const char *dn; + int num_mods; + struct ldap_mod *mods; +}; + +struct ldap_AddRequest { + const char *dn; + int num_attributes; + struct ldap_attribute *attributes; +}; + +struct ldap_DelRequest { + const char *dn; +}; + +struct ldap_ModifyDNRequest { + const char *dn; + const char *newrdn; + BOOL deleteolddn; + const char *newsuperior; +}; + +struct ldap_CompareRequest { + const char *dn; + const char *attribute; + const char *value; +}; + +struct ldap_AbandonRequest { + uint32 messageid; +}; + +struct ldap_ExtendedRequest { + const char *oid; + DATA_BLOB value; +}; + +struct ldap_ExtendedResponse { + struct ldap_Result response; + const char *name; + DATA_BLOB value; +}; + +union ldap_Request { + struct ldap_BindRequest BindRequest; + struct ldap_BindResponse BindResponse; + struct ldap_UnbindRequest UnbindRequest; + struct ldap_SearchRequest SearchRequest; + struct ldap_SearchResEntry SearchResultEntry; + struct ldap_Result SearchResultDone; + struct ldap_SearchResRef SearchResultReference; + struct ldap_ModifyRequest ModifyRequest; + struct ldap_Result ModifyResponse; + struct ldap_AddRequest AddRequest; + struct ldap_Result AddResponse; + struct ldap_DelRequest DelRequest; + struct ldap_Result DelResponse; + struct ldap_ModifyDNRequest ModifyDNRequest; + struct ldap_Result ModifyDNResponse; + struct ldap_CompareRequest CompareRequest; + struct ldap_Result CompareResponse; + struct ldap_AbandonRequest AbandonRequest; + struct ldap_ExtendedRequest ExtendedRequest; + struct ldap_ExtendedResponse ExtendedResponse; +}; + +struct ldap_Control { + const char *oid; + BOOL critical; + DATA_BLOB value; +}; + +struct ldap_message { + TALLOC_CTX *mem_ctx; + uint32 messageid; + uint8 type; + union ldap_Request r; + int num_controls; + struct ldap_Control *controls; +}; + +struct ldap_queue_entry { + struct ldap_queue_entry *next, *prev; + int msgid; + struct ldap_message *msg; +}; + +struct ldap_connection { + TALLOC_CTX *mem_ctx; + int sock; + int next_msgid; + char *host; + uint16 port; + BOOL ldaps; + + const char *auth_dn; + const char *simple_pw; + + /* Current outstanding search entry */ + int searchid; + + /* List for incoming search entries */ + struct ldap_queue_entry *search_entries; + + /* Outstanding LDAP requests that have not yet been replied to */ + struct ldap_queue_entry *outstanding; +}; + +#endif -- cgit From 2b51ce3ca44943758f70017c7553dd2bb0bb977c Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 12 Aug 2004 06:37:12 +0000 Subject: r1761: start porting valuable volker's work on ldap from trunk all ldb functions has been renamed to ldap_ as we don't really want to include ldb functions here, let's keep ldap and ldb separate. (This used to be commit f9d7b731c910b530a0a6c0f0c09c809f3e7b4167) --- source4/libcli/ldap/ldap.c | 126 ++++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 64 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 38fff7e357..ef1d43022f 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -22,48 +22,47 @@ */ #include "includes.h" -#include "smb_ldap.h" /**************************************************************************** * - * LDAP filter parser -- main routine is ldb_parse_filter + * LDAP filter parser -- main routine is ldap_parse_filter * - * Shamelessly stolen and adapted from Samba 4. + * Shamelessly stolen and adapted from ldb. * ***************************************************************************/ /* Hmm. A blob might be more appropriate here :-) */ -struct ldb_val { +struct ldap_val { unsigned int length; void *data; }; -enum ldb_parse_op {LDB_OP_SIMPLE, LDB_OP_AND, LDB_OP_OR, LDB_OP_NOT}; +enum ldap_parse_op {LDAP_OP_SIMPLE, LDAP_OP_AND, LDAP_OP_OR, LDAP_OP_NOT}; -struct ldb_parse_tree { - enum ldb_parse_op operation; +struct ldap_parse_tree { + enum ldap_parse_op operation; union { struct { char *attr; - struct ldb_val value; + struct ldap_val value; } simple; struct { unsigned int num_elements; - struct ldb_parse_tree **elements; + struct ldap_parse_tree **elements; } list; struct { - struct ldb_parse_tree *child; + struct ldap_parse_tree *child; } not; } u; }; -#define LDB_ALL_SEP "()&|=!" +#define LDAP_ALL_SEP "()&|=!" /* return next token element. Caller frees */ -static char *ldb_parse_lex(TALLOC_CTX *mem_ctx, const char **s, +static char *ldap_parse_lex(TALLOC_CTX *mem_ctx, const char **s, const char *sep) { const char *p = *s; @@ -127,19 +126,19 @@ static const char *match_brace(const char *s) return s; } -static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, +static struct ldap_parse_tree *ldap_parse_filter(TALLOC_CTX *mem_ctx, const char **s); /* ::= */ -static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *mem_ctx, +static struct ldap_parse_tree *ldap_parse_simple(TALLOC_CTX *mem_ctx, const char *s) { char *eq, *val, *l; - struct ldb_parse_tree *ret; + struct ldap_parse_tree *ret; - l = ldb_parse_lex(mem_ctx, &s, LDB_ALL_SEP); + l = ldap_parse_lex(mem_ctx, &s, LDAP_ALL_SEP); if (!l) { return NULL; } @@ -147,11 +146,11 @@ static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *mem_ctx, if (strchr("()&|=", *l)) return NULL; - eq = ldb_parse_lex(mem_ctx, &s, LDB_ALL_SEP); + eq = ldap_parse_lex(mem_ctx, &s, LDAP_ALL_SEP); if (!eq || strcmp(eq, "=") != 0) return NULL; - val = ldb_parse_lex(mem_ctx, &s, ")"); + val = ldap_parse_lex(mem_ctx, &s, ")"); if (val && strchr("()&|", *val)) return NULL; @@ -161,7 +160,7 @@ static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *mem_ctx, return NULL; } - ret->operation = LDB_OP_SIMPLE; + ret->operation = LDAP_OP_SIMPLE; ret->u.simple.attr = l; ret->u.simple.value.data = val; ret->u.simple.value.length = val?strlen(val):0; @@ -176,11 +175,11 @@ static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *mem_ctx, ::= '|' ::= | */ -static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *mem_ctx, - enum ldb_parse_op op, +static struct ldap_parse_tree *ldap_parse_filterlist(TALLOC_CTX *mem_ctx, + enum ldap_parse_op op, const char *s) { - struct ldb_parse_tree *ret, *next; + struct ldap_parse_tree *ret, *next; ret = talloc(mem_ctx, sizeof(*ret)); @@ -197,17 +196,17 @@ static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *mem_ctx, return NULL; } - ret->u.list.elements[0] = ldb_parse_filter(mem_ctx, &s); + ret->u.list.elements[0] = ldap_parse_filter(mem_ctx, &s); if (!ret->u.list.elements[0]) { return NULL; } while (isspace(*s)) s++; - while (*s && (next = ldb_parse_filter(mem_ctx, &s))) { - struct ldb_parse_tree **e; + while (*s && (next = ldap_parse_filter(mem_ctx, &s))) { + struct ldap_parse_tree **e; e = talloc_realloc(mem_ctx, ret->u.list.elements, - sizeof(struct ldb_parse_tree) * + sizeof(struct ldap_parse_tree) * (ret->u.list.num_elements+1)); if (!e) { errno = ENOMEM; @@ -226,9 +225,9 @@ static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *mem_ctx, /* ::= '!' */ -static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *mem_ctx, const char *s) +static struct ldap_parse_tree *ldap_parse_not(TALLOC_CTX *mem_ctx, const char *s) { - struct ldb_parse_tree *ret; + struct ldap_parse_tree *ret; ret = talloc(mem_ctx, sizeof(*ret)); if (!ret) { @@ -236,8 +235,8 @@ static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *mem_ctx, const char *s) return NULL; } - ret->operation = LDB_OP_NOT; - ret->u.not.child = ldb_parse_filter(mem_ctx, &s); + ret->operation = LDAP_OP_NOT; + ret->u.not.child = ldap_parse_filter(mem_ctx, &s); if (!ret->u.not.child) return NULL; @@ -248,41 +247,41 @@ static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *mem_ctx, const char *s) parse a filtercomp ::= | | | */ -static struct ldb_parse_tree *ldb_parse_filtercomp(TALLOC_CTX *mem_ctx, +static struct ldap_parse_tree *ldap_parse_filtercomp(TALLOC_CTX *mem_ctx, const char *s) { while (isspace(*s)) s++; switch (*s) { case '&': - return ldb_parse_filterlist(mem_ctx, LDB_OP_AND, s+1); + return ldap_parse_filterlist(mem_ctx, LDAP_OP_AND, s+1); case '|': - return ldb_parse_filterlist(mem_ctx, LDB_OP_OR, s+1); + return ldap_parse_filterlist(mem_ctx, LDAP_OP_OR, s+1); case '!': - return ldb_parse_not(mem_ctx, s+1); + return ldap_parse_not(mem_ctx, s+1); case '(': case ')': return NULL; } - return ldb_parse_simple(mem_ctx, s); + return ldap_parse_simple(mem_ctx, s); } /* ::= '(' ')' */ -static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, +static struct ldap_parse_tree *ldap_parse_filter(TALLOC_CTX *mem_ctx, const char **s) { char *l, *s2; const char *p, *p2; - struct ldb_parse_tree *ret; + struct ldap_parse_tree *ret; - l = ldb_parse_lex(mem_ctx, s, LDB_ALL_SEP); + l = ldap_parse_lex(mem_ctx, s, LDAP_ALL_SEP); if (!l) { return NULL; } @@ -303,7 +302,7 @@ static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, return NULL; } - ret = ldb_parse_filtercomp(mem_ctx, s2); + ret = ldap_parse_filtercomp(mem_ctx, s2); *s = p2; @@ -315,21 +314,21 @@ static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, expression ::= | */ -static struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s) +static struct ldap_parse_tree *ldap_parse_tree(TALLOC_CTX *mem_ctx, const char *s) { while (isspace(*s)) s++; if (*s == '(') { - return ldb_parse_filter(mem_ctx, &s); + return ldap_parse_filter(mem_ctx, &s); } - return ldb_parse_simple(mem_ctx, s); + return ldap_parse_simple(mem_ctx, s); } -static BOOL ldap_push_filter(ASN1_DATA *data, struct ldb_parse_tree *tree) +static BOOL ldap_push_filter(ASN1_DATA *data, struct ldap_parse_tree *tree) { switch (tree->operation) { - case LDB_OP_SIMPLE: { + case LDAP_OP_SIMPLE: { if ((tree->u.simple.value.length == 1) && (((char *)(tree->u.simple.value.data))[0] == '*')) { /* Just a presence test */ @@ -350,7 +349,7 @@ static BOOL ldap_push_filter(ASN1_DATA *data, struct ldb_parse_tree *tree) break; } - case LDB_OP_AND: { + case LDAP_OP_AND: { int i; asn1_push_tag(data, 0xa0); @@ -361,7 +360,7 @@ static BOOL ldap_push_filter(ASN1_DATA *data, struct ldb_parse_tree *tree) break; } - case LDB_OP_OR: { + case LDAP_OP_OR: { int i; asn1_push_tag(data, 0xa1); @@ -454,7 +453,7 @@ static char *next_chunk(TALLOC_CTX *mem_ctx, } /* simple ldif attribute parser */ -static int next_attr(char **s, const char **attr, struct ldb_val *value) +static int next_attr(char **s, const char **attr, struct ldap_val *value) { char *p; int base64_encoded = 0; @@ -507,7 +506,7 @@ static int next_attr(char **s, const char **attr, struct ldb_val *value) return 0; } -static BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, +static BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldap_val *value, struct ldap_attribute *attrib) { attrib->values = talloc_realloc(mem_ctx, attrib->values, @@ -526,7 +525,7 @@ static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) { struct ldap_AddRequest *r = &msg->r.AddRequest; const char *attr_name; - struct ldb_val value; + struct ldap_val value; r->num_attributes = 0; r->attributes = NULL; @@ -583,7 +582,7 @@ static BOOL fill_mods(struct ldap_message *msg, char **chunk) { struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; const char *attr_name; - struct ldb_val value; + struct ldap_val value; r->num_mods = 0; r->mods = NULL; @@ -647,7 +646,7 @@ static struct ldap_message *ldif_read(int (*fgetc_fn)(void *), const char *attr=NULL; const char *dn; char *chunk=NULL, *s; - struct ldb_val value; + struct ldap_val value; value.data = NULL; @@ -822,13 +821,13 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) asn1_write_BOOLEAN2(&data, r->attributesonly); { - TALLOC_CTX *mem_ctx = talloc_init("ldb_parse_tree"); - struct ldb_parse_tree *tree; + TALLOC_CTX *mem_ctx = talloc_init("ldap_parse_tree"); + struct ldap_parse_tree *tree; if (mem_ctx == NULL) return False; - tree = ldb_parse_tree(mem_ctx, r->filter); + tree = ldap_parse_tree(mem_ctx, r->filter); if (tree == NULL) return False; @@ -872,7 +871,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) break; } case LDAP_TAG_SearchResultDone: { - struct ldap_SearchResultDone *r = &msg->r.SearchResultDone; + struct ldap_Result *r = &msg->r.SearchResultDone; ldap_encode_response(msg->type, r, &data); break; } @@ -1195,7 +1194,7 @@ static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, ASN1_DATA *data, asn1_start_tag(data, ASN1_SET); while (asn1_peek_tag(data, ASN1_OCTET_STRING)) { DATA_BLOB blob; - struct ldb_val value; + struct ldap_val value; asn1_read_OctetString(data, &blob); value.data = blob.data; value.length = blob.length; @@ -1323,7 +1322,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) } case ASN1_APPLICATION(LDAP_TAG_SearchResultDone): { - struct ldap_SearchResultDone *r = &msg->r.SearchResultDone; + struct ldap_Result *r = &msg->r.SearchResultDone; msg->type = LDAP_TAG_SearchResultDone; ldap_decode_response(msg->mem_ctx, data, LDAP_TAG_SearchResultDone, r); @@ -1364,7 +1363,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) } case ASN1_APPLICATION(LDAP_TAG_ModifyResponse): { - struct ldap_ModifyResponse *r = &msg->r.ModifyResponse; + struct ldap_Result *r = &msg->r.ModifyResponse; msg->type = LDAP_TAG_ModifyResponse; ldap_decode_response(msg->mem_ctx, data, LDAP_TAG_ModifyResponse, r); @@ -1387,7 +1386,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) } case ASN1_APPLICATION(LDAP_TAG_AddResponse): { - struct ldap_AddResponse *r = &msg->r.AddResponse; + struct ldap_Result *r = &msg->r.AddResponse; msg->type = LDAP_TAG_AddResponse; ldap_decode_response(msg->mem_ctx, data, LDAP_TAG_AddResponse, r); @@ -1413,7 +1412,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) } case ASN1_APPLICATION(LDAP_TAG_DelResponse): { - struct ldap_DelResponse *r = &msg->r.DelResponse; + struct ldap_Result *r = &msg->r.DelResponse; msg->type = LDAP_TAG_DelResponse; ldap_decode_response(msg->mem_ctx, data, LDAP_TAG_DelResponse, r); @@ -1427,7 +1426,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) } case ASN1_APPLICATION(LDAP_TAG_ModifyDNResponse): { - struct ldap_ModifyDNResponse *r = &msg->r.ModifyDNResponse; + struct ldap_Result *r = &msg->r.ModifyDNResponse; msg->type = LDAP_TAG_ModifyDNResponse; ldap_decode_response(msg->mem_ctx, data, LDAP_TAG_ModifyDNResponse, r); @@ -1441,7 +1440,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) } case ASN1_APPLICATION(LDAP_TAG_CompareResponse): { - struct ldap_CompareResponse *r = &msg->r.CompareResponse; + struct ldap_Result *r = &msg->r.CompareResponse; msg->type = LDAP_TAG_CompareResponse; ldap_decode_response(msg->mem_ctx, data, LDAP_TAG_CompareResponse, r); @@ -1666,13 +1665,12 @@ static void add_search_entry(struct ldap_connection *conn, struct ldap_message *msg) { struct ldap_queue_entry *e = malloc(sizeof *e); - struct ldap_queue_entry *tmp; if (e == NULL) return; e->msg = msg; - DLIST_ADD_END(conn->search_entries, e, tmp); + DLIST_ADD_END(conn->search_entries, e, struct ldap_queue_entry *); return; } -- cgit From 2e28edd233964f54b46fde10217f93f571ed1d6d Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 12 Aug 2004 08:00:45 +0000 Subject: r1771: OK Let's add tests for ldap. Thanks to Metze and Volker for their unvaluable support :) (This used to be commit e6a6c0737ab94d58930c0d4e1ef0bb4d99510833) --- source4/libcli/ldap/ldap.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index ef1d43022f..63dd7d4c7b 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -58,6 +58,7 @@ struct ldap_parse_tree { }; #define LDAP_ALL_SEP "()&|=!" +#define LDAP_CONNECTION_TIMEOUT 10000 /* return next token element. Caller frees @@ -1534,6 +1535,8 @@ struct ldap_connection *new_ldap_connection(void) result->outstanding = NULL; result->searchid = 0; result->search_entries = NULL; + result->auth_dn = NULL; + result->simple_pw = NULL; return result; } @@ -1553,7 +1556,7 @@ BOOL ldap_connect(struct ldap_connection *conn, const char *url) putip((char *)&ip, (char *)hp->h_addr); - conn->sock = open_socket_out(SOCK_STREAM, &ip, conn->port, 10000); + conn->sock = open_socket_out(SOCK_STREAM, &ip, conn->port, LDAP_CONNECTION_TIMEOUT); return (conn->sock >= 0); } @@ -1753,9 +1756,17 @@ BOOL ldap_setup_connection(struct ldap_connection *conn, msg->messageid = conn->next_msgid++; msg->type = LDAP_TAG_BindRequest; msg->r.BindRequest.version = 3; - msg->r.BindRequest.dn = conn->auth_dn; + if (conn->auth_dn) { + msg->r.BindRequest.dn = conn->auth_dn; + } else { + msg->r.BindRequest.dn = ""; + } msg->r.BindRequest.mechanism = LDAP_AUTH_MECH_SIMPLE; - msg->r.BindRequest.creds.password = conn->simple_pw; + if (conn->simple_pw) { + msg->r.BindRequest.creds.password = conn->simple_pw; + } else { + msg->r.BindRequest.creds.password = ""; + } if ((response = ldap_transaction(conn, msg)) == NULL) return False; -- cgit From 28ea8b8785e5e8e3b3f3ddf0c12c0c8c69ea77c5 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 12 Aug 2004 19:29:52 +0000 Subject: r1785: remove unneeded dependencies on openldap client libraries (This used to be commit 44083e317855f6d8a0b4a81002a3376e8775df28) --- source4/libcli/ldap/ldap.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 63dd7d4c7b..5afd595293 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -596,13 +596,13 @@ static BOOL fill_mods(struct ldap_message *msg, char **chunk) mod.attrib.name = talloc_strdup(msg->mem_ctx, value.data); if (strequal(attr_name, "add")) - mod.type = LDAP_MOD_ADD; + mod.type = LDAP_MODIFY_ADD; if (strequal(attr_name, "delete")) - mod.type = LDAP_MOD_DELETE; + mod.type = LDAP_MODIFY_DELETE; if (strequal(attr_name, "replace")) - mod.type = LDAP_MOD_REPLACE; + mod.type = LDAP_MODIFY_REPLACE; if (mod.type == LDAP_MODIFY_NONE) { DEBUG(2, ("ldif modification type %s unsupported\n", @@ -1537,6 +1537,7 @@ struct ldap_connection *new_ldap_connection(void) result->search_entries = NULL; result->auth_dn = NULL; result->simple_pw = NULL; + return result; } -- cgit From 16c52f7a0786a2583c32fb44ee12ff4f1863f355 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 12 Aug 2004 22:23:57 +0000 Subject: r1792: split ldap_setup_connection() and provide an ldap_bind_simple() function (This used to be commit d9f8f97c9eaa8078f411adf0a8db607365082197) --- source4/libcli/ldap/ldap.c | 64 ++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 22 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 5afd595293..d7c24e8c03 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1739,42 +1739,62 @@ struct ldap_message *ldap_transaction(struct ldap_connection *conn, return ldap_receive(conn, request->messageid, NULL); } -BOOL ldap_setup_connection(struct ldap_connection *conn, - const char *url) +struct ldap_message *ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const char *password) { - struct ldap_message *msg = new_ldap_message(); struct ldap_message *response; - BOOL result; + struct ldap_message *msg; + const char *dn, *pw; - if (msg == NULL) + if (conn == NULL || msg == NULL) return False; - if (!ldap_connect(conn, url)) { - destroy_ldap_message(msg); - return False; - } - - msg->messageid = conn->next_msgid++; - msg->type = LDAP_TAG_BindRequest; - msg->r.BindRequest.version = 3; - if (conn->auth_dn) { - msg->r.BindRequest.dn = conn->auth_dn; + if (userdn) { + dn = userdn; } else { - msg->r.BindRequest.dn = ""; + if (conn->auth_dn) { + dn = conn->auth_dn; + } else { + dn = ""; + } } - msg->r.BindRequest.mechanism = LDAP_AUTH_MECH_SIMPLE; - if (conn->simple_pw) { - msg->r.BindRequest.creds.password = conn->simple_pw; + + if (password) { + pw = password; } else { - msg->r.BindRequest.creds.password = ""; + if (conn->simple_pw) { + pw = conn->simple_pw; + } else { + pw = ""; + } } - if ((response = ldap_transaction(conn, msg)) == NULL) + msg = new_ldap_simple_bind_msg(dn, pw); + if (!msg) return False; - result = (response->r.BindResponse.response.resultcode == 0); + response = ldap_transaction(conn, msg); destroy_ldap_message(msg); + return response; +} + +BOOL ldap_setup_connection(struct ldap_connection *conn, + const char *url, const char *userdn, const char *password) +{ + struct ldap_message *response; + BOOL result; + + if (!ldap_connect(conn, url)) { + return False; + } + + response = ldap_bind_simple(conn, userdn, password); + if (response == NULL) { + result = False; + } else { + result = (response->r.BindResponse.response.resultcode == 0); + } + destroy_ldap_message(response); return result; } -- cgit From 2129ba5082d10e3934b57074231a74150265fece Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 13 Aug 2004 00:55:15 +0000 Subject: r1798: fix the build metze (This used to be commit a1bfc94ab35c426b75efedea0df21acec7d1eeed) --- source4/libcli/ldap/ldap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index d7c24e8c03..16f775a451 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1705,9 +1705,10 @@ struct ldap_message *ldap_receive(struct ldap_connection *conn, int msgid, while (True) { struct asn1_data data; - result = new_ldap_message(); BOOL res; + result = new_ldap_message(); + if (!asn1_read_sequence_until(conn->sock, &data, endtime)) return NULL; -- cgit From 01b58ebf83eca8b3909f3ba5becd6615bb89039f Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 13 Aug 2004 05:26:38 +0000 Subject: r1802: start to support SASL in our ldap libraries does not work yet but we are close currently we send the right data on wire and fail to decode the answer (This used to be commit 10baf585821bf1f10a3786045a0965000cdffd12) --- source4/libcli/ldap/ldap.c | 169 ++++++++++++++++++++++++++++++++++++++++----- source4/libcli/ldap/ldap.h | 15 +++- 2 files changed, 165 insertions(+), 19 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 16f775a451..3048c94114 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -790,8 +790,8 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) asn1_push_tag(&data, r->mechanism | 0xa0); asn1_write_OctetString(&data, r->creds.SASL.mechanism, strlen(r->creds.SASL.mechanism)); - asn1_write_OctetString(&data, r->creds.SASL.creds.data, - r->creds.SASL.creds.length); + asn1_write_OctetString(&data, r->creds.SASL.secblob.data, + r->creds.SASL.secblob.length); asn1_pop_tag(&data); break; default: @@ -1537,6 +1537,7 @@ struct ldap_connection *new_ldap_connection(void) result->search_entries = NULL; result->auth_dn = NULL; result->simple_pw = NULL; + result->gensec = NULL; return result; } @@ -1740,14 +1741,15 @@ struct ldap_message *ldap_transaction(struct ldap_connection *conn, return ldap_receive(conn, request->messageid, NULL); } -struct ldap_message *ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const char *password) +int ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const char *password) { struct ldap_message *response; struct ldap_message *msg; const char *dn, *pw; + int result = LDAP_OTHER; - if (conn == NULL || msg == NULL) - return False; + if (conn == NULL) + return result; if (userdn) { dn = userdn; @@ -1771,33 +1773,152 @@ struct ldap_message *ldap_bind_simple(struct ldap_connection *conn, const char * msg = new_ldap_simple_bind_msg(dn, pw); if (!msg) - return False; + return result; response = ldap_transaction(conn, msg); + if (!response) { + destroy_ldap_message(msg); + return result; + } + + result = response->r.BindResponse.response.resultcode; destroy_ldap_message(msg); - return response; + destroy_ldap_message(response); + + return result; +} + +int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const char *domain, const char *password) +{ + NTSTATUS status; + TALLOC_CTX *mem_ctx = NULL; + struct ldap_message *response; + struct ldap_message *msg; + DATA_BLOB input = data_blob(NULL, 0); + DATA_BLOB output = data_blob(NULL, 0); + int result = LDAP_OTHER; + + if (conn == NULL) + return result; + + status = gensec_client_start(&conn->gensec); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); + return result; + } + + status = gensec_set_domain(conn->gensec, domain); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n", + domain, nt_errstr(status))); + goto done; + } + + status = gensec_set_username(conn->gensec, username); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client username to %s: %s\n", + username, nt_errstr(status))); + goto done; + } + + status = gensec_set_password(conn->gensec, password); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client password: %s\n", + nt_errstr(status))); + goto done; + } + + status = gensec_set_target_hostname(conn->gensec, conn->host); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", + nt_errstr(status))); + goto done; + } + + status = gensec_start_mech_by_sasl_name(conn->gensec, "GSS-SPNEGO"); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism: %s\n", + nt_errstr(status))); + goto done; + } + + mem_ctx = talloc_init("ldap_bind_sasl"); + if (!mem_ctx) + goto done; + + status = gensec_update(conn->gensec, mem_ctx, + input, + &output); + + while(1) { + if (NT_STATUS_IS_OK(status) && output.length == 0) { + break; + } + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) { + break; + } + + msg = new_ldap_sasl_bind_msg("GSS-SPNEGO", &output); + if (!msg) + goto done; + + response = ldap_transaction(conn, msg); + destroy_ldap_message(msg); + + result = response->r.BindResponse.response.resultcode; + + if (result != LDAP_SUCCESS && result != LDAP_SASL_BIND_IN_PROGRESS) { + break; + } + + status = gensec_update(conn->gensec, mem_ctx, + response->r.BindResponse.SASL.creds, + &output); + + destroy_ldap_message(response); + } + +done: + if (conn->gensec) + gensec_end(&conn->gensec); + if (mem_ctx) + talloc_destroy(mem_ctx); + + return result; } BOOL ldap_setup_connection(struct ldap_connection *conn, const char *url, const char *userdn, const char *password) { - struct ldap_message *response; - BOOL result; + int result; if (!ldap_connect(conn, url)) { return False; } - response = ldap_bind_simple(conn, userdn, password); - if (response == NULL) { - result = False; - } else { - result = (response->r.BindResponse.response.resultcode == 0); + result = ldap_bind_simple(conn, userdn, password); + if (result == LDAP_SUCCESS) { + return True; } - destroy_ldap_message(response); - return result; + return False; +} + +BOOL ldap_setup_connection_with_sasl(struct ldap_connection *conn, const char *url, const char *username, const char *domain, const char *password) +{ + int result; + + if (!ldap_connect(conn, url)) { + return False; + } + + result = ldap_bind_sasl(conn, username, domain, password); + if (result == LDAP_SUCCESS) { + return True; + } + + return False; } static BOOL ldap_abandon_message(struct ldap_connection *conn, int msgid, @@ -1856,6 +1977,22 @@ struct ldap_message *new_ldap_simple_bind_msg(const char *dn, const char *pw) return res; } +struct ldap_message *new_ldap_sasl_bind_msg(const char *sasl_mechanism, DATA_BLOB *secblob) +{ + struct ldap_message *res = new_ldap_message(); + + if (res == NULL) + return NULL; + + res->type = LDAP_TAG_BindRequest; + res->r.BindRequest.version = 3; + res->r.BindRequest.dn = ""; + res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SASL; + res->r.BindRequest.creds.SASL.mechanism = talloc_strdup(res->mem_ctx, sasl_mechanism); + res->r.BindRequest.creds.SASL.secblob = *secblob; + return res; +} + BOOL ldap_setsearchent(struct ldap_connection *conn, struct ldap_message *msg, const struct timeval *endtime) { diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 96c1b82ca3..fcd660f841 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -50,6 +50,12 @@ enum ldap_auth_mechanism { LDAP_AUTH_MECH_SASL = 3 }; +enum ldap_result_code { + LDAP_SUCCESS = 0, + LDAP_SASL_BIND_IN_PROGRESS = 0x0e, + LDAP_OTHER = 0x50 +}; + struct ldap_Result { int resultcode; const char *dn; @@ -71,7 +77,7 @@ struct ldap_BindRequest { const char *password; struct { const char *mechanism; - DATA_BLOB creds; + DATA_BLOB secblob; } SASL; } creds; }; @@ -79,8 +85,8 @@ struct ldap_BindRequest { struct ldap_BindResponse { struct ldap_Result response; union { - DATA_BLOB credentials; - } SASL_Credentials; + DATA_BLOB creds; + } SASL; }; struct ldap_UnbindRequest { @@ -241,6 +247,9 @@ struct ldap_connection { /* Outstanding LDAP requests that have not yet been replied to */ struct ldap_queue_entry *outstanding; + + /* Let's support SASL */ + struct gensec_security *gensec; }; #endif -- cgit From cd5421b8ab189a35fe4f546ed1a4893f20e24ab3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 13 Aug 2004 06:27:02 +0000 Subject: r1803: more progress on sasl binds, but decoding the response still fails metze (This used to be commit f6c44201073df37881191509ffb7badee3baac71) --- source4/libcli/ldap/ldap.c | 30 +++++++++++++++++++++++++++--- source4/libcli/ldap/ldap.h | 2 +- 2 files changed, 28 insertions(+), 4 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 3048c94114..b17d5dc461 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1066,6 +1066,26 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, asn1_end_tag(data); } +static void ldap_decode_BindResponse(TALLOC_CTX *mem_ctx, + ASN1_DATA *data, + enum ldap_request_tag tag, + struct ldap_BindResponse *BindResp) +{ + asn1_start_tag(data, ASN1_APPLICATION(tag)); + asn1_read_enumerated(data, &BindResp->response.resultcode); + asn1_read_OctetString_talloc(mem_ctx, data, &BindResp->response.dn); + asn1_read_OctetString_talloc(mem_ctx, data, &BindResp->response.errormessage); + if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { + DATA_BLOB tmp_blob = data_blob(NULL, 0); + asn1_read_OctetString(data, &tmp_blob); + BindResp->SASL.secblob = data_blob_talloc(mem_ctx, tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + BindResp->SASL.secblob = data_blob(NULL, 0); + } + asn1_end_tag(data); +} + static BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, const struct ldap_attribute *attrib, struct ldap_attribute **attribs, @@ -1261,9 +1281,9 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_BindResponse): { struct ldap_BindResponse *r = &msg->r.BindResponse; msg->type = LDAP_TAG_BindResponse; - ldap_decode_response(msg->mem_ctx, + ldap_decode_BindResponse(msg->mem_ctx, data, LDAP_TAG_BindResponse, - &r->response); + r); break; } @@ -1866,6 +1886,10 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha response = ldap_transaction(conn, msg); destroy_ldap_message(msg); + if (!response) { + goto done; + } + result = response->r.BindResponse.response.resultcode; if (result != LDAP_SUCCESS && result != LDAP_SASL_BIND_IN_PROGRESS) { @@ -1873,7 +1897,7 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha } status = gensec_update(conn->gensec, mem_ctx, - response->r.BindResponse.SASL.creds, + response->r.BindResponse.SASL.secblob, &output); destroy_ldap_message(response); diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index fcd660f841..af322e783a 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -85,7 +85,7 @@ struct ldap_BindRequest { struct ldap_BindResponse { struct ldap_Result response; union { - DATA_BLOB creds; + DATA_BLOB secblob; } SASL; }; -- cgit From e0a6215cdfd7ea1aca95bc81c7ce4e40e5f545a9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 13 Aug 2004 07:04:45 +0000 Subject: r1804: get a bit closer to a sasl bind metze (This used to be commit d0278c6bef622feeda8da7a120e3d1abce4a74e5) --- source4/libcli/ldap/ldap.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index b17d5dc461..5b22825da4 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1066,6 +1066,23 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, asn1_end_tag(data); } +/* read a octet string blob */ +static BOOL asn1_read_ContextSimple(ASN1_DATA *data, uint8_t num, DATA_BLOB *blob) +{ + int len; + ZERO_STRUCTP(blob); + if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(num))) return False; + len = asn1_tag_remaining(data); + if (len < 0) { + data->has_error = True; + return False; + } + *blob = data_blob(NULL, len); + asn1_read(data, blob->data, len); + asn1_end_tag(data); + return !data->has_error; +} + static void ldap_decode_BindResponse(TALLOC_CTX *mem_ctx, ASN1_DATA *data, enum ldap_request_tag tag, @@ -1075,9 +1092,9 @@ static void ldap_decode_BindResponse(TALLOC_CTX *mem_ctx, asn1_read_enumerated(data, &BindResp->response.resultcode); asn1_read_OctetString_talloc(mem_ctx, data, &BindResp->response.dn); asn1_read_OctetString_talloc(mem_ctx, data, &BindResp->response.errormessage); - if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) { DATA_BLOB tmp_blob = data_blob(NULL, 0); - asn1_read_OctetString(data, &tmp_blob); + asn1_read_ContextSimple(data, 7, &tmp_blob); BindResp->SASL.secblob = data_blob_talloc(mem_ctx, tmp_blob.data, tmp_blob.length); data_blob_free(&tmp_blob); } else { -- cgit From 16757c52d626d324566f504774525641a4785cd9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 13 Aug 2004 07:10:46 +0000 Subject: r1805: ...I just forgot to say that the sasl bind actually works now:-) metze (This used to be commit a2cd725681fa7b10a5cca337554be17f628465c0) --- source4/libcli/ldap/ldap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 5b22825da4..b6272f694e 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -4,6 +4,8 @@ Copyright (C) Andrew Tridgell 2004 Copyright (C) Volker Lendecke 2004 + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Simo Sorce 2004 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 -- cgit From c074e30e2eacaacebb95efd755ad7de74a0970e8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Aug 2004 11:22:44 +0000 Subject: r1856: - move asn1 functions to asn1.c - merge some stuff from trunk metze (This used to be commit 267edf1c0bb1ed73f1ba19148e6412b9a1c41979) --- source4/libcli/ldap/ldap.c | 90 ++++++++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 43 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index b6272f694e..b319299b1e 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -971,7 +971,8 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) break; } case LDAP_TAG_ModifyDNResponse: { -/* struct ldap_Result *r = &msg->r.ModifyDNResponse; */ + struct ldap_Result *r = &msg->r.ModifyDNResponse; + ldap_encode_response(msg->type, r, &data); break; } case LDAP_TAG_CompareRequest: { @@ -1061,46 +1062,12 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, asn1_read_enumerated(data, &result->resultcode); asn1_read_OctetString_talloc(mem_ctx, data, &result->dn); asn1_read_OctetString_talloc(mem_ctx, data, &result->errormessage); - if (asn1_peek_tag(data, ASN1_OCTET_STRING)) + if (asn1_peek_tag(data, ASN1_CONTEXT(3))) { + asn1_start_tag(data, ASN1_CONTEXT(3)); asn1_read_OctetString_talloc(mem_ctx, data, &result->referral); - else - result->referral = NULL; - asn1_end_tag(data); -} - -/* read a octet string blob */ -static BOOL asn1_read_ContextSimple(ASN1_DATA *data, uint8_t num, DATA_BLOB *blob) -{ - int len; - ZERO_STRUCTP(blob); - if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(num))) return False; - len = asn1_tag_remaining(data); - if (len < 0) { - data->has_error = True; - return False; - } - *blob = data_blob(NULL, len); - asn1_read(data, blob->data, len); - asn1_end_tag(data); - return !data->has_error; -} - -static void ldap_decode_BindResponse(TALLOC_CTX *mem_ctx, - ASN1_DATA *data, - enum ldap_request_tag tag, - struct ldap_BindResponse *BindResp) -{ - asn1_start_tag(data, ASN1_APPLICATION(tag)); - asn1_read_enumerated(data, &BindResp->response.resultcode); - asn1_read_OctetString_talloc(mem_ctx, data, &BindResp->response.dn); - asn1_read_OctetString_talloc(mem_ctx, data, &BindResp->response.errormessage); - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) { - DATA_BLOB tmp_blob = data_blob(NULL, 0); - asn1_read_ContextSimple(data, 7, &tmp_blob); - BindResp->SASL.secblob = data_blob_talloc(mem_ctx, tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); + asn1_end_tag(data); } else { - BindResp->SASL.secblob = data_blob(NULL, 0); + result->referral = NULL; } asn1_end_tag(data); } @@ -1300,9 +1267,26 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_BindResponse): { struct ldap_BindResponse *r = &msg->r.BindResponse; msg->type = LDAP_TAG_BindResponse; - ldap_decode_BindResponse(msg->mem_ctx, - data, LDAP_TAG_BindResponse, - r); + asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_BindResponse)); + asn1_read_enumerated(data, &r->response.resultcode); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->response.dn); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->response.errormessage); + if (asn1_peek_tag(data, ASN1_CONTEXT(3))) { + asn1_start_tag(data, ASN1_CONTEXT(3)); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->response.referral); + asn1_end_tag(data); + } else { + r->response.referral = NULL; + } + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) { + DATA_BLOB tmp_blob = data_blob(NULL, 0); + asn1_read_ContextSimple(data, 7, &tmp_blob); + r->SASL.secblob = data_blob_talloc(msg->mem_ctx, tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->SASL.secblob = data_blob(NULL, 0); + } + asn1_end_tag(data); break; } @@ -1460,8 +1444,28 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) } case ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest): { -/* struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; */ + struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; msg->type = LDAP_TAG_ModifyDNRequest; + asn1_start_tag(data, + ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest)); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->newrdn); + asn1_read_BOOLEAN2(data, &r->deleteolddn); + r->newsuperior = NULL; + if (asn1_tag_remaining(data) > 0) { + int len; + char *newsup; + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); + len = asn1_tag_remaining(data); + newsup = talloc(msg->mem_ctx, len+1); + if (newsup == NULL) + break; + asn1_read(data, newsup, len); + newsup[len] = '\0'; + r->newsuperior = newsup; + asn1_end_tag(data); + } + asn1_end_tag(data); break; } -- cgit From ebd696bd8c73d39a3f72624e25bf85965bdf93ef Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Aug 2004 14:34:01 +0000 Subject: r1862: add invalid_creds ldap error metze (This used to be commit 11c866d602fb4daefc1dced349606bd8ccd38ef2) --- source4/libcli/ldap/ldap.h | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index af322e783a..b777bb5252 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -53,6 +53,7 @@ enum ldap_auth_mechanism { enum ldap_result_code { LDAP_SUCCESS = 0, LDAP_SASL_BIND_IN_PROGRESS = 0x0e, + LDAP_INVALID_CREDENTIALS = 0x31, LDAP_OTHER = 0x50 }; -- cgit From 46003a56a8508c0b15a763b5a723bb77eba32094 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Aug 2004 13:01:10 +0000 Subject: r1881: empty structs are not allowed by all compilers metze (This used to be commit 4c6c4d6bc8927b93f29beecf44aef5c228533a43) --- source4/libcli/ldap/ldap.h | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index b777bb5252..da844afa3e 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -91,6 +91,7 @@ struct ldap_BindResponse { }; struct ldap_UnbindRequest { + uint8_t __dummy; }; enum ldap_scope { -- cgit From 333aaf01e8dc1aba8cb7bba3e8fa792ff136e647 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 20 Aug 2004 07:39:19 +0000 Subject: r1944: put ldif functions in a separate file (This used to be commit 8be31e5c854e4462163b97b897ff41de95f181c4) --- source4/libcli/ldap/config.mk | 3 +- source4/libcli/ldap/ldap.c | 411 ---------------------------------------- source4/libcli/ldap/ldap.h | 29 +++ source4/libcli/ldap/ldap_ldif.c | 409 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 440 insertions(+), 412 deletions(-) create mode 100644 source4/libcli/ldap/ldap_ldif.c (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 397cfe0b72..ac047214ca 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,6 +1,7 @@ ################################# # Start SUBSYSTEM LIBCLI_LDAP [SUBSYSTEM::LIBCLI_LDAP] -ADD_OBJ_FILES = libcli/ldap/ldap.o +ADD_OBJ_FILES = libcli/ldap/ldap.o \ + libcli/ldap/ldap_ldif.o # End SUBSYSTEM LIBCLI_LDAP ################################# diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index b319299b1e..123def9416 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -33,35 +33,6 @@ * ***************************************************************************/ -/* Hmm. A blob might be more appropriate here :-) */ - -struct ldap_val { - unsigned int length; - void *data; -}; - -enum ldap_parse_op {LDAP_OP_SIMPLE, LDAP_OP_AND, LDAP_OP_OR, LDAP_OP_NOT}; - -struct ldap_parse_tree { - enum ldap_parse_op operation; - union { - struct { - char *attr; - struct ldap_val value; - } simple; - struct { - unsigned int num_elements; - struct ldap_parse_tree **elements; - } list; - struct { - struct ldap_parse_tree *child; - } not; - } u; -}; - -#define LDAP_ALL_SEP "()&|=!" -#define LDAP_CONNECTION_TIMEOUT 10000 - /* return next token element. Caller frees */ @@ -379,372 +350,6 @@ static BOOL ldap_push_filter(ASN1_DATA *data, struct ldap_parse_tree *tree) return !data->has_error; } -/**************************************************************************** - * - * LDIF parser - * - * Shamelessly stolen and adapted from Samba 4. - * - ***************************************************************************/ - -/* - pull a ldif chunk, which is defined as a piece of data ending in \n\n or EOF - this routine removes any RFC2849 continuations and comments - - caller frees -*/ -static char *next_chunk(TALLOC_CTX *mem_ctx, - int (*fgetc_fn)(void *), void *private_data) -{ - size_t alloc_size=0, chunk_size = 0; - char *chunk = NULL; - int c; - int in_comment = 0; - - while ((c = fgetc_fn(private_data)) != EOF) { - if (chunk_size+1 >= alloc_size) { - char *c2; - alloc_size += 1024; - c2 = talloc_realloc(mem_ctx, chunk, alloc_size); - if (!c2) { - errno = ENOMEM; - return NULL; - } - chunk = c2; - } - - if (in_comment) { - if (c == '\n') { - in_comment = 0; - } - continue; - } - - /* handle continuation lines - see RFC2849 */ - if (c == ' ' && chunk_size > 1 && - chunk[chunk_size-1] == '\n') { - chunk_size--; - continue; - } - - /* chunks are terminated by a double line-feed */ - if (c == '\n' && chunk_size > 0 && - chunk[chunk_size-1] == '\n') { - chunk[chunk_size-1] = 0; - return chunk; - } - - if (c == '#' && - (chunk_size == 0 || chunk[chunk_size-1] == '\n')) { - in_comment = 1; - continue; - } - - /* ignore leading blank lines */ - if (chunk_size == 0 && c == '\n') { - continue; - } - - chunk[chunk_size++] = c; - } - - if (chunk) { - chunk[chunk_size] = 0; - } - - return chunk; -} - -/* simple ldif attribute parser */ -static int next_attr(char **s, const char **attr, struct ldap_val *value) -{ - char *p; - int base64_encoded = 0; - - if (strncmp(*s, "-\n", 2) == 0) { - value->length = 0; - *attr = "-"; - *s += 2; - return 0; - } - - p = strchr(*s, ':'); - if (!p) { - return -1; - } - - *p++ = 0; - - if (*p == ':') { - base64_encoded = 1; - p++; - } - - *attr = *s; - - while (isspace(*p)) { - p++; - } - - value->data = p; - - p = strchr(p, '\n'); - - if (!p) { - value->length = strlen((char *)value->data); - *s = ((char *)value->data) + value->length; - } else { - value->length = p - (char *)value->data; - *s = p+1; - *p = 0; - } - - if (base64_encoded) { - DATA_BLOB blob = base64_decode_data_blob(value->data); - memcpy(value->data, blob.data, blob.length); - value->length = blob.length; - ((char *)value->data)[value->length] = '\0'; - } - - return 0; -} - -static BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldap_val *value, - struct ldap_attribute *attrib) -{ - attrib->values = talloc_realloc(mem_ctx, attrib->values, - sizeof(*attrib->values) * - (attrib->num_values+1)); - if (attrib->values == NULL) - return False; - - attrib->values[attrib->num_values] = - data_blob_talloc(mem_ctx, value->data, value->length); - attrib->num_values += 1; - return True; -} - -static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) -{ - struct ldap_AddRequest *r = &msg->r.AddRequest; - const char *attr_name; - struct ldap_val value; - - r->num_attributes = 0; - r->attributes = NULL; - - while (next_attr(chunk, &attr_name, &value) == 0) { - int i; - struct ldap_attribute *attrib = NULL; - - for (i=0; inum_attributes; i++) { - if (strequal(r->attributes[i].name, attr_name)) { - attrib = &r->attributes[i]; - break; - } - } - - if (attrib == NULL) { - r->attributes = talloc_realloc(msg->mem_ctx, - r->attributes, - sizeof(*r->attributes) * - (r->num_attributes+1)); - if (r->attributes == NULL) - return False; - - attrib = &(r->attributes[r->num_attributes]); - r->num_attributes += 1; - ZERO_STRUCTP(attrib); - attrib->name = talloc_strdup(msg->mem_ctx, - attr_name); - } - - if (!add_value_to_attrib(msg->mem_ctx, &value, attrib)) - return False; - } - return True; -} - -static BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, - struct ldap_mod *mod, - struct ldap_mod **mods, - int *num_mods) -{ - *mods = talloc_realloc(mem_ctx, *mods, - sizeof(**mods) * ((*num_mods)+1)); - - if (*mods == NULL) - return False; - - (*mods)[*num_mods] = *mod; - *num_mods += 1; - return True; -} - -static BOOL fill_mods(struct ldap_message *msg, char **chunk) -{ - struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; - const char *attr_name; - struct ldap_val value; - - r->num_mods = 0; - r->mods = NULL; - - while (next_attr(chunk, &attr_name, &value) == 0) { - - struct ldap_mod mod; - mod.type = LDAP_MODIFY_NONE; - - mod.attrib.name = talloc_strdup(msg->mem_ctx, value.data); - - if (strequal(attr_name, "add")) - mod.type = LDAP_MODIFY_ADD; - - if (strequal(attr_name, "delete")) - mod.type = LDAP_MODIFY_DELETE; - - if (strequal(attr_name, "replace")) - mod.type = LDAP_MODIFY_REPLACE; - - if (mod.type == LDAP_MODIFY_NONE) { - DEBUG(2, ("ldif modification type %s unsupported\n", - attr_name)); - return False; - } - - mod.attrib.num_values = 0; - mod.attrib.values = NULL; - - while (next_attr(chunk, &attr_name, &value) == 0) { - if (strequal(attr_name, "-")) - break; - if (!strequal(attr_name, mod.attrib.name)) { - DEBUG(3, ("attrib name %s does not " - "match %s\n", attr_name, - mod.attrib.name)); - return False; - } - if (!add_value_to_attrib(msg->mem_ctx, &value, - &mod.attrib)) { - DEBUG(3, ("Could not add value\n")); - return False; - } - } - - if (!add_mod_to_array_talloc(msg->mem_ctx, &mod, &r->mods, - &r->num_mods)) - return False; - } - - return True; -} - -/* - read from a LDIF source, creating a ldap_message -*/ -static struct ldap_message *ldif_read(int (*fgetc_fn)(void *), - void *private_data) -{ - struct ldap_message *msg; - const char *attr=NULL; - const char *dn; - char *chunk=NULL, *s; - struct ldap_val value; - - value.data = NULL; - - msg = new_ldap_message(); - if (msg == NULL) - return NULL; - - chunk = next_chunk(msg->mem_ctx, fgetc_fn, private_data); - if (!chunk) { - goto failed; - } - - s = chunk; - - if (next_attr(&s, &attr, &value) != 0) { - goto failed; - } - - /* first line must be a dn */ - if (!strequal(attr, "dn")) { - DEBUG(5, ("Error: First line of ldif must be a dn not '%s'\n", - attr)); - goto failed; - } - - dn = talloc_strdup(msg->mem_ctx, value.data); - - if (next_attr(&s, &attr, &value) != 0) { - goto failed; - } - - if (!strequal(attr, "changetype")) { - DEBUG(5, ("Error: Second line of ldif must be a changetype " - "not '%s'\n", attr)); - goto failed; - } - - if (strequal(value.data, "delete")) { - msg->type = LDAP_TAG_DelRequest; - msg->r.DelRequest.dn = dn; - return msg; - } - - if (strequal(value.data, "add")) { - msg->type = LDAP_TAG_AddRequest; - - msg->r.AddRequest.dn = dn; - - if (!fill_add_attributes(msg, &s)) - goto failed; - - return msg; - } - - if (strequal(value.data, "modify")) { - msg->type = LDAP_TAG_ModifyRequest; - - msg->r.ModifyRequest.dn = dn; - - if (!fill_mods(msg, &s)) - goto failed; - - return msg; - } - - DEBUG(3, ("changetype %s not supported\n", (char *)value.data)); - -failed: - destroy_ldap_message(msg); - return NULL; -} - -/* - a wrapper around ldif_read() for reading from const char* -*/ -struct ldif_read_string_state { - const char *s; -}; - -static int fgetc_string(void *private_data) -{ - struct ldif_read_string_state *state = private_data; - if (state->s[0] != 0) { - return *state->s++; - } - return EOF; -} - -struct ldap_message *ldap_ldif2msg(const char *s) -{ - struct ldif_read_string_state state; - state.s = s; - return ldif_read(fgetc_string, &state); -} - static void ldap_encode_response(enum ldap_request_tag tag, struct ldap_Result *result, ASN1_DATA *data) @@ -1072,22 +677,6 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, asn1_end_tag(data); } -static BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, - const struct ldap_attribute *attrib, - struct ldap_attribute **attribs, - int *num_attribs) -{ - *attribs = talloc_realloc(mem_ctx, *attribs, - sizeof(**attribs) * (*num_attribs+1)); - - if (*attribs == NULL) - return False; - - (*attribs)[*num_attribs] = *attrib; - *num_attribs += 1; - return True; -} - static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, ASN1_DATA *data, char **filter) { diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index da844afa3e..449be9e015 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -254,4 +254,33 @@ struct ldap_connection { struct gensec_security *gensec; }; +/* Hmm. A blob might be more appropriate here :-) */ + +struct ldap_val { + unsigned int length; + void *data; +}; + +enum ldap_parse_op {LDAP_OP_SIMPLE, LDAP_OP_AND, LDAP_OP_OR, LDAP_OP_NOT}; + +struct ldap_parse_tree { + enum ldap_parse_op operation; + union { + struct { + char *attr; + struct ldap_val value; + } simple; + struct { + unsigned int num_elements; + struct ldap_parse_tree **elements; + } list; + struct { + struct ldap_parse_tree *child; + } not; + } u; +}; + +#define LDAP_ALL_SEP "()&|=!" +#define LDAP_CONNECTION_TIMEOUT 10000 + #endif diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c new file mode 100644 index 0000000000..2f23dd16a6 --- /dev/null +++ b/source4/libcli/ldap/ldap_ldif.c @@ -0,0 +1,409 @@ +/* + Unix SMB/CIFS mplementation. + LDAP protocol helper functions for SAMBA + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Volker Lendecke 2004 + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Simo Sorce 2004 + + 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" + +/**************************************************************************** + * + * LDIF parser + * + * Shamelessly stolen and adapted from ldb. + * + ***************************************************************************/ + +/* + pull a ldif chunk, which is defined as a piece of data ending in \n\n or EOF + this routine removes any RFC2849 continuations and comments + + caller frees +*/ +static char *next_chunk(TALLOC_CTX *mem_ctx, + int (*fgetc_fn)(void *), void *private_data) +{ + size_t alloc_size=0, chunk_size = 0; + char *chunk = NULL; + int c; + int in_comment = 0; + + while ((c = fgetc_fn(private_data)) != EOF) { + if (chunk_size+1 >= alloc_size) { + char *c2; + alloc_size += 1024; + c2 = talloc_realloc(mem_ctx, chunk, alloc_size); + if (!c2) { + errno = ENOMEM; + return NULL; + } + chunk = c2; + } + + if (in_comment) { + if (c == '\n') { + in_comment = 0; + } + continue; + } + + /* handle continuation lines - see RFC2849 */ + if (c == ' ' && chunk_size > 1 && + chunk[chunk_size-1] == '\n') { + chunk_size--; + continue; + } + + /* chunks are terminated by a double line-feed */ + if (c == '\n' && chunk_size > 0 && + chunk[chunk_size-1] == '\n') { + chunk[chunk_size-1] = 0; + return chunk; + } + + if (c == '#' && + (chunk_size == 0 || chunk[chunk_size-1] == '\n')) { + in_comment = 1; + continue; + } + + /* ignore leading blank lines */ + if (chunk_size == 0 && c == '\n') { + continue; + } + + chunk[chunk_size++] = c; + } + + if (chunk) { + chunk[chunk_size] = 0; + } + + return chunk; +} + +/* simple ldif attribute parser */ +static int next_attr(char **s, const char **attr, struct ldap_val *value) +{ + char *p; + int base64_encoded = 0; + + if (strncmp(*s, "-\n", 2) == 0) { + value->length = 0; + *attr = "-"; + *s += 2; + return 0; + } + + p = strchr(*s, ':'); + if (!p) { + return -1; + } + + *p++ = 0; + + if (*p == ':') { + base64_encoded = 1; + p++; + } + + *attr = *s; + + while (isspace(*p)) { + p++; + } + + value->data = p; + + p = strchr(p, '\n'); + + if (!p) { + value->length = strlen((char *)value->data); + *s = ((char *)value->data) + value->length; + } else { + value->length = p - (char *)value->data; + *s = p+1; + *p = 0; + } + + if (base64_encoded) { + DATA_BLOB blob = base64_decode_data_blob(value->data); + memcpy(value->data, blob.data, blob.length); + value->length = blob.length; + ((char *)value->data)[value->length] = '\0'; + } + + return 0; +} + +BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldap_val *value, + struct ldap_attribute *attrib) +{ + attrib->values = talloc_realloc(mem_ctx, attrib->values, + sizeof(*attrib->values) * + (attrib->num_values+1)); + if (attrib->values == NULL) + return False; + + attrib->values[attrib->num_values] = + data_blob_talloc(mem_ctx, value->data, value->length); + attrib->num_values += 1; + return True; +} + +BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, + const struct ldap_attribute *attrib, + struct ldap_attribute **attribs, + int *num_attribs) +{ + *attribs = talloc_realloc(mem_ctx, *attribs, + sizeof(**attribs) * (*num_attribs+1)); + + if (*attribs == NULL) + return False; + + (*attribs)[*num_attribs] = *attrib; + *num_attribs += 1; + return True; +} + +static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) +{ + struct ldap_AddRequest *r = &msg->r.AddRequest; + const char *attr_name; + struct ldap_val value; + + r->num_attributes = 0; + r->attributes = NULL; + + while (next_attr(chunk, &attr_name, &value) == 0) { + int i; + struct ldap_attribute *attrib = NULL; + + for (i=0; inum_attributes; i++) { + if (strequal(r->attributes[i].name, attr_name)) { + attrib = &r->attributes[i]; + break; + } + } + + if (attrib == NULL) { + r->attributes = talloc_realloc(msg->mem_ctx, + r->attributes, + sizeof(*r->attributes) * + (r->num_attributes+1)); + if (r->attributes == NULL) + return False; + + attrib = &(r->attributes[r->num_attributes]); + r->num_attributes += 1; + ZERO_STRUCTP(attrib); + attrib->name = talloc_strdup(msg->mem_ctx, + attr_name); + } + + if (!add_value_to_attrib(msg->mem_ctx, &value, attrib)) + return False; + } + return True; +} + +BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, + struct ldap_mod *mod, + struct ldap_mod **mods, + int *num_mods) +{ + *mods = talloc_realloc(mem_ctx, *mods, + sizeof(**mods) * ((*num_mods)+1)); + + if (*mods == NULL) + return False; + + (*mods)[*num_mods] = *mod; + *num_mods += 1; + return True; +} + +static BOOL fill_mods(struct ldap_message *msg, char **chunk) +{ + struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; + const char *attr_name; + struct ldap_val value; + + r->num_mods = 0; + r->mods = NULL; + + while (next_attr(chunk, &attr_name, &value) == 0) { + + struct ldap_mod mod; + mod.type = LDAP_MODIFY_NONE; + + mod.attrib.name = talloc_strdup(msg->mem_ctx, value.data); + + if (strequal(attr_name, "add")) + mod.type = LDAP_MODIFY_ADD; + + if (strequal(attr_name, "delete")) + mod.type = LDAP_MODIFY_DELETE; + + if (strequal(attr_name, "replace")) + mod.type = LDAP_MODIFY_REPLACE; + + if (mod.type == LDAP_MODIFY_NONE) { + DEBUG(2, ("ldif modification type %s unsupported\n", + attr_name)); + return False; + } + + mod.attrib.num_values = 0; + mod.attrib.values = NULL; + + while (next_attr(chunk, &attr_name, &value) == 0) { + if (strequal(attr_name, "-")) + break; + if (!strequal(attr_name, mod.attrib.name)) { + DEBUG(3, ("attrib name %s does not " + "match %s\n", attr_name, + mod.attrib.name)); + return False; + } + if (!add_value_to_attrib(msg->mem_ctx, &value, + &mod.attrib)) { + DEBUG(3, ("Could not add value\n")); + return False; + } + } + + if (!add_mod_to_array_talloc(msg->mem_ctx, &mod, &r->mods, + &r->num_mods)) + return False; + } + + return True; +} + +/* + read from a LDIF source, creating a ldap_message +*/ +static struct ldap_message *ldif_read(int (*fgetc_fn)(void *), + void *private_data) +{ + struct ldap_message *msg; + const char *attr=NULL; + const char *dn; + char *chunk=NULL, *s; + struct ldap_val value; + + value.data = NULL; + + msg = new_ldap_message(); + if (msg == NULL) + return NULL; + + chunk = next_chunk(msg->mem_ctx, fgetc_fn, private_data); + if (!chunk) { + goto failed; + } + + s = chunk; + + if (next_attr(&s, &attr, &value) != 0) { + goto failed; + } + + /* first line must be a dn */ + if (!strequal(attr, "dn")) { + DEBUG(5, ("Error: First line of ldif must be a dn not '%s'\n", + attr)); + goto failed; + } + + dn = talloc_strdup(msg->mem_ctx, value.data); + + if (next_attr(&s, &attr, &value) != 0) { + goto failed; + } + + if (!strequal(attr, "changetype")) { + DEBUG(5, ("Error: Second line of ldif must be a changetype " + "not '%s'\n", attr)); + goto failed; + } + + if (strequal(value.data, "delete")) { + msg->type = LDAP_TAG_DelRequest; + msg->r.DelRequest.dn = dn; + return msg; + } + + if (strequal(value.data, "add")) { + msg->type = LDAP_TAG_AddRequest; + + msg->r.AddRequest.dn = dn; + + if (!fill_add_attributes(msg, &s)) + goto failed; + + return msg; + } + + if (strequal(value.data, "modify")) { + msg->type = LDAP_TAG_ModifyRequest; + + msg->r.ModifyRequest.dn = dn; + + if (!fill_mods(msg, &s)) + goto failed; + + return msg; + } + + DEBUG(3, ("changetype %s not supported\n", (char *)value.data)); + +failed: + destroy_ldap_message(msg); + return NULL; +} + +/* + a wrapper around ldif_read() for reading from const char* +*/ +struct ldif_read_string_state { + const char *s; +}; + +static int fgetc_string(void *private_data) +{ + struct ldif_read_string_state *state = private_data; + if (state->s[0] != 0) { + return *state->s++; + } + return EOF; +} + +struct ldap_message *ldap_ldif2msg(const char *s) +{ + struct ldif_read_string_state state; + state.s = s; + return ldif_read(fgetc_string, &state); +} + -- cgit From b83ba93eaeb2dcb0bf11615591d886fda84e4162 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 21 Aug 2004 01:54:46 +0000 Subject: r1983: a completely new implementation of talloc This version does the following: 1) talloc_free(), talloc_realloc() and talloc_steal() lose their (redundent) first arguments 2) you can use _any_ talloc pointer as a talloc context to allocate more memory. This allows you to create complex data structures where the top level structure is the logical parent of the next level down, and those are the parents of the level below that. Then destroy either the lot with a single talloc_free() or destroy any sub-part with a talloc_free() of that part 3) you can name any pointer. Use talloc_named() which is just like talloc() but takes the printf style name argument as well as the parent context and the size. The whole thing ends up being a very simple piece of code, although some of the pointer walking gets hairy. So far, I'm just using the new talloc() like the old one. The next step is to actually take advantage of the new interface properly. Expect some new commits soon that simplify some common coding styles in samba4 by using the new talloc(). (This used to be commit e35bb094c52e550b3105dd1638d8d90de71d854f) --- source4/libcli/ldap/ldap.c | 2 +- source4/libcli/ldap/ldap_ldif.c | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 123def9416..7e60e48293 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -179,7 +179,7 @@ static struct ldap_parse_tree *ldap_parse_filterlist(TALLOC_CTX *mem_ctx, while (*s && (next = ldap_parse_filter(mem_ctx, &s))) { struct ldap_parse_tree **e; - e = talloc_realloc(mem_ctx, ret->u.list.elements, + e = talloc_realloc(ret->u.list.elements, sizeof(struct ldap_parse_tree) * (ret->u.list.num_elements+1)); if (!e) { diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index 2f23dd16a6..2ec3b827ce 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -51,7 +51,7 @@ static char *next_chunk(TALLOC_CTX *mem_ctx, if (chunk_size+1 >= alloc_size) { char *c2; alloc_size += 1024; - c2 = talloc_realloc(mem_ctx, chunk, alloc_size); + c2 = talloc_realloc(chunk, alloc_size); if (!c2) { errno = ENOMEM; return NULL; @@ -158,7 +158,7 @@ static int next_attr(char **s, const char **attr, struct ldap_val *value) BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldap_val *value, struct ldap_attribute *attrib) { - attrib->values = talloc_realloc(mem_ctx, attrib->values, + attrib->values = talloc_realloc(attrib->values, sizeof(*attrib->values) * (attrib->num_values+1)); if (attrib->values == NULL) @@ -175,7 +175,7 @@ BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, struct ldap_attribute **attribs, int *num_attribs) { - *attribs = talloc_realloc(mem_ctx, *attribs, + *attribs = talloc_realloc(*attribs, sizeof(**attribs) * (*num_attribs+1)); if (*attribs == NULL) @@ -207,8 +207,7 @@ static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) } if (attrib == NULL) { - r->attributes = talloc_realloc(msg->mem_ctx, - r->attributes, + r->attributes = talloc_realloc(r->attributes, sizeof(*r->attributes) * (r->num_attributes+1)); if (r->attributes == NULL) @@ -232,7 +231,7 @@ BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, struct ldap_mod **mods, int *num_mods) { - *mods = talloc_realloc(mem_ctx, *mods, + *mods = talloc_realloc(*mods, sizeof(**mods) * ((*num_mods)+1)); if (*mods == NULL) -- cgit From 3e454a5891b73c9b021406bdb662127e1a3180dc Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 1 Sep 2004 14:49:43 +0000 Subject: r2173: Fix asn1 BOOLEANs. Thanks to Love Hornquist-Astrand. Volker (This used to be commit 53f58c053b643c8b45d2f9394faf8cfdd5005f6d) --- source4/libcli/ldap/ldap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 7e60e48293..b7ae58f7f5 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -426,7 +426,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) asn1_write_enumerated(&data, r->deref); asn1_write_Integer(&data, r->sizelimit); asn1_write_Integer(&data, r->timelimit); - asn1_write_BOOLEAN2(&data, r->attributesonly); + asn1_write_BOOLEAN(&data, r->attributesonly); { TALLOC_CTX *mem_ctx = talloc_init("ldap_parse_tree"); @@ -565,7 +565,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest)); asn1_write_OctetString(&data, r->dn, strlen(r->dn)); asn1_write_OctetString(&data, r->newrdn, strlen(r->newrdn)); - asn1_write_BOOLEAN2(&data, r->deleteolddn); + asn1_write_BOOLEAN(&data, r->deleteolddn); if (r->newsuperior != NULL) { asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(0)); asn1_write(&data, r->newsuperior, @@ -893,7 +893,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) asn1_read_enumerated(data, (int *)&(r->deref)); asn1_read_Integer(data, &r->sizelimit); asn1_read_Integer(data, &r->timelimit); - asn1_read_BOOLEAN2(data, &r->attributesonly); + asn1_read_BOOLEAN(data, &r->attributesonly); /* Maybe create a TALLOC_CTX for the filter? This can waste * quite a bit of memory recursing down. */ @@ -1039,7 +1039,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest)); asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->newrdn); - asn1_read_BOOLEAN2(data, &r->deleteolddn); + asn1_read_BOOLEAN(data, &r->deleteolddn); r->newsuperior = NULL; if (asn1_tag_remaining(data) > 0) { int len; -- cgit From d9d634ce97b2fd7d49410d26271eacd98660bbc4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Sep 2004 13:29:59 +0000 Subject: r2347: merge LDAP ASN.1 fixes from trunk metze (This used to be commit 492a00d909d6f3ff8305f102551f60d91d988ccd) --- source4/libcli/ldap/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index b7ae58f7f5..7af9ca42c5 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -602,7 +602,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; asn1_push_tag(&data, ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest)); - asn1_write_Integer(&data, r->messageid); + asn1_write_implicit_Integer(&data, r->messageid); asn1_pop_tag(&data); break; } -- cgit From defe32e9f47d9eca44533056b652f3b1c3f56c8e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 20 Sep 2004 07:24:00 +0000 Subject: r2432: more string function updates. btw, the reason I want to use strncasecmp() instead of StrnCaseCmp() is that the Samba internal functions are built to deal with multi-byte, whereas in the cases I am converting we know we are dealing with solely ascii string constants, so going via the slow conversion libraries is pointless. (This used to be commit cef08d5789277bdaa25d5bf0e7cfca8615230f1b) --- source4/libcli/ldap/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 7af9ca42c5..72e8f605dc 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1121,7 +1121,7 @@ BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, const char *p = url; /* skip leading "URL:" (if any) */ - if ( strnequal( p, "URL:", 4 ) ) { + if (strncasecmp( p, "URL:", 4) == 0) { p += 4; } -- cgit From 566c38c820a273c8ce25f16c35346a68561d50fa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 22 Sep 2004 10:42:58 +0000 Subject: r2508: - implemented ldap_decode() for UnbindRequest and ExtendedRequest - fail when we got a wrong tag in ldap_decode() metze (This used to be commit e942f414c5f9130c7ac9996612caaefd29f5eeca) --- source4/libcli/ldap/ldap.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 72e8f605dc..5d233bcdca 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -879,8 +879,10 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) break; } - case ASN1_APPLICATION(LDAP_TAG_UnbindRequest): { + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_UnbindRequest): { msg->type = LDAP_TAG_UnbindRequest; + asn1_start_tag(data, ASN1_APPLICATION_SIMPLE(LDAP_TAG_UnbindRequest)); + asn1_end_tag(data); break; } @@ -1087,8 +1089,29 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) } case ASN1_APPLICATION(LDAP_TAG_ExtendedRequest): { -/* struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; */ + struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; + DATA_BLOB tmp_blob = data_blob(NULL, 0); + msg->type = LDAP_TAG_ExtendedRequest; + asn1_start_tag(data,ASN1_APPLICATION(LDAP_TAG_ExtendedRequest)); + if (!asn1_read_ContextSimple(data, 0, &tmp_blob)) { + return False; + } + r->oid = blob2string_talloc(msg->mem_ctx, tmp_blob); + data_blob_free(&tmp_blob); + if (!r->oid) { + return False; + } + + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { + asn1_read_ContextSimple(data, 1, &tmp_blob); + r->value = data_blob_talloc(msg->mem_ctx, tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->value = data_blob(NULL, 0); + } + + asn1_end_tag(data); break; } @@ -1105,7 +1128,8 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) r->value.length = 0; break; } - + default: + return False; } asn1_end_tag(data); -- cgit From c5f4378361b9671e39fa83b043f28c972ab30b70 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 25 Sep 2004 12:08:57 +0000 Subject: r2629: convert gensec to the new talloc model by making our gensec structures a talloc child of the open connection we can be sure that it will be destroyed when the connection is dropped. (This used to be commit f12ee2f241aab1549bc1d9ca4c35a35a1ca0d09d) --- source4/libcli/ldap/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 5d233bcdca..a94a4f2f30 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1458,7 +1458,7 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha if (conn == NULL) return result; - status = gensec_client_start(&conn->gensec); + status = gensec_client_start(conn, &conn->gensec); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); return result; -- cgit From 5b44130afad1bb1764d986de3ef0e8e04b0e7357 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Sep 2004 01:36:19 +0000 Subject: r2671: we're getting too many errors caused by the talloc_realloc() API not taking a context (so when you pass a NULL pointer you end up with memory in a top level context). Fixed it by changing the API to take a context. The context is only used if the pointer you are reallocing is NULL. (This used to be commit 8dc23821c9f54b2f13049b5e608a0cafb81aa540) --- source4/libcli/ldap/ldap.c | 7 ++++--- source4/libcli/ldap/ldap_ldif.c | 27 +++++++++++++++------------ 2 files changed, 19 insertions(+), 15 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index a94a4f2f30..af21962265 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -179,9 +179,10 @@ static struct ldap_parse_tree *ldap_parse_filterlist(TALLOC_CTX *mem_ctx, while (*s && (next = ldap_parse_filter(mem_ctx, &s))) { struct ldap_parse_tree **e; - e = talloc_realloc(ret->u.list.elements, - sizeof(struct ldap_parse_tree) * - (ret->u.list.num_elements+1)); + e = talloc_realloc_p(ret, + ret->u.list.elements, + struct ldap_parse_tree *, + ret->u.list.num_elements+1); if (!e) { errno = ENOMEM; return NULL; diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index 2ec3b827ce..8fe50b6d08 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -51,7 +51,7 @@ static char *next_chunk(TALLOC_CTX *mem_ctx, if (chunk_size+1 >= alloc_size) { char *c2; alloc_size += 1024; - c2 = talloc_realloc(chunk, alloc_size); + c2 = talloc_realloc(mem_ctx, chunk, alloc_size); if (!c2) { errno = ENOMEM; return NULL; @@ -156,11 +156,12 @@ static int next_attr(char **s, const char **attr, struct ldap_val *value) } BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldap_val *value, - struct ldap_attribute *attrib) + struct ldap_attribute *attrib) { - attrib->values = talloc_realloc(attrib->values, - sizeof(*attrib->values) * - (attrib->num_values+1)); + attrib->values = talloc_realloc_p(mem_ctx, + attrib->values, + DATA_BLOB, + attrib->num_values+1); if (attrib->values == NULL) return False; @@ -175,8 +176,10 @@ BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, struct ldap_attribute **attribs, int *num_attribs) { - *attribs = talloc_realloc(*attribs, - sizeof(**attribs) * (*num_attribs+1)); + *attribs = talloc_realloc_p(mem_ctx, + *attribs, + struct ldap_attribute, + *num_attribs+1); if (*attribs == NULL) return False; @@ -207,9 +210,10 @@ static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) } if (attrib == NULL) { - r->attributes = talloc_realloc(r->attributes, - sizeof(*r->attributes) * - (r->num_attributes+1)); + r->attributes = talloc_realloc_p(msg->mem_ctx, + r->attributes, + struct ldap_attribute, + r->num_attributes+1); if (r->attributes == NULL) return False; @@ -231,8 +235,7 @@ BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, struct ldap_mod **mods, int *num_mods) { - *mods = talloc_realloc(*mods, - sizeof(**mods) * ((*num_mods)+1)); + *mods = talloc_realloc_p(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1); if (*mods == NULL) return False; -- cgit From 456e2f82e801cbc26898fad20c273b05248ee0d6 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 27 Sep 2004 14:11:11 +0000 Subject: r2689: Use consistent naming Del -> Delete Add delete functionality to ldb simple lda server backend add some const in ldap.h (This used to be commit 5ed9a6eb184f34eb572dd81202237042518ec7cd) --- source4/libcli/ldap/ldap.c | 26 +++++++++++++------------- source4/libcli/ldap/ldap.h | 11 ++++++----- source4/libcli/ldap/ldap_ldif.c | 7 ++----- 3 files changed, 21 insertions(+), 23 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index af21962265..12842b4dc4 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -547,16 +547,16 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) ldap_encode_response(msg->type, r, &data); break; } - case LDAP_TAG_DelRequest: { - struct ldap_DelRequest *r = &msg->r.DelRequest; + case LDAP_TAG_DeleteRequest: { + struct ldap_DeleteRequest *r = &msg->r.DeleteRequest; asn1_push_tag(&data, - ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); + ASN1_APPLICATION_SIMPLE(LDAP_TAG_DeleteRequest)); asn1_write(&data, r->dn, strlen(r->dn)); asn1_pop_tag(&data); break; } - case LDAP_TAG_DelResponse: { - struct ldap_Result *r = &msg->r.DelResponse; + case LDAP_TAG_DeleteResponse: { + struct ldap_Result *r = &msg->r.DeleteResponse; ldap_encode_response(msg->type, r, &data); break; } @@ -1009,13 +1009,13 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) break; } - case ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest): { - struct ldap_DelRequest *r = &msg->r.DelRequest; + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_DeleteRequest): { + struct ldap_DeleteRequest *r = &msg->r.DeleteRequest; int len; char *dn; - msg->type = LDAP_TAG_DelRequest; + msg->type = LDAP_TAG_DeleteRequest; asn1_start_tag(data, - ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); + ASN1_APPLICATION_SIMPLE(LDAP_TAG_DeleteRequest)); len = asn1_tag_remaining(data); dn = talloc(msg->mem_ctx, len+1); if (dn == NULL) @@ -1027,11 +1027,11 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) break; } - case ASN1_APPLICATION(LDAP_TAG_DelResponse): { - struct ldap_Result *r = &msg->r.DelResponse; - msg->type = LDAP_TAG_DelResponse; + case ASN1_APPLICATION(LDAP_TAG_DeleteResponse): { + struct ldap_Result *r = &msg->r.DeleteResponse; + msg->type = LDAP_TAG_DeleteResponse; ldap_decode_response(msg->mem_ctx, data, - LDAP_TAG_DelResponse, r); + LDAP_TAG_DeleteResponse, r); break; } diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 449be9e015..cda065ce6e 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -33,8 +33,8 @@ enum ldap_request_tag { LDAP_TAG_ModifyResponse = 7, LDAP_TAG_AddRequest = 8, LDAP_TAG_AddResponse = 9, - LDAP_TAG_DelRequest = 10, - LDAP_TAG_DelResponse = 11, + LDAP_TAG_DeleteRequest = 10, + LDAP_TAG_DeleteResponse = 11, LDAP_TAG_ModifyDNRequest = 12, LDAP_TAG_ModifyDNResponse = 13, LDAP_TAG_CompareRequest = 14, @@ -53,6 +53,7 @@ enum ldap_auth_mechanism { enum ldap_result_code { LDAP_SUCCESS = 0, LDAP_SASL_BIND_IN_PROGRESS = 0x0e, + LDAP_NO_SUCH_OBJECT = 0x20, LDAP_INVALID_CREDENTIALS = 0x31, LDAP_OTHER = 0x50 }; @@ -154,7 +155,7 @@ struct ldap_AddRequest { struct ldap_attribute *attributes; }; -struct ldap_DelRequest { +struct ldap_DeleteRequest { const char *dn; }; @@ -198,8 +199,8 @@ union ldap_Request { struct ldap_Result ModifyResponse; struct ldap_AddRequest AddRequest; struct ldap_Result AddResponse; - struct ldap_DelRequest DelRequest; - struct ldap_Result DelResponse; + struct ldap_DeleteRequest DeleteRequest; + struct ldap_Result DeleteResponse; struct ldap_ModifyDNRequest ModifyDNRequest; struct ldap_Result ModifyDNResponse; struct ldap_CompareRequest CompareRequest; diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index 8fe50b6d08..df912c038a 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -3,9 +3,6 @@ LDAP protocol helper functions for SAMBA Copyright (C) Andrew Tridgell 2004 - Copyright (C) Volker Lendecke 2004 - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Simo Sorce 2004 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 @@ -352,8 +349,8 @@ static struct ldap_message *ldif_read(int (*fgetc_fn)(void *), } if (strequal(value.data, "delete")) { - msg->type = LDAP_TAG_DelRequest; - msg->r.DelRequest.dn = dn; + msg->type = LDAP_TAG_DeleteRequest; + msg->r.DeleteRequest.dn = dn; return msg; } -- cgit From 159b8c2d386af821d265c9cfb5896c001ae8852a Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 27 Sep 2004 14:18:25 +0000 Subject: r2690: deleted by mistake (This used to be commit 3d587a7141908362657afc2dfd0c78d73a5fed07) --- source4/libcli/ldap/ldap_ldif.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index df912c038a..8530a60a29 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -3,6 +3,9 @@ LDAP protocol helper functions for SAMBA Copyright (C) Andrew Tridgell 2004 + Copyright (C) Volker Lendecke 2004 + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Simo Sorce 2004 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 -- cgit From eac532ee3af95654b62d4db57feea0df6abab345 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 27 Sep 2004 15:40:12 +0000 Subject: r2695: revert "Del" renaming (This used to be commit ddd74dae8efe4e04b5a56ee9ecd9d4f87f99d104) --- source4/libcli/ldap/ldap.c | 26 +++++++++++++------------- source4/libcli/ldap/ldap.h | 10 +++++----- source4/libcli/ldap/ldap_ldif.c | 4 ++-- 3 files changed, 20 insertions(+), 20 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 12842b4dc4..af21962265 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -547,16 +547,16 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) ldap_encode_response(msg->type, r, &data); break; } - case LDAP_TAG_DeleteRequest: { - struct ldap_DeleteRequest *r = &msg->r.DeleteRequest; + case LDAP_TAG_DelRequest: { + struct ldap_DelRequest *r = &msg->r.DelRequest; asn1_push_tag(&data, - ASN1_APPLICATION_SIMPLE(LDAP_TAG_DeleteRequest)); + ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); asn1_write(&data, r->dn, strlen(r->dn)); asn1_pop_tag(&data); break; } - case LDAP_TAG_DeleteResponse: { - struct ldap_Result *r = &msg->r.DeleteResponse; + case LDAP_TAG_DelResponse: { + struct ldap_Result *r = &msg->r.DelResponse; ldap_encode_response(msg->type, r, &data); break; } @@ -1009,13 +1009,13 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) break; } - case ASN1_APPLICATION_SIMPLE(LDAP_TAG_DeleteRequest): { - struct ldap_DeleteRequest *r = &msg->r.DeleteRequest; + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest): { + struct ldap_DelRequest *r = &msg->r.DelRequest; int len; char *dn; - msg->type = LDAP_TAG_DeleteRequest; + msg->type = LDAP_TAG_DelRequest; asn1_start_tag(data, - ASN1_APPLICATION_SIMPLE(LDAP_TAG_DeleteRequest)); + ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); len = asn1_tag_remaining(data); dn = talloc(msg->mem_ctx, len+1); if (dn == NULL) @@ -1027,11 +1027,11 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) break; } - case ASN1_APPLICATION(LDAP_TAG_DeleteResponse): { - struct ldap_Result *r = &msg->r.DeleteResponse; - msg->type = LDAP_TAG_DeleteResponse; + case ASN1_APPLICATION(LDAP_TAG_DelResponse): { + struct ldap_Result *r = &msg->r.DelResponse; + msg->type = LDAP_TAG_DelResponse; ldap_decode_response(msg->mem_ctx, data, - LDAP_TAG_DeleteResponse, r); + LDAP_TAG_DelResponse, r); break; } diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index cda065ce6e..ca546e11e1 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -33,8 +33,8 @@ enum ldap_request_tag { LDAP_TAG_ModifyResponse = 7, LDAP_TAG_AddRequest = 8, LDAP_TAG_AddResponse = 9, - LDAP_TAG_DeleteRequest = 10, - LDAP_TAG_DeleteResponse = 11, + LDAP_TAG_DelRequest = 10, + LDAP_TAG_DelResponse = 11, LDAP_TAG_ModifyDNRequest = 12, LDAP_TAG_ModifyDNResponse = 13, LDAP_TAG_CompareRequest = 14, @@ -155,7 +155,7 @@ struct ldap_AddRequest { struct ldap_attribute *attributes; }; -struct ldap_DeleteRequest { +struct ldap_DelRequest { const char *dn; }; @@ -199,8 +199,8 @@ union ldap_Request { struct ldap_Result ModifyResponse; struct ldap_AddRequest AddRequest; struct ldap_Result AddResponse; - struct ldap_DeleteRequest DeleteRequest; - struct ldap_Result DeleteResponse; + struct ldap_DelRequest DelRequest; + struct ldap_Result DelResponse; struct ldap_ModifyDNRequest ModifyDNRequest; struct ldap_Result ModifyDNResponse; struct ldap_CompareRequest CompareRequest; diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index 8530a60a29..8fe50b6d08 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -352,8 +352,8 @@ static struct ldap_message *ldif_read(int (*fgetc_fn)(void *), } if (strequal(value.data, "delete")) { - msg->type = LDAP_TAG_DeleteRequest; - msg->r.DeleteRequest.dn = dn; + msg->type = LDAP_TAG_DelRequest; + msg->r.DelRequest.dn = dn; return msg; } -- cgit From 88ead90b1d6f7e32181b5e9bf2b48cf0ef0b7c95 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 29 Sep 2004 12:18:06 +0000 Subject: r2747: use DATA_BLOB for attribute values en/decode CompareRequest/Response correct metze (This used to be commit 72dfea2b07aea83d0965a585f6e388eb88a7c6d1) --- source4/libcli/ldap/ldap.c | 20 ++++++++++++++++---- source4/libcli/ldap/ldap.h | 2 +- 2 files changed, 17 insertions(+), 5 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index af21962265..a2f8e91b6c 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -589,14 +589,15 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) asn1_push_tag(&data, ASN1_SEQUENCE(0)); asn1_write_OctetString(&data, r->attribute, strlen(r->attribute)); - asn1_write_OctetString(&data, r->value, - strlen(r->value)); + asn1_write_OctetString(&data, r->value.data, + r->value.length); asn1_pop_tag(&data); asn1_pop_tag(&data); break; } case LDAP_TAG_CompareResponse: { -/* struct ldap_Result *r = &msg->r.CompareResponse; */ + struct ldap_Result *r = &msg->r.ModifyDNResponse; + ldap_encode_response(msg->type, r, &data); break; } case LDAP_TAG_AbandonRequest: { @@ -1070,8 +1071,19 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) } case ASN1_APPLICATION(LDAP_TAG_CompareRequest): { -/* struct ldap_CompareRequest *r = &msg->r.CompareRequest; */ + struct ldap_CompareRequest *r = &msg->r.CompareRequest; msg->type = LDAP_TAG_CompareRequest; + asn1_start_tag(data, + ASN1_APPLICATION(LDAP_TAG_CompareRequest)); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->attribute); + asn1_read_OctetString(data, &r->value); + if (r->value.data) { + talloc_steal(msg->mem_ctx, r->value.data); + } + asn1_end_tag(data); + asn1_end_tag(data); break; } diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index ca546e11e1..c0d16e67a3 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -169,7 +169,7 @@ struct ldap_ModifyDNRequest { struct ldap_CompareRequest { const char *dn; const char *attribute; - const char *value; + DATA_BLOB value; }; struct ldap_AbandonRequest { -- cgit From cd5326a44ee1f83ff9a1d96d50b56db9a2eb0d94 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 29 Sep 2004 13:06:26 +0000 Subject: r2750: decode AbandonRequest correct (untested:-) metze (This used to be commit 4233067921d386d4bf02218b479083cdbe2bd3c1) --- source4/libcli/ldap/ldap.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index a2f8e91b6c..c78e49bdfe 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1095,9 +1095,13 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) break; } - case ASN1_APPLICATION(LDAP_TAG_AbandonRequest): { -/* struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; */ + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest): { + struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; msg->type = LDAP_TAG_AbandonRequest; + asn1_start_tag(data, + ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest)); + asn1_read_implicit_Integer(data, &r->messageid); + asn1_end_tag(data); break; } -- cgit From dba5773d9d0b2a92938b8f3c434a4d6ef17cc236 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 7 Oct 2004 14:46:58 +0000 Subject: r2851: don't destroy the gensec context it's used for sign and seal check the result of ldap_receive() metze (This used to be commit 778cf6d92bc3c50add43b573652c2aefef65026c) --- source4/libcli/ldap/ldap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index c78e49bdfe..bea78a8928 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1557,8 +1557,6 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha } done: - if (conn->gensec) - gensec_end(&conn->gensec); if (mem_ctx) talloc_destroy(mem_ctx); @@ -1696,6 +1694,9 @@ struct ldap_message *ldap_getsearchent(struct ldap_connection *conn, } result = ldap_receive(conn, conn->searchid, endtime); + if (!result) { + return NULL; + } if (result->type == LDAP_TAG_SearchResultEntry) return result; -- cgit From 6aa4a9bd1648237cac01724932efdd991786441e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 7 Oct 2004 15:13:20 +0000 Subject: r2853: add torture test to find the defaultNamingContext on the RootDSE try a sasl sealed CompareRequest abartlet: we need to check how SINGING only can work, it failed for me:-( metze (This used to be commit 1dabd04e265bbc1e8335f816708c2639746d9afd) --- source4/libcli/ldap/ldap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index bea78a8928..b589b6dd6d 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1481,6 +1481,8 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha return result; } + gensec_want_feature(conn->gensec, GENSEC_WANT_SIGN|GENSEC_WANT_SEAL); + status = gensec_set_domain(conn->gensec, domain); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n", -- cgit From 78782df5542290a7a10a4e8c933f99d9962dfffd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Oct 2004 12:08:43 +0000 Subject: r2861: encode and decode BindRequest/Response correct and some minor changes - make ldap_encode/decode_response maore usable metze (This used to be commit cc77baf729a56499e19a50dcb1a404a4777b36d5) --- source4/libcli/ldap/ldap.c | 151 ++++++++++++++++++++++++--------------------- 1 file changed, 82 insertions(+), 69 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index b589b6dd6d..fbb5a21d84 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -351,11 +351,8 @@ static BOOL ldap_push_filter(ASN1_DATA *data, struct ldap_parse_tree *tree) return !data->has_error; } -static void ldap_encode_response(enum ldap_request_tag tag, - struct ldap_Result *result, - ASN1_DATA *data) +static void ldap_encode_response(ASN1_DATA *data, struct ldap_Result *result) { - asn1_push_tag(data, ASN1_APPLICATION(tag)); asn1_write_enumerated(data, result->resultcode); asn1_write_OctetString(data, result->dn, (result->dn) ? strlen(result->dn) : 0); @@ -365,7 +362,6 @@ static void ldap_encode_response(enum ldap_request_tag tag, if (result->referral != NULL) asn1_write_OctetString(data, result->referral, strlen(result->referral)); - asn1_pop_tag(data); } BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) @@ -380,7 +376,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) switch (msg->type) { case LDAP_TAG_BindRequest: { struct ldap_BindRequest *r = &msg->r.BindRequest; - asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_BindRequest)); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); asn1_write_Integer(&data, r->version); asn1_write_OctetString(&data, r->dn, (r->dn != NULL) ? strlen(r->dn) : 0); @@ -388,14 +384,14 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) switch (r->mechanism) { case LDAP_AUTH_MECH_SIMPLE: /* context, primitive */ - asn1_push_tag(&data, r->mechanism | 0x80); + asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(0)); asn1_write(&data, r->creds.password, strlen(r->creds.password)); asn1_pop_tag(&data); break; case LDAP_AUTH_MECH_SASL: /* context, constructed */ - asn1_push_tag(&data, r->mechanism | 0xa0); + asn1_push_tag(&data, ASN1_CONTEXT(3)); asn1_write_OctetString(&data, r->creds.SASL.mechanism, strlen(r->creds.SASL.mechanism)); asn1_write_OctetString(&data, r->creds.SASL.secblob.data, @@ -412,7 +408,12 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_BindResponse: { struct ldap_BindResponse *r = &msg->r.BindResponse; - ldap_encode_response(msg->type, &r->response, &data); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(&data, &r->response); + if (r->SASL.secblob.length > 0) { + asn1_write_ContextSimple(&data, 7, &r->SASL.secblob); + } + asn1_pop_tag(&data); break; } case LDAP_TAG_UnbindRequest: { @@ -421,7 +422,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_SearchRequest: { struct ldap_SearchRequest *r = &msg->r.SearchRequest; - asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_SearchRequest)); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); asn1_write_OctetString(&data, r->basedn, strlen(r->basedn)); asn1_write_enumerated(&data, r->scope); asn1_write_enumerated(&data, r->deref); @@ -458,7 +459,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_SearchResultEntry: { struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; - asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_SearchResultEntry)); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); asn1_write_OctetString(&data, r->dn, strlen(r->dn)); asn1_push_tag(&data, ASN1_SEQUENCE(0)); for (i=0; inum_attributes; i++) { @@ -481,12 +482,14 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_SearchResultDone: { struct ldap_Result *r = &msg->r.SearchResultDone; - ldap_encode_response(msg->type, r, &data); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(&data, r); + asn1_pop_tag(&data); break; } case LDAP_TAG_ModifyRequest: { struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; - asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest)); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); asn1_write_OctetString(&data, r->dn, strlen(r->dn)); asn1_push_tag(&data, ASN1_SEQUENCE(0)); @@ -515,12 +518,14 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_ModifyResponse: { struct ldap_Result *r = &msg->r.ModifyResponse; - ldap_encode_response(msg->type, r, &data); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(&data, r); + asn1_pop_tag(&data); break; } case LDAP_TAG_AddRequest: { struct ldap_AddRequest *r = &msg->r.AddRequest; - asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_AddRequest)); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); asn1_write_OctetString(&data, r->dn, strlen(r->dn)); asn1_push_tag(&data, ASN1_SEQUENCE(0)); @@ -544,26 +549,28 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_AddResponse: { struct ldap_Result *r = &msg->r.AddResponse; - ldap_encode_response(msg->type, r, &data); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(&data, r); + asn1_pop_tag(&data); break; } case LDAP_TAG_DelRequest: { struct ldap_DelRequest *r = &msg->r.DelRequest; - asn1_push_tag(&data, - ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); + asn1_push_tag(&data, ASN1_APPLICATION_SIMPLE(msg->type)); asn1_write(&data, r->dn, strlen(r->dn)); asn1_pop_tag(&data); break; } case LDAP_TAG_DelResponse: { struct ldap_Result *r = &msg->r.DelResponse; - ldap_encode_response(msg->type, r, &data); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(&data, r); + asn1_pop_tag(&data); break; } case LDAP_TAG_ModifyDNRequest: { struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; - asn1_push_tag(&data, - ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest)); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); asn1_write_OctetString(&data, r->dn, strlen(r->dn)); asn1_write_OctetString(&data, r->newrdn, strlen(r->newrdn)); asn1_write_BOOLEAN(&data, r->deleteolddn); @@ -578,13 +585,14 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_ModifyDNResponse: { struct ldap_Result *r = &msg->r.ModifyDNResponse; - ldap_encode_response(msg->type, r, &data); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(&data, r); + asn1_pop_tag(&data); break; } case LDAP_TAG_CompareRequest: { struct ldap_CompareRequest *r = &msg->r.CompareRequest; - asn1_push_tag(&data, - ASN1_APPLICATION(LDAP_TAG_CompareRequest)); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); asn1_write_OctetString(&data, r->dn, strlen(r->dn)); asn1_push_tag(&data, ASN1_SEQUENCE(0)); asn1_write_OctetString(&data, r->attribute, @@ -597,13 +605,14 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_CompareResponse: { struct ldap_Result *r = &msg->r.ModifyDNResponse; - ldap_encode_response(msg->type, r, &data); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(&data, r); + asn1_pop_tag(&data); break; } case LDAP_TAG_AbandonRequest: { struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; - asn1_push_tag(&data, - ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest)); + asn1_push_tag(&data, ASN1_APPLICATION_SIMPLE(msg->type)); asn1_write_implicit_Integer(&data, r->messageid); asn1_pop_tag(&data); break; @@ -614,7 +623,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_ExtendedRequest: { struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; - asn1_push_tag(&data, ASN1_APPLICATION(LDAP_TAG_ExtendedRequest)); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(0)); asn1_write(&data, r->oid, strlen(r->oid)); asn1_pop_tag(&data); @@ -626,7 +635,9 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_ExtendedResponse: { struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; - ldap_encode_response(msg->type, &r->response, &data); + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(&data, &r->response); + asn1_pop_tag(&data); break; } default: @@ -662,10 +673,8 @@ static BOOL asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, static void ldap_decode_response(TALLOC_CTX *mem_ctx, ASN1_DATA *data, - enum ldap_request_tag tag, struct ldap_Result *result) { - asn1_start_tag(data, ASN1_APPLICATION(tag)); asn1_read_enumerated(data, &result->resultcode); asn1_read_OctetString_talloc(mem_ctx, data, &result->dn); asn1_read_OctetString_talloc(mem_ctx, data, &result->errormessage); @@ -676,7 +685,6 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, } else { result->referral = NULL; } - asn1_end_tag(data); } static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, ASN1_DATA *data, @@ -834,14 +842,14 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_BindRequest): { struct ldap_BindRequest *r = &msg->r.BindRequest; msg->type = LDAP_TAG_BindRequest; - asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_BindRequest)); + asn1_start_tag(data, tag); asn1_read_Integer(data, &r->version); asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); - if (asn1_peek_tag(data, 0x80)) { + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(0))) { int pwlen; r->creds.password = ""; - /* Mechanism 0 (SIMPLE) */ - asn1_start_tag(data, 0x80); + r->mechanism = LDAP_AUTH_MECH_SIMPLE; + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); pwlen = asn1_tag_remaining(data); if (pwlen != 0) { char *pw = talloc(msg->mem_ctx, pwlen+1); @@ -850,6 +858,15 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) r->creds.password = pw; } asn1_end_tag(data); + } else if (asn1_peek_tag(data, ASN1_CONTEXT(3))){ + asn1_start_tag(data, ASN1_CONTEXT(3)); + r->mechanism = LDAP_AUTH_MECH_SASL; + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->creds.SASL.mechanism); + asn1_read_OctetString(data, &r->creds.SASL.secblob); + if (r->creds.SASL.secblob.data) { + talloc_steal(msg->mem_ctx, r->creds.SASL.secblob.data); + } + asn1_end_tag(data); } asn1_end_tag(data); break; @@ -858,17 +875,8 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_BindResponse): { struct ldap_BindResponse *r = &msg->r.BindResponse; msg->type = LDAP_TAG_BindResponse; - asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_BindResponse)); - asn1_read_enumerated(data, &r->response.resultcode); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->response.dn); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->response.errormessage); - if (asn1_peek_tag(data, ASN1_CONTEXT(3))) { - asn1_start_tag(data, ASN1_CONTEXT(3)); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->response.referral); - asn1_end_tag(data); - } else { - r->response.referral = NULL; - } + asn1_start_tag(data, tag); + ldap_decode_response(msg->mem_ctx, data, &r->response); if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) { DATA_BLOB tmp_blob = data_blob(NULL, 0); asn1_read_ContextSimple(data, 7, &tmp_blob); @@ -883,7 +891,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION_SIMPLE(LDAP_TAG_UnbindRequest): { msg->type = LDAP_TAG_UnbindRequest; - asn1_start_tag(data, ASN1_APPLICATION_SIMPLE(LDAP_TAG_UnbindRequest)); + asn1_start_tag(data, tag); asn1_end_tag(data); break; } @@ -891,7 +899,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_SearchRequest): { struct ldap_SearchRequest *r = &msg->r.SearchRequest; msg->type = LDAP_TAG_SearchRequest; - asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_SearchRequest)); + asn1_start_tag(data, tag); asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->basedn); asn1_read_enumerated(data, (int *)&(r->scope)); asn1_read_enumerated(data, (int *)&(r->deref)); @@ -929,8 +937,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) msg->type = LDAP_TAG_SearchResultEntry; r->attributes = NULL; r->num_attributes = 0; - asn1_start_tag(data, - ASN1_APPLICATION(LDAP_TAG_SearchResultEntry)); + asn1_start_tag(data, tag); asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); ldap_decode_attribs(msg->mem_ctx, data, &r->attributes, &r->num_attributes); @@ -941,8 +948,9 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_SearchResultDone): { struct ldap_Result *r = &msg->r.SearchResultDone; msg->type = LDAP_TAG_SearchResultDone; - ldap_decode_response(msg->mem_ctx, data, - LDAP_TAG_SearchResultDone, r); + asn1_start_tag(data, tag); + ldap_decode_response(msg->mem_ctx, data, r); + asn1_end_tag(data); break; } @@ -982,15 +990,16 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_ModifyResponse): { struct ldap_Result *r = &msg->r.ModifyResponse; msg->type = LDAP_TAG_ModifyResponse; - ldap_decode_response(msg->mem_ctx, data, - LDAP_TAG_ModifyResponse, r); + asn1_start_tag(data, tag); + ldap_decode_response(msg->mem_ctx, data, r); + asn1_end_tag(data); break; } case ASN1_APPLICATION(LDAP_TAG_AddRequest): { struct ldap_AddRequest *r = &msg->r.AddRequest; msg->type = LDAP_TAG_AddRequest; - asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_AddRequest)); + asn1_start_tag(data, tag); asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); r->attributes = NULL; @@ -1005,8 +1014,9 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_AddResponse): { struct ldap_Result *r = &msg->r.AddResponse; msg->type = LDAP_TAG_AddResponse; - ldap_decode_response(msg->mem_ctx, data, - LDAP_TAG_AddResponse, r); + asn1_start_tag(data, tag); + ldap_decode_response(msg->mem_ctx, data, r); + asn1_end_tag(data); break; } @@ -1031,8 +1041,9 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_DelResponse): { struct ldap_Result *r = &msg->r.DelResponse; msg->type = LDAP_TAG_DelResponse; - ldap_decode_response(msg->mem_ctx, data, - LDAP_TAG_DelResponse, r); + asn1_start_tag(data, tag); + ldap_decode_response(msg->mem_ctx, data, r); + asn1_end_tag(data); break; } @@ -1065,8 +1076,9 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_ModifyDNResponse): { struct ldap_Result *r = &msg->r.ModifyDNResponse; msg->type = LDAP_TAG_ModifyDNResponse; - ldap_decode_response(msg->mem_ctx, data, - LDAP_TAG_ModifyDNResponse, r); + asn1_start_tag(data, tag); + ldap_decode_response(msg->mem_ctx, data, r); + asn1_end_tag(data); break; } @@ -1090,16 +1102,16 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_CompareResponse): { struct ldap_Result *r = &msg->r.CompareResponse; msg->type = LDAP_TAG_CompareResponse; - ldap_decode_response(msg->mem_ctx, data, - LDAP_TAG_CompareResponse, r); + asn1_start_tag(data, tag); + ldap_decode_response(msg->mem_ctx, data, r); + asn1_end_tag(data); break; } case ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest): { struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; msg->type = LDAP_TAG_AbandonRequest; - asn1_start_tag(data, - ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest)); + asn1_start_tag(data, tag); asn1_read_implicit_Integer(data, &r->messageid); asn1_end_tag(data); break; @@ -1110,7 +1122,7 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) DATA_BLOB tmp_blob = data_blob(NULL, 0); msg->type = LDAP_TAG_ExtendedRequest; - asn1_start_tag(data,ASN1_APPLICATION(LDAP_TAG_ExtendedRequest)); + asn1_start_tag(data,tag); if (!asn1_read_ContextSimple(data, 0, &tmp_blob)) { return False; } @@ -1135,14 +1147,15 @@ BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_ExtendedResponse): { struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; msg->type = LDAP_TAG_ExtendedResponse; - ldap_decode_response(msg->mem_ctx, data, - LDAP_TAG_ExtendedResponse, &r->response); + asn1_start_tag(data, tag); + ldap_decode_response(msg->mem_ctx, data, &r->response); /* I have to come across an operation that actually sends * something back to really see what's going on. The currently * needed pwdchange does not send anything back. */ r->name = NULL; r->value.data = NULL; r->value.length = 0; + asn1_end_tag(data); break; } default: -- cgit From f49f6e0c83a8296bcaba3cb11b5fcaa55dd5ce5d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 9 Oct 2004 23:59:12 +0000 Subject: r2884: parse LDAP Control messages metze (This used to be commit e23dcb18870450be4252a0dba3e427f73291da25) --- source4/libcli/ldap/ldap.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index fbb5a21d84..7e12f42f06 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1162,6 +1162,47 @@ BOOL ldap_decode(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; + + 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_p(msg->mem_ctx, ctrl, struct ldap_Control, i+1); + 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); + } + + if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { + asn1_read_OctetString(data, &ctrl[i].value); + if (ctrl[i].value.data) { + talloc_steal(msg->mem_ctx, ctrl[i].value.data); + } + } + + asn1_end_tag(data); + } + msg->num_controls = i; + msg->controls = ctrl; + + asn1_end_tag(data); + } + asn1_end_tag(data); return ((!data->has_error) && (data->nesting == NULL)); } -- cgit From d0d86b53483f1455fa41ed457502d1452be336fb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 20 Oct 2004 02:14:28 +0000 Subject: r3079: make code more pretty :-) Andrew Bartlett (This used to be commit 9c911b361c4dbb058eb48150c113c2e95b8053da) --- source4/libcli/ldap/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 7e12f42f06..6e182c3843 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1535,7 +1535,7 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha return result; } - gensec_want_feature(conn->gensec, GENSEC_WANT_SIGN|GENSEC_WANT_SEAL); + gensec_want_feature(conn->gensec, GENSEC_WANT_SIGN | GENSEC_WANT_SEAL); status = gensec_set_domain(conn->gensec, domain); if (!NT_STATUS_IS_OK(status)) { -- cgit From 86ab5f126723b3af71506b2f7f43741018b6286a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 20 Oct 2004 20:34:32 +0000 Subject: r3094: import all LDAP error codes from the RFC 2251 metze (This used to be commit f1d8f4bc5df5b4f284739096684c9dbc76352511) --- source4/libcli/ldap/ldap.h | 44 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index c0d16e67a3..6492df41d9 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -51,11 +51,45 @@ enum ldap_auth_mechanism { }; enum ldap_result_code { - LDAP_SUCCESS = 0, - LDAP_SASL_BIND_IN_PROGRESS = 0x0e, - LDAP_NO_SUCH_OBJECT = 0x20, - LDAP_INVALID_CREDENTIALS = 0x31, - LDAP_OTHER = 0x50 + LDAP_SUCCESS = 0, + LDAP_OPERATIONS_ERROR = 1, + LDAP_PROTOCOL_ERROR = 2, + LDAP_TIME_LIMIT_EXCEEDED = 3, + LDAP_SIZE_LIMIT_EXCEEDED = 4, + LDAP_COMPARE_FALSE = 5, + LDAP_COMPARE_TRUe = 6, + LDAP_AUTH_METHOD_NOT_SUPPORTED = 7, + LDAP_STRONG_AUTH_REQUIRED = 8, + LDAP_REFERRAL = 10, + LDAP_ADMIN_LIMIT_EXCEEDED = 11, + LDAP_UNAVAILABLE_CRITICAL_EXTENSION = 12, + LDAP_CONFIDENTIALITY_REQUIRED = 13, + LDAP_SASL_BIND_IN_PROGRESS = 14, + LDAP_NO_SUCH_ATTRIBUTE = 16, + LDAP_UNDEFINED_ATTRIBUTE_TYPE = 17, + LDAP_INAPPROPRIATE_MATCHING = 18, + LDAP_CONSTRAINT_VIOLATION = 19, + LDAP_ATTRIBUTE_OR_VALUE_EXISTS = 20, + LDAP_INVALID_ATTRIBUTE_SYNTAX = 21, + LDAP_NO_SUCH_OBJECT = 32, + LDAP_ALIAS_PROBLEM = 33, + LDAP_INVALID_DN_SYNTAX = 34, + LDAP_ALIAS_DEREFERENCING_PROBLEM = 36, + LDAP_INAPPROPRIATE_AUTHENTICATION = 48, + LDAP_INVALID_CREDENTIALS = 49, + LDAP_INSUFFICIENT_ACCESS_RIGHTs = 50, + LDAP_BUSY = 51, + LDAP_UNAVAILABLE = 52, + LDAP_UNWILLING_TO_PERFORM = 53, + LDAP_LOOP_DETECT = 54, + LDAP_NAMING_VIOLATION = 64, + LDAP_OBJECT_CLASS_VIOLATION = 65, + LDAP_NOT_ALLOWED_ON_NON_LEAF = 66, + LDAP_NOT_ALLOWED_ON_RDN = 67, + LDAP_ENTRY_ALREADY_EXISTS = 68, + LDAP_OBJECT_CLASS_MODS_PROHIBITED = 69, + LDAP_AFFECTS_MULTIPLE_DSAS = 71, + LDAP_OTHER = 80 }; struct ldap_Result { -- cgit From 367b3bfa12aada4254cfdb8e1de5929be675c952 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 20 Oct 2004 22:44:08 +0000 Subject: r3096: typo metze (This used to be commit c730d7d638875c239f0b67c1d4b25eb1fb01c5ff) --- source4/libcli/ldap/ldap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 6492df41d9..c27aba8d7a 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -57,7 +57,7 @@ enum ldap_result_code { LDAP_TIME_LIMIT_EXCEEDED = 3, LDAP_SIZE_LIMIT_EXCEEDED = 4, LDAP_COMPARE_FALSE = 5, - LDAP_COMPARE_TRUe = 6, + LDAP_COMPARE_TRUE = 6, LDAP_AUTH_METHOD_NOT_SUPPORTED = 7, LDAP_STRONG_AUTH_REQUIRED = 8, LDAP_REFERRAL = 10, -- cgit From 284349482f5293a9a23d0f72d7c2aab46b55843b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Nov 2004 22:48:25 +0000 Subject: r3443: the next stage in the include files re-organisation. I have created the include/system/ directory, which will contain the wrappers for the system includes for logical subsystems. So far I have created include/system/kerberos.h and include/system/network.h, which contain all the system includes for kerberos code and networking code. These are the included in subsystems that need kerberos or networking respectively. Note that this method avoids the mess of #ifdef HAVE_XXX_H in every C file, instead each C module includes the include/system/XXX.h file for the logical system support it needs, and the details are kept isolated in include/system/ This patch also creates a "struct ipv4_addr" which replaces "struct in_addr" in our code. That avoids every C file needing to import all the system networking headers. (This used to be commit 2e25c71853f8996f73755277e448e7d670810349) --- source4/libcli/ldap/ldap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 6e182c3843..1eb7888d41 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -24,6 +24,7 @@ */ #include "includes.h" +#include "system/network.h" /**************************************************************************** * @@ -1272,7 +1273,7 @@ struct ldap_connection *new_ldap_connection(void) BOOL ldap_connect(struct ldap_connection *conn, const char *url) { struct hostent *hp; - struct in_addr ip; + struct ipv4_addr ip; if (!ldap_parse_basic_url(conn->mem_ctx, url, &conn->host, &conn->port, &conn->ldaps)) -- cgit From 26c6b4c70bd85d8030a96651f2a255a4d48fcda1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 01:42:45 +0000 Subject: r3449: more include file reduction the ldb part isn't ideal, I will have to think of a better solution (This used to be commit 6b1f86aea8427a8e957b1aeb0ec2f507297f07cb) --- source4/libcli/ldap/ldap.c | 1 + source4/libcli/ldap/ldap_ldif.c | 1 + 2 files changed, 2 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 1eb7888d41..987a822219 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -25,6 +25,7 @@ #include "includes.h" #include "system/network.h" +#include "system/iconv.h" /**************************************************************************** * diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index 8fe50b6d08..19f4e56e73 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -24,6 +24,7 @@ */ #include "includes.h" +#include "system/iconv.h" /**************************************************************************** * -- cgit From edbfc0f6e70150e321822365bf0eead2821551bd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 02:57:18 +0000 Subject: r3453: - split out the auth and popt includes - tidied up some of the system includes - moved a few more structures back from misc.idl to netlogon.idl and samr.idl now that pidl knows about inter-IDL dependencies (This used to be commit 7b7477ac42d96faac1b0ff361525d2c63cedfc64) --- source4/libcli/ldap/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 987a822219..9b481313e3 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -26,6 +26,7 @@ #include "includes.h" #include "system/network.h" #include "system/iconv.h" +#include "auth/auth.h" /**************************************************************************** * -- cgit From 3643fb11092e28a9538ef32cedce8ff21ad86a28 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 06:42:15 +0000 Subject: r3463: separated out some more headers (asn_1.h, messages.h, dlinklist.h and ioctl.h) (This used to be commit b97e395c814762024336c1cf4d7c25be8da5813a) --- source4/libcli/ldap/ldap.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 9b481313e3..5224373afc 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -27,6 +27,8 @@ #include "system/network.h" #include "system/iconv.h" #include "auth/auth.h" +#include "asn_1.h" +#include "dlinklist.h" /**************************************************************************** * @@ -303,7 +305,7 @@ static struct ldap_parse_tree *ldap_parse_tree(TALLOC_CTX *mem_ctx, const char * return ldap_parse_simple(mem_ctx, s); } -static BOOL ldap_push_filter(ASN1_DATA *data, struct ldap_parse_tree *tree) +static BOOL ldap_push_filter(struct asn1_data *data, struct ldap_parse_tree *tree) { switch (tree->operation) { case LDAP_OP_SIMPLE: { @@ -354,7 +356,7 @@ static BOOL ldap_push_filter(ASN1_DATA *data, struct ldap_parse_tree *tree) return !data->has_error; } -static void ldap_encode_response(ASN1_DATA *data, struct ldap_Result *result) +static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *result) { asn1_write_enumerated(data, result->resultcode); asn1_write_OctetString(data, result->dn, @@ -369,7 +371,7 @@ static void ldap_encode_response(ASN1_DATA *data, struct ldap_Result *result) BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) { - ASN1_DATA data; + struct asn1_data data; int i, j; ZERO_STRUCT(data); @@ -663,7 +665,7 @@ static const char *blob2string_talloc(TALLOC_CTX *mem_ctx, } static BOOL asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, - ASN1_DATA *data, + struct asn1_data *data, const char **result) { DATA_BLOB string; @@ -675,7 +677,7 @@ static BOOL asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, } static void ldap_decode_response(TALLOC_CTX *mem_ctx, - ASN1_DATA *data, + struct asn1_data *data, struct ldap_Result *result) { asn1_read_enumerated(data, &result->resultcode); @@ -690,7 +692,7 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, } } -static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, ASN1_DATA *data, +static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, char **filter) { uint8 filter_tag, tag_desc; @@ -795,7 +797,7 @@ static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, ASN1_DATA *data, return True; } -static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, ASN1_DATA *data, +static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, struct ldap_attribute *attrib) { asn1_start_tag(data, ASN1_SEQUENCE(0)); @@ -815,7 +817,7 @@ static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, ASN1_DATA *data, } -static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, ASN1_DATA *data, +static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, struct ldap_attribute **attributes, int *num_attributes) { @@ -830,7 +832,7 @@ static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, ASN1_DATA *data, asn1_end_tag(data); } -BOOL ldap_decode(ASN1_DATA *data, struct ldap_message *msg) +BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) { uint8 tag; -- cgit From c5e4c834648fd7639d9024f15f4e4f8163340581 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 11:16:34 +0000 Subject: r3475: don't pass a ptr to an enum as a ptr to an int (bug found by tcc) (This used to be commit a7e5bde6befa8da8fc7447b295d9177126f74964) --- source4/libcli/ldap/ldap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 5224373afc..6d2cef8bdb 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -977,9 +977,11 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) while (asn1_tag_remaining(data) > 0) { struct ldap_mod mod; + int v; ZERO_STRUCT(mod); asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_enumerated(data, &mod.type); + asn1_read_enumerated(data, &v); + mod.type = v; ldap_decode_attrib(msg->mem_ctx, data, &mod.attrib); asn1_end_tag(data); if (!add_mod_to_array_talloc(msg->mem_ctx, &mod, -- cgit From 8408b3428d8c263f8453a0da8ef71e7fc1e4ec81 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 6 Nov 2004 20:15:39 +0000 Subject: r3583: - seperate the ldap client code and the ldap parsing code (vl: we should only sync the parsing code with trunk) - use hierachical talloc in the ldap client code metze (This used to be commit 1e9c0b68ca9ddb28877d45fc1b47653b13a7446d) --- source4/libcli/ldap/config.mk | 1 + source4/libcli/ldap/ldap.c | 655 +----------------------------------- source4/libcli/ldap/ldap_client.c | 690 ++++++++++++++++++++++++++++++++++++++ source4/libcli/ldap/ldap_ldif.c | 10 +- 4 files changed, 699 insertions(+), 657 deletions(-) create mode 100644 source4/libcli/ldap/ldap_client.c (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index ac047214ca..284edfd95e 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -2,6 +2,7 @@ # Start SUBSYSTEM LIBCLI_LDAP [SUBSYSTEM::LIBCLI_LDAP] ADD_OBJ_FILES = libcli/ldap/ldap.o \ + libcli/ldap/ldap_client.o \ libcli/ldap/ldap_ldif.o # End SUBSYSTEM LIBCLI_LDAP ################################# diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 6d2cef8bdb..315241e5b1 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -24,11 +24,8 @@ */ #include "includes.h" -#include "system/network.h" #include "system/iconv.h" -#include "auth/auth.h" #include "asn_1.h" -#include "dlinklist.h" /**************************************************************************** * @@ -1218,8 +1215,8 @@ BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, char **host, uint16 *port, BOOL *ldaps) { int tmp_port = 0; - fstring protocol; - fstring tmp_host; + char protocol[11]; + char tmp_host[255]; const char *p = url; /* skip leading "URL:" (if any) */ @@ -1245,654 +1242,8 @@ BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, if (tmp_port != 0) *port = tmp_port; - + *host = talloc_strdup(mem_ctx, tmp_host); return (*host != NULL); } - -struct ldap_connection *new_ldap_connection(void) -{ - TALLOC_CTX *mem_ctx = talloc_init("ldap_connection"); - struct ldap_connection *result; - - if (mem_ctx == NULL) - return NULL; - - result = talloc(mem_ctx, sizeof(*result)); - - if (result == NULL) - return NULL; - - result->mem_ctx = mem_ctx; - result->next_msgid = 1; - result->outstanding = NULL; - result->searchid = 0; - result->search_entries = NULL; - result->auth_dn = NULL; - result->simple_pw = NULL; - result->gensec = NULL; - - return result; -} - -BOOL ldap_connect(struct ldap_connection *conn, const char *url) -{ - struct hostent *hp; - struct ipv4_addr ip; - - if (!ldap_parse_basic_url(conn->mem_ctx, url, &conn->host, - &conn->port, &conn->ldaps)) - return False; - - hp = sys_gethostbyname(conn->host); - - if ((hp == NULL) || (hp->h_addr == NULL)) - return False; - - putip((char *)&ip, (char *)hp->h_addr); - - conn->sock = open_socket_out(SOCK_STREAM, &ip, conn->port, LDAP_CONNECTION_TIMEOUT); - - return (conn->sock >= 0); -} - -BOOL ldap_set_simple_creds(struct ldap_connection *conn, - const char *dn, const char *password) -{ - conn->auth_dn = talloc_strdup(conn->mem_ctx, dn); - conn->simple_pw = talloc_strdup(conn->mem_ctx, password); - - return ((conn->auth_dn != NULL) && (conn->simple_pw != NULL)); -} - -struct ldap_message *new_ldap_message(void) -{ - TALLOC_CTX *mem_ctx = talloc_init("ldap_message"); - struct ldap_message *result; - - if (mem_ctx == NULL) - return NULL; - - result = talloc(mem_ctx, sizeof(*result)); - - if (result == NULL) - return NULL; - - result->mem_ctx = mem_ctx; - return result; -} - -void destroy_ldap_message(struct ldap_message *msg) -{ - if (msg != NULL) - talloc_destroy(msg->mem_ctx); -} - -BOOL ldap_send_msg(struct ldap_connection *conn, struct ldap_message *msg, - const struct timeval *endtime) -{ - DATA_BLOB request; - BOOL result; - struct ldap_queue_entry *entry; - - msg->messageid = conn->next_msgid++; - - if (!ldap_encode(msg, &request)) - return False; - - result = (write_data_until(conn->sock, request.data, request.length, - endtime) == request.length); - - data_blob_free(&request); - - if (!result) - return result; - - /* abandon and unbind don't expect results */ - - if ((msg->type == LDAP_TAG_AbandonRequest) || - (msg->type == LDAP_TAG_UnbindRequest)) - return True; - - entry = malloc(sizeof(*entry)); - - if (entry == NULL) - return False; - - entry->msgid = msg->messageid; - entry->msg = NULL; - DLIST_ADD(conn->outstanding, entry); - - return True; -} - -BOOL ldap_receive_msg(struct ldap_connection *conn, struct ldap_message *msg, - const struct timeval *endtime) -{ - struct asn1_data data; - BOOL result; - - if (!asn1_read_sequence_until(conn->sock, &data, endtime)) - return False; - - result = ldap_decode(&data, msg); - - asn1_free(&data); - return result; -} - -static struct ldap_message *recv_from_queue(struct ldap_connection *conn, - int msgid) -{ - struct ldap_queue_entry *e; - - for (e = conn->outstanding; e != NULL; e = e->next) { - - if (e->msgid == msgid) { - struct ldap_message *result = e->msg; - DLIST_REMOVE(conn->outstanding, e); - SAFE_FREE(e); - return result; - } - } - - return NULL; -} - -static void add_search_entry(struct ldap_connection *conn, - struct ldap_message *msg) -{ - struct ldap_queue_entry *e = malloc(sizeof *e); - - if (e == NULL) - return; - - e->msg = msg; - DLIST_ADD_END(conn->search_entries, e, struct ldap_queue_entry *); - return; -} - -static void fill_outstanding_request(struct ldap_connection *conn, - struct ldap_message *msg) -{ - struct ldap_queue_entry *e; - - for (e = conn->outstanding; e != NULL; e = e->next) { - if (e->msgid == msg->messageid) { - e->msg = msg; - return; - } - } - - /* This reply has not been expected, destroy the incoming msg */ - destroy_ldap_message(msg); - return; -} - -struct ldap_message *ldap_receive(struct ldap_connection *conn, int msgid, - const struct timeval *endtime) -{ - struct ldap_message *result = recv_from_queue(conn, msgid); - - if (result != NULL) - return result; - - while (True) { - struct asn1_data data; - BOOL res; - - result = new_ldap_message(); - - if (!asn1_read_sequence_until(conn->sock, &data, endtime)) - return NULL; - - res = ldap_decode(&data, result); - asn1_free(&data); - - if (!res) - return NULL; - - if (result->messageid == msgid) - return result; - - if (result->type == LDAP_TAG_SearchResultEntry) { - add_search_entry(conn, result); - } else { - fill_outstanding_request(conn, result); - } - } - - return NULL; -} - -struct ldap_message *ldap_transaction(struct ldap_connection *conn, - struct ldap_message *request) -{ - if (!ldap_send_msg(conn, request, NULL)) - return False; - - return ldap_receive(conn, request->messageid, NULL); -} - -int ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const char *password) -{ - struct ldap_message *response; - struct ldap_message *msg; - const char *dn, *pw; - int result = LDAP_OTHER; - - if (conn == NULL) - return result; - - if (userdn) { - dn = userdn; - } else { - if (conn->auth_dn) { - dn = conn->auth_dn; - } else { - dn = ""; - } - } - - if (password) { - pw = password; - } else { - if (conn->simple_pw) { - pw = conn->simple_pw; - } else { - pw = ""; - } - } - - msg = new_ldap_simple_bind_msg(dn, pw); - if (!msg) - return result; - - response = ldap_transaction(conn, msg); - if (!response) { - destroy_ldap_message(msg); - return result; - } - - result = response->r.BindResponse.response.resultcode; - - destroy_ldap_message(msg); - destroy_ldap_message(response); - - return result; -} - -int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const char *domain, const char *password) -{ - NTSTATUS status; - TALLOC_CTX *mem_ctx = NULL; - struct ldap_message *response; - struct ldap_message *msg; - DATA_BLOB input = data_blob(NULL, 0); - DATA_BLOB output = data_blob(NULL, 0); - int result = LDAP_OTHER; - - if (conn == NULL) - return result; - - status = gensec_client_start(conn, &conn->gensec); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); - return result; - } - - gensec_want_feature(conn->gensec, GENSEC_WANT_SIGN | GENSEC_WANT_SEAL); - - status = gensec_set_domain(conn->gensec, domain); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n", - domain, nt_errstr(status))); - goto done; - } - - status = gensec_set_username(conn->gensec, username); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client username to %s: %s\n", - username, nt_errstr(status))); - goto done; - } - - status = gensec_set_password(conn->gensec, password); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client password: %s\n", - nt_errstr(status))); - goto done; - } - - status = gensec_set_target_hostname(conn->gensec, conn->host); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", - nt_errstr(status))); - goto done; - } - - status = gensec_start_mech_by_sasl_name(conn->gensec, "GSS-SPNEGO"); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism: %s\n", - nt_errstr(status))); - goto done; - } - - mem_ctx = talloc_init("ldap_bind_sasl"); - if (!mem_ctx) - goto done; - - status = gensec_update(conn->gensec, mem_ctx, - input, - &output); - - while(1) { - if (NT_STATUS_IS_OK(status) && output.length == 0) { - break; - } - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) { - break; - } - - msg = new_ldap_sasl_bind_msg("GSS-SPNEGO", &output); - if (!msg) - goto done; - - response = ldap_transaction(conn, msg); - destroy_ldap_message(msg); - - if (!response) { - goto done; - } - - result = response->r.BindResponse.response.resultcode; - - if (result != LDAP_SUCCESS && result != LDAP_SASL_BIND_IN_PROGRESS) { - break; - } - - status = gensec_update(conn->gensec, mem_ctx, - response->r.BindResponse.SASL.secblob, - &output); - - destroy_ldap_message(response); - } - -done: - if (mem_ctx) - talloc_destroy(mem_ctx); - - return result; -} - -BOOL ldap_setup_connection(struct ldap_connection *conn, - const char *url, const char *userdn, const char *password) -{ - int result; - - if (!ldap_connect(conn, url)) { - return False; - } - - result = ldap_bind_simple(conn, userdn, password); - if (result == LDAP_SUCCESS) { - return True; - } - - return False; -} - -BOOL ldap_setup_connection_with_sasl(struct ldap_connection *conn, const char *url, const char *username, const char *domain, const char *password) -{ - int result; - - if (!ldap_connect(conn, url)) { - return False; - } - - result = ldap_bind_sasl(conn, username, domain, password); - if (result == LDAP_SUCCESS) { - return True; - } - - return False; -} - -static BOOL ldap_abandon_message(struct ldap_connection *conn, int msgid, - const struct timeval *endtime) -{ - struct ldap_message *msg = new_ldap_message(); - BOOL result; - - if (msg == NULL) - return False; - - msg->type = LDAP_TAG_AbandonRequest; - msg->r.AbandonRequest.messageid = msgid; - - result = ldap_send_msg(conn, msg, endtime); - destroy_ldap_message(msg); - return result; -} - -struct ldap_message *new_ldap_search_message(const char *base, - enum ldap_scope scope, - char *filter, - int num_attributes, - const char **attributes) -{ - struct ldap_message *res = new_ldap_message(); - - if (res == NULL) - return NULL; - - res->type = LDAP_TAG_SearchRequest; - res->r.SearchRequest.basedn = base; - res->r.SearchRequest.scope = scope; - res->r.SearchRequest.deref = LDAP_DEREFERENCE_NEVER; - res->r.SearchRequest.timelimit = 0; - res->r.SearchRequest.sizelimit = 0; - res->r.SearchRequest.attributesonly = False; - res->r.SearchRequest.filter = filter; - res->r.SearchRequest.num_attributes = num_attributes; - res->r.SearchRequest.attributes = attributes; - return res; -} - -struct ldap_message *new_ldap_simple_bind_msg(const char *dn, const char *pw) -{ - struct ldap_message *res = new_ldap_message(); - - if (res == NULL) - return NULL; - - res->type = LDAP_TAG_BindRequest; - res->r.BindRequest.version = 3; - res->r.BindRequest.dn = talloc_strdup(res->mem_ctx, dn); - res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SIMPLE; - res->r.BindRequest.creds.password = talloc_strdup(res->mem_ctx, pw); - return res; -} - -struct ldap_message *new_ldap_sasl_bind_msg(const char *sasl_mechanism, DATA_BLOB *secblob) -{ - struct ldap_message *res = new_ldap_message(); - - if (res == NULL) - return NULL; - - res->type = LDAP_TAG_BindRequest; - res->r.BindRequest.version = 3; - res->r.BindRequest.dn = ""; - res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SASL; - res->r.BindRequest.creds.SASL.mechanism = talloc_strdup(res->mem_ctx, sasl_mechanism); - res->r.BindRequest.creds.SASL.secblob = *secblob; - return res; -} - -BOOL ldap_setsearchent(struct ldap_connection *conn, struct ldap_message *msg, - const struct timeval *endtime) -{ - if ((conn->searchid != 0) && - (!ldap_abandon_message(conn, conn->searchid, endtime))) - return False; - - conn->searchid = conn->next_msgid; - return ldap_send_msg(conn, msg, endtime); -} - -struct ldap_message *ldap_getsearchent(struct ldap_connection *conn, - const struct timeval *endtime) -{ - struct ldap_message *result; - - if (conn->search_entries != NULL) { - struct ldap_queue_entry *e = conn->search_entries; - - result = e->msg; - DLIST_REMOVE(conn->search_entries, e); - SAFE_FREE(e); - return result; - } - - result = ldap_receive(conn, conn->searchid, endtime); - if (!result) { - return NULL; - } - - if (result->type == LDAP_TAG_SearchResultEntry) - return result; - - if (result->type == LDAP_TAG_SearchResultDone) { - /* TODO: Handle Paged Results */ - destroy_ldap_message(result); - return NULL; - } - - /* TODO: Handle Search References here */ - return NULL; -} - -void ldap_endsearchent(struct ldap_connection *conn, - const struct timeval *endtime) -{ - struct ldap_queue_entry *e; - - e = conn->search_entries; - - while (e != NULL) { - struct ldap_queue_entry *next = e->next; - DLIST_REMOVE(conn->search_entries, e); - SAFE_FREE(e); - e = next; - } -} - -struct ldap_message *ldap_searchone(struct ldap_connection *conn, - struct ldap_message *msg, - const struct timeval *endtime) -{ - struct ldap_message *res1, *res2 = NULL; - if (!ldap_setsearchent(conn, msg, endtime)) - return NULL; - - res1 = ldap_getsearchent(conn, endtime); - - if (res1 != NULL) - res2 = ldap_getsearchent(conn, endtime); - - ldap_endsearchent(conn, endtime); - - if (res1 == NULL) - return NULL; - - if (res2 != NULL) { - /* More than one entry */ - destroy_ldap_message(res1); - destroy_ldap_message(res2); - return NULL; - } - - return res1; -} - -BOOL ldap_find_single_value(struct ldap_message *msg, const char *attr, - DATA_BLOB *value) -{ - int i; - struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; - - if (msg->type != LDAP_TAG_SearchResultEntry) - return False; - - for (i=0; inum_attributes; i++) { - if (strequal(attr, r->attributes[i].name)) { - if (r->attributes[i].num_values != 1) - return False; - - *value = r->attributes[i].values[0]; - return True; - } - } - return False; -} - -BOOL ldap_find_single_string(struct ldap_message *msg, const char *attr, - TALLOC_CTX *mem_ctx, char **value) -{ - DATA_BLOB blob; - - if (!ldap_find_single_value(msg, attr, &blob)) - return False; - - *value = talloc(mem_ctx, blob.length+1); - - if (*value == NULL) - return False; - - memcpy(*value, blob.data, blob.length); - (*value)[blob.length] = '\0'; - return True; -} - -BOOL ldap_find_single_int(struct ldap_message *msg, const char *attr, - int *value) -{ - DATA_BLOB blob; - char *val; - int errno_save; - BOOL res; - - if (!ldap_find_single_value(msg, attr, &blob)) - return False; - - val = malloc(blob.length+1); - if (val == NULL) - return False; - - memcpy(val, blob.data, blob.length); - val[blob.length] = '\0'; - - errno_save = errno; - errno = 0; - - *value = strtol(val, NULL, 10); - - res = (errno == 0); - - free(val); - errno = errno_save; - - return res; -} - -int ldap_error(struct ldap_connection *conn) -{ - return 0; -} - -NTSTATUS ldap2nterror(int ldaperror) -{ - return NT_STATUS_OK; -} diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c new file mode 100644 index 0000000000..7a72734c57 --- /dev/null +++ b/source4/libcli/ldap/ldap_client.c @@ -0,0 +1,690 @@ +/* + Unix SMB/CIFS mplementation. + LDAP protocol helper functions for SAMBA + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Volker Lendecke 2004 + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Simo Sorce 2004 + + 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/network.h" +#include "auth/auth.h" +#include "asn_1.h" +#include "dlinklist.h" + +#if 0 +static struct ldap_message *new_ldap_search_message(struct ldap_connection *conn, + const char *base, + enum ldap_scope scope, + char *filter, + int num_attributes, + const char **attributes) +{ + struct ldap_message *res; + + res = new_ldap_message(conn); + if (!res) { + return NULL; + } + + res->type = LDAP_TAG_SearchRequest; + res->r.SearchRequest.basedn = base; + res->r.SearchRequest.scope = scope; + res->r.SearchRequest.deref = LDAP_DEREFERENCE_NEVER; + res->r.SearchRequest.timelimit = 0; + res->r.SearchRequest.sizelimit = 0; + res->r.SearchRequest.attributesonly = False; + res->r.SearchRequest.filter = filter; + res->r.SearchRequest.num_attributes = num_attributes; + res->r.SearchRequest.attributes = attributes; + + return res; +} +#endif + +static struct ldap_message *new_ldap_simple_bind_msg(struct ldap_connection *conn, const char *dn, const char *pw) +{ + struct ldap_message *res; + + res = new_ldap_message(conn); + if (!res) { + return NULL; + } + + res->type = LDAP_TAG_BindRequest; + res->r.BindRequest.version = 3; + res->r.BindRequest.dn = talloc_strdup(res->mem_ctx, dn); + res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SIMPLE; + res->r.BindRequest.creds.password = talloc_strdup(res->mem_ctx, pw); + + return res; +} + +static struct ldap_message *new_ldap_sasl_bind_msg(struct ldap_connection *conn, const char *sasl_mechanism, DATA_BLOB *secblob) +{ + struct ldap_message *res; + + res = new_ldap_message(conn); + if (!res) { + return NULL; + } + + res->type = LDAP_TAG_BindRequest; + res->r.BindRequest.version = 3; + res->r.BindRequest.dn = ""; + res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SASL; + res->r.BindRequest.creds.SASL.mechanism = talloc_strdup(res->mem_ctx, sasl_mechanism); + res->r.BindRequest.creds.SASL.secblob = *secblob; + + return res; +} + +static struct ldap_connection *new_ldap_connection(TALLOC_CTX *mem_ctx) +{ + struct ldap_connection *result; + + result = talloc_p(mem_ctx, struct ldap_connection); + + if (!result) { + return NULL; + } + + result->mem_ctx = result; + result->next_msgid = 1; + result->outstanding = NULL; + result->searchid = 0; + result->search_entries = NULL; + result->auth_dn = NULL; + result->simple_pw = NULL; + result->gensec = NULL; + + return result; +} + +struct ldap_connection *ldap_connect(TALLOC_CTX *mem_ctx, const char *url) +{ + struct hostent *hp; + struct ipv4_addr ip; + struct ldap_connection *conn; + BOOL ret; + + conn = new_ldap_connection(mem_ctx); + if (!conn) { + return NULL; + } + + ret = ldap_parse_basic_url(conn->mem_ctx, url, &conn->host, + &conn->port, &conn->ldaps); + if (!ret) { + talloc_free(conn); + return NULL; + } + + hp = sys_gethostbyname(conn->host); + if (!hp || !hp->h_addr) { + talloc_free(conn); + return NULL; + } + + putip((char *)&ip, (char *)hp->h_addr); + + conn->sock = open_socket_out(SOCK_STREAM, &ip, conn->port, LDAP_CONNECTION_TIMEOUT); + if (conn->sock < 0) { + talloc_free(conn); + return NULL; + } + + return conn; +} + +struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) +{ + struct ldap_message *result; + + result = talloc_p(mem_ctx, struct ldap_message); + + if (!result) { + return NULL; + } + + result->mem_ctx = result; + + return result; +} + +BOOL ldap_send_msg(struct ldap_connection *conn, struct ldap_message *msg, + const struct timeval *endtime) +{ + DATA_BLOB request; + BOOL result; + struct ldap_queue_entry *entry; + + msg->messageid = conn->next_msgid++; + + if (!ldap_encode(msg, &request)) + return False; + + result = (write_data_until(conn->sock, request.data, request.length, + endtime) == request.length); + + data_blob_free(&request); + + if (!result) + return result; + + /* abandon and unbind don't expect results */ + + if ((msg->type == LDAP_TAG_AbandonRequest) || + (msg->type == LDAP_TAG_UnbindRequest)) + return True; + + entry = malloc(sizeof(*entry)); + + if (entry == NULL) + return False; + + entry->msgid = msg->messageid; + entry->msg = NULL; + DLIST_ADD(conn->outstanding, entry); + + return True; +} + +BOOL ldap_receive_msg(struct ldap_connection *conn, struct ldap_message *msg, + const struct timeval *endtime) +{ + struct asn1_data data; + BOOL result; + + if (!asn1_read_sequence_until(conn->sock, &data, endtime)) + return False; + + result = ldap_decode(&data, msg); + + asn1_free(&data); + return result; +} + +static struct ldap_message *recv_from_queue(struct ldap_connection *conn, + int msgid) +{ + struct ldap_queue_entry *e; + + for (e = conn->outstanding; e != NULL; e = e->next) { + + if (e->msgid == msgid) { + struct ldap_message *result = e->msg; + DLIST_REMOVE(conn->outstanding, e); + SAFE_FREE(e); + return result; + } + } + + return NULL; +} + +static void add_search_entry(struct ldap_connection *conn, + struct ldap_message *msg) +{ + struct ldap_queue_entry *e = malloc(sizeof *e); + + if (e == NULL) + return; + + e->msg = msg; + DLIST_ADD_END(conn->search_entries, e, struct ldap_queue_entry *); + return; +} + +static void fill_outstanding_request(struct ldap_connection *conn, + struct ldap_message *msg) +{ + struct ldap_queue_entry *e; + + for (e = conn->outstanding; e != NULL; e = e->next) { + if (e->msgid == msg->messageid) { + e->msg = msg; + return; + } + } + + /* This reply has not been expected, destroy the incoming msg */ + talloc_free(msg); + return; +} + +struct ldap_message *ldap_receive(struct ldap_connection *conn, int msgid, + const struct timeval *endtime) +{ + struct ldap_message *result = recv_from_queue(conn, msgid); + + if (result != NULL) + return result; + + while (True) { + struct asn1_data data; + BOOL res; + + result = new_ldap_message(conn); + + if (!asn1_read_sequence_until(conn->sock, &data, endtime)) + return NULL; + + res = ldap_decode(&data, result); + asn1_free(&data); + + if (!res) + return NULL; + + if (result->messageid == msgid) + return result; + + if (result->type == LDAP_TAG_SearchResultEntry) { + add_search_entry(conn, result); + } else { + fill_outstanding_request(conn, result); + } + } + + return NULL; +} + +struct ldap_message *ldap_transaction(struct ldap_connection *conn, + struct ldap_message *request) +{ + if (!ldap_send_msg(conn, request, NULL)) + return False; + + return ldap_receive(conn, request->messageid, NULL); +} + +int ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const char *password) +{ + struct ldap_message *response; + struct ldap_message *msg; + const char *dn, *pw; + int result = LDAP_OTHER; + + if (conn == NULL) + return result; + + if (userdn) { + dn = userdn; + } else { + if (conn->auth_dn) { + dn = conn->auth_dn; + } else { + dn = ""; + } + } + + if (password) { + pw = password; + } else { + if (conn->simple_pw) { + pw = conn->simple_pw; + } else { + pw = ""; + } + } + + msg = new_ldap_simple_bind_msg(conn, dn, pw); + if (!msg) + return result; + + response = ldap_transaction(conn, msg); + if (!response) { + talloc_free(msg); + return result; + } + + result = response->r.BindResponse.response.resultcode; + + talloc_free(msg); + talloc_free(response); + + return result; +} + +int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const char *domain, const char *password) +{ + NTSTATUS status; + TALLOC_CTX *mem_ctx = NULL; + struct ldap_message *response; + struct ldap_message *msg; + DATA_BLOB input = data_blob(NULL, 0); + DATA_BLOB output = data_blob(NULL, 0); + int result = LDAP_OTHER; + + if (conn == NULL) + return result; + + status = gensec_client_start(conn, &conn->gensec); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); + return result; + } + + gensec_want_feature(conn->gensec, GENSEC_WANT_SIGN | GENSEC_WANT_SEAL); + + status = gensec_set_domain(conn->gensec, domain); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n", + domain, nt_errstr(status))); + goto done; + } + + status = gensec_set_username(conn->gensec, username); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client username to %s: %s\n", + username, nt_errstr(status))); + goto done; + } + + status = gensec_set_password(conn->gensec, password); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client password: %s\n", + nt_errstr(status))); + goto done; + } + + status = gensec_set_target_hostname(conn->gensec, conn->host); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", + nt_errstr(status))); + goto done; + } + + status = gensec_start_mech_by_sasl_name(conn->gensec, "GSS-SPNEGO"); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism: %s\n", + nt_errstr(status))); + goto done; + } + + mem_ctx = talloc_init("ldap_bind_sasl"); + if (!mem_ctx) + goto done; + + status = gensec_update(conn->gensec, mem_ctx, + input, + &output); + + while(1) { + if (NT_STATUS_IS_OK(status) && output.length == 0) { + break; + } + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) { + break; + } + + msg = new_ldap_sasl_bind_msg(conn, "GSS-SPNEGO", &output); + if (!msg) + goto done; + + response = ldap_transaction(conn, msg); + talloc_free(msg); + + if (!response) { + goto done; + } + + result = response->r.BindResponse.response.resultcode; + + if (result != LDAP_SUCCESS && result != LDAP_SASL_BIND_IN_PROGRESS) { + break; + } + + status = gensec_update(conn->gensec, mem_ctx, + response->r.BindResponse.SASL.secblob, + &output); + + talloc_free(response); + } + +done: + if (mem_ctx) + talloc_destroy(mem_ctx); + + return result; +} + +struct ldap_connection *ldap_setup_connection(TALLOC_CTX *mem_ctx, const char *url, + const char *userdn, const char *password) +{ + struct ldap_connection *conn; + int result; + + conn =ldap_connect(mem_ctx, url); + if (!conn) { + return NULL; + } + + result = ldap_bind_simple(conn, userdn, password); + if (result != LDAP_SUCCESS) { + talloc_free(conn); + return NULL; + } + + return conn; +} + +struct ldap_connection *ldap_setup_connection_with_sasl(TALLOC_CTX *mem_ctx, const char *url, + const char *username, const char *domain, const char *password) +{ + struct ldap_connection *conn; + int result; + + conn =ldap_connect(mem_ctx, url); + if (!conn) { + return NULL; + } + + result = ldap_bind_sasl(conn, username, domain, password); + if (result != LDAP_SUCCESS) { + talloc_free(conn); + return NULL; + } + + return conn; +} + +BOOL ldap_abandon_message(struct ldap_connection *conn, int msgid, + const struct timeval *endtime) +{ + struct ldap_message *msg = new_ldap_message(conn); + BOOL result; + + if (msg == NULL) + return False; + + msg->type = LDAP_TAG_AbandonRequest; + msg->r.AbandonRequest.messageid = msgid; + + result = ldap_send_msg(conn, msg, endtime); + talloc_free(msg); + return result; +} + +BOOL ldap_setsearchent(struct ldap_connection *conn, struct ldap_message *msg, + const struct timeval *endtime) +{ + if ((conn->searchid != 0) && + (!ldap_abandon_message(conn, conn->searchid, endtime))) + return False; + + conn->searchid = conn->next_msgid; + return ldap_send_msg(conn, msg, endtime); +} + +struct ldap_message *ldap_getsearchent(struct ldap_connection *conn, + const struct timeval *endtime) +{ + struct ldap_message *result; + + if (conn->search_entries != NULL) { + struct ldap_queue_entry *e = conn->search_entries; + + result = e->msg; + DLIST_REMOVE(conn->search_entries, e); + SAFE_FREE(e); + return result; + } + + result = ldap_receive(conn, conn->searchid, endtime); + if (!result) { + return NULL; + } + + if (result->type == LDAP_TAG_SearchResultEntry) + return result; + + if (result->type == LDAP_TAG_SearchResultDone) { + /* TODO: Handle Paged Results */ + talloc_free(result); + return NULL; + } + + /* TODO: Handle Search References here */ + return NULL; +} + +void ldap_endsearchent(struct ldap_connection *conn, + const struct timeval *endtime) +{ + struct ldap_queue_entry *e; + + e = conn->search_entries; + + while (e != NULL) { + struct ldap_queue_entry *next = e->next; + DLIST_REMOVE(conn->search_entries, e); + SAFE_FREE(e); + e = next; + } +} + +struct ldap_message *ldap_searchone(struct ldap_connection *conn, + struct ldap_message *msg, + const struct timeval *endtime) +{ + struct ldap_message *res1, *res2 = NULL; + if (!ldap_setsearchent(conn, msg, endtime)) + return NULL; + + res1 = ldap_getsearchent(conn, endtime); + + if (res1 != NULL) + res2 = ldap_getsearchent(conn, endtime); + + ldap_endsearchent(conn, endtime); + + if (res1 == NULL) + return NULL; + + if (res2 != NULL) { + /* More than one entry */ + talloc_free(res1); + talloc_free(res2); + return NULL; + } + + return res1; +} + +BOOL ldap_find_single_value(struct ldap_message *msg, const char *attr, + DATA_BLOB *value) +{ + int i; + struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; + + if (msg->type != LDAP_TAG_SearchResultEntry) + return False; + + for (i=0; inum_attributes; i++) { + if (strequal(attr, r->attributes[i].name)) { + if (r->attributes[i].num_values != 1) + return False; + + *value = r->attributes[i].values[0]; + return True; + } + } + return False; +} + +BOOL ldap_find_single_string(struct ldap_message *msg, const char *attr, + TALLOC_CTX *mem_ctx, char **value) +{ + DATA_BLOB blob; + + if (!ldap_find_single_value(msg, attr, &blob)) + return False; + + *value = talloc(mem_ctx, blob.length+1); + + if (*value == NULL) + return False; + + memcpy(*value, blob.data, blob.length); + (*value)[blob.length] = '\0'; + return True; +} + +BOOL ldap_find_single_int(struct ldap_message *msg, const char *attr, + int *value) +{ + DATA_BLOB blob; + char *val; + int errno_save; + BOOL res; + + if (!ldap_find_single_value(msg, attr, &blob)) + return False; + + val = malloc(blob.length+1); + if (val == NULL) + return False; + + memcpy(val, blob.data, blob.length); + val[blob.length] = '\0'; + + errno_save = errno; + errno = 0; + + *value = strtol(val, NULL, 10); + + res = (errno == 0); + + free(val); + errno = errno_save; + + return res; +} + +int ldap_error(struct ldap_connection *conn) +{ + return 0; +} + +NTSTATUS ldap2nterror(int ldaperror) +{ + return NT_STATUS_OK; +} diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index 19f4e56e73..c276b7e917 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -307,7 +307,7 @@ static BOOL fill_mods(struct ldap_message *msg, char **chunk) /* read from a LDIF source, creating a ldap_message */ -static struct ldap_message *ldif_read(int (*fgetc_fn)(void *), +static struct ldap_message *ldif_read(TALLOC_CTX *mem_ctx, int (*fgetc_fn)(void *), void *private_data) { struct ldap_message *msg; @@ -318,7 +318,7 @@ static struct ldap_message *ldif_read(int (*fgetc_fn)(void *), value.data = NULL; - msg = new_ldap_message(); + msg = new_ldap_message(mem_ctx); if (msg == NULL) return NULL; @@ -383,7 +383,7 @@ static struct ldap_message *ldif_read(int (*fgetc_fn)(void *), DEBUG(3, ("changetype %s not supported\n", (char *)value.data)); failed: - destroy_ldap_message(msg); + talloc_free(msg); return NULL; } @@ -403,10 +403,10 @@ static int fgetc_string(void *private_data) return EOF; } -struct ldap_message *ldap_ldif2msg(const char *s) +struct ldap_message *ldap_ldif2msg(TALLOC_CTX *mem_ctx, const char *s) { struct ldif_read_string_state state; state.s = s; - return ldif_read(fgetc_string, &state); + return ldif_read(mem_ctx, fgetc_string, &state); } -- cgit From e5c8e21129a2144633b518979f9a66eb8953dae6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 6 Nov 2004 20:43:36 +0000 Subject: r3584: fix referral handling metze (This used to be commit 4868f1ea857e94f60dbde83bfb54def8a5ee728f) --- source4/libcli/ldap/ldap.c | 15 ++++++++++++--- source4/libcli/ldap/ldap.h | 3 +-- 2 files changed, 13 insertions(+), 5 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 315241e5b1..2eea7b035a 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -361,9 +361,12 @@ static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *res asn1_write_OctetString(data, result->errormessage, (result->errormessage) ? strlen(result->errormessage) : 0); - if (result->referral != NULL) + if (result->referral) { + asn1_push_tag(data, ASN1_CONTEXT(3)); asn1_write_OctetString(data, result->referral, strlen(result->referral)); + asn1_pop_tag(data); + } } BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) @@ -620,7 +623,10 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) break; } case LDAP_TAG_SearchResultReference: { -/* struct ldap_SearchResRef *r = &msg->r.SearchResultReference; */ + struct ldap_SearchResRef *r = &msg->r.SearchResultReference; + asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(&data, r->referral, strlen(r->referral)); + asn1_pop_tag(&data); break; } case LDAP_TAG_ExtendedRequest: { @@ -957,8 +963,11 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) } case ASN1_APPLICATION(LDAP_TAG_SearchResultReference): { -/* struct ldap_SearchResRef *r = &msg->r.SearchResultReference; */ + struct ldap_SearchResRef *r = &msg->r.SearchResultReference; msg->type = LDAP_TAG_SearchResultReference; + asn1_start_tag(data, tag); + asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->referral); + asn1_end_tag(data); break; } diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index c27aba8d7a..65962bf5b5 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -161,8 +161,7 @@ struct ldap_SearchResEntry { }; struct ldap_SearchResRef { - int num_referrals; - const char **referrals; + const char *referral; }; enum ldap_modify_type { -- cgit From b012ab557b8f8a2f58dfbbe8b7818f3e6d8cf38f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 6 Nov 2004 21:51:22 +0000 Subject: r3585: check sscanf return code metze (This used to be commit 9701abfa3a5f6351c8c7bced6adb751be9f5ff31) --- source4/libcli/ldap/ldap.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 2eea7b035a..dd689027f9 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1227,6 +1227,7 @@ BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, char protocol[11]; char tmp_host[255]; const char *p = url; + int ret; /* skip leading "URL:" (if any) */ if (strncasecmp( p, "URL:", 4) == 0) { @@ -1236,7 +1237,10 @@ BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, /* Paranoia check */ SMB_ASSERT(sizeof(protocol)>10 && sizeof(tmp_host)>254); - sscanf(p, "%10[^:]://%254[^:/]:%d", protocol, tmp_host, &tmp_port); + ret = sscanf(p, "%10[^:]://%254[^:/]:%d", protocol, tmp_host, &tmp_port); + if (ret < 2) { + return False; + } if (strequal(protocol, "ldap")) { *port = 389; -- cgit From 8e16d8a76f8a3b8ccc89eb317c8e5daa6cf43b71 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 14 Nov 2004 16:22:01 +0000 Subject: r3733: More build system fixes/features: - Use .mk files directly (no need for a SMB_*_MK() macro when adding a new SUBSYSTEM, MODULE or BINARY). This allows addition of new modules and subsystems without running configure - Add support for generating .dot files with the Samba4 dependency tree (as used by the graphviz and springgraph utilities) (This used to be commit 64826da834e26ee0488674e27a0eae36491ee179) --- source4/libcli/ldap/config.m4 | 1 - 1 file changed, 1 deletion(-) delete mode 100644 source4/libcli/ldap/config.m4 (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.m4 b/source4/libcli/ldap/config.m4 deleted file mode 100644 index 01f78279bf..0000000000 --- a/source4/libcli/ldap/config.m4 +++ /dev/null @@ -1 +0,0 @@ -SMB_SUBSYSTEM_MK(LIBCLI_LDAP,libcli/ldap/config.mk) -- cgit From 58c326809a816703dc516c3022c9c4dbb9d09445 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 3 Dec 2004 06:24:38 +0000 Subject: r4052: fixed a bunch of code to use the type safe _p allocation macros (This used to be commit 80d15fa3402a9d1183467463f6b21c0b674bc442) --- source4/libcli/ldap/ldap_client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 7a72734c57..88c84d880b 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -195,7 +195,7 @@ BOOL ldap_send_msg(struct ldap_connection *conn, struct ldap_message *msg, (msg->type == LDAP_TAG_UnbindRequest)) return True; - entry = malloc(sizeof(*entry)); + entry = malloc_p(struct ldap_queue_entry); if (entry == NULL) return False; @@ -243,7 +243,7 @@ static struct ldap_message *recv_from_queue(struct ldap_connection *conn, static void add_search_entry(struct ldap_connection *conn, struct ldap_message *msg) { - struct ldap_queue_entry *e = malloc(sizeof *e); + struct ldap_queue_entry *e = malloc_p(struct ldap_queue_entry); if (e == NULL) return; -- cgit From 6e6374cb5bcffb4df8bdb0a83327fff92b61ac84 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 3 Dec 2004 07:20:30 +0000 Subject: r4055: fixed more places to use type safe allocation macros (This used to be commit eec698254f67365f27b4b7569fa982e22472aca1) --- source4/libcli/ldap/ldap.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index dd689027f9..076d088ee2 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -130,7 +130,7 @@ static struct ldap_parse_tree *ldap_parse_simple(TALLOC_CTX *mem_ctx, if (val && strchr("()&|", *val)) return NULL; - ret = talloc(mem_ctx, sizeof(*ret)); + ret = talloc_p(mem_ctx, struct ldap_parse_tree); if (!ret) { errno = ENOMEM; return NULL; @@ -157,8 +157,7 @@ static struct ldap_parse_tree *ldap_parse_filterlist(TALLOC_CTX *mem_ctx, { struct ldap_parse_tree *ret, *next; - ret = talloc(mem_ctx, sizeof(*ret)); - + ret = talloc_p(mem_ctx, struct ldap_parse_tree); if (!ret) { errno = ENOMEM; return NULL; @@ -166,7 +165,7 @@ static struct ldap_parse_tree *ldap_parse_filterlist(TALLOC_CTX *mem_ctx, ret->operation = op; ret->u.list.num_elements = 1; - ret->u.list.elements = talloc(mem_ctx, sizeof(*ret->u.list.elements)); + ret->u.list.elements = talloc_p(mem_ctx, struct ldap_parse_tree *); if (!ret->u.list.elements) { errno = ENOMEM; return NULL; @@ -206,7 +205,7 @@ static struct ldap_parse_tree *ldap_parse_not(TALLOC_CTX *mem_ctx, const char *s { struct ldap_parse_tree *ret; - ret = talloc(mem_ctx, sizeof(*ret)); + ret = talloc_p(mem_ctx, struct ldap_parse_tree); if (!ret) { errno = ENOMEM; return NULL; -- cgit From 0ad10aec63201c45b09f91541e9eee17fcf7ede5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 6 Dec 2004 15:44:17 +0000 Subject: r4079: implement the gensec_have_feature() correctly by asking the backend what is actually in use metze (This used to be commit 6f3eb7bc03609108b9e0ea5676fca3d04140e737) --- source4/libcli/ldap/ldap_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 88c84d880b..a9b20b4ea8 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -382,7 +382,7 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha return result; } - gensec_want_feature(conn->gensec, GENSEC_WANT_SIGN | GENSEC_WANT_SEAL); + gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL); status = gensec_set_domain(conn->gensec, domain); if (!NT_STATUS_IS_OK(status)) { -- cgit From ecabb2dce5a7e651664ddaf47385cd792fb53347 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 28 Dec 2004 23:59:22 +0000 Subject: r4385: Set the correct target service. Andrew Bartlett (This used to be commit 722f59c7c8d09f548d9325c6051d6687d7aa16c2) --- source4/libcli/ldap/ldap_client.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index a9b20b4ea8..b405b4f417 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -412,6 +412,13 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha goto done; } + status = gensec_set_target_service(conn->gensec, "ldap"); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", + nt_errstr(status))); + goto done; + } + status = gensec_start_mech_by_sasl_name(conn->gensec, "GSS-SPNEGO"); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism: %s\n", -- cgit From e3da3b48b16bc6f166034189d2907d6ffa11a07a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 29 Dec 2004 00:03:34 +0000 Subject: r4386: Grr, fix copy-and-paste bug. Andrew Bartlett (This used to be commit 13aa88ed65a8914000cccbecf80929db3df65037) --- source4/libcli/ldap/ldap_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index b405b4f417..77356cbe70 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -414,7 +414,7 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha status = gensec_set_target_service(conn->gensec, "ldap"); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", + DEBUG(1, ("Failed to start set GENSEC target service: %s\n", nt_errstr(status))); goto done; } -- cgit From 740ee4a8977512c03800ef88603cf65fd044443b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 1 Jan 2005 00:19:08 +0000 Subject: r4460: Add a new GENSEC module: gensec_gssapi (disabled by default, set parametric option: gensec:gssapi=yes to enable). This module backs directly onto GSSAPI, and allows us to sign and seal GSSAPI/Krb5 connections in particular. This avoids me reinventing the entire GSSAPI wheel. Currently a lot of things are left as default - we will soon start specifiying OIDs as well as passwords (it uses the keytab only at the moment). Tested with our LDAP-* torture tests against Win2k3. My hope is to use this module to access the new SPNEGO implementation in Heimdal, to avoid having to standards-verify our own. Andrew Bartlett (This used to be commit 14b650c85db14a9bf97e24682b2643b63c51ff35) --- source4/libcli/ldap/ldap_client.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 77356cbe70..9ca9e4b5c4 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -459,9 +459,13 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha break; } - status = gensec_update(conn->gensec, mem_ctx, - response->r.BindResponse.SASL.secblob, - &output); + if (!NT_STATUS_IS_OK(status)) { + status = gensec_update(conn->gensec, mem_ctx, + response->r.BindResponse.SASL.secblob, + &output); + } else { + output.length = 0; + } talloc_free(response); } -- cgit From ddc10d4d37984246a6547e34a32d629c689c40d1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Jan 2005 03:06:58 +0000 Subject: r4549: got rid of a lot more uses of plain talloc(), instead using talloc_size() or talloc_array_p() where appropriate. also fixed a memory leak in pvfs_copy_file() (failed to free a memory context) (This used to be commit 89b74b53546e1570b11b3702f40bee58aed8c503) --- source4/libcli/ldap/ldap.c | 8 ++++---- source4/libcli/ldap/ldap_client.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 076d088ee2..b2a6bd957a 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -660,7 +660,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) static const char *blob2string_talloc(TALLOC_CTX *mem_ctx, DATA_BLOB blob) { - char *result = talloc(mem_ctx, blob.length+1); + char *result = talloc_size(mem_ctx, blob.length+1); memcpy(result, blob.data, blob.length); result[blob.length] = '\0'; return result; @@ -859,7 +859,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); pwlen = asn1_tag_remaining(data); if (pwlen != 0) { - char *pw = talloc(msg->mem_ctx, pwlen+1); + char *pw = talloc_size(msg->mem_ctx, pwlen+1); asn1_read(data, pw, pwlen); pw[pwlen] = '\0'; r->creds.password = pw; @@ -1040,7 +1040,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_start_tag(data, ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); len = asn1_tag_remaining(data); - dn = talloc(msg->mem_ctx, len+1); + dn = talloc_size(msg->mem_ctx, len+1); if (dn == NULL) break; asn1_read(data, dn, len); @@ -1073,7 +1073,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) char *newsup; asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); len = asn1_tag_remaining(data); - newsup = talloc(msg->mem_ctx, len+1); + newsup = talloc_size(msg->mem_ctx, len+1); if (newsup == NULL) break; asn1_read(data, newsup, len); diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 9ca9e4b5c4..84fd0f1d64 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -649,7 +649,7 @@ BOOL ldap_find_single_string(struct ldap_message *msg, const char *attr, if (!ldap_find_single_value(msg, attr, &blob)) return False; - *value = talloc(mem_ctx, blob.length+1); + *value = talloc_size(mem_ctx, blob.length+1); if (*value == NULL) return False; -- cgit From 11ce2cfd70df264c5c91b4daaa9a01c5abc673b0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 7 Jan 2005 04:39:16 +0000 Subject: r4591: - converted the other _p talloc functions to not need _p - added #if TALLOC_DEPRECATED around the _p functions - fixes the code that broke from the above while doing this I fixed quite a number of places that were incorrectly using the non type-safe talloc functions to use the type safe ones. Some were even doing multiplies for array allocation, which is potentially unsafe. (This used to be commit 6e7754abd0c225527fb38363996a6e241b87b37e) --- source4/libcli/ldap/ldap_ldif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index c276b7e917..809c75cf96 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -52,7 +52,7 @@ static char *next_chunk(TALLOC_CTX *mem_ctx, if (chunk_size+1 >= alloc_size) { char *c2; alloc_size += 1024; - c2 = talloc_realloc(mem_ctx, chunk, alloc_size); + c2 = talloc_realloc(mem_ctx, chunk, char, alloc_size); if (!c2) { errno = ENOMEM; return NULL; -- cgit From 3dd17f128831e09c230a8d56e34495d3b31dbacb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 27 Jan 2005 06:16:59 +0000 Subject: r5034: - added a type mapping function in pidl, so the type names in our IDL files don't need to match the type names in the generated headers - with this type mapping we no longer need definitions for the deprecated "int32", "uint8" etc form of types. We can now force everyone to use the standard types int32_t, uint8_t etc. - fixed all the code that used the deprecated types - converted the IDL types "int64" and "uint64" to "dlong" and "udlong". These are the 4 byte aligned 64 bit integers that Microsoft internally define as two 32 bit integers in a structure. After discussions with Ronnie Sahlberg we decided that calling these "int64" was confusing, as it implied a true 8 byte aligned type - fixed all the cases where we incorrectly used things like "NTTIME_hyper" in our C code. The generated API now uses a NTTIME for those. The fact that it is hyper-aligned on the wire is not relevant to the API, and should remain just a IDL property (This used to be commit f86521677d7ff16bdc4815f9524e5286026f10f3) --- source4/libcli/ldap/ldap.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 65962bf5b5..8947562b77 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -146,8 +146,8 @@ struct ldap_SearchRequest { const char *basedn; enum ldap_scope scope; enum ldap_deref deref; - uint32 timelimit; - uint32 sizelimit; + uint32_t timelimit; + uint32_t sizelimit; BOOL attributesonly; char *filter; int num_attributes; @@ -206,7 +206,7 @@ struct ldap_CompareRequest { }; struct ldap_AbandonRequest { - uint32 messageid; + uint32_t messageid; }; struct ldap_ExtendedRequest { @@ -251,8 +251,8 @@ struct ldap_Control { struct ldap_message { TALLOC_CTX *mem_ctx; - uint32 messageid; - uint8 type; + uint32_t messageid; + uint8_t type; union ldap_Request r; int num_controls; struct ldap_Control *controls; @@ -269,7 +269,7 @@ struct ldap_connection { int sock; int next_msgid; char *host; - uint16 port; + uint16_t port; BOOL ldaps; const char *auth_dn; -- cgit From 759da3b915e2006d4c87b5ace47f399accd9ce91 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 27 Jan 2005 07:08:20 +0000 Subject: r5037: got rid of all of the TALLOC_DEPRECATED stuff. My apologies for the large commit. I thought this was worthwhile to get done for consistency. (This used to be commit ec32b22ed5ec224f6324f5e069d15e92e38e15c0) --- source4/libcli/ldap/ldap.c | 14 +++++++------- source4/libcli/ldap/ldap_client.c | 6 +++--- source4/libcli/ldap/ldap_ldif.c | 8 ++++---- 3 files changed, 14 insertions(+), 14 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index b2a6bd957a..eab94bb194 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -130,7 +130,7 @@ static struct ldap_parse_tree *ldap_parse_simple(TALLOC_CTX *mem_ctx, if (val && strchr("()&|", *val)) return NULL; - ret = talloc_p(mem_ctx, struct ldap_parse_tree); + ret = talloc(mem_ctx, struct ldap_parse_tree); if (!ret) { errno = ENOMEM; return NULL; @@ -157,7 +157,7 @@ static struct ldap_parse_tree *ldap_parse_filterlist(TALLOC_CTX *mem_ctx, { struct ldap_parse_tree *ret, *next; - ret = talloc_p(mem_ctx, struct ldap_parse_tree); + ret = talloc(mem_ctx, struct ldap_parse_tree); if (!ret) { errno = ENOMEM; return NULL; @@ -165,7 +165,7 @@ static struct ldap_parse_tree *ldap_parse_filterlist(TALLOC_CTX *mem_ctx, ret->operation = op; ret->u.list.num_elements = 1; - ret->u.list.elements = talloc_p(mem_ctx, struct ldap_parse_tree *); + ret->u.list.elements = talloc(mem_ctx, struct ldap_parse_tree *); if (!ret->u.list.elements) { errno = ENOMEM; return NULL; @@ -180,7 +180,7 @@ static struct ldap_parse_tree *ldap_parse_filterlist(TALLOC_CTX *mem_ctx, while (*s && (next = ldap_parse_filter(mem_ctx, &s))) { struct ldap_parse_tree **e; - e = talloc_realloc_p(ret, + e = talloc_realloc(ret, ret->u.list.elements, struct ldap_parse_tree *, ret->u.list.num_elements+1); @@ -205,7 +205,7 @@ static struct ldap_parse_tree *ldap_parse_not(TALLOC_CTX *mem_ctx, const char *s { struct ldap_parse_tree *ret; - ret = talloc_p(mem_ctx, struct ldap_parse_tree); + ret = talloc(mem_ctx, struct ldap_parse_tree); if (!ret) { errno = ENOMEM; return NULL; @@ -448,7 +448,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) ldap_push_filter(&data, tree); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); } asn1_push_tag(&data, ASN1_SEQUENCE(0)); @@ -1186,7 +1186,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) for (i=0; asn1_peek_tag(data, ASN1_SEQUENCE(0)); i++) { asn1_start_tag(data, ASN1_SEQUENCE(0)); - ctrl = talloc_realloc_p(msg->mem_ctx, ctrl, struct ldap_Control, i+1); + ctrl = talloc_realloc(msg->mem_ctx, ctrl, struct ldap_Control, i+1); if (!ctrl) { return False; } diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 84fd0f1d64..c9e81ac28f 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -100,7 +100,7 @@ static struct ldap_connection *new_ldap_connection(TALLOC_CTX *mem_ctx) { struct ldap_connection *result; - result = talloc_p(mem_ctx, struct ldap_connection); + result = talloc(mem_ctx, struct ldap_connection); if (!result) { return NULL; @@ -158,7 +158,7 @@ struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) { struct ldap_message *result; - result = talloc_p(mem_ctx, struct ldap_message); + result = talloc(mem_ctx, struct ldap_message); if (!result) { return NULL; @@ -472,7 +472,7 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha done: if (mem_ctx) - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return result; } diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index 809c75cf96..a0249a4ba0 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -159,7 +159,7 @@ static int next_attr(char **s, const char **attr, struct ldap_val *value) BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldap_val *value, struct ldap_attribute *attrib) { - attrib->values = talloc_realloc_p(mem_ctx, + attrib->values = talloc_realloc(mem_ctx, attrib->values, DATA_BLOB, attrib->num_values+1); @@ -177,7 +177,7 @@ BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, struct ldap_attribute **attribs, int *num_attribs) { - *attribs = talloc_realloc_p(mem_ctx, + *attribs = talloc_realloc(mem_ctx, *attribs, struct ldap_attribute, *num_attribs+1); @@ -211,7 +211,7 @@ static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) } if (attrib == NULL) { - r->attributes = talloc_realloc_p(msg->mem_ctx, + r->attributes = talloc_realloc(msg->mem_ctx, r->attributes, struct ldap_attribute, r->num_attributes+1); @@ -236,7 +236,7 @@ BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, struct ldap_mod **mods, int *num_mods) { - *mods = talloc_realloc_p(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1); + *mods = talloc_realloc(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1); if (*mods == NULL) return False; -- cgit From a0ab1f7afda62964d480af9dc26e60a38d1350e0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 30 Jan 2005 07:22:16 +0000 Subject: r5107: moved the horrible ldap socket code, and the even worse asn1-tied-to-blocking-sockets code into the ldap client and torture suite, and out of the generic libs, so nobody else is tempted to use it for any new code. (This used to be commit 39d1ced21baeca40d1fca62ba65243ca8f15757e) --- source4/libcli/ldap/ldap_client.c | 240 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 240 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index c9e81ac28f..73099ec1be 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -29,6 +29,246 @@ #include "asn_1.h" #include "dlinklist.h" + + +/**************************************************************************** + Check the timeout. +****************************************************************************/ +static BOOL timeout_until(struct timeval *timeout, + const struct timeval *endtime) +{ + struct timeval now; + + GetTimeOfDay(&now); + + if ((now.tv_sec > endtime->tv_sec) || + ((now.tv_sec == endtime->tv_sec) && + (now.tv_usec > endtime->tv_usec))) + return False; + + timeout->tv_sec = endtime->tv_sec - now.tv_sec; + timeout->tv_usec = endtime->tv_usec - now.tv_usec; + return True; +} + + +/**************************************************************************** + Read data from the client, reading exactly N bytes, with timeout. +****************************************************************************/ +static ssize_t read_data_until(int fd,char *buffer,size_t N, + const struct timeval *endtime) +{ + ssize_t ret; + size_t total=0; + + while (total < N) { + + if (endtime != NULL) { + fd_set r_fds; + struct timeval timeout; + int res; + + FD_ZERO(&r_fds); + FD_SET(fd, &r_fds); + + if (!timeout_until(&timeout, endtime)) + return -1; + + res = sys_select(fd+1, &r_fds, NULL, NULL, &timeout); + if (res <= 0) + return -1; + } + + ret = sys_read(fd,buffer + total,N - total); + + if (ret == 0) { + DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) )); + return 0; + } + + if (ret == -1) { + DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) )); + return -1; + } + total += ret; + } + return (ssize_t)total; +} + + +/**************************************************************************** + Write data to a fd with timeout. +****************************************************************************/ +static ssize_t write_data_until(int fd,char *buffer,size_t N, + const struct timeval *endtime) +{ + size_t total=0; + ssize_t ret; + + while (total < N) { + + if (endtime != NULL) { + fd_set w_fds; + struct timeval timeout; + int res; + + FD_ZERO(&w_fds); + FD_SET(fd, &w_fds); + + if (!timeout_until(&timeout, endtime)) + return -1; + + res = sys_select(fd+1, NULL, &w_fds, NULL, &timeout); + if (res <= 0) + return -1; + } + + ret = sys_write(fd,buffer + total,N - total); + + if (ret == -1) { + DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) )); + return -1; + } + if (ret == 0) + return total; + + total += ret; + } + return (ssize_t)total; +} + + + +static BOOL read_one_uint8(int sock, uint8_t *result, struct asn1_data *data, + const struct timeval *endtime) +{ + if (read_data_until(sock, result, 1, endtime) != 1) + return False; + + return asn1_write(data, result, 1); +} + +/* Read a complete ASN sequence (ie LDAP result) from a socket */ +static BOOL asn1_read_sequence_until(int sock, struct asn1_data *data, + const struct timeval *endtime) +{ + uint8_t b; + size_t len; + char *buf; + + ZERO_STRUCTP(data); + + if (!read_one_uint8(sock, &b, data, endtime)) + return False; + + if (b != 0x30) { + data->has_error = True; + return False; + } + + if (!read_one_uint8(sock, &b, data, endtime)) + return False; + + if (b & 0x80) { + int n = b & 0x7f; + if (!read_one_uint8(sock, &b, data, endtime)) + return False; + len = b; + while (n > 1) { + if (!read_one_uint8(sock, &b, data, endtime)) + return False; + len = (len<<8) | b; + n--; + } + } else { + len = b; + } + + buf = talloc_size(NULL, len); + if (buf == NULL) + return False; + + if (read_data_until(sock, buf, len, endtime) != len) + return False; + + if (!asn1_write(data, buf, len)) + return False; + + talloc_free(buf); + + data->ofs = 0; + + return True; +} + + + +/**************************************************************************** + create an outgoing socket. timeout is in milliseconds. + **************************************************************************/ +static int open_socket_out(int type, struct ipv4_addr *addr, int port, int timeout) +{ + struct sockaddr_in sock_out; + int res,ret; + int connect_loop = 250; /* 250 milliseconds */ + int loops = (timeout) / connect_loop; + + /* create a socket to write to */ + res = socket(PF_INET, type, 0); + if (res == -1) + { DEBUG(0,("socket error\n")); return -1; } + + if (type != SOCK_STREAM) return(res); + + memset((char *)&sock_out,'\0',sizeof(sock_out)); + putip((char *)&sock_out.sin_addr,(char *)addr); + + sock_out.sin_port = htons( port ); + sock_out.sin_family = PF_INET; + + /* set it non-blocking */ + set_blocking(res,False); + + DEBUG(3,("Connecting to %s at port %d\n", sys_inet_ntoa(*addr),port)); + + /* and connect it to the destination */ +connect_again: + ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out)); + + /* Some systems return EAGAIN when they mean EINPROGRESS */ + if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || + errno == EAGAIN) && loops--) { + msleep(connect_loop); + goto connect_again; + } + + if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || + errno == EAGAIN)) { + DEBUG(1,("timeout connecting to %s:%d\n", sys_inet_ntoa(*addr),port)); + close(res); + return -1; + } + +#ifdef EISCONN + if (ret < 0 && errno == EISCONN) { + errno = 0; + ret = 0; + } +#endif + + if (ret < 0) { + DEBUG(2,("error connecting to %s:%d (%s)\n", + sys_inet_ntoa(*addr),port,strerror(errno))); + close(res); + return -1; + } + + /* set it blocking again */ + set_blocking(res,True); + + return res; +} + #if 0 static struct ldap_message *new_ldap_search_message(struct ldap_connection *conn, const char *base, -- cgit From d8d3a5ffe3fb73d64869c133fe398efeb4e79d77 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 31 Jan 2005 16:06:21 +0000 Subject: r5137: fix types metze (This used to be commit add1c579375d08040f722946da31ee3862f9e7ac) --- source4/libcli/ldap/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index eab94bb194..655838b64f 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1220,7 +1220,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) } BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, - char **host, uint16 *port, BOOL *ldaps) + char **host, uint16_t *port, BOOL *ldaps) { int tmp_port = 0; char protocol[11]; -- cgit From e82aad1ce39a6b7a2e51b9e2cb494d74ec70e158 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2005 05:09:35 +0000 Subject: r5298: - got rid of pstring.h from includes.h. This at least makes it a bit less likely that anyone will use pstring for new code - got rid of winbind_client.h from includes.h. This one triggered a huge change, as winbind_client.h was including system/filesys.h and defining the old uint32 and uint16 types, as well as its own pstring and fstring. (This used to be commit 9db6c79e902ec538108d6b7d3324039aabe1704f) --- source4/libcli/ldap/ldap.c | 5 +++-- source4/libcli/ldap/ldap_client.c | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 655838b64f..545759c494 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -25,6 +25,7 @@ #include "includes.h" #include "system/iconv.h" +#include "system/filesys.h" #include "asn_1.h" /**************************************************************************** @@ -697,7 +698,7 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, char **filter) { - uint8 filter_tag, tag_desc; + uint8_t filter_tag, tag_desc; if (!asn1_peek_uint8(data, &filter_tag)) return False; @@ -836,7 +837,7 @@ static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) { - uint8 tag; + uint8_t tag; asn1_start_tag(data, ASN1_SEQUENCE(0)); asn1_read_Integer(data, &msg->messageid); diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 73099ec1be..ddf0932fa1 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -25,6 +25,7 @@ #include "includes.h" #include "system/network.h" +#include "system/filesys.h" #include "auth/auth.h" #include "asn_1.h" #include "dlinklist.h" -- cgit From 501379431c7fc6c9a78e74eca43b208184debce6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2005 07:08:40 +0000 Subject: r5305: removed libcli/ldap/ldap.h from includes.h (This used to be commit 0df3fdd8178085c40f9cd776cc3e1486ca559c8e) --- source4/libcli/ldap/config.mk | 1 + source4/libcli/ldap/ldap.c | 1 + source4/libcli/ldap/ldap.h | 59 +++++++++++++++++++++++++++++++++++++++ source4/libcli/ldap/ldap_client.c | 1 + source4/libcli/ldap/ldap_ldif.c | 1 + 5 files changed, 63 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 284edfd95e..87bfdfdbba 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -4,5 +4,6 @@ ADD_OBJ_FILES = libcli/ldap/ldap.o \ libcli/ldap/ldap_client.o \ libcli/ldap/ldap_ldif.o +NOPROTO=YES # End SUBSYSTEM LIBCLI_LDAP ################################# diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 545759c494..4b449e5123 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -27,6 +27,7 @@ #include "system/iconv.h" #include "system/filesys.h" #include "asn_1.h" +#include "libcli/ldap/ldap.h" /**************************************************************************** * diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 8947562b77..3e51e4f60f 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -317,4 +317,63 @@ struct ldap_parse_tree { #define LDAP_ALL_SEP "()&|=!" #define LDAP_CONNECTION_TIMEOUT 10000 +/* The following definitions come from libcli/ldap/ldap.c */ + +BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result); +BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg); +BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, + char **host, uint16_t *port, BOOL *ldaps); + +/* The following definitions come from libcli/ldap/ldap_client.c */ + +struct ldap_connection *ldap_connect(TALLOC_CTX *mem_ctx, const char *url); +struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx); +BOOL ldap_send_msg(struct ldap_connection *conn, struct ldap_message *msg, + const struct timeval *endtime); +BOOL ldap_receive_msg(struct ldap_connection *conn, struct ldap_message *msg, + const struct timeval *endtime); +struct ldap_message *ldap_receive(struct ldap_connection *conn, int msgid, + const struct timeval *endtime); +struct ldap_message *ldap_transaction(struct ldap_connection *conn, + struct ldap_message *request); +int ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const char *password); +int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const char *domain, const char *password); +struct ldap_connection *ldap_setup_connection(TALLOC_CTX *mem_ctx, const char *url, + const char *userdn, const char *password); +struct ldap_connection *ldap_setup_connection_with_sasl(TALLOC_CTX *mem_ctx, const char *url, + const char *username, const char *domain, const char *password); +BOOL ldap_abandon_message(struct ldap_connection *conn, int msgid, + const struct timeval *endtime); +BOOL ldap_setsearchent(struct ldap_connection *conn, struct ldap_message *msg, + const struct timeval *endtime); +struct ldap_message *ldap_getsearchent(struct ldap_connection *conn, + const struct timeval *endtime); +void ldap_endsearchent(struct ldap_connection *conn, + const struct timeval *endtime); +struct ldap_message *ldap_searchone(struct ldap_connection *conn, + struct ldap_message *msg, + const struct timeval *endtime); +BOOL ldap_find_single_value(struct ldap_message *msg, const char *attr, + DATA_BLOB *value); +BOOL ldap_find_single_string(struct ldap_message *msg, const char *attr, + TALLOC_CTX *mem_ctx, char **value); +BOOL ldap_find_single_int(struct ldap_message *msg, const char *attr, + int *value); +int ldap_error(struct ldap_connection *conn); +NTSTATUS ldap2nterror(int ldaperror); + +/* The following definitions come from libcli/ldap/ldap_ldif.c */ + +BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldap_val *value, + struct ldap_attribute *attrib); +BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, + const struct ldap_attribute *attrib, + struct ldap_attribute **attribs, + int *num_attribs); +BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, + struct ldap_mod *mod, + struct ldap_mod **mods, + int *num_mods); +struct ldap_message *ldap_ldif2msg(TALLOC_CTX *mem_ctx, const char *s); + #endif diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index ddf0932fa1..11815ddd6d 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -29,6 +29,7 @@ #include "auth/auth.h" #include "asn_1.h" #include "dlinklist.h" +#include "libcli/ldap/ldap.h" diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index a0249a4ba0..e5e5cdd6df 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -25,6 +25,7 @@ #include "includes.h" #include "system/iconv.h" +#include "libcli/ldap/ldap.h" /**************************************************************************** * -- cgit From 75ddf59ea110117578acd3a7b889549bfb40473c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2005 07:39:14 +0000 Subject: r5308: trimmed back a lot of the old macros from smb_macros.h (This used to be commit bf43c9bdcf9e654d123f6a2b29feb9189ca9e561) --- source4/libcli/ldap/ldap_client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 11815ddd6d..e3904c7a6b 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -223,7 +223,7 @@ static int open_socket_out(int type, struct ipv4_addr *addr, int port, int timeo if (type != SOCK_STREAM) return(res); memset((char *)&sock_out,'\0',sizeof(sock_out)); - putip((char *)&sock_out.sin_addr,(char *)addr); + sock_out.sin_addr.s_addr = addr->addr; sock_out.sin_port = htons( port ); sock_out.sin_family = PF_INET; @@ -385,7 +385,7 @@ struct ldap_connection *ldap_connect(TALLOC_CTX *mem_ctx, const char *url) return NULL; } - putip((char *)&ip, (char *)hp->h_addr); + memcpy((char *)&ip, (char *)hp->h_addr, 4); conn->sock = open_socket_out(SOCK_STREAM, &ip, conn->port, LDAP_CONNECTION_TIMEOUT); if (conn->sock < 0) { -- cgit From 9515fc4406464b6a015a06d89ca0370810977486 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Feb 2005 02:08:39 +0000 Subject: r5322: removed a whole bunch of #include lines that minimal_includes.pl thinks are not needed. Now to see how this fares on the build farm :) (This used to be commit 80ffcc650c9c86141507edd8338b97814a85f868) --- source4/libcli/ldap/ldap.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 4b449e5123..2962f7eef4 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -25,7 +25,6 @@ #include "includes.h" #include "system/iconv.h" -#include "system/filesys.h" #include "asn_1.h" #include "libcli/ldap/ldap.h" -- cgit From 2eb3d680625286431a3a60e37b75f47e0738f253 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 24 Mar 2005 04:14:06 +0000 Subject: r6028: A MAJOR update to intergrate the new credentails system fully with GENSEC, and to pull SCHANNEL into GENSEC, by making it less 'special'. GENSEC now no longer has it's own handling of 'set username' etc, instead it uses cli_credentials calls. In order to link the credentails code right though Samba, a lot of interfaces have changed to remove 'username, domain, password' arguments, and these have been replaced with a single 'struct cli_credentials'. In the session setup code, a new parameter 'workgroup' contains the client/server current workgroup, which seems unrelated to the authentication exchange (it was being filled in from the auth info). This allows in particular kerberos to only call back for passwords when it actually needs to perform the kinit. The kerberos code has been modified not to use the SPNEGO provided 'principal name' (in the mechListMIC), but to instead use the name the host was connected to as. This better matches Microsoft behaviour, is more secure and allows better use of standard kerberos functions. To achieve this, I made changes to our socket code so that the hostname (before name resolution) is now recorded on the socket. In schannel, most of the code from librpc/rpc/dcerpc_schannel.c is now in libcli/auth/schannel.c, and it looks much more like a standard GENSEC module. The actual sign/seal code moved to libcli/auth/schannel_sign.c in a previous commit. The schannel credentails structure is now merged with the rest of the credentails, as many of the values (username, workstation, domain) where already present there. This makes handling this in a generic manner much easier, as there is no longer a custom entry-point. The auth_domain module continues to be developed, but is now just as functional as auth_winbind. The changes here are consequential to the schannel changes. The only removed function at this point is the RPC-LOGIN test (simulating the load of a WinXP login), which needs much more work to clean it up (it contains copies of too much code from all over the torture suite, and I havn't been able to penetrate its 'structure'). Andrew Bartlett (This used to be commit 2301a4b38a21aa60917973451687063d83d18d66) --- source4/libcli/ldap/ldap.h | 4 ++-- source4/libcli/ldap/ldap_client.c | 27 +++++++-------------------- 2 files changed, 9 insertions(+), 22 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 3e51e4f60f..710c022a3c 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -337,11 +337,11 @@ struct ldap_message *ldap_receive(struct ldap_connection *conn, int msgid, struct ldap_message *ldap_transaction(struct ldap_connection *conn, struct ldap_message *request); int ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const char *password); -int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const char *domain, const char *password); +int ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds); struct ldap_connection *ldap_setup_connection(TALLOC_CTX *mem_ctx, const char *url, const char *userdn, const char *password); struct ldap_connection *ldap_setup_connection_with_sasl(TALLOC_CTX *mem_ctx, const char *url, - const char *username, const char *domain, const char *password); + struct cli_credentials *creds); BOOL ldap_abandon_message(struct ldap_connection *conn, int msgid, const struct timeval *endtime); BOOL ldap_setsearchent(struct ldap_connection *conn, struct ldap_message *msg, diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index e3904c7a6b..71b57e116e 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -605,7 +605,7 @@ int ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const cha return result; } -int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const char *domain, const char *password) +int ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds) { NTSTATUS status; TALLOC_CTX *mem_ctx = NULL; @@ -626,23 +626,9 @@ int ldap_bind_sasl(struct ldap_connection *conn, const char *username, const cha gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL); - status = gensec_set_domain(conn->gensec, domain); + status = gensec_set_credentials(conn->gensec, creds); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n", - domain, nt_errstr(status))); - goto done; - } - - status = gensec_set_username(conn->gensec, username); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client username to %s: %s\n", - username, nt_errstr(status))); - goto done; - } - - status = gensec_set_password(conn->gensec, password); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client password: %s\n", + DEBUG(1, ("Failed to start set GENSEC creds: %s\n", nt_errstr(status))); goto done; } @@ -739,8 +725,9 @@ struct ldap_connection *ldap_setup_connection(TALLOC_CTX *mem_ctx, const char *u return conn; } -struct ldap_connection *ldap_setup_connection_with_sasl(TALLOC_CTX *mem_ctx, const char *url, - const char *username, const char *domain, const char *password) +struct ldap_connection *ldap_setup_connection_with_sasl(TALLOC_CTX *mem_ctx, + const char *url, + struct cli_credentials *creds) { struct ldap_connection *conn; int result; @@ -750,7 +737,7 @@ struct ldap_connection *ldap_setup_connection_with_sasl(TALLOC_CTX *mem_ctx, con return NULL; } - result = ldap_bind_sasl(conn, username, domain, password); + result = ldap_bind_sasl(conn, creds); if (result != LDAP_SUCCESS) { talloc_free(conn); return NULL; -- cgit From f6c0bee79125e779ab0036a77506e2f688c4872f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 May 2005 01:57:47 +0000 Subject: r6689: minor ldap client library work - added support for binary encoded search filters - fixed some const handling - changed the message type to an enum, to help debugging (This used to be commit d5353b63428698d1ce95c50e2626f1841fa637e3) --- source4/libcli/ldap/ldap.c | 79 ++++++++++++++++++++++++++++++++++------------ source4/libcli/ldap/ldap.h | 8 ++--- 2 files changed, 63 insertions(+), 24 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 2962f7eef4..37c3266b97 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -106,6 +106,40 @@ static const char *match_brace(const char *s) static struct ldap_parse_tree *ldap_parse_filter(TALLOC_CTX *mem_ctx, const char **s); +/* + decode a RFC2254 binary string representation of a buffer. + Used in LDAP filters. +*/ +static struct ldap_val ldap_binary_decode(TALLOC_CTX *mem_ctx, const char *str) +{ + int i, j; + struct ldap_val ret; + int slen = strlen(str); + + ret.data = talloc_size(mem_ctx, slen); + ret.length = 0; + if (ret.data == NULL) return ret; + + for (i=j=0;i ::= */ @@ -139,8 +173,7 @@ static struct ldap_parse_tree *ldap_parse_simple(TALLOC_CTX *mem_ctx, ret->operation = LDAP_OP_SIMPLE; ret->u.simple.attr = l; - ret->u.simple.value.data = val; - ret->u.simple.value.length = val?strlen(val):0; + ret->u.simple.value = ldap_binary_decode(ret, val); return ret; } @@ -696,9 +729,12 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, } static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, - char **filter) + const char **filterp) { uint8_t filter_tag, tag_desc; + char *filter = NULL; + + *filterp = NULL; if (!asn1_peek_uint8(data, &filter_tag)) return False; @@ -715,22 +751,21 @@ static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, asn1_start_tag(data, ASN1_CONTEXT(0)); - *filter = talloc_strdup(mem_ctx, "(&"); - if (*filter == NULL) + filter = talloc_strdup(mem_ctx, "(&"); + if (filter == NULL) return False; while (asn1_tag_remaining(data) > 0) { - char *subfilter; + const char *subfilter; if (!ldap_decode_filter(mem_ctx, data, &subfilter)) return False; - *filter = talloc_asprintf(mem_ctx, "%s%s", *filter, - subfilter); - if (*filter == NULL) + filter = talloc_asprintf_append(filter, "%s", subfilter); + if (filter == NULL) return False; } asn1_end_tag(data); - *filter = talloc_asprintf(mem_ctx, "%s)", *filter); + filter = talloc_asprintf(mem_ctx, "%s)", filter); break; } case 1: { @@ -740,23 +775,22 @@ static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, asn1_start_tag(data, ASN1_CONTEXT(1)); - *filter = talloc_strdup(mem_ctx, "(|"); - if (*filter == NULL) + filter = talloc_strdup(mem_ctx, "(|"); + if (filter == NULL) return False; while (asn1_tag_remaining(data) > 0) { - char *subfilter; + const char *subfilter; if (!ldap_decode_filter(mem_ctx, data, &subfilter)) return False; - *filter = talloc_asprintf(mem_ctx, "%s%s", *filter, - subfilter); - if (*filter == NULL) + filter = talloc_asprintf_append(filter, "%s", subfilter); + if (filter == NULL) return False; } asn1_end_tag(data); - *filter = talloc_asprintf(mem_ctx, "%s)", *filter); + filter = talloc_asprintf(mem_ctx, "%s)", filter); break; } case 3: { @@ -770,7 +804,7 @@ static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, asn1_end_tag(data); if ((data->has_error) || (attrib == NULL) || (value == NULL)) return False; - *filter = talloc_asprintf(mem_ctx, "(%s=%s)", attrib, value); + filter = talloc_asprintf(mem_ctx, "(%s=%s)", attrib, value); break; } case 7: { @@ -787,7 +821,7 @@ static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, return False; asn1_read(data, attr_name, attr_len); attr_name[attr_len] = '\0'; - *filter = talloc_asprintf(mem_ctx, "(%s=*)", attr_name); + filter = talloc_asprintf(mem_ctx, "(%s=*)", attr_name); SAFE_FREE(attr_name); asn1_end_tag(data); break; @@ -795,8 +829,11 @@ static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, default: return False; } - if (*filter == NULL) + if (filter == NULL) return False; + + *filterp = filter; + return True; } @@ -1260,3 +1297,5 @@ BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, return (*host != NULL); } + + diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 710c022a3c..50031fd60c 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -149,7 +149,7 @@ struct ldap_SearchRequest { uint32_t timelimit; uint32_t sizelimit; BOOL attributesonly; - char *filter; + const char *filter; int num_attributes; const char **attributes; }; @@ -251,9 +251,9 @@ struct ldap_Control { struct ldap_message { TALLOC_CTX *mem_ctx; - uint32_t messageid; - uint8_t type; - union ldap_Request r; + uint32_t messageid; + enum ldap_request_tag type; + union ldap_Request r; int num_controls; struct ldap_Control *controls; }; -- cgit From 49304e965f87d00b7ba5d66fe929611d3ad2ebef Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 11 May 2005 05:59:46 +0000 Subject: r6726: support binary search elements in ldap_decode() (This used to be commit 2b36f1dfdd6cf3ab89f63b541ae4cd905fb03c8d) --- source4/libcli/ldap/ldap.c | 48 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 37c3266b97..1a4f323ebf 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -140,6 +140,39 @@ static struct ldap_val ldap_binary_decode(TALLOC_CTX *mem_ctx, const char *str) } +/* + encode a blob as a RFC2254 binary string, escaping any + non-printable or '\' characters +*/ +static const char *ldap_binary_encode(TALLOC_CTX *mem_ctx, DATA_BLOB blob) +{ + int i; + char *ret; + int len = blob.length; + for (i=0;i ::= */ @@ -765,7 +798,7 @@ static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, } asn1_end_tag(data); - filter = talloc_asprintf(mem_ctx, "%s)", filter); + filter = talloc_asprintf_append(filter, ")"); break; } case 1: { @@ -790,21 +823,24 @@ static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, asn1_end_tag(data); - filter = talloc_asprintf(mem_ctx, "%s)", filter); + filter = talloc_asprintf_append(filter, ")"); break; } case 3: { /* equalityMatch */ - const char *attrib, *value; + const char *attrib; + DATA_BLOB value; if (tag_desc != 0xa0) /* context compound */ return False; asn1_start_tag(data, ASN1_CONTEXT(3)); asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString_talloc(mem_ctx, data, &value); + asn1_read_OctetString(data, &value); asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value == NULL)) + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) return False; - filter = talloc_asprintf(mem_ctx, "(%s=%s)", attrib, value); + filter = talloc_asprintf(mem_ctx, "(%s=%s)", + attrib, ldap_binary_encode(mem_ctx, value)); + data_blob_free(&value); break; } case 7: { -- cgit From 2542d54e9384302c6c9a7b2b2bf4be07b6d95f9c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 11 May 2005 14:38:13 +0000 Subject: r6732: - move sasl send recv code to the ldap lib - support 'modrdn' ldif metze (This used to be commit b6a1734699953964fcde6fe6ea7048496492eb33) --- source4/libcli/ldap/ldap_client.c | 131 +++++++++++++++++++++++++++++++++++++- source4/libcli/ldap/ldap_ldif.c | 58 +++++++++++++++++ 2 files changed, 188 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 71b57e116e..8867344de3 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -548,9 +548,138 @@ struct ldap_message *ldap_receive(struct ldap_connection *conn, int msgid, return NULL; } +/* + Write data to a fd +*/ +static ssize_t write_data(int fd, char *buffer, size_t N) +{ + size_t total=0; + ssize_t ret; + + while (total < N) { + ret = sys_write(fd,buffer + total,N - total); + + if (ret == -1) { + DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) )); + return -1; + } + if (ret == 0) + return total; + + total += ret; + } + + return (ssize_t)total; +} + + +/* + Read data from the client, reading exactly N bytes +*/ +static ssize_t read_data(int fd, char *buffer, size_t N) +{ + ssize_t ret; + size_t total=0; + + while (total < N) { + + ret = sys_read(fd,buffer + total,N - total); + + if (ret == 0) { + DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", + (int)(N - total), strerror(errno) )); + return 0; + } + + if (ret == -1) { + DEBUG(0,("read_data: read failure for %d. Error = %s\n", + (int)(N - total), strerror(errno) )); + return -1; + } + total += ret; + } + + return (ssize_t)total; +} + +static struct ldap_message *ldap_transaction_sasl(struct ldap_connection *conn, struct ldap_message *req) +{ + NTSTATUS status; + DATA_BLOB request; + BOOL result; + DATA_BLOB wrapped; + int len; + char length[4]; + struct asn1_data asn1; + struct ldap_message *rep; + + req->messageid = conn->next_msgid++; + + if (!ldap_encode(req, &request)) + return NULL; + + status = gensec_wrap(conn->gensec, + req->mem_ctx, + &request, + &wrapped); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("gensec_wrap: %s\n",nt_errstr(status))); + return NULL; + } + + RSIVAL(length, 0, wrapped.length); + + result = (write_data(conn->sock, length, 4) == 4); + if (!result) + return NULL; + + result = (write_data(conn->sock, wrapped.data, wrapped.length) == wrapped.length); + if (!result) + return NULL; + + wrapped = data_blob(NULL, 0x4000); + data_blob_clear(&wrapped); + + result = (read_data(conn->sock, length, 4) == 4); + if (!result) + return NULL; + + len = RIVAL(length,0); + + result = (read_data(conn->sock, wrapped.data, MIN(wrapped.length,len)) == len); + if (!result) + return NULL; + + wrapped.length = len; + + status = gensec_unwrap(conn->gensec, + req->mem_ctx, + &wrapped, + &request); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("gensec_unwrap: %s\n",nt_errstr(status))); + return NULL; + } + + rep = new_ldap_message(req->mem_ctx); + + asn1_load(&asn1, request); + if (!ldap_decode(&asn1, rep)) { + return NULL; + } + + return rep; +} + struct ldap_message *ldap_transaction(struct ldap_connection *conn, struct ldap_message *request) { + if ((request->type != LDAP_TAG_BindRequest) && conn->gensec && + (gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) || + gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN))) { + return ldap_transaction_sasl(conn, request); + } + if (!ldap_send_msg(conn, request, NULL)) return False; @@ -624,7 +753,7 @@ int ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds) return result; } - gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL); + gensec_want_feature(conn->gensec, 0 | GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL); status = gensec_set_credentials(conn->gensec, creds); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index e5e5cdd6df..c36106e116 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -305,6 +305,53 @@ static BOOL fill_mods(struct ldap_message *msg, char **chunk) return True; } +static BOOL fill_modrdn(struct ldap_message *msg, char **chunk) +{ + struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; + const char *attr_name; + struct ldap_val value; + + r->newrdn = NULL; + r->deleteolddn = False; + r->newsuperior = NULL; + + if (next_attr(chunk, &attr_name, &value) != 0) { + return False; + } + + if (!strequal(attr_name, "newrdn")) { + return False; + } + + r->newrdn = value.data; + + if (next_attr(chunk, &attr_name, &value) != 0) { + return False; + } + + if (!strequal(attr_name, "deleteoldrdn")) { + return False; + } + + if (value.data && (((char *)value.data)[0] != '0')) { + r->deleteolddn = True; + } + + if (next_attr(chunk, &attr_name, &value) != 0) { + /* newsuperior is optional */ + return True; + } + + if (!strequal(attr_name, "newsuperior")) { + return False; + } + + r->newsuperior = value.data; + + return True; +} + + /* read from a LDIF source, creating a ldap_message */ @@ -381,6 +428,17 @@ static struct ldap_message *ldif_read(TALLOC_CTX *mem_ctx, int (*fgetc_fn)(void return msg; } + if (strequal(value.data, "modrdn")) { + msg->type = LDAP_TAG_ModifyDNRequest; + + msg->r.ModifyDNRequest.dn = dn; + + if (!fill_modrdn(msg, &s)) + goto failed; + + return msg; + } + DEBUG(3, ("changetype %s not supported\n", (char *)value.data)); failed: -- cgit From c956f4f98205c376062c4d634fd4ba4fb41031e4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 12 May 2005 08:26:26 +0000 Subject: r6745: - escape spaces in binary ldap blobs - expose the ldap filter string parsing outside of ldap.c (This used to be commit b644ff6fe164fbe359c47e4d34f5ad490ff61d5b) --- source4/libcli/ldap/ldap.c | 16 +++++++++++++--- source4/libcli/ldap/ldap.h | 2 ++ 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 1a4f323ebf..9a8a7bb589 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -150,7 +150,7 @@ static const char *ldap_binary_encode(TALLOC_CTX *mem_ctx, DATA_BLOB blob) char *ret; int len = blob.length; for (i=0;i ::= '(' ')' */ static struct ldap_parse_tree *ldap_parse_filter(TALLOC_CTX *mem_ctx, - const char **s) + const char **s) { char *l, *s2; const char *p, *p2; @@ -1335,3 +1335,13 @@ BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, } + +/* + externally callable version of filter string parsing - used in the + cldap server +*/ +struct ldap_parse_tree *ldap_parse_filter_string(TALLOC_CTX *mem_ctx, + const char *s) +{ + return ldap_parse_filter(mem_ctx, &s); +} diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 50031fd60c..63d79628a9 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -323,6 +323,8 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result); BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg); BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, char **host, uint16_t *port, BOOL *ldaps); +struct ldap_parse_tree *ldap_parse_filter_string(TALLOC_CTX *mem_ctx, + const char *s); /* The following definitions come from libcli/ldap/ldap_client.c */ -- cgit From 4029df5e602760a0a0f8851e9f7bb28e1434f4f0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 13 May 2005 06:07:53 +0000 Subject: r6763: added functions in libcli/ldap/ to binary encode some NDR structures into ldap friendly filter strings (This used to be commit 8890dd3ac331cffe83226a356c52df89c917c2b0) --- source4/libcli/ldap/config.mk | 3 +- source4/libcli/ldap/ldap.c | 5 ++- source4/libcli/ldap/ldap.h | 7 ++++ source4/libcli/ldap/ldap_ndr.c | 76 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 source4/libcli/ldap/ldap_ndr.c (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 87bfdfdbba..888590ec5e 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -3,7 +3,8 @@ [SUBSYSTEM::LIBCLI_LDAP] ADD_OBJ_FILES = libcli/ldap/ldap.o \ libcli/ldap/ldap_client.o \ - libcli/ldap/ldap_ldif.o + libcli/ldap/ldap_ldif.o \ + libcli/ldap/ldap_ndr.o NOPROTO=YES # End SUBSYSTEM LIBCLI_LDAP ################################# diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 9a8a7bb589..cc7f1a10bc 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -144,7 +144,7 @@ static struct ldap_val ldap_binary_decode(TALLOC_CTX *mem_ctx, const char *str) encode a blob as a RFC2254 binary string, escaping any non-printable or '\' characters */ -static const char *ldap_binary_encode(TALLOC_CTX *mem_ctx, DATA_BLOB blob) +const char *ldap_binary_encode(TALLOC_CTX *mem_ctx, DATA_BLOB blob) { int i; char *ret; @@ -1345,3 +1345,6 @@ struct ldap_parse_tree *ldap_parse_filter_string(TALLOC_CTX *mem_ctx, { return ldap_parse_filter(mem_ctx, &s); } + + + diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 63d79628a9..8d4294cf76 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -325,6 +325,7 @@ BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, char **host, uint16_t *port, BOOL *ldaps); struct ldap_parse_tree *ldap_parse_filter_string(TALLOC_CTX *mem_ctx, const char *s); +const char *ldap_binary_encode(TALLOC_CTX *mem_ctx, DATA_BLOB blob); /* The following definitions come from libcli/ldap/ldap_client.c */ @@ -378,4 +379,10 @@ BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, int *num_mods); struct ldap_message *ldap_ldif2msg(TALLOC_CTX *mem_ctx, const char *s); +/* The following definitions come from libcli/ldap/ldap_ndr.c */ + +const char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value); +const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, struct dom_sid *sid); +const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid); + #endif diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c new file mode 100644 index 0000000000..45d9b2729e --- /dev/null +++ b/source4/libcli/ldap/ldap_ndr.c @@ -0,0 +1,76 @@ +/* + Unix SMB/CIFS mplementation. + + wrap/unwrap NDR encoded elements for ldap calls + + Copyright (C) Andrew Tridgell 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 "libcli/ldap/ldap.h" +#include "librpc/gen_ndr/ndr_security.h" + +/* + encode a NDR uint32 as a ldap filter element +*/ +const char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value) +{ + uint8_t buf[4]; + DATA_BLOB blob; + SIVAL(buf, 0, value); + blob.data = buf; + blob.length = 4; + return ldap_binary_encode(mem_ctx, blob); +} + +/* + encode a NDR dom_sid as a ldap filter element +*/ +const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, struct dom_sid *sid) +{ + DATA_BLOB blob; + NTSTATUS status; + const char *ret; + status = ndr_push_struct_blob(&blob, mem_ctx, sid, + (ndr_push_flags_fn_t)ndr_push_dom_sid); + if (!NT_STATUS_IS_OK(status)) { + return NULL; + } + ret = ldap_binary_encode(mem_ctx, blob); + data_blob_free(&blob); + return ret; +} + + +/* + encode a NDR GUID as a ldap filter element +*/ +const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) +{ + DATA_BLOB blob; + NTSTATUS status; + const char *ret; + status = ndr_push_struct_blob(&blob, mem_ctx, guid, + (ndr_push_flags_fn_t)ndr_push_GUID); + if (!NT_STATUS_IS_OK(status)) { + return NULL; + } + ret = ldap_binary_encode(mem_ctx, blob); + data_blob_free(&blob); + return ret; +} -- cgit From 9469051d5bcdd6a91b688d20bc91bb3cb2ba094d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 16 May 2005 11:17:57 +0000 Subject: r6817: - fixed empty ldap search elements in filters - added support for guids in cldap netlogon searches. the cldap server now passes the LDAP-CLDAP torture test (This used to be commit eb7979d9def389942fa1c54693d2dfcb8828f544) --- source4/libcli/ldap/ldap.c | 2 +- source4/libcli/ldap/ldap.h | 2 ++ source4/libcli/ldap/ldap_ndr.c | 16 ++++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index cc7f1a10bc..0c6a466f27 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -110,7 +110,7 @@ static struct ldap_parse_tree *ldap_parse_filter(TALLOC_CTX *mem_ctx, decode a RFC2254 binary string representation of a buffer. Used in LDAP filters. */ -static struct ldap_val ldap_binary_decode(TALLOC_CTX *mem_ctx, const char *str) +struct ldap_val ldap_binary_decode(TALLOC_CTX *mem_ctx, const char *str) { int i, j; struct ldap_val ret; diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 8d4294cf76..54a96d9672 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -326,6 +326,7 @@ BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, struct ldap_parse_tree *ldap_parse_filter_string(TALLOC_CTX *mem_ctx, const char *s); const char *ldap_binary_encode(TALLOC_CTX *mem_ctx, DATA_BLOB blob); +struct ldap_val ldap_binary_decode(TALLOC_CTX *mem_ctx, const char *str); /* The following definitions come from libcli/ldap/ldap_client.c */ @@ -384,5 +385,6 @@ struct ldap_message *ldap_ldif2msg(TALLOC_CTX *mem_ctx, const char *s); const char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value); const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, struct dom_sid *sid); const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid); +NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldap_val val, struct GUID *guid); #endif diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index 45d9b2729e..2db85d8f09 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -74,3 +74,19 @@ const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) data_blob_free(&blob); return ret; } + +/* + decode a NDR GUID from a ldap filter element +*/ +NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldap_val val, struct GUID *guid) +{ + DATA_BLOB blob; + NTSTATUS status; + + blob.data = val.data; + blob.length = val.length; + status = ndr_pull_struct_blob(&blob, mem_ctx, guid, + (ndr_pull_flags_fn_t)ndr_pull_GUID); + talloc_free(val.data); + return status; +} -- cgit From 816f4f7c4afa1022075fb36563fadf4820f37afd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Jun 2005 06:06:29 +0000 Subject: r7519: rip the copy of the ldap expression parser out of libcli/ldap/ and use the original one in lib/ldb/ instead. Having two copies of this code is silly. (This used to be commit 0e9f18c44858b692c724c004f362de9e3dc15db5) --- source4/libcli/ldap/ldap.c | 392 ++-------------------------------------- source4/libcli/ldap/ldap.h | 38 +--- source4/libcli/ldap/ldap_ldif.c | 12 +- source4/libcli/ldap/ldap_ndr.c | 22 ++- 4 files changed, 43 insertions(+), 421 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 0c6a466f27..f383d08074 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -28,350 +28,11 @@ #include "asn_1.h" #include "libcli/ldap/ldap.h" -/**************************************************************************** - * - * LDAP filter parser -- main routine is ldap_parse_filter - * - * Shamelessly stolen and adapted from ldb. - * - ***************************************************************************/ - -/* - return next token element. Caller frees -*/ -static char *ldap_parse_lex(TALLOC_CTX *mem_ctx, const char **s, - const char *sep) -{ - const char *p = *s; - char *ret; - - while (isspace(*p)) { - p++; - } - *s = p; - - if (*p == 0) { - return NULL; - } - - if (strchr(sep, *p)) { - (*s) = p+1; - ret = talloc_strndup(mem_ctx, p, 1); - if (!ret) { - errno = ENOMEM; - } - return ret; - } - - while (*p && (isalnum(*p) || !strchr(sep, *p))) { - p++; - } - - if (p == *s) { - return NULL; - } - - ret = talloc_strndup(mem_ctx, *s, p - *s); - if (!ret) { - errno = ENOMEM; - } - - *s = p; - - return ret; -} - - -/* - find a matching close brace in a string -*/ -static const char *match_brace(const char *s) -{ - unsigned int count = 0; - while (*s && (count != 0 || *s != ')')) { - if (*s == '(') { - count++; - } - if (*s == ')') { - count--; - } - s++; - } - if (! *s) { - return NULL; - } - return s; -} - -static struct ldap_parse_tree *ldap_parse_filter(TALLOC_CTX *mem_ctx, - const char **s); - -/* - decode a RFC2254 binary string representation of a buffer. - Used in LDAP filters. -*/ -struct ldap_val ldap_binary_decode(TALLOC_CTX *mem_ctx, const char *str) -{ - int i, j; - struct ldap_val ret; - int slen = strlen(str); - - ret.data = talloc_size(mem_ctx, slen); - ret.length = 0; - if (ret.data == NULL) return ret; - - for (i=j=0;i ::= -*/ -static struct ldap_parse_tree *ldap_parse_simple(TALLOC_CTX *mem_ctx, - const char *s) -{ - char *eq, *val, *l; - struct ldap_parse_tree *ret; - - l = ldap_parse_lex(mem_ctx, &s, LDAP_ALL_SEP); - if (!l) { - return NULL; - } - - if (strchr("()&|=", *l)) - return NULL; - - eq = ldap_parse_lex(mem_ctx, &s, LDAP_ALL_SEP); - if (!eq || strcmp(eq, "=") != 0) - return NULL; - - val = ldap_parse_lex(mem_ctx, &s, ")"); - if (val && strchr("()&|", *val)) - return NULL; - - ret = talloc(mem_ctx, struct ldap_parse_tree); - if (!ret) { - errno = ENOMEM; - return NULL; - } - - ret->operation = LDAP_OP_SIMPLE; - ret->u.simple.attr = l; - ret->u.simple.value = ldap_binary_decode(ret, val); - - return ret; -} - - -/* - parse a filterlist - ::= '&' - ::= '|' - ::= | -*/ -static struct ldap_parse_tree *ldap_parse_filterlist(TALLOC_CTX *mem_ctx, - enum ldap_parse_op op, - const char *s) -{ - struct ldap_parse_tree *ret, *next; - - ret = talloc(mem_ctx, struct ldap_parse_tree); - if (!ret) { - errno = ENOMEM; - return NULL; - } - - ret->operation = op; - ret->u.list.num_elements = 1; - ret->u.list.elements = talloc(mem_ctx, struct ldap_parse_tree *); - if (!ret->u.list.elements) { - errno = ENOMEM; - return NULL; - } - - ret->u.list.elements[0] = ldap_parse_filter(mem_ctx, &s); - if (!ret->u.list.elements[0]) { - return NULL; - } - - while (isspace(*s)) s++; - - while (*s && (next = ldap_parse_filter(mem_ctx, &s))) { - struct ldap_parse_tree **e; - e = talloc_realloc(ret, - ret->u.list.elements, - struct ldap_parse_tree *, - ret->u.list.num_elements+1); - if (!e) { - errno = ENOMEM; - return NULL; - } - ret->u.list.elements = e; - ret->u.list.elements[ret->u.list.num_elements] = next; - ret->u.list.num_elements++; - while (isspace(*s)) s++; - } - - return ret; -} - - -/* - ::= '!' -*/ -static struct ldap_parse_tree *ldap_parse_not(TALLOC_CTX *mem_ctx, const char *s) -{ - struct ldap_parse_tree *ret; - - ret = talloc(mem_ctx, struct ldap_parse_tree); - if (!ret) { - errno = ENOMEM; - return NULL; - } - - ret->operation = LDAP_OP_NOT; - ret->u.not.child = ldap_parse_filter(mem_ctx, &s); - if (!ret->u.not.child) - return NULL; - - return ret; -} - -/* - parse a filtercomp - ::= | | | -*/ -static struct ldap_parse_tree *ldap_parse_filtercomp(TALLOC_CTX *mem_ctx, - const char *s) -{ - while (isspace(*s)) s++; - - switch (*s) { - case '&': - return ldap_parse_filterlist(mem_ctx, LDAP_OP_AND, s+1); - - case '|': - return ldap_parse_filterlist(mem_ctx, LDAP_OP_OR, s+1); - - case '!': - return ldap_parse_not(mem_ctx, s+1); - - case '(': - case ')': - return NULL; - } - - return ldap_parse_simple(mem_ctx, s); -} - - -/* - ::= '(' ')' -*/ -static struct ldap_parse_tree *ldap_parse_filter(TALLOC_CTX *mem_ctx, - const char **s) -{ - char *l, *s2; - const char *p, *p2; - struct ldap_parse_tree *ret; - - l = ldap_parse_lex(mem_ctx, s, LDAP_ALL_SEP); - if (!l) { - return NULL; - } - - if (strcmp(l, "(") != 0) { - return NULL; - } - - p = match_brace(*s); - if (!p) { - return NULL; - } - p2 = p + 1; - - s2 = talloc_strndup(mem_ctx, *s, p - *s); - if (!s2) { - errno = ENOMEM; - return NULL; - } - - ret = ldap_parse_filtercomp(mem_ctx, s2); - - *s = p2; - - return ret; -} - -/* - main parser entry point. Takes a search string and returns a parse tree - - expression ::= | -*/ -static struct ldap_parse_tree *ldap_parse_tree(TALLOC_CTX *mem_ctx, const char *s) -{ - while (isspace(*s)) s++; - - if (*s == '(') { - return ldap_parse_filter(mem_ctx, &s); - } - - return ldap_parse_simple(mem_ctx, s); -} - -static BOOL ldap_push_filter(struct asn1_data *data, struct ldap_parse_tree *tree) +static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree) { switch (tree->operation) { - case LDAP_OP_SIMPLE: { + case LDB_OP_SIMPLE: { if ((tree->u.simple.value.length == 1) && (((char *)(tree->u.simple.value.data))[0] == '*')) { /* Just a presence test */ @@ -392,7 +53,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldap_parse_tree *tre break; } - case LDAP_OP_AND: { + case LDB_OP_AND: { int i; asn1_push_tag(data, 0xa0); @@ -403,7 +64,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldap_parse_tree *tre break; } - case LDAP_OP_OR: { + case LDB_OP_OR: { int i; asn1_push_tag(data, 0xa1); @@ -481,9 +142,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) struct ldap_BindResponse *r = &msg->r.BindResponse; asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); ldap_encode_response(&data, &r->response); - if (r->SASL.secblob.length > 0) { - asn1_write_ContextSimple(&data, 7, &r->SASL.secblob); - } + asn1_write_ContextSimple(&data, 7, &r->SASL.secblob); asn1_pop_tag(&data); break; } @@ -493,6 +152,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_SearchRequest: { struct ldap_SearchRequest *r = &msg->r.SearchRequest; + struct ldb_parse_tree *tree; asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); asn1_write_OctetString(&data, r->basedn, strlen(r->basedn)); asn1_write_enumerated(&data, r->scope); @@ -501,22 +161,14 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) asn1_write_Integer(&data, r->timelimit); asn1_write_BOOLEAN(&data, r->attributesonly); - { - TALLOC_CTX *mem_ctx = talloc_init("ldap_parse_tree"); - struct ldap_parse_tree *tree; - - if (mem_ctx == NULL) - return False; + tree = ldb_parse_tree(NULL, r->filter); - tree = ldap_parse_tree(mem_ctx, r->filter); - - if (tree == NULL) - return False; + if (tree == NULL) + return False; - ldap_push_filter(&data, tree); + ldap_push_filter(&data, tree); - talloc_free(mem_ctx); - } + talloc_free(tree); asn1_push_tag(&data, ASN1_SEQUENCE(0)); for (i=0; inum_attributes; i++) { @@ -830,6 +482,8 @@ static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, /* equalityMatch */ const char *attrib; DATA_BLOB value; + struct ldb_val val; + if (tag_desc != 0xa0) /* context compound */ return False; asn1_start_tag(data, ASN1_CONTEXT(3)); @@ -838,8 +492,10 @@ static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, asn1_end_tag(data); if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) return False; + val.data = value.data; + val.length = value.length; filter = talloc_asprintf(mem_ctx, "(%s=%s)", - attrib, ldap_binary_encode(mem_ctx, value)); + attrib, ldb_binary_encode(mem_ctx, val)); data_blob_free(&value); break; } @@ -881,7 +537,7 @@ static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, asn1_start_tag(data, ASN1_SET); while (asn1_peek_tag(data, ASN1_OCTET_STRING)) { DATA_BLOB blob; - struct ldap_val value; + struct ldb_val value; asn1_read_OctetString(data, &blob); value.data = blob.data; value.length = blob.length; @@ -1334,17 +990,3 @@ BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, return (*host != NULL); } - - -/* - externally callable version of filter string parsing - used in the - cldap server -*/ -struct ldap_parse_tree *ldap_parse_filter_string(TALLOC_CTX *mem_ctx, - const char *s) -{ - return ldap_parse_filter(mem_ctx, &s); -} - - - diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 54a96d9672..12d30a2610 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -22,6 +22,9 @@ #ifndef _SMB_LDAP_H #define _SMB_LDAP_H +#include "lib/ldb/include/ldb.h" +#include "lib/ldb/include/ldb_parse.h" + enum ldap_request_tag { LDAP_TAG_BindRequest = 0, LDAP_TAG_BindResponse = 1, @@ -288,33 +291,6 @@ struct ldap_connection { struct gensec_security *gensec; }; -/* Hmm. A blob might be more appropriate here :-) */ - -struct ldap_val { - unsigned int length; - void *data; -}; - -enum ldap_parse_op {LDAP_OP_SIMPLE, LDAP_OP_AND, LDAP_OP_OR, LDAP_OP_NOT}; - -struct ldap_parse_tree { - enum ldap_parse_op operation; - union { - struct { - char *attr; - struct ldap_val value; - } simple; - struct { - unsigned int num_elements; - struct ldap_parse_tree **elements; - } list; - struct { - struct ldap_parse_tree *child; - } not; - } u; -}; - -#define LDAP_ALL_SEP "()&|=!" #define LDAP_CONNECTION_TIMEOUT 10000 /* The following definitions come from libcli/ldap/ldap.c */ @@ -323,10 +299,6 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result); BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg); BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, char **host, uint16_t *port, BOOL *ldaps); -struct ldap_parse_tree *ldap_parse_filter_string(TALLOC_CTX *mem_ctx, - const char *s); -const char *ldap_binary_encode(TALLOC_CTX *mem_ctx, DATA_BLOB blob); -struct ldap_val ldap_binary_decode(TALLOC_CTX *mem_ctx, const char *str); /* The following definitions come from libcli/ldap/ldap_client.c */ @@ -368,7 +340,7 @@ NTSTATUS ldap2nterror(int ldaperror); /* The following definitions come from libcli/ldap/ldap_ldif.c */ -BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldap_val *value, +BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, struct ldap_attribute *attrib); BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, const struct ldap_attribute *attrib, @@ -385,6 +357,6 @@ struct ldap_message *ldap_ldif2msg(TALLOC_CTX *mem_ctx, const char *s); const char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value); const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, struct dom_sid *sid); const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid); -NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldap_val val, struct GUID *guid); +NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GUID *guid); #endif diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index c36106e116..2489a97748 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -104,7 +104,7 @@ static char *next_chunk(TALLOC_CTX *mem_ctx, } /* simple ldif attribute parser */ -static int next_attr(char **s, const char **attr, struct ldap_val *value) +static int next_attr(char **s, const char **attr, struct ldb_val *value) { char *p; int base64_encoded = 0; @@ -157,7 +157,7 @@ static int next_attr(char **s, const char **attr, struct ldap_val *value) return 0; } -BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldap_val *value, +BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, struct ldap_attribute *attrib) { attrib->values = talloc_realloc(mem_ctx, @@ -195,7 +195,7 @@ static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) { struct ldap_AddRequest *r = &msg->r.AddRequest; const char *attr_name; - struct ldap_val value; + struct ldb_val value; r->num_attributes = 0; r->attributes = NULL; @@ -251,7 +251,7 @@ static BOOL fill_mods(struct ldap_message *msg, char **chunk) { struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; const char *attr_name; - struct ldap_val value; + struct ldb_val value; r->num_mods = 0; r->mods = NULL; @@ -309,7 +309,7 @@ static BOOL fill_modrdn(struct ldap_message *msg, char **chunk) { struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; const char *attr_name; - struct ldap_val value; + struct ldb_val value; r->newrdn = NULL; r->deleteolddn = False; @@ -362,7 +362,7 @@ static struct ldap_message *ldif_read(TALLOC_CTX *mem_ctx, int (*fgetc_fn)(void const char *attr=NULL; const char *dn; char *chunk=NULL, *s; - struct ldap_val value; + struct ldb_val value; value.data = NULL; diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index 2db85d8f09..720022c6c2 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -25,17 +25,25 @@ #include "libcli/ldap/ldap.h" #include "librpc/gen_ndr/ndr_security.h" +struct ldb_val ldb_blob(DATA_BLOB blob) +{ + struct ldb_val val; + val.data = blob.data; + val.length = blob.length; + return val; +} + /* encode a NDR uint32 as a ldap filter element */ const char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value) { uint8_t buf[4]; - DATA_BLOB blob; + struct ldb_val val; SIVAL(buf, 0, value); - blob.data = buf; - blob.length = 4; - return ldap_binary_encode(mem_ctx, blob); + val.data = buf; + val.length = 4; + return ldb_binary_encode(mem_ctx, val); } /* @@ -51,7 +59,7 @@ const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, struct dom_sid *sid) if (!NT_STATUS_IS_OK(status)) { return NULL; } - ret = ldap_binary_encode(mem_ctx, blob); + ret = ldb_binary_encode(mem_ctx, ldb_blob(blob)); data_blob_free(&blob); return ret; } @@ -70,7 +78,7 @@ const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) if (!NT_STATUS_IS_OK(status)) { return NULL; } - ret = ldap_binary_encode(mem_ctx, blob); + ret = ldb_binary_encode(mem_ctx, ldb_blob(blob)); data_blob_free(&blob); return ret; } @@ -78,7 +86,7 @@ const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) /* decode a NDR GUID from a ldap filter element */ -NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldap_val val, struct GUID *guid) +NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GUID *guid) { DATA_BLOB blob; NTSTATUS status; -- cgit From 8fd5825a890db4f08966e4b262b03fb7868cc4c2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Jun 2005 07:36:52 +0000 Subject: r7524: make the ldap ASN.1 filter parse code go via a struct ldb_parse_tree. This also fixes the error handling. next step will be to pass the parse tree straight into ldb, avoiding the string encoding completely. (This used to be commit 235cf625e20767c8d5d30c5955ae45e1fdf88bf2) --- source4/libcli/ldap/ldap.c | 184 ++++++++++++++++++++++++++------------------- 1 file changed, 107 insertions(+), 77 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index f383d08074..2718dd7e34 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -413,122 +413,152 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, } } -static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, - const char **filterp) +static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, + struct asn1_data *data) { uint8_t filter_tag, tag_desc; - char *filter = NULL; - - *filterp = NULL; + struct ldb_parse_tree *ret; - if (!asn1_peek_uint8(data, &filter_tag)) - return False; + if (!asn1_peek_uint8(data, &filter_tag)) { + return NULL; + } tag_desc = filter_tag; filter_tag &= 0x1f; /* strip off the asn1 stuff */ tag_desc &= 0xe0; - switch(filter_tag) { - case 0: { - /* AND of one or more filters */ - if (tag_desc != 0xa0) /* context compount */ - return False; - - asn1_start_tag(data, ASN1_CONTEXT(0)); + ret = talloc(mem_ctx, struct ldb_parse_tree); + if (ret == NULL) return NULL; - filter = talloc_strdup(mem_ctx, "(&"); - if (filter == NULL) - return False; - - while (asn1_tag_remaining(data) > 0) { - const char *subfilter; - if (!ldap_decode_filter(mem_ctx, data, &subfilter)) - return False; - filter = talloc_asprintf_append(filter, "%s", subfilter); - if (filter == NULL) - return False; + switch(filter_tag) { + case 0: + case 1: + /* AND or OR of one or more filters */ + ret->operation = (filter_tag == 0)?LDB_OP_AND:LDB_OP_OR; + ret->u.list.num_elements = 0; + ret->u.list.elements = NULL; + + if (tag_desc != 0xa0) { + /* context compount */ + goto failed; } - asn1_end_tag(data); - - filter = talloc_asprintf_append(filter, ")"); - break; - } - case 1: { - /* OR of one or more filters */ - if (tag_desc != 0xa0) /* context compount */ - return False; - asn1_start_tag(data, ASN1_CONTEXT(1)); - - filter = talloc_strdup(mem_ctx, "(|"); - if (filter == NULL) - return False; + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } while (asn1_tag_remaining(data) > 0) { - const char *subfilter; - if (!ldap_decode_filter(mem_ctx, data, &subfilter)) - return False; - filter = talloc_asprintf_append(filter, "%s", subfilter); - if (filter == NULL) - return False; + struct ldb_parse_tree *subtree; + subtree = ldap_decode_filter_tree(ret, data); + if (subtree == NULL) { + goto failed; + } + ret->u.list.elements = + talloc_realloc(ret, ret->u.list.elements, + struct ldb_parse_tree *, + ret->u.list.num_elements+1); + if (ret->u.list.elements == NULL) { + goto failed; + } + talloc_steal(ret->u.list.elements, subtree); + ret->u.list.elements[ret->u.list.num_elements] = subtree; + ret->u.list.num_elements++; + } + if (!asn1_end_tag(data)) { + goto failed; } - - asn1_end_tag(data); - - filter = talloc_asprintf_append(filter, ")"); break; - } + case 3: { /* equalityMatch */ const char *attrib; DATA_BLOB value; - struct ldb_val val; - if (tag_desc != 0xa0) /* context compound */ - return False; + ret->operation = LDB_OP_SIMPLE; + + if (tag_desc != 0xa0) { + /* context compound */ + goto failed; + } + asn1_start_tag(data, ASN1_CONTEXT(3)); asn1_read_OctetString_talloc(mem_ctx, data, &attrib); asn1_read_OctetString(data, &value); asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) - return False; - val.data = value.data; - val.length = value.length; - filter = talloc_asprintf(mem_ctx, "(%s=%s)", - attrib, ldb_binary_encode(mem_ctx, val)); - data_blob_free(&value); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + ret->u.simple.attr = talloc_steal(ret, attrib); + ret->u.simple.value.data = talloc_steal(ret, value.data); + ret->u.simple.value.length = value.length; break; } case 7: { /* Normal presence, "attribute=*" */ int attr_len; - char *attr_name; - if (tag_desc != 0x80) /* context simple */ - return False; - if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(7))) - return False; + if (tag_desc != 0x80) { + /* context simple */ + goto failed; + } + if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(7))) { + goto failed; + } + + ret->operation = LDB_OP_SIMPLE; + attr_len = asn1_tag_remaining(data); - attr_name = malloc(attr_len+1); - if (attr_name == NULL) - return False; - asn1_read(data, attr_name, attr_len); - attr_name[attr_len] = '\0'; - filter = talloc_asprintf(mem_ctx, "(%s=*)", attr_name); - SAFE_FREE(attr_name); - asn1_end_tag(data); + + ret->u.simple.attr = talloc_size(ret, attr_len+1); + if (ret->u.simple.attr == NULL) { + goto failed; + } + if (!asn1_read(data, ret->u.simple.attr, attr_len)) { + goto failed; + } + ret->u.simple.attr[attr_len] = 0; + ret->u.simple.value.data = talloc_strdup(ret, "*"); + if (ret->u.simple.value.data == NULL) { + goto failed; + } + ret->u.simple.value.length = 1; + if (!asn1_end_tag(data)) { + goto failed; + } break; } default: - return False; + DEBUG(0,("Unsupported LDAP filter operation 0x%x\n", filter_tag)); + goto failed; } - if (filter == NULL) - return False; + + return ret; - *filterp = filter; +failed: + talloc_free(ret); + DEBUG(0,("Failed to parse ASN.1 LDAP filter\n")); + return NULL; +} + + +static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, + const char **filterp) +{ + struct ldb_parse_tree *tree; + tree = ldap_decode_filter_tree(mem_ctx, data); + if (tree == NULL) { + return False; + } + *filterp = ldb_filter_from_tree(mem_ctx, tree); + talloc_free(tree); + if (*filterp == NULL) { + return False; + } return True; } + + static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, struct ldap_attribute *attrib) { -- cgit From 4b0e5bd75373ffa2d847706a71fd0349dfa15e71 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Jun 2005 09:10:17 +0000 Subject: r7527: - added a ldb_search_bytree() interface, which takes a ldb_parse_tree instead of a search expression. This allows our ldap server to pass its ASN.1 parsed search expressions straight to ldb, instead of going via strings. - updated all the ldb modules code to handle the new interface - got rid of the separate ldb_parse.h now that the ldb_parse structures are exposed externally - moved to C99 structure initialisation in ldb - switched ldap server to using ldb_search_bytree() (This used to be commit 96620ab2ee5d440bbbc51c1bc0cad9977770f897) --- source4/libcli/ldap/ldap.c | 41 +++++++++-------------------------------- source4/libcli/ldap/ldap.h | 3 +-- 2 files changed, 10 insertions(+), 34 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 2718dd7e34..0d310b4eed 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -152,7 +152,6 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } case LDAP_TAG_SearchRequest: { struct ldap_SearchRequest *r = &msg->r.SearchRequest; - struct ldb_parse_tree *tree; asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); asn1_write_OctetString(&data, r->basedn, strlen(r->basedn)); asn1_write_enumerated(&data, r->scope); @@ -161,14 +160,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) asn1_write_Integer(&data, r->timelimit); asn1_write_BOOLEAN(&data, r->attributesonly); - tree = ldb_parse_tree(NULL, r->filter); - - if (tree == NULL) - return False; - - ldap_push_filter(&data, tree); - - talloc_free(tree); + ldap_push_filter(&data, r->tree); asn1_push_tag(&data, ASN1_SEQUENCE(0)); for (i=0; inum_attributes; i++) { @@ -176,7 +168,6 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) strlen(r->attributes[i])); } asn1_pop_tag(&data); - asn1_pop_tag(&data); break; } @@ -413,6 +404,10 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, } } + +/* + parse the ASN.1 formatted search string into a ldb_parse_tree +*/ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, struct asn1_data *data) { @@ -540,25 +535,6 @@ failed: } -static BOOL ldap_decode_filter(TALLOC_CTX *mem_ctx, struct asn1_data *data, - const char **filterp) -{ - struct ldb_parse_tree *tree; - - tree = ldap_decode_filter_tree(mem_ctx, data); - if (tree == NULL) { - return False; - } - *filterp = ldb_filter_from_tree(mem_ctx, tree); - talloc_free(tree); - if (*filterp == NULL) { - return False; - } - return True; -} - - - static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, struct ldap_attribute *attrib) { @@ -674,9 +650,10 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_read_Integer(data, &r->timelimit); asn1_read_BOOLEAN(data, &r->attributesonly); - /* Maybe create a TALLOC_CTX for the filter? This can waste - * quite a bit of memory recursing down. */ - ldap_decode_filter(msg->mem_ctx, data, &r->filter); + r->tree = ldap_decode_filter_tree(msg->mem_ctx, data); + if (r->tree == NULL) { + return False; + } asn1_start_tag(data, ASN1_SEQUENCE(0)); diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 12d30a2610..a44c249e7a 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -23,7 +23,6 @@ #define _SMB_LDAP_H #include "lib/ldb/include/ldb.h" -#include "lib/ldb/include/ldb_parse.h" enum ldap_request_tag { LDAP_TAG_BindRequest = 0, @@ -152,7 +151,7 @@ struct ldap_SearchRequest { uint32_t timelimit; uint32_t sizelimit; BOOL attributesonly; - const char *filter; + struct ldb_parse_tree *tree; int num_attributes; const char **attributes; }; -- cgit From 6426f2a39ab42e164e29265b6d04cec9dca92eca Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 14 Jun 2005 03:53:35 +0000 Subject: r7567: added wire parsing of NOT and extended ldap search requests. This allows us to parse and handle the complex queries we are getting from w2k, such as (|(|(&(!(groupType:1.2.840.113556.1.4.803=1))(groupType:1.2.840.113556.1.4.803=2147483648)(groupType:1.2.840.113556.1.4.804=6))(samAccountType=805306368))(samAccountType=805306369)) (This used to be commit 041bce591306a0fb26bd31fe371e30021ea5c0c1) --- source4/libcli/ldap/ldap.c | 134 ++++++++++++++++++++++++++++++++------------- 1 file changed, 97 insertions(+), 37 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 0d310b4eed..048a60317a 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -31,8 +31,10 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree) { + int i; + switch (tree->operation) { - case LDB_OP_SIMPLE: { + case LDB_OP_SIMPLE: if ((tree->u.simple.value.length == 1) && (((char *)(tree->u.simple.value.data))[0] == '*')) { /* Just a presence test */ @@ -43,7 +45,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree return !data->has_error; } - /* Equality is all we currently do... */ + /* equality test */ asn1_push_tag(data, 0xa3); asn1_write_OctetString(data, tree->u.simple.attr, strlen(tree->u.simple.attr)); @@ -51,29 +53,51 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree tree->u.simple.value.length); asn1_pop_tag(data); break; - } - - case LDB_OP_AND: { - int i; - asn1_push_tag(data, 0xa0); - for (i=0; iu.list.num_elements; i++) { - ldap_push_filter(data, tree->u.list.elements[i]); + case LDB_OP_EXTENDED: + /* + MatchingRuleAssertion ::= SEQUENCE { + matchingRule [1] MatchingRuleID OPTIONAL, + type [2] AttributeDescription OPTIONAL, + matchValue [3] AssertionValue, + dnAttributes [4] BOOLEAN DEFAULT FALSE + } + */ + asn1_push_tag(data, 0xa9); + if (tree->u.extended.rule_id) { + asn1_push_tag(data, 1); + asn1_write_OctetString(data, tree->u.extended.rule_id, + strlen(tree->u.extended.rule_id)); + asn1_pop_tag(data); + } + if (tree->u.extended.attr) { + asn1_push_tag(data, 2); + asn1_write_OctetString(data, tree->u.extended.attr, + strlen(tree->u.extended.attr)); + asn1_pop_tag(data); + } + asn1_push_tag(data, 3); + asn1_write_OctetString(data, tree->u.extended.value.data, + tree->u.extended.value.length); + asn1_pop_tag(data); + if (tree->u.extended.dnAttributes) { + asn1_push_tag(data, 4); + asn1_write_BOOLEAN(data, True); + asn1_pop_tag(data); } asn1_pop_tag(data); break; - } - - case LDB_OP_OR: { - int i; + - asn1_push_tag(data, 0xa1); + case LDB_OP_AND: + case LDB_OP_OR: + asn1_push_tag(data, 0xa0 | (tree->operation==LDB_OP_AND?0:1)); for (i=0; iu.list.num_elements; i++) { ldap_push_filter(data, tree->u.list.elements[i]); } asn1_pop_tag(data); break; - } + default: return False; } @@ -464,25 +488,34 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, } break; - case 3: { - /* equalityMatch */ - const char *attrib; - DATA_BLOB value; + case 2: + /* 'not' operation */ + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } - ret->operation = LDB_OP_SIMPLE; + ret->operation = LDB_OP_NOT; + ret->u.not.child = ldap_decode_filter_tree(ret, data); - if (tag_desc != 0xa0) { - /* context compound */ + if (!asn1_end_tag(data)) { goto failed; } + break; - asn1_start_tag(data, ASN1_CONTEXT(3)); + case 3: { + /* equalityMatch */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); asn1_read_OctetString_talloc(mem_ctx, data, &attrib); asn1_read_OctetString(data, &value); asn1_end_tag(data); if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { goto failed; } + + ret->operation = LDB_OP_SIMPLE; ret->u.simple.attr = talloc_steal(ret, attrib); ret->u.simple.value.data = talloc_steal(ret, value.data); ret->u.simple.value.length = value.length; @@ -490,37 +523,64 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, } case 7: { /* Normal presence, "attribute=*" */ - int attr_len; - if (tag_desc != 0x80) { - /* context simple */ + char *attr; + + if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(filter_tag))) { goto failed; } - if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(7))) { + if (!asn1_read_LDAPString(data, &attr)) { goto failed; } ret->operation = LDB_OP_SIMPLE; - - attr_len = asn1_tag_remaining(data); - - ret->u.simple.attr = talloc_size(ret, attr_len+1); - if (ret->u.simple.attr == NULL) { + ret->u.simple.attr = talloc_steal(ret, attr); + ret->u.simple.value.data = talloc_strdup(ret, "*"); + if (ret->u.simple.value.data == NULL) { goto failed; } - if (!asn1_read(data, ret->u.simple.attr, attr_len)) { + ret->u.simple.value.length = 1; + if (!asn1_end_tag(data)) { goto failed; } - ret->u.simple.attr[attr_len] = 0; - ret->u.simple.value.data = talloc_strdup(ret, "*"); - if (ret->u.simple.value.data == NULL) { + break; + } + case 9: { + char *oid, *attr, *value; + uint8_t dnAttributes; + /* an extended search */ + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { goto failed; } - ret->u.simple.value.length = 1; + + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1)); + asn1_read_LDAPString(data, &oid); + asn1_end_tag(data); + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2)); + asn1_read_LDAPString(data, &attr); + asn1_end_tag(data); + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(3)); + asn1_read_LDAPString(data, &value); + asn1_end_tag(data); + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(4)); + asn1_read_uint8(data, &dnAttributes); + asn1_end_tag(data); + if ((data->has_error) || (oid == NULL) || (value == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_EXTENDED; + ret->u.extended.attr = talloc_steal(ret, attr); + ret->u.extended.rule_id = talloc_steal(ret, oid); + ret->u.extended.value.data = talloc_steal(ret, value); + ret->u.extended.value.length = strlen(value); + ret->u.extended.dnAttributes = dnAttributes; + if (!asn1_end_tag(data)) { goto failed; } break; } + default: DEBUG(0,("Unsupported LDAP filter operation 0x%x\n", filter_tag)); goto failed; -- cgit From c0947b0d7f809f5139fbfcdbd618ed7b0a77d2be Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 15 Jun 2005 00:27:51 +0000 Subject: r7593: simplified the memory management in the ldap code. Having a mem_ctx element in a structure is not necessary any more. (This used to be commit 912d0427f52eac811b27bf7e385b0642f7dc7f53) --- source4/libcli/ldap/ldap.c | 72 +++++++++++++++++++-------------------- source4/libcli/ldap/ldap.h | 2 -- source4/libcli/ldap/ldap_client.c | 34 ++++++------------ source4/libcli/ldap/ldap_ldif.c | 16 ++++----- 4 files changed, 55 insertions(+), 69 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 048a60317a..0ac17c39bd 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -647,7 +647,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) msg->type = LDAP_TAG_BindRequest; asn1_start_tag(data, tag); asn1_read_Integer(data, &r->version); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); + asn1_read_OctetString_talloc(msg, data, &r->dn); if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(0))) { int pwlen; r->creds.password = ""; @@ -655,7 +655,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); pwlen = asn1_tag_remaining(data); if (pwlen != 0) { - char *pw = talloc_size(msg->mem_ctx, pwlen+1); + char *pw = talloc_size(msg, pwlen+1); asn1_read(data, pw, pwlen); pw[pwlen] = '\0'; r->creds.password = pw; @@ -664,10 +664,10 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) } else if (asn1_peek_tag(data, ASN1_CONTEXT(3))){ asn1_start_tag(data, ASN1_CONTEXT(3)); r->mechanism = LDAP_AUTH_MECH_SASL; - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->creds.SASL.mechanism); + asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism); asn1_read_OctetString(data, &r->creds.SASL.secblob); if (r->creds.SASL.secblob.data) { - talloc_steal(msg->mem_ctx, r->creds.SASL.secblob.data); + talloc_steal(msg, r->creds.SASL.secblob.data); } asn1_end_tag(data); } @@ -679,11 +679,11 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) struct ldap_BindResponse *r = &msg->r.BindResponse; msg->type = LDAP_TAG_BindResponse; asn1_start_tag(data, tag); - ldap_decode_response(msg->mem_ctx, data, &r->response); + ldap_decode_response(msg, data, &r->response); if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) { DATA_BLOB tmp_blob = data_blob(NULL, 0); asn1_read_ContextSimple(data, 7, &tmp_blob); - r->SASL.secblob = data_blob_talloc(msg->mem_ctx, tmp_blob.data, tmp_blob.length); + r->SASL.secblob = data_blob_talloc(msg, tmp_blob.data, tmp_blob.length); data_blob_free(&tmp_blob); } else { r->SASL.secblob = data_blob(NULL, 0); @@ -703,14 +703,14 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) struct ldap_SearchRequest *r = &msg->r.SearchRequest; msg->type = LDAP_TAG_SearchRequest; asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->basedn); + asn1_read_OctetString_talloc(msg, data, &r->basedn); asn1_read_enumerated(data, (int *)&(r->scope)); asn1_read_enumerated(data, (int *)&(r->deref)); asn1_read_Integer(data, &r->sizelimit); asn1_read_Integer(data, &r->timelimit); asn1_read_BOOLEAN(data, &r->attributesonly); - r->tree = ldap_decode_filter_tree(msg->mem_ctx, data); + r->tree = ldap_decode_filter_tree(msg, data); if (r->tree == NULL) { return False; } @@ -722,10 +722,10 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) while (asn1_tag_remaining(data) > 0) { const char *attr; - if (!asn1_read_OctetString_talloc(msg->mem_ctx, data, + if (!asn1_read_OctetString_talloc(msg, data, &attr)) return False; - if (!add_string_to_array(msg->mem_ctx, attr, + if (!add_string_to_array(msg, attr, &r->attributes, &r->num_attributes)) return False; @@ -742,8 +742,8 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) r->attributes = NULL; r->num_attributes = 0; asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); - ldap_decode_attribs(msg->mem_ctx, data, &r->attributes, + asn1_read_OctetString_talloc(msg, data, &r->dn); + ldap_decode_attribs(msg, data, &r->attributes, &r->num_attributes); asn1_end_tag(data); break; @@ -753,7 +753,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) struct ldap_Result *r = &msg->r.SearchResultDone; msg->type = LDAP_TAG_SearchResultDone; asn1_start_tag(data, tag); - ldap_decode_response(msg->mem_ctx, data, r); + ldap_decode_response(msg, data, r); asn1_end_tag(data); break; } @@ -762,7 +762,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) struct ldap_SearchResRef *r = &msg->r.SearchResultReference; msg->type = LDAP_TAG_SearchResultReference; asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->referral); + asn1_read_OctetString_talloc(msg, data, &r->referral); asn1_end_tag(data); break; } @@ -771,7 +771,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; msg->type = LDAP_TAG_ModifyRequest; asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest)); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); + asn1_read_OctetString_talloc(msg, data, &r->dn); asn1_start_tag(data, ASN1_SEQUENCE(0)); r->num_mods = 0; @@ -784,9 +784,9 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_start_tag(data, ASN1_SEQUENCE(0)); asn1_read_enumerated(data, &v); mod.type = v; - ldap_decode_attrib(msg->mem_ctx, data, &mod.attrib); + ldap_decode_attrib(msg, data, &mod.attrib); asn1_end_tag(data); - if (!add_mod_to_array_talloc(msg->mem_ctx, &mod, + if (!add_mod_to_array_talloc(msg, &mod, &r->mods, &r->num_mods)) break; } @@ -800,7 +800,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) struct ldap_Result *r = &msg->r.ModifyResponse; msg->type = LDAP_TAG_ModifyResponse; asn1_start_tag(data, tag); - ldap_decode_response(msg->mem_ctx, data, r); + ldap_decode_response(msg, data, r); asn1_end_tag(data); break; } @@ -809,11 +809,11 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) struct ldap_AddRequest *r = &msg->r.AddRequest; msg->type = LDAP_TAG_AddRequest; asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); + asn1_read_OctetString_talloc(msg, data, &r->dn); r->attributes = NULL; r->num_attributes = 0; - ldap_decode_attribs(msg->mem_ctx, data, &r->attributes, + ldap_decode_attribs(msg, data, &r->attributes, &r->num_attributes); asn1_end_tag(data); @@ -824,7 +824,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) struct ldap_Result *r = &msg->r.AddResponse; msg->type = LDAP_TAG_AddResponse; asn1_start_tag(data, tag); - ldap_decode_response(msg->mem_ctx, data, r); + ldap_decode_response(msg, data, r); asn1_end_tag(data); break; } @@ -837,7 +837,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_start_tag(data, ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); len = asn1_tag_remaining(data); - dn = talloc_size(msg->mem_ctx, len+1); + dn = talloc_size(msg, len+1); if (dn == NULL) break; asn1_read(data, dn, len); @@ -851,7 +851,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) struct ldap_Result *r = &msg->r.DelResponse; msg->type = LDAP_TAG_DelResponse; asn1_start_tag(data, tag); - ldap_decode_response(msg->mem_ctx, data, r); + ldap_decode_response(msg, data, r); asn1_end_tag(data); break; } @@ -861,8 +861,8 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) msg->type = LDAP_TAG_ModifyDNRequest; asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest)); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->newrdn); + asn1_read_OctetString_talloc(msg, data, &r->dn); + asn1_read_OctetString_talloc(msg, data, &r->newrdn); asn1_read_BOOLEAN(data, &r->deleteolddn); r->newsuperior = NULL; if (asn1_tag_remaining(data) > 0) { @@ -870,7 +870,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) char *newsup; asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); len = asn1_tag_remaining(data); - newsup = talloc_size(msg->mem_ctx, len+1); + newsup = talloc_size(msg, len+1); if (newsup == NULL) break; asn1_read(data, newsup, len); @@ -886,7 +886,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) struct ldap_Result *r = &msg->r.ModifyDNResponse; msg->type = LDAP_TAG_ModifyDNResponse; asn1_start_tag(data, tag); - ldap_decode_response(msg->mem_ctx, data, r); + ldap_decode_response(msg, data, r); asn1_end_tag(data); break; } @@ -896,12 +896,12 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) msg->type = LDAP_TAG_CompareRequest; asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_CompareRequest)); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->dn); + asn1_read_OctetString_talloc(msg, data, &r->dn); asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_OctetString_talloc(msg->mem_ctx, data, &r->attribute); + asn1_read_OctetString_talloc(msg, data, &r->attribute); asn1_read_OctetString(data, &r->value); if (r->value.data) { - talloc_steal(msg->mem_ctx, r->value.data); + talloc_steal(msg, r->value.data); } asn1_end_tag(data); asn1_end_tag(data); @@ -912,7 +912,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) struct ldap_Result *r = &msg->r.CompareResponse; msg->type = LDAP_TAG_CompareResponse; asn1_start_tag(data, tag); - ldap_decode_response(msg->mem_ctx, data, r); + ldap_decode_response(msg, data, r); asn1_end_tag(data); break; } @@ -935,7 +935,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) if (!asn1_read_ContextSimple(data, 0, &tmp_blob)) { return False; } - r->oid = blob2string_talloc(msg->mem_ctx, tmp_blob); + r->oid = blob2string_talloc(msg, tmp_blob); data_blob_free(&tmp_blob); if (!r->oid) { return False; @@ -943,7 +943,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { asn1_read_ContextSimple(data, 1, &tmp_blob); - r->value = data_blob_talloc(msg->mem_ctx, tmp_blob.data, tmp_blob.length); + r->value = data_blob_talloc(msg, tmp_blob.data, tmp_blob.length); data_blob_free(&tmp_blob); } else { r->value = data_blob(NULL, 0); @@ -957,7 +957,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; msg->type = LDAP_TAG_ExtendedResponse; asn1_start_tag(data, tag); - ldap_decode_response(msg->mem_ctx, data, &r->response); + ldap_decode_response(msg, data, &r->response); /* I have to come across an operation that actually sends * something back to really see what's going on. The currently * needed pwdchange does not send anything back. */ @@ -983,7 +983,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) for (i=0; asn1_peek_tag(data, ASN1_SEQUENCE(0)); i++) { asn1_start_tag(data, ASN1_SEQUENCE(0)); - ctrl = talloc_realloc(msg->mem_ctx, ctrl, struct ldap_Control, i+1); + ctrl = talloc_realloc(msg, ctrl, struct ldap_Control, i+1); if (!ctrl) { return False; } @@ -1000,7 +1000,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { asn1_read_OctetString(data, &ctrl[i].value); if (ctrl[i].value.data) { - talloc_steal(msg->mem_ctx, ctrl[i].value.data); + talloc_steal(msg, ctrl[i].value.data); } } diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index a44c249e7a..f0f43e65fc 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -252,7 +252,6 @@ struct ldap_Control { }; struct ldap_message { - TALLOC_CTX *mem_ctx; uint32_t messageid; enum ldap_request_tag type; union ldap_Request r; @@ -267,7 +266,6 @@ struct ldap_queue_entry { }; struct ldap_connection { - TALLOC_CTX *mem_ctx; int sock; int next_msgid; char *host; diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 8867344de3..6ff8db85a5 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -312,9 +312,9 @@ static struct ldap_message *new_ldap_simple_bind_msg(struct ldap_connection *con res->type = LDAP_TAG_BindRequest; res->r.BindRequest.version = 3; - res->r.BindRequest.dn = talloc_strdup(res->mem_ctx, dn); + res->r.BindRequest.dn = talloc_strdup(res, dn); res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SIMPLE; - res->r.BindRequest.creds.password = talloc_strdup(res->mem_ctx, pw); + res->r.BindRequest.creds.password = talloc_strdup(res, pw); return res; } @@ -332,7 +332,7 @@ static struct ldap_message *new_ldap_sasl_bind_msg(struct ldap_connection *conn, res->r.BindRequest.version = 3; res->r.BindRequest.dn = ""; res->r.BindRequest.mechanism = LDAP_AUTH_MECH_SASL; - res->r.BindRequest.creds.SASL.mechanism = talloc_strdup(res->mem_ctx, sasl_mechanism); + res->r.BindRequest.creds.SASL.mechanism = talloc_strdup(res, sasl_mechanism); res->r.BindRequest.creds.SASL.secblob = *secblob; return res; @@ -348,7 +348,6 @@ static struct ldap_connection *new_ldap_connection(TALLOC_CTX *mem_ctx) return NULL; } - result->mem_ctx = result; result->next_msgid = 1; result->outstanding = NULL; result->searchid = 0; @@ -372,8 +371,8 @@ struct ldap_connection *ldap_connect(TALLOC_CTX *mem_ctx, const char *url) return NULL; } - ret = ldap_parse_basic_url(conn->mem_ctx, url, &conn->host, - &conn->port, &conn->ldaps); + ret = ldap_parse_basic_url(conn, url, &conn->host, + &conn->port, &conn->ldaps); if (!ret) { talloc_free(conn); return NULL; @@ -398,17 +397,7 @@ struct ldap_connection *ldap_connect(TALLOC_CTX *mem_ctx, const char *url) struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) { - struct ldap_message *result; - - result = talloc(mem_ctx, struct ldap_message); - - if (!result) { - return NULL; - } - - result->mem_ctx = result; - - return result; + return talloc(mem_ctx, struct ldap_message); } BOOL ldap_send_msg(struct ldap_connection *conn, struct ldap_message *msg, @@ -619,7 +608,7 @@ static struct ldap_message *ldap_transaction_sasl(struct ldap_connection *conn, return NULL; status = gensec_wrap(conn->gensec, - req->mem_ctx, + req, &request, &wrapped); if (!NT_STATUS_IS_OK(status)) { @@ -653,7 +642,7 @@ static struct ldap_message *ldap_transaction_sasl(struct ldap_connection *conn, wrapped.length = len; status = gensec_unwrap(conn->gensec, - req->mem_ctx, + req, &wrapped, &request); if (!NT_STATUS_IS_OK(status)) { @@ -661,7 +650,7 @@ static struct ldap_message *ldap_transaction_sasl(struct ldap_connection *conn, return NULL; } - rep = new_ldap_message(req->mem_ctx); + rep = new_ldap_message(req); asn1_load(&asn1, request); if (!ldap_decode(&asn1, rep)) { @@ -776,7 +765,7 @@ int ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds) goto done; } - status = gensec_start_mech_by_sasl_name(conn->gensec, "GSS-SPNEGO"); + status = gensec_start_mech_by_sasl_name(conn->gensec, "NTLM"); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism: %s\n", nt_errstr(status))); @@ -828,8 +817,7 @@ int ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds) } done: - if (mem_ctx) - talloc_free(mem_ctx); + talloc_free(mem_ctx); return result; } diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index 2489a97748..0e0885c1cc 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -212,7 +212,7 @@ static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) } if (attrib == NULL) { - r->attributes = talloc_realloc(msg->mem_ctx, + r->attributes = talloc_realloc(msg, r->attributes, struct ldap_attribute, r->num_attributes+1); @@ -222,11 +222,11 @@ static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) attrib = &(r->attributes[r->num_attributes]); r->num_attributes += 1; ZERO_STRUCTP(attrib); - attrib->name = talloc_strdup(msg->mem_ctx, + attrib->name = talloc_strdup(msg, attr_name); } - if (!add_value_to_attrib(msg->mem_ctx, &value, attrib)) + if (!add_value_to_attrib(msg, &value, attrib)) return False; } return True; @@ -261,7 +261,7 @@ static BOOL fill_mods(struct ldap_message *msg, char **chunk) struct ldap_mod mod; mod.type = LDAP_MODIFY_NONE; - mod.attrib.name = talloc_strdup(msg->mem_ctx, value.data); + mod.attrib.name = talloc_strdup(msg, value.data); if (strequal(attr_name, "add")) mod.type = LDAP_MODIFY_ADD; @@ -290,14 +290,14 @@ static BOOL fill_mods(struct ldap_message *msg, char **chunk) mod.attrib.name)); return False; } - if (!add_value_to_attrib(msg->mem_ctx, &value, + if (!add_value_to_attrib(msg, &value, &mod.attrib)) { DEBUG(3, ("Could not add value\n")); return False; } } - if (!add_mod_to_array_talloc(msg->mem_ctx, &mod, &r->mods, + if (!add_mod_to_array_talloc(msg, &mod, &r->mods, &r->num_mods)) return False; } @@ -370,7 +370,7 @@ static struct ldap_message *ldif_read(TALLOC_CTX *mem_ctx, int (*fgetc_fn)(void if (msg == NULL) return NULL; - chunk = next_chunk(msg->mem_ctx, fgetc_fn, private_data); + chunk = next_chunk(msg, fgetc_fn, private_data); if (!chunk) { goto failed; } @@ -388,7 +388,7 @@ static struct ldap_message *ldif_read(TALLOC_CTX *mem_ctx, int (*fgetc_fn)(void goto failed; } - dn = talloc_strdup(msg->mem_ctx, value.data); + dn = talloc_strdup(msg, value.data); if (next_attr(&s, &attr, &value) != 0) { goto failed; -- cgit From 3e92471d4cfa169b97da73752b6eb6d1ea8cb466 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 15 Jun 2005 01:02:53 +0000 Subject: r7596: next step in ldap cleanup. I'm aiming to get rid of the cut&pasted ldif parsing code in libcli/ldap/ldap_ldif.c, and instead use the ldb ldif code. To do that I have changed the ldap code to use 'struct ldb_message_element' instead of 'struct ldap_attribute'. They are essentially the same structure anyway, so by making them really the same it will be much easier to use the ldb code in libcli/ldap/ I have also made 'struct ldb_val' the same as a DATA_BLOB, which will simplify data handling in quite a few places (I haven't yet removed all the code that maps between these two, that will come later) (This used to be commit 87fc3073392236221a3a6b933284e9e477c24ae5) --- source4/libcli/ldap/ldap.c | 12 ++++++------ source4/libcli/ldap/ldap.h | 18 ++++++------------ source4/libcli/ldap/ldap_ldif.c | 12 ++++++------ 3 files changed, 18 insertions(+), 24 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 0ac17c39bd..1a3ab6e0a5 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -201,7 +201,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) asn1_write_OctetString(&data, r->dn, strlen(r->dn)); asn1_push_tag(&data, ASN1_SEQUENCE(0)); for (i=0; inum_attributes; i++) { - struct ldap_attribute *attr = &r->attributes[i]; + struct ldb_message_element *attr = &r->attributes[i]; asn1_push_tag(&data, ASN1_SEQUENCE(0)); asn1_write_OctetString(&data, attr->name, strlen(attr->name)); @@ -232,7 +232,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) asn1_push_tag(&data, ASN1_SEQUENCE(0)); for (i=0; inum_mods; i++) { - struct ldap_attribute *attrib = &r->mods[i].attrib; + struct ldb_message_element *attrib = &r->mods[i].attrib; asn1_push_tag(&data, ASN1_SEQUENCE(0)); asn1_write_enumerated(&data, r->mods[i].type); asn1_push_tag(&data, ASN1_SEQUENCE(0)); @@ -268,7 +268,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) asn1_push_tag(&data, ASN1_SEQUENCE(0)); for (i=0; inum_attributes; i++) { - struct ldap_attribute *attrib = &r->attributes[i]; + struct ldb_message_element *attrib = &r->attributes[i]; asn1_push_tag(&data, ASN1_SEQUENCE(0)); asn1_write_OctetString(&data, attrib->name, strlen(attrib->name)); @@ -596,7 +596,7 @@ failed: static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldap_attribute *attrib) + struct ldb_message_element *attrib) { asn1_start_tag(data, ASN1_SEQUENCE(0)); asn1_read_OctetString_talloc(mem_ctx, data, &attrib->name); @@ -616,12 +616,12 @@ 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 ldap_attribute **attributes, + struct ldb_message_element **attributes, int *num_attributes) { asn1_start_tag(data, ASN1_SEQUENCE(0)); while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { - struct ldap_attribute attrib; + struct ldb_message_element attrib; ZERO_STRUCT(attrib); ldap_decode_attrib(mem_ctx, data, &attrib); add_attrib_to_array_talloc(mem_ctx, &attrib, diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index f0f43e65fc..577df1fc3d 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -101,12 +101,6 @@ struct ldap_Result { const char *referral; }; -struct ldap_attribute { - const char *name; - int num_values; - DATA_BLOB *values; -}; - struct ldap_BindRequest { int version; const char *dn; @@ -159,7 +153,7 @@ struct ldap_SearchRequest { struct ldap_SearchResEntry { const char *dn; int num_attributes; - struct ldap_attribute *attributes; + struct ldb_message_element *attributes; }; struct ldap_SearchResRef { @@ -175,7 +169,7 @@ enum ldap_modify_type { struct ldap_mod { enum ldap_modify_type type; - struct ldap_attribute attrib; + struct ldb_message_element attrib; }; struct ldap_ModifyRequest { @@ -187,7 +181,7 @@ struct ldap_ModifyRequest { struct ldap_AddRequest { const char *dn; int num_attributes; - struct ldap_attribute *attributes; + struct ldb_message_element *attributes; }; struct ldap_DelRequest { @@ -338,10 +332,10 @@ NTSTATUS ldap2nterror(int ldaperror); /* The following definitions come from libcli/ldap/ldap_ldif.c */ BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, - struct ldap_attribute *attrib); + struct ldb_message_element *attrib); BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, - const struct ldap_attribute *attrib, - struct ldap_attribute **attribs, + const struct ldb_message_element *attrib, + struct ldb_message_element **attribs, int *num_attribs); BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, struct ldap_mod *mod, diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index 0e0885c1cc..594640179e 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -158,7 +158,7 @@ static int next_attr(char **s, const char **attr, struct ldb_val *value) } BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, - struct ldap_attribute *attrib) + struct ldb_message_element *attrib) { attrib->values = talloc_realloc(mem_ctx, attrib->values, @@ -174,13 +174,13 @@ BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, } BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, - const struct ldap_attribute *attrib, - struct ldap_attribute **attribs, + const struct ldb_message_element *attrib, + struct ldb_message_element **attribs, int *num_attribs) { *attribs = talloc_realloc(mem_ctx, *attribs, - struct ldap_attribute, + struct ldb_message_element, *num_attribs+1); if (*attribs == NULL) @@ -202,7 +202,7 @@ static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) while (next_attr(chunk, &attr_name, &value) == 0) { int i; - struct ldap_attribute *attrib = NULL; + struct ldb_message_element *attrib = NULL; for (i=0; inum_attributes; i++) { if (strequal(r->attributes[i].name, attr_name)) { @@ -214,7 +214,7 @@ static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) if (attrib == NULL) { r->attributes = talloc_realloc(msg, r->attributes, - struct ldap_attribute, + struct ldb_message_element, r->num_attributes+1); if (r->attributes == NULL) return False; -- cgit From 49bc2672f8c2d75ce35f1ef537057fd05d4689e0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 15 Jun 2005 01:12:31 +0000 Subject: r7598: take advantage of struct data_blob and struct ldb_val being the same structure in a couple of places (This used to be commit bcd4671acae2be51958cbae23a0ab2dd2b194a5e) --- source4/libcli/ldap/ldap.c | 5 +---- source4/libcli/ldap/ldap_ndr.c | 12 ++---------- 2 files changed, 3 insertions(+), 14 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 1a3ab6e0a5..bce3da94ae 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -603,11 +603,8 @@ static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, asn1_start_tag(data, ASN1_SET); while (asn1_peek_tag(data, ASN1_OCTET_STRING)) { DATA_BLOB blob; - struct ldb_val value; asn1_read_OctetString(data, &blob); - value.data = blob.data; - value.length = blob.length; - add_value_to_attrib(mem_ctx, &value, attrib); + add_value_to_attrib(mem_ctx, &blob, attrib); data_blob_free(&blob); } asn1_end_tag(data); diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index 720022c6c2..88ca1ece77 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -25,14 +25,6 @@ #include "libcli/ldap/ldap.h" #include "librpc/gen_ndr/ndr_security.h" -struct ldb_val ldb_blob(DATA_BLOB blob) -{ - struct ldb_val val; - val.data = blob.data; - val.length = blob.length; - return val; -} - /* encode a NDR uint32 as a ldap filter element */ @@ -59,7 +51,7 @@ const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, struct dom_sid *sid) if (!NT_STATUS_IS_OK(status)) { return NULL; } - ret = ldb_binary_encode(mem_ctx, ldb_blob(blob)); + ret = ldb_binary_encode(mem_ctx, blob); data_blob_free(&blob); return ret; } @@ -78,7 +70,7 @@ const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) if (!NT_STATUS_IS_OK(status)) { return NULL; } - ret = ldb_binary_encode(mem_ctx, ldb_blob(blob)); + ret = ldb_binary_encode(mem_ctx, blob); data_blob_free(&blob); return ret; } -- cgit From ec4a99ffe89656c4ef89e21109c4136d491952d5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 15 Jun 2005 01:22:30 +0000 Subject: r7599: it turns out we were not using the ldif code in libcli/ldap/ at all, so best to just remove it. If we need it again, then it will be easy to just use a wrapper around the ldb code. (This used to be commit b316e1c2d3e4dc09c321ec72b40d78ffb855e101) --- source4/libcli/ldap/ldap_ldif.c | 393 ---------------------------------------- 1 file changed, 393 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c index 594640179e..55e902ecad 100644 --- a/source4/libcli/ldap/ldap_ldif.c +++ b/source4/libcli/ldap/ldap_ldif.c @@ -27,136 +27,6 @@ #include "system/iconv.h" #include "libcli/ldap/ldap.h" -/**************************************************************************** - * - * LDIF parser - * - * Shamelessly stolen and adapted from ldb. - * - ***************************************************************************/ - -/* - pull a ldif chunk, which is defined as a piece of data ending in \n\n or EOF - this routine removes any RFC2849 continuations and comments - - caller frees -*/ -static char *next_chunk(TALLOC_CTX *mem_ctx, - int (*fgetc_fn)(void *), void *private_data) -{ - size_t alloc_size=0, chunk_size = 0; - char *chunk = NULL; - int c; - int in_comment = 0; - - while ((c = fgetc_fn(private_data)) != EOF) { - if (chunk_size+1 >= alloc_size) { - char *c2; - alloc_size += 1024; - c2 = talloc_realloc(mem_ctx, chunk, char, alloc_size); - if (!c2) { - errno = ENOMEM; - return NULL; - } - chunk = c2; - } - - if (in_comment) { - if (c == '\n') { - in_comment = 0; - } - continue; - } - - /* handle continuation lines - see RFC2849 */ - if (c == ' ' && chunk_size > 1 && - chunk[chunk_size-1] == '\n') { - chunk_size--; - continue; - } - - /* chunks are terminated by a double line-feed */ - if (c == '\n' && chunk_size > 0 && - chunk[chunk_size-1] == '\n') { - chunk[chunk_size-1] = 0; - return chunk; - } - - if (c == '#' && - (chunk_size == 0 || chunk[chunk_size-1] == '\n')) { - in_comment = 1; - continue; - } - - /* ignore leading blank lines */ - if (chunk_size == 0 && c == '\n') { - continue; - } - - chunk[chunk_size++] = c; - } - - if (chunk) { - chunk[chunk_size] = 0; - } - - return chunk; -} - -/* simple ldif attribute parser */ -static int next_attr(char **s, const char **attr, struct ldb_val *value) -{ - char *p; - int base64_encoded = 0; - - if (strncmp(*s, "-\n", 2) == 0) { - value->length = 0; - *attr = "-"; - *s += 2; - return 0; - } - - p = strchr(*s, ':'); - if (!p) { - return -1; - } - - *p++ = 0; - - if (*p == ':') { - base64_encoded = 1; - p++; - } - - *attr = *s; - - while (isspace(*p)) { - p++; - } - - value->data = p; - - p = strchr(p, '\n'); - - if (!p) { - value->length = strlen((char *)value->data); - *s = ((char *)value->data) + value->length; - } else { - value->length = p - (char *)value->data; - *s = p+1; - *p = 0; - } - - if (base64_encoded) { - DATA_BLOB blob = base64_decode_data_blob(value->data); - memcpy(value->data, blob.data, blob.length); - value->length = blob.length; - ((char *)value->data)[value->length] = '\0'; - } - - return 0; -} - BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, struct ldb_message_element *attrib) { @@ -191,47 +61,6 @@ BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, return True; } -static BOOL fill_add_attributes(struct ldap_message *msg, char **chunk) -{ - struct ldap_AddRequest *r = &msg->r.AddRequest; - const char *attr_name; - struct ldb_val value; - - r->num_attributes = 0; - r->attributes = NULL; - - while (next_attr(chunk, &attr_name, &value) == 0) { - int i; - struct ldb_message_element *attrib = NULL; - - for (i=0; inum_attributes; i++) { - if (strequal(r->attributes[i].name, attr_name)) { - attrib = &r->attributes[i]; - break; - } - } - - if (attrib == NULL) { - r->attributes = talloc_realloc(msg, - r->attributes, - struct ldb_message_element, - r->num_attributes+1); - if (r->attributes == NULL) - return False; - - attrib = &(r->attributes[r->num_attributes]); - r->num_attributes += 1; - ZERO_STRUCTP(attrib); - attrib->name = talloc_strdup(msg, - attr_name); - } - - if (!add_value_to_attrib(msg, &value, attrib)) - return False; - } - return True; -} - BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, struct ldap_mod *mod, struct ldap_mod **mods, @@ -247,225 +76,3 @@ BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, return True; } -static BOOL fill_mods(struct ldap_message *msg, char **chunk) -{ - struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; - const char *attr_name; - struct ldb_val value; - - r->num_mods = 0; - r->mods = NULL; - - while (next_attr(chunk, &attr_name, &value) == 0) { - - struct ldap_mod mod; - mod.type = LDAP_MODIFY_NONE; - - mod.attrib.name = talloc_strdup(msg, value.data); - - if (strequal(attr_name, "add")) - mod.type = LDAP_MODIFY_ADD; - - if (strequal(attr_name, "delete")) - mod.type = LDAP_MODIFY_DELETE; - - if (strequal(attr_name, "replace")) - mod.type = LDAP_MODIFY_REPLACE; - - if (mod.type == LDAP_MODIFY_NONE) { - DEBUG(2, ("ldif modification type %s unsupported\n", - attr_name)); - return False; - } - - mod.attrib.num_values = 0; - mod.attrib.values = NULL; - - while (next_attr(chunk, &attr_name, &value) == 0) { - if (strequal(attr_name, "-")) - break; - if (!strequal(attr_name, mod.attrib.name)) { - DEBUG(3, ("attrib name %s does not " - "match %s\n", attr_name, - mod.attrib.name)); - return False; - } - if (!add_value_to_attrib(msg, &value, - &mod.attrib)) { - DEBUG(3, ("Could not add value\n")); - return False; - } - } - - if (!add_mod_to_array_talloc(msg, &mod, &r->mods, - &r->num_mods)) - return False; - } - - return True; -} - -static BOOL fill_modrdn(struct ldap_message *msg, char **chunk) -{ - struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; - const char *attr_name; - struct ldb_val value; - - r->newrdn = NULL; - r->deleteolddn = False; - r->newsuperior = NULL; - - if (next_attr(chunk, &attr_name, &value) != 0) { - return False; - } - - if (!strequal(attr_name, "newrdn")) { - return False; - } - - r->newrdn = value.data; - - if (next_attr(chunk, &attr_name, &value) != 0) { - return False; - } - - if (!strequal(attr_name, "deleteoldrdn")) { - return False; - } - - if (value.data && (((char *)value.data)[0] != '0')) { - r->deleteolddn = True; - } - - if (next_attr(chunk, &attr_name, &value) != 0) { - /* newsuperior is optional */ - return True; - } - - if (!strequal(attr_name, "newsuperior")) { - return False; - } - - r->newsuperior = value.data; - - return True; -} - - -/* - read from a LDIF source, creating a ldap_message -*/ -static struct ldap_message *ldif_read(TALLOC_CTX *mem_ctx, int (*fgetc_fn)(void *), - void *private_data) -{ - struct ldap_message *msg; - const char *attr=NULL; - const char *dn; - char *chunk=NULL, *s; - struct ldb_val value; - - value.data = NULL; - - msg = new_ldap_message(mem_ctx); - if (msg == NULL) - return NULL; - - chunk = next_chunk(msg, fgetc_fn, private_data); - if (!chunk) { - goto failed; - } - - s = chunk; - - if (next_attr(&s, &attr, &value) != 0) { - goto failed; - } - - /* first line must be a dn */ - if (!strequal(attr, "dn")) { - DEBUG(5, ("Error: First line of ldif must be a dn not '%s'\n", - attr)); - goto failed; - } - - dn = talloc_strdup(msg, value.data); - - if (next_attr(&s, &attr, &value) != 0) { - goto failed; - } - - if (!strequal(attr, "changetype")) { - DEBUG(5, ("Error: Second line of ldif must be a changetype " - "not '%s'\n", attr)); - goto failed; - } - - if (strequal(value.data, "delete")) { - msg->type = LDAP_TAG_DelRequest; - msg->r.DelRequest.dn = dn; - return msg; - } - - if (strequal(value.data, "add")) { - msg->type = LDAP_TAG_AddRequest; - - msg->r.AddRequest.dn = dn; - - if (!fill_add_attributes(msg, &s)) - goto failed; - - return msg; - } - - if (strequal(value.data, "modify")) { - msg->type = LDAP_TAG_ModifyRequest; - - msg->r.ModifyRequest.dn = dn; - - if (!fill_mods(msg, &s)) - goto failed; - - return msg; - } - - if (strequal(value.data, "modrdn")) { - msg->type = LDAP_TAG_ModifyDNRequest; - - msg->r.ModifyDNRequest.dn = dn; - - if (!fill_modrdn(msg, &s)) - goto failed; - - return msg; - } - - DEBUG(3, ("changetype %s not supported\n", (char *)value.data)); - -failed: - talloc_free(msg); - return NULL; -} - -/* - a wrapper around ldif_read() for reading from const char* -*/ -struct ldif_read_string_state { - const char *s; -}; - -static int fgetc_string(void *private_data) -{ - struct ldif_read_string_state *state = private_data; - if (state->s[0] != 0) { - return *state->s++; - } - return EOF; -} - -struct ldap_message *ldap_ldif2msg(TALLOC_CTX *mem_ctx, const char *s) -{ - struct ldif_read_string_state state; - state.s = s; - return ldif_read(mem_ctx, fgetc_string, &state); -} - -- cgit From bab977dad76e9204278c7afe0bb905cda064f488 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 16 Jun 2005 05:39:40 +0000 Subject: r7626: a new ldap client library. Main features are: - hooked into events system, so requests can be truly async and won't interfere with other processing happening at the same time - uses NTSTATUS codes for errors (previously errors were mostly ignored). In a similar fashion to the DOS error handling, I have reserved a range of the NTSTATUS code 32 bit space for LDAP error codes, so a function can return a LDAP error code in a NTSTATUS - much cleaner packet handling (This used to be commit 2e3c660b2fc20e046d82bf1cc296422b6e7dfad0) --- source4/libcli/ldap/config.mk | 4 +- source4/libcli/ldap/ldap.c | 40 -- source4/libcli/ldap/ldap.h | 97 --- source4/libcli/ldap/ldap_bind.c | 250 ++++++++ source4/libcli/ldap/ldap_client.c | 1275 ++++++++++++------------------------- source4/libcli/ldap/ldap_client.h | 86 +++ source4/libcli/ldap/ldap_ldif.c | 78 --- source4/libcli/ldap/ldap_msg.c | 84 +++ 8 files changed, 841 insertions(+), 1073 deletions(-) create mode 100644 source4/libcli/ldap/ldap_bind.c create mode 100644 source4/libcli/ldap/ldap_client.h delete mode 100644 source4/libcli/ldap/ldap_ldif.c create mode 100644 source4/libcli/ldap/ldap_msg.c (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 888590ec5e..ca33581043 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -3,8 +3,8 @@ [SUBSYSTEM::LIBCLI_LDAP] ADD_OBJ_FILES = libcli/ldap/ldap.o \ libcli/ldap/ldap_client.o \ - libcli/ldap/ldap_ldif.o \ + libcli/ldap/ldap_bind.o \ + libcli/ldap/ldap_msg.o \ libcli/ldap/ldap_ndr.o -NOPROTO=YES # End SUBSYSTEM LIBCLI_LDAP ################################# diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index bce3da94ae..c642fc3e4b 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1013,44 +1013,4 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) return ((!data->has_error) && (data->nesting == NULL)); } -BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, - char **host, uint16_t *port, BOOL *ldaps) -{ - int tmp_port = 0; - char protocol[11]; - char tmp_host[255]; - const char *p = url; - int ret; - - /* skip leading "URL:" (if any) */ - if (strncasecmp( p, "URL:", 4) == 0) { - p += 4; - } - - /* Paranoia check */ - SMB_ASSERT(sizeof(protocol)>10 && sizeof(tmp_host)>254); - - ret = sscanf(p, "%10[^:]://%254[^:/]:%d", protocol, tmp_host, &tmp_port); - if (ret < 2) { - return False; - } - - if (strequal(protocol, "ldap")) { - *port = 389; - *ldaps = False; - } else if (strequal(protocol, "ldaps")) { - *port = 636; - *ldaps = True; - } else { - DEBUG(0, ("unrecognised protocol (%s)!\n", protocol)); - return False; - } - - if (tmp_port != 0) - *port = tmp_port; - - *host = talloc_strdup(mem_ctx, tmp_host); - - return (*host != NULL); -} diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 577df1fc3d..072070f723 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -253,101 +253,4 @@ struct ldap_message { struct ldap_Control *controls; }; -struct ldap_queue_entry { - struct ldap_queue_entry *next, *prev; - int msgid; - struct ldap_message *msg; -}; - -struct ldap_connection { - int sock; - int next_msgid; - char *host; - uint16_t port; - BOOL ldaps; - - const char *auth_dn; - const char *simple_pw; - - /* Current outstanding search entry */ - int searchid; - - /* List for incoming search entries */ - struct ldap_queue_entry *search_entries; - - /* Outstanding LDAP requests that have not yet been replied to */ - struct ldap_queue_entry *outstanding; - - /* Let's support SASL */ - struct gensec_security *gensec; -}; - -#define LDAP_CONNECTION_TIMEOUT 10000 - -/* The following definitions come from libcli/ldap/ldap.c */ - -BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result); -BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg); -BOOL ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, - char **host, uint16_t *port, BOOL *ldaps); - -/* The following definitions come from libcli/ldap/ldap_client.c */ - -struct ldap_connection *ldap_connect(TALLOC_CTX *mem_ctx, const char *url); -struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx); -BOOL ldap_send_msg(struct ldap_connection *conn, struct ldap_message *msg, - const struct timeval *endtime); -BOOL ldap_receive_msg(struct ldap_connection *conn, struct ldap_message *msg, - const struct timeval *endtime); -struct ldap_message *ldap_receive(struct ldap_connection *conn, int msgid, - const struct timeval *endtime); -struct ldap_message *ldap_transaction(struct ldap_connection *conn, - struct ldap_message *request); -int ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const char *password); -int ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds); -struct ldap_connection *ldap_setup_connection(TALLOC_CTX *mem_ctx, const char *url, - const char *userdn, const char *password); -struct ldap_connection *ldap_setup_connection_with_sasl(TALLOC_CTX *mem_ctx, const char *url, - struct cli_credentials *creds); -BOOL ldap_abandon_message(struct ldap_connection *conn, int msgid, - const struct timeval *endtime); -BOOL ldap_setsearchent(struct ldap_connection *conn, struct ldap_message *msg, - const struct timeval *endtime); -struct ldap_message *ldap_getsearchent(struct ldap_connection *conn, - const struct timeval *endtime); -void ldap_endsearchent(struct ldap_connection *conn, - const struct timeval *endtime); -struct ldap_message *ldap_searchone(struct ldap_connection *conn, - struct ldap_message *msg, - const struct timeval *endtime); -BOOL ldap_find_single_value(struct ldap_message *msg, const char *attr, - DATA_BLOB *value); -BOOL ldap_find_single_string(struct ldap_message *msg, const char *attr, - TALLOC_CTX *mem_ctx, char **value); -BOOL ldap_find_single_int(struct ldap_message *msg, const char *attr, - int *value); -int ldap_error(struct ldap_connection *conn); -NTSTATUS ldap2nterror(int ldaperror); - -/* The following definitions come from libcli/ldap/ldap_ldif.c */ - -BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, - struct ldb_message_element *attrib); -BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, - const struct ldb_message_element *attrib, - struct ldb_message_element **attribs, - int *num_attribs); -BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, - struct ldap_mod *mod, - struct ldap_mod **mods, - int *num_mods); -struct ldap_message *ldap_ldif2msg(TALLOC_CTX *mem_ctx, const char *s); - -/* The following definitions come from libcli/ldap/ldap_ndr.c */ - -const char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value); -const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, struct dom_sid *sid); -const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid); -NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GUID *guid); - #endif diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c new file mode 100644 index 0000000000..11a6997fb2 --- /dev/null +++ b/source4/libcli/ldap/ldap_bind.c @@ -0,0 +1,250 @@ +/* + Unix SMB/CIFS mplementation. + + LDAP bind calls + + Copyright (C) Andrew Tridgell 2005 + Copyright (C) Volker Lendecke 2004 + + 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 "libcli/ldap/ldap.h" +#include "libcli/ldap/ldap_client.h" +#include "auth/auth.h" + +static struct ldap_message *new_ldap_simple_bind_msg(struct ldap_connection *conn, + const char *dn, const char *pw) +{ + struct ldap_message *res; + + res = new_ldap_message(conn); + if (!res) { + return NULL; + } + + res->type = LDAP_TAG_BindRequest; + res->r.BindRequest.version = 3; + 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); + + return res; +} + + +/* + perform a simple username/password bind +*/ +NTSTATUS ldap_bind_simple(struct ldap_connection *conn, + const char *userdn, const char *password) +{ + struct ldap_request *req; + struct ldap_message *msg; + const char *dn, *pw; + NTSTATUS status; + + if (conn == NULL) { + return NT_STATUS_INVALID_CONNECTION; + } + + if (userdn) { + dn = userdn; + } else { + if (conn->auth_dn) { + dn = conn->auth_dn; + } else { + dn = ""; + } + } + + if (password) { + pw = password; + } else { + if (conn->simple_pw) { + pw = conn->simple_pw; + } else { + pw = ""; + } + } + + msg = new_ldap_simple_bind_msg(conn, dn, pw); + NT_STATUS_HAVE_NO_MEMORY(msg); + + /* send the request */ + req = ldap_request_send(conn, msg); + talloc_free(msg); + NT_STATUS_HAVE_NO_MEMORY(req); + + /* wait for replies */ + status = ldap_request_wait(req); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return status; + } + + /* check its a valid reply */ + msg = req->replies[0]; + if (msg->type != LDAP_TAG_BindResponse) { + talloc_free(req); + return NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + + status = ldap_check_response(conn, &msg->r.BindResponse.response); + + talloc_free(req); + + return status; +} + + +static struct ldap_message *new_ldap_sasl_bind_msg(struct ldap_connection *conn, + const char *sasl_mechanism, + DATA_BLOB *secblob) +{ + struct ldap_message *res; + + res = new_ldap_message(conn); + if (!res) { + return NULL; + } + + res->type = LDAP_TAG_BindRequest; + res->r.BindRequest.version = 3; + res->r.BindRequest.dn = ""; + 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; + + return res; +} + + +/* + perform a sasl bind using the given credentials +*/ +NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds) +{ + NTSTATUS status; + TALLOC_CTX *tmp_ctx = NULL; + DATA_BLOB input = data_blob(NULL, 0); + DATA_BLOB output = data_blob(NULL, 0); + + status = gensec_client_start(conn, &conn->gensec); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); + goto failed; + } + + gensec_want_feature(conn->gensec, 0 | GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL); + + status = gensec_set_credentials(conn->gensec, creds); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC creds: %s\n", + nt_errstr(status))); + goto failed; + } + + status = gensec_set_target_hostname(conn->gensec, conn->host); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", + nt_errstr(status))); + goto failed; + } + + status = gensec_set_target_service(conn->gensec, "ldap"); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC target service: %s\n", + nt_errstr(status))); + goto failed; + } + + status = gensec_start_mech_by_sasl_name(conn->gensec, "NTLM"); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism: %s\n", + nt_errstr(status))); + goto failed; + } + + tmp_ctx = talloc_new(conn); + if (tmp_ctx == NULL) goto failed; + + status = gensec_update(conn->gensec, tmp_ctx, input, &output); + + while (1) { + struct ldap_message *response; + struct ldap_message *msg; + struct ldap_request *req; + int result = LDAP_OTHER; + + if (NT_STATUS_IS_OK(status) && output.length == 0) { + break; + } + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && + !NT_STATUS_IS_OK(status)) { + break; + } + + msg = new_ldap_sasl_bind_msg(tmp_ctx, "GSS-SPNEGO", &output); + if (msg == NULL) { + status = NT_STATUS_NO_MEMORY; + goto failed; + } + + req = ldap_request_send(conn, msg); + if (req == NULL) { + status = NT_STATUS_NO_MEMORY; + goto failed; + } + talloc_steal(tmp_ctx, req); + + status = ldap_result_n(req, 0, &response); + if (!NT_STATUS_IS_OK(status)) { + goto failed; + } + + if (response->type != LDAP_TAG_BindResponse) { + status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + goto failed; + } + + result = response->r.BindResponse.response.resultcode; + + if (result != LDAP_SUCCESS && result != LDAP_SASL_BIND_IN_PROGRESS) { + break; + } + + status = gensec_update(conn->gensec, tmp_ctx, + response->r.BindResponse.SASL.secblob, + &output); + } + + if (NT_STATUS_IS_OK(status) && + (gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) || + gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN))) { + conn->enable_wrap = True; + } + + talloc_free(tmp_ctx); + return status; + +failed: + talloc_free(tmp_ctx); + talloc_free(conn->gensec); + conn->gensec = NULL; + return status; +} diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 6ff8db85a5..f3a7f104d4 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -24,1024 +24,587 @@ */ #include "includes.h" -#include "system/network.h" -#include "system/filesys.h" -#include "auth/auth.h" #include "asn_1.h" #include "dlinklist.h" +#include "lib/events/events.h" +#include "lib/socket/socket.h" #include "libcli/ldap/ldap.h" +#include "libcli/ldap/ldap_client.h" - -/**************************************************************************** - Check the timeout. -****************************************************************************/ -static BOOL timeout_until(struct timeval *timeout, - const struct timeval *endtime) -{ - struct timeval now; - - GetTimeOfDay(&now); - - if ((now.tv_sec > endtime->tv_sec) || - ((now.tv_sec == endtime->tv_sec) && - (now.tv_usec > endtime->tv_usec))) - return False; - - timeout->tv_sec = endtime->tv_sec - now.tv_sec; - timeout->tv_usec = endtime->tv_usec - now.tv_usec; - return True; -} - - -/**************************************************************************** - Read data from the client, reading exactly N bytes, with timeout. -****************************************************************************/ -static ssize_t read_data_until(int fd,char *buffer,size_t N, - const struct timeval *endtime) +/* + create a new ldap_connection stucture. The event context is optional +*/ +struct ldap_connection *ldap_new_connection(TALLOC_CTX *mem_ctx, + struct event_context *ev) { - ssize_t ret; - size_t total=0; - - while (total < N) { - - if (endtime != NULL) { - fd_set r_fds; - struct timeval timeout; - int res; - - FD_ZERO(&r_fds); - FD_SET(fd, &r_fds); - - if (!timeout_until(&timeout, endtime)) - return -1; - - res = sys_select(fd+1, &r_fds, NULL, NULL, &timeout); - if (res <= 0) - return -1; - } - - ret = sys_read(fd,buffer + total,N - total); - - if (ret == 0) { - DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) )); - return 0; - } + struct ldap_connection *conn; - if (ret == -1) { - DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) )); - return -1; - } - total += ret; + conn = talloc_zero(mem_ctx, struct ldap_connection); + if (conn == NULL) { + return NULL; } - return (ssize_t)total; -} - -/**************************************************************************** - Write data to a fd with timeout. -****************************************************************************/ -static ssize_t write_data_until(int fd,char *buffer,size_t N, - const struct timeval *endtime) -{ - size_t total=0; - ssize_t ret; - - while (total < N) { - - if (endtime != NULL) { - fd_set w_fds; - struct timeval timeout; - int res; - - FD_ZERO(&w_fds); - FD_SET(fd, &w_fds); - - if (!timeout_until(&timeout, endtime)) - return -1; - - res = sys_select(fd+1, NULL, &w_fds, NULL, &timeout); - if (res <= 0) - return -1; - } - - ret = sys_write(fd,buffer + total,N - total); - - if (ret == -1) { - DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) )); - return -1; + if (ev == NULL) { + ev = event_context_init(conn); + if (ev == NULL) { + talloc_free(conn); + return NULL; } - if (ret == 0) - return total; - - total += ret; } - return (ssize_t)total; -} + conn->next_messageid = 1; + conn->event.event_ctx = ev; + /* set a reasonable request timeout */ + conn->timeout = 60; -static BOOL read_one_uint8(int sock, uint8_t *result, struct asn1_data *data, - const struct timeval *endtime) -{ - if (read_data_until(sock, result, 1, endtime) != 1) - return False; - - return asn1_write(data, result, 1); + return conn; } -/* Read a complete ASN sequence (ie LDAP result) from a socket */ -static BOOL asn1_read_sequence_until(int sock, struct asn1_data *data, - const struct timeval *endtime) -{ - uint8_t b; - size_t len; - char *buf; - - ZERO_STRUCTP(data); - - if (!read_one_uint8(sock, &b, data, endtime)) - return False; - if (b != 0x30) { - data->has_error = True; - return False; - } +/* + the connection is dead +*/ +static void ldap_connection_dead(struct ldap_connection *conn) +{ + struct ldap_request *req; - if (!read_one_uint8(sock, &b, data, endtime)) - return False; - - if (b & 0x80) { - int n = b & 0x7f; - if (!read_one_uint8(sock, &b, data, endtime)) - return False; - len = b; - while (n > 1) { - if (!read_one_uint8(sock, &b, data, endtime)) - return False; - len = (len<<8) | b; - n--; + while (conn->pending) { + req = conn->pending; + DLIST_REMOVE(req->conn->pending, req); + req->state = LDAP_REQUEST_DONE; + req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + if (req->async.fn) { + req->async.fn(req); + } + } + + while (conn->send_queue) { + req = conn->send_queue; + DLIST_REMOVE(req->conn->send_queue, req); + req->state = LDAP_REQUEST_DONE; + req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + if (req->async.fn) { + req->async.fn(req); } - } else { - len = b; } - buf = talloc_size(NULL, len); - if (buf == NULL) - return False; - - if (read_data_until(sock, buf, len, endtime) != len) - return False; - - if (!asn1_write(data, buf, len)) - return False; - - talloc_free(buf); - - data->ofs = 0; - - return True; + talloc_free(conn->sock); + conn->sock = NULL; } - -/**************************************************************************** - create an outgoing socket. timeout is in milliseconds. - **************************************************************************/ -static int open_socket_out(int type, struct ipv4_addr *addr, int port, int timeout) -{ - struct sockaddr_in sock_out; - int res,ret; - int connect_loop = 250; /* 250 milliseconds */ - int loops = (timeout) / connect_loop; - - /* create a socket to write to */ - res = socket(PF_INET, type, 0); - if (res == -1) - { DEBUG(0,("socket error\n")); return -1; } - - if (type != SOCK_STREAM) return(res); - - memset((char *)&sock_out,'\0',sizeof(sock_out)); - sock_out.sin_addr.s_addr = addr->addr; - - sock_out.sin_port = htons( port ); - sock_out.sin_family = PF_INET; - - /* set it non-blocking */ - set_blocking(res,False); - - DEBUG(3,("Connecting to %s at port %d\n", sys_inet_ntoa(*addr),port)); - - /* and connect it to the destination */ -connect_again: - ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out)); - - /* Some systems return EAGAIN when they mean EINPROGRESS */ - if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || - errno == EAGAIN) && loops--) { - msleep(connect_loop); - goto connect_again; - } - - if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || - errno == EAGAIN)) { - DEBUG(1,("timeout connecting to %s:%d\n", sys_inet_ntoa(*addr),port)); - close(res); - return -1; - } - -#ifdef EISCONN - if (ret < 0 && errno == EISCONN) { - errno = 0; - ret = 0; - } -#endif - - if (ret < 0) { - DEBUG(2,("error connecting to %s:%d (%s)\n", - sys_inet_ntoa(*addr),port,strerror(errno))); - close(res); - return -1; - } - - /* set it blocking again */ - set_blocking(res,True); - - return res; -} - -#if 0 -static struct ldap_message *new_ldap_search_message(struct ldap_connection *conn, - const char *base, - enum ldap_scope scope, - char *filter, - int num_attributes, - const char **attributes) +/* + match up with a pending message, adding to the replies list +*/ +static void ldap_match_message(struct ldap_connection *conn, struct ldap_message *msg) { - struct ldap_message *res; + struct ldap_request *req; - res = new_ldap_message(conn); - if (!res) { - return NULL; + for (req=conn->pending; req; req=req->next) { + if (req->messageid == msg->messageid) break; } - - res->type = LDAP_TAG_SearchRequest; - res->r.SearchRequest.basedn = base; - res->r.SearchRequest.scope = scope; - res->r.SearchRequest.deref = LDAP_DEREFERENCE_NEVER; - res->r.SearchRequest.timelimit = 0; - res->r.SearchRequest.sizelimit = 0; - res->r.SearchRequest.attributesonly = False; - res->r.SearchRequest.filter = filter; - res->r.SearchRequest.num_attributes = num_attributes; - res->r.SearchRequest.attributes = attributes; - - return res; -} -#endif - -static struct ldap_message *new_ldap_simple_bind_msg(struct ldap_connection *conn, const char *dn, const char *pw) -{ - struct ldap_message *res; - - res = new_ldap_message(conn); - if (!res) { - return NULL; + if (req == NULL) { + DEBUG(0,("ldap: no matching message id for %u\n", + msg->messageid)); + talloc_free(msg); + return; } - res->type = LDAP_TAG_BindRequest; - res->r.BindRequest.version = 3; - 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); - - return res; -} - -static struct ldap_message *new_ldap_sasl_bind_msg(struct ldap_connection *conn, const char *sasl_mechanism, DATA_BLOB *secblob) -{ - struct ldap_message *res; - - res = new_ldap_message(conn); - if (!res) { - return NULL; + /* add to the list of replies received */ + talloc_steal(req, msg); + req->replies = talloc_realloc(req, req->replies, + struct ldap_message *, req->num_replies+1); + if (req->replies == NULL) { + req->status = NT_STATUS_NO_MEMORY; + req->state = LDAP_REQUEST_DONE; + DLIST_REMOVE(conn->pending, req); + if (req->async.fn) { + req->async.fn(req); + } + return; } - res->type = LDAP_TAG_BindRequest; - res->r.BindRequest.version = 3; - res->r.BindRequest.dn = ""; - 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; - - return res; -} - -static struct ldap_connection *new_ldap_connection(TALLOC_CTX *mem_ctx) -{ - struct ldap_connection *result; + req->replies[req->num_replies] = talloc_steal(req->replies, msg); + req->num_replies++; - result = talloc(mem_ctx, struct ldap_connection); - - if (!result) { - return NULL; + if (msg->type != LDAP_TAG_SearchResultEntry) { + /* currently only search results expect multiple + replies */ + req->state = LDAP_REQUEST_DONE; + DLIST_REMOVE(conn->pending, req); } - result->next_msgid = 1; - result->outstanding = NULL; - result->searchid = 0; - result->search_entries = NULL; - result->auth_dn = NULL; - result->simple_pw = NULL; - result->gensec = NULL; - - return result; + if (req->async.fn) { + req->async.fn(req); + } } -struct ldap_connection *ldap_connect(TALLOC_CTX *mem_ctx, const char *url) +/* + try and decode/process plain data +*/ +static void ldap_try_decode_plain(struct ldap_connection *conn) { - struct hostent *hp; - struct ipv4_addr ip; - struct ldap_connection *conn; - BOOL ret; + struct asn1_data asn1; - conn = new_ldap_connection(mem_ctx); - if (!conn) { - return NULL; + if (!asn1_load(&asn1, conn->partial)) { + ldap_connection_dead(conn); + return; } - ret = ldap_parse_basic_url(conn, url, &conn->host, - &conn->port, &conn->ldaps); - if (!ret) { - talloc_free(conn); - return NULL; - } + /* try and decode - this will fail if we don't have a full packet yet */ + while (asn1.ofs < asn1.length) { + struct ldap_message *msg = talloc(conn, struct ldap_message); + if (msg == NULL) { + ldap_connection_dead(conn); + return; + } - hp = sys_gethostbyname(conn->host); - if (!hp || !hp->h_addr) { - talloc_free(conn); - return NULL; + if (ldap_decode(&asn1, msg)) { + ldap_match_message(conn, msg); + } else { + talloc_free(msg); + break; + } } - memcpy((char *)&ip, (char *)hp->h_addr, 4); - - conn->sock = open_socket_out(SOCK_STREAM, &ip, conn->port, LDAP_CONNECTION_TIMEOUT); - if (conn->sock < 0) { - talloc_free(conn); - return NULL; + /* keep any remaining data in conn->partial */ + data_blob_free(&conn->partial); + if (asn1.ofs != conn->partial.length) { + conn->partial = data_blob_talloc(conn, + asn1.data + asn1.ofs, + asn1.length - asn1.ofs); } - - return conn; -} - -struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) -{ - return talloc(mem_ctx, struct ldap_message); -} - -BOOL ldap_send_msg(struct ldap_connection *conn, struct ldap_message *msg, - const struct timeval *endtime) -{ - DATA_BLOB request; - BOOL result; - struct ldap_queue_entry *entry; - - msg->messageid = conn->next_msgid++; - - if (!ldap_encode(msg, &request)) - return False; - - result = (write_data_until(conn->sock, request.data, request.length, - endtime) == request.length); - - data_blob_free(&request); - - if (!result) - return result; - - /* abandon and unbind don't expect results */ - - if ((msg->type == LDAP_TAG_AbandonRequest) || - (msg->type == LDAP_TAG_UnbindRequest)) - return True; - - entry = malloc_p(struct ldap_queue_entry); - - if (entry == NULL) - return False; - - entry->msgid = msg->messageid; - entry->msg = NULL; - DLIST_ADD(conn->outstanding, entry); - - return True; -} - -BOOL ldap_receive_msg(struct ldap_connection *conn, struct ldap_message *msg, - const struct timeval *endtime) -{ - struct asn1_data data; - BOOL result; - - if (!asn1_read_sequence_until(conn->sock, &data, endtime)) - return False; - - result = ldap_decode(&data, msg); - - asn1_free(&data); - return result; + asn1_free(&asn1); } -static struct ldap_message *recv_from_queue(struct ldap_connection *conn, - int msgid) +/* + try and decode/process wrapped data +*/ +static void ldap_try_decode_wrapped(struct ldap_connection *conn) { - struct ldap_queue_entry *e; + uint32_t len; - for (e = conn->outstanding; e != NULL; e = e->next) { + /* keep decoding while we have a full wrapped packet */ + while (conn->partial.length >= 4 && + (len=RIVAL(conn->partial.data, 0)) <= conn->partial.length-4) { + DATA_BLOB wrapped, unwrapped; + struct asn1_data asn1; + struct ldap_message *msg = talloc(conn, struct ldap_message); + NTSTATUS status; - if (e->msgid == msgid) { - struct ldap_message *result = e->msg; - DLIST_REMOVE(conn->outstanding, e); - SAFE_FREE(e); - return result; + if (msg == NULL) { + ldap_connection_dead(conn); + return; } - } - return NULL; -} - -static void add_search_entry(struct ldap_connection *conn, - struct ldap_message *msg) -{ - struct ldap_queue_entry *e = malloc_p(struct ldap_queue_entry); - - if (e == NULL) - return; + wrapped.data = conn->partial.data+4; + wrapped.length = len; - e->msg = msg; - DLIST_ADD_END(conn->search_entries, e, struct ldap_queue_entry *); - return; -} - -static void fill_outstanding_request(struct ldap_connection *conn, - struct ldap_message *msg) -{ - struct ldap_queue_entry *e; - - for (e = conn->outstanding; e != NULL; e = e->next) { - if (e->msgid == msg->messageid) { - e->msg = msg; + status = gensec_unwrap(conn->gensec, msg, &wrapped, &unwrapped); + if (!NT_STATUS_IS_OK(status)) { + ldap_connection_dead(conn); return; } - } - - /* This reply has not been expected, destroy the incoming msg */ - talloc_free(msg); - return; -} - -struct ldap_message *ldap_receive(struct ldap_connection *conn, int msgid, - const struct timeval *endtime) -{ - struct ldap_message *result = recv_from_queue(conn, msgid); - - if (result != NULL) - return result; - while (True) { - struct asn1_data data; - BOOL res; - - result = new_ldap_message(conn); - - if (!asn1_read_sequence_until(conn->sock, &data, endtime)) - return NULL; - - res = ldap_decode(&data, result); - asn1_free(&data); - - if (!res) - return NULL; + if (!asn1_load(&asn1, unwrapped)) { + ldap_connection_dead(conn); + return; + } - if (result->messageid == msgid) - return result; + if (ldap_decode(&asn1, msg)) { + ldap_match_message(conn, msg); + } else { + talloc_free(msg); + } + + asn1_free(&asn1); - if (result->type == LDAP_TAG_SearchResultEntry) { - add_search_entry(conn, result); + if (conn->partial.length == len + 4) { + data_blob_free(&conn->partial); } else { - fill_outstanding_request(conn, result); + memmove(conn->partial.data, conn->partial.data+len+4, + conn->partial.length - (len+4)); + conn->partial.length -= len + 4; } } - - return NULL; } + /* - Write data to a fd + handle ldap recv events */ -static ssize_t write_data(int fd, char *buffer, size_t N) +static void ldap_recv_handler(struct ldap_connection *conn) { - size_t total=0; - ssize_t ret; + NTSTATUS status; + size_t npending=0, nread; - while (total < N) { - ret = sys_write(fd,buffer + total,N - total); + /* work out how much data is pending */ + status = socket_pending(conn->sock, &npending); + if (!NT_STATUS_IS_OK(status) || npending == 0) { + DEBUG(0,("ldap_recv_handler - pending=%d - %s\n", + (int)npending, nt_errstr(status))); + return; + } - if (ret == -1) { - DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) )); - return -1; - } - if (ret == 0) - return total; + conn->partial.data = talloc_realloc_size(conn, conn->partial.data, + conn->partial.length + npending); + if (conn->partial.data == NULL) { + ldap_connection_dead(conn); + return; + } - total += ret; + /* receive the pending data */ + status = socket_recv(conn->sock, conn->partial.data + conn->partial.length, + npending, &nread, 0); + if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { + return; } + if (!NT_STATUS_IS_OK(status)) { + ldap_connection_dead(conn); + return; + } + conn->partial.length += nread; - return (ssize_t)total; + /* see if we can decode what we have */ + if (conn->enable_wrap) { + ldap_try_decode_wrapped(conn); + } else { + ldap_try_decode_plain(conn); + } } /* - Read data from the client, reading exactly N bytes + handle ldap send events */ -static ssize_t read_data(int fd, char *buffer, size_t N) +static void ldap_send_handler(struct ldap_connection *conn) { - ssize_t ret; - size_t total=0; - - while (total < N) { + while (conn->send_queue) { + struct ldap_request *req = conn->send_queue; + size_t nsent; + NTSTATUS status; - ret = sys_read(fd,buffer + total,N - total); - - if (ret == 0) { - DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", - (int)(N - total), strerror(errno) )); - return 0; + status = socket_send(conn->sock, &req->data, &nsent, 0); + if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { + break; } - - if (ret == -1) { - DEBUG(0,("read_data: read failure for %d. Error = %s\n", - (int)(N - total), strerror(errno) )); - return -1; + if (!NT_STATUS_IS_OK(status)) { + ldap_connection_dead(conn); + return; } - total += ret; - } - - return (ssize_t)total; -} - -static struct ldap_message *ldap_transaction_sasl(struct ldap_connection *conn, struct ldap_message *req) -{ - NTSTATUS status; - DATA_BLOB request; - BOOL result; - DATA_BLOB wrapped; - int len; - char length[4]; - struct asn1_data asn1; - struct ldap_message *rep; - - req->messageid = conn->next_msgid++; - - if (!ldap_encode(req, &request)) - return NULL; - - status = gensec_wrap(conn->gensec, - req, - &request, - &wrapped); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("gensec_wrap: %s\n",nt_errstr(status))); - return NULL; - } - - RSIVAL(length, 0, wrapped.length); - result = (write_data(conn->sock, length, 4) == 4); - if (!result) - return NULL; - - result = (write_data(conn->sock, wrapped.data, wrapped.length) == wrapped.length); - if (!result) - return NULL; - - wrapped = data_blob(NULL, 0x4000); - data_blob_clear(&wrapped); - - result = (read_data(conn->sock, length, 4) == 4); - if (!result) - return NULL; - - len = RIVAL(length,0); - - result = (read_data(conn->sock, wrapped.data, MIN(wrapped.length,len)) == len); - if (!result) - return NULL; - - wrapped.length = len; - - status = gensec_unwrap(conn->gensec, - req, - &wrapped, - &request); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("gensec_unwrap: %s\n",nt_errstr(status))); - return NULL; + req->data.data += nsent; + req->data.length -= nsent; + if (req->data.length == 0) { + req->state = LDAP_REQUEST_PENDING; + DLIST_REMOVE(conn->send_queue, req); + + /* some types of requests don't expect a reply */ + if (req->type == LDAP_TAG_AbandonRequest || + req->type == LDAP_TAG_UnbindRequest) { + req->status = NT_STATUS_OK; + req->state = LDAP_REQUEST_DONE; + if (req->async.fn) { + req->async.fn(req); + } + } else { + DLIST_ADD(conn->pending, req); + } + } } - - rep = new_ldap_message(req); - - asn1_load(&asn1, request); - if (!ldap_decode(&asn1, rep)) { - return NULL; + if (conn->send_queue == NULL) { + EVENT_FD_NOT_WRITEABLE(conn->event.fde); } - - return rep; } -struct ldap_message *ldap_transaction(struct ldap_connection *conn, - struct ldap_message *request) + +/* + handle ldap socket events +*/ +static void ldap_io_handler(struct event_context *ev, struct fd_event *fde, + uint16_t flags, void *private) { - if ((request->type != LDAP_TAG_BindRequest) && conn->gensec && - (gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) || - gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN))) { - return ldap_transaction_sasl(conn, request); + struct ldap_connection *conn = talloc_get_type(private, struct ldap_connection); + if (flags & EVENT_FD_WRITE) { + ldap_send_handler(conn); + if (conn->sock == NULL) return; + } + if (flags & EVENT_FD_READ) { + ldap_recv_handler(conn); } - - if (!ldap_send_msg(conn, request, NULL)) - return False; - - return ldap_receive(conn, request->messageid, NULL); } -int ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const char *password) +/* + parse a ldap URL +*/ +static NTSTATUS ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, + char **host, uint16_t *port, BOOL *ldaps) { - struct ldap_message *response; - struct ldap_message *msg; - const char *dn, *pw; - int result = LDAP_OTHER; + int tmp_port = 0; + char protocol[11]; + char tmp_host[255]; + const char *p = url; + int ret; - if (conn == NULL) - return result; + /* skip leading "URL:" (if any) */ + if (strncasecmp(p, "URL:", 4) == 0) { + p += 4; + } - if (userdn) { - dn = userdn; - } else { - if (conn->auth_dn) { - dn = conn->auth_dn; - } else { - dn = ""; - } + /* Paranoia check */ + SMB_ASSERT(sizeof(protocol)>10 && sizeof(tmp_host)>254); + + ret = sscanf(p, "%10[^:]://%254[^:/]:%d", protocol, tmp_host, &tmp_port); + if (ret < 2) { + return NT_STATUS_INVALID_PARAMETER; } - if (password) { - pw = password; + if (strequal(protocol, "ldap")) { + *port = 389; + *ldaps = False; + } else if (strequal(protocol, "ldaps")) { + *port = 636; + *ldaps = True; } else { - if (conn->simple_pw) { - pw = conn->simple_pw; - } else { - pw = ""; - } + DEBUG(0, ("unrecognised ldap protocol (%s)!\n", protocol)); + return NT_STATUS_PROTOCOL_UNREACHABLE; } - msg = new_ldap_simple_bind_msg(conn, dn, pw); - if (!msg) - return result; + if (tmp_port != 0) + *port = tmp_port; - response = ldap_transaction(conn, msg); - if (!response) { - talloc_free(msg); - return result; - } - - result = response->r.BindResponse.response.resultcode; - - talloc_free(msg); - talloc_free(response); + *host = talloc_strdup(mem_ctx, tmp_host); + NT_STATUS_HAVE_NO_MEMORY(*host); - return result; + return NT_STATUS_OK; } -int ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds) +/* + connect to a ldap server +*/ +NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url) { NTSTATUS status; - TALLOC_CTX *mem_ctx = NULL; - struct ldap_message *response; - struct ldap_message *msg; - DATA_BLOB input = data_blob(NULL, 0); - DATA_BLOB output = data_blob(NULL, 0); - int result = LDAP_OTHER; - if (conn == NULL) - return result; + status = ldap_parse_basic_url(conn, url, &conn->host, + &conn->port, &conn->ldaps); + NT_STATUS_NOT_OK_RETURN(status); - status = gensec_client_start(conn, &conn->gensec); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); - return result; - } - - gensec_want_feature(conn->gensec, 0 | GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL); - - status = gensec_set_credentials(conn->gensec, creds); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC creds: %s\n", - nt_errstr(status))); - goto done; - } + status = socket_create("ipv4", SOCKET_TYPE_STREAM, &conn->sock, 0); + NT_STATUS_NOT_OK_RETURN(status); - status = gensec_set_target_hostname(conn->gensec, conn->host); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", - nt_errstr(status))); - goto done; - } + talloc_steal(conn, conn->sock); - status = gensec_set_target_service(conn->gensec, "ldap"); + /* connect in a event friendly way */ + status = socket_connect_ev(conn->sock, NULL, 0, conn->host, conn->port, 0, + conn->event.event_ctx); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC target service: %s\n", - nt_errstr(status))); - goto done; + talloc_free(conn->sock); + return status; } - status = gensec_start_mech_by_sasl_name(conn->gensec, "NTLM"); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism: %s\n", - nt_errstr(status))); - goto done; + /* setup a handler for events on this socket */ + conn->event.fde = event_add_fd(conn->event.event_ctx, conn->sock, + socket_get_fd(conn->sock), + EVENT_FD_READ, ldap_io_handler, conn); + if (conn->event.fde == NULL) { + talloc_free(conn->sock); + return NT_STATUS_INTERNAL_ERROR; } - mem_ctx = talloc_init("ldap_bind_sasl"); - if (!mem_ctx) - goto done; - - status = gensec_update(conn->gensec, mem_ctx, - input, - &output); - - while(1) { - if (NT_STATUS_IS_OK(status) && output.length == 0) { - break; - } - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) { - break; - } - - msg = new_ldap_sasl_bind_msg(conn, "GSS-SPNEGO", &output); - if (!msg) - goto done; - - response = ldap_transaction(conn, msg); - talloc_free(msg); - - if (!response) { - goto done; - } - - result = response->r.BindResponse.response.resultcode; - - if (result != LDAP_SUCCESS && result != LDAP_SASL_BIND_IN_PROGRESS) { - break; - } - - if (!NT_STATUS_IS_OK(status)) { - status = gensec_update(conn->gensec, mem_ctx, - response->r.BindResponse.SASL.secblob, - &output); - } else { - output.length = 0; - } - - talloc_free(response); - } - -done: - talloc_free(mem_ctx); - - return result; + return NT_STATUS_OK; } -struct ldap_connection *ldap_setup_connection(TALLOC_CTX *mem_ctx, const char *url, - const char *userdn, const char *password) +/* destroy an open ldap request */ +static int ldap_request_destructor(void *ptr) { - struct ldap_connection *conn; - int result; - - conn =ldap_connect(mem_ctx, url); - if (!conn) { - return NULL; + struct ldap_request *req = talloc_get_type(ptr, struct ldap_request); + if (req->state == LDAP_REQUEST_SEND) { + DLIST_REMOVE(req->conn->send_queue, req); } - - result = ldap_bind_simple(conn, userdn, password); - if (result != LDAP_SUCCESS) { - talloc_free(conn); - return NULL; + if (req->state == LDAP_REQUEST_PENDING) { + DLIST_REMOVE(req->conn->pending, req); } - - return conn; + return 0; } -struct ldap_connection *ldap_setup_connection_with_sasl(TALLOC_CTX *mem_ctx, - const char *url, - struct cli_credentials *creds) +/* + called on timeout of a ldap request +*/ +static void ldap_request_timeout(struct event_context *ev, struct timed_event *te, + struct timeval t, void *private) { - struct ldap_connection *conn; - int result; - - conn =ldap_connect(mem_ctx, url); - if (!conn) { - return NULL; + struct ldap_request *req = talloc_get_type(private, struct ldap_request); + req->status = NT_STATUS_IO_TIMEOUT; + if (req->state == LDAP_REQUEST_SEND) { + DLIST_REMOVE(req->conn->send_queue, req); } - - result = ldap_bind_sasl(conn, creds); - if (result != LDAP_SUCCESS) { - talloc_free(conn); - return NULL; + if (req->state == LDAP_REQUEST_PENDING) { + DLIST_REMOVE(req->conn->pending, req); + } + req->state = LDAP_REQUEST_DONE; + if (req->async.fn) { + req->async.fn(req); } - - return conn; } -BOOL ldap_abandon_message(struct ldap_connection *conn, int msgid, - const struct timeval *endtime) +/* + send a ldap message - async interface +*/ +struct ldap_request *ldap_request_send(struct ldap_connection *conn, + struct ldap_message *msg) { - struct ldap_message *msg = new_ldap_message(conn); - BOOL result; + struct ldap_request *req; - if (msg == NULL) - return False; + if (conn->sock == NULL) { + return NULL; + } - msg->type = LDAP_TAG_AbandonRequest; - msg->r.AbandonRequest.messageid = msgid; + req = talloc_zero(conn, struct ldap_request); + if (req == NULL) goto failed; - result = ldap_send_msg(conn, msg, endtime); - talloc_free(msg); - return result; -} + req->state = LDAP_REQUEST_SEND; + req->conn = conn; + req->messageid = conn->next_messageid++; + req->type = msg->type; + if (req->messageid == -1) { + goto failed; + } -BOOL ldap_setsearchent(struct ldap_connection *conn, struct ldap_message *msg, - const struct timeval *endtime) -{ - if ((conn->searchid != 0) && - (!ldap_abandon_message(conn, conn->searchid, endtime))) - return False; + talloc_set_destructor(req, ldap_request_destructor); - conn->searchid = conn->next_msgid; - return ldap_send_msg(conn, msg, endtime); -} + msg->messageid = req->messageid; -struct ldap_message *ldap_getsearchent(struct ldap_connection *conn, - const struct timeval *endtime) -{ - struct ldap_message *result; + if (!ldap_encode(msg, &req->data)) { + goto failed; + } - if (conn->search_entries != NULL) { - struct ldap_queue_entry *e = conn->search_entries; + /* possibly encrypt/sign the request */ + if (conn->enable_wrap) { + DATA_BLOB wrapped; + NTSTATUS status; - result = e->msg; - DLIST_REMOVE(conn->search_entries, e); - SAFE_FREE(e); - return result; + status = gensec_wrap(conn->gensec, req, &req->data, &wrapped); + if (!NT_STATUS_IS_OK(status)) { + goto failed; + } + data_blob_free(&req->data); + req->data = data_blob_talloc(req, NULL, wrapped.length + 4); + if (req->data.data == NULL) { + goto failed; + } + RSIVAL(req->data.data, 0, wrapped.length); + memcpy(req->data.data+4, wrapped.data, wrapped.length); + data_blob_free(&wrapped); } - result = ldap_receive(conn, conn->searchid, endtime); - if (!result) { - return NULL; + + if (conn->send_queue == NULL) { + EVENT_FD_WRITEABLE(conn->event.fde); } + DLIST_ADD_END(conn->send_queue, req, struct ldap_request *); - if (result->type == LDAP_TAG_SearchResultEntry) - return result; + /* put a timeout on the request */ + event_add_timed(conn->event.event_ctx, req, + timeval_current_ofs(conn->timeout, 0), + ldap_request_timeout, req); - if (result->type == LDAP_TAG_SearchResultDone) { - /* TODO: Handle Paged Results */ - talloc_free(result); - return NULL; - } + return req; - /* TODO: Handle Search References here */ +failed: + talloc_free(req); return NULL; } -void ldap_endsearchent(struct ldap_connection *conn, - const struct timeval *endtime) -{ - struct ldap_queue_entry *e; - - e = conn->search_entries; - while (e != NULL) { - struct ldap_queue_entry *next = e->next; - DLIST_REMOVE(conn->search_entries, e); - SAFE_FREE(e); - e = next; +/* + wait for a request to complete + note that this does not destroy the request +*/ +NTSTATUS ldap_request_wait(struct ldap_request *req) +{ + while (req->state != LDAP_REQUEST_DONE) { + if (event_loop_once(req->conn->event.event_ctx) != 0) { + req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + break; + } } + return req->status; } -struct ldap_message *ldap_searchone(struct ldap_connection *conn, - struct ldap_message *msg, - const struct timeval *endtime) -{ - struct ldap_message *res1, *res2 = NULL; - if (!ldap_setsearchent(conn, msg, endtime)) - return NULL; - - res1 = ldap_getsearchent(conn, endtime); - - if (res1 != NULL) - res2 = ldap_getsearchent(conn, endtime); - - ldap_endsearchent(conn, endtime); - - if (res1 == NULL) - return NULL; - if (res2 != NULL) { - /* More than one entry */ - talloc_free(res1); - talloc_free(res2); - return NULL; +/* + used to setup the status code from a ldap response +*/ +NTSTATUS ldap_check_response(struct ldap_connection *conn, struct ldap_Result *r) +{ + if (r->resultcode == LDAP_SUCCESS) { + return NT_STATUS_OK; } - return res1; + if (conn->last_error) { + talloc_free(conn->last_error); + } + conn->last_error = talloc_asprintf(conn, "LDAP error %u - %s <%s> <%s>", + r->resultcode, + r->dn, r->errormessage, r->referral); + + return NT_STATUS_LDAP(r->resultcode); } -BOOL ldap_find_single_value(struct ldap_message *msg, const char *attr, - DATA_BLOB *value) +/* + return error string representing the last error +*/ +const char *ldap_errstr(struct ldap_connection *conn, NTSTATUS status) { - int i; - struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; - - if (msg->type != LDAP_TAG_SearchResultEntry) - return False; - - for (i=0; inum_attributes; i++) { - if (strequal(attr, r->attributes[i].name)) { - if (r->attributes[i].num_values != 1) - return False; - - *value = r->attributes[i].values[0]; - return True; - } + if (NT_STATUS_IS_LDAP(status) && conn->last_error != NULL) { + return conn->last_error; } - return False; + return nt_errstr(status); } -BOOL ldap_find_single_string(struct ldap_message *msg, const char *attr, - TALLOC_CTX *mem_ctx, char **value) -{ - DATA_BLOB blob; - - if (!ldap_find_single_value(msg, attr, &blob)) - return False; - - *value = talloc_size(mem_ctx, blob.length+1); - - if (*value == NULL) - return False; - memcpy(*value, blob.data, blob.length); - (*value)[blob.length] = '\0'; - return True; -} - -BOOL ldap_find_single_int(struct ldap_message *msg, const char *attr, - int *value) +/* + return the Nth result message, waiting if necessary +*/ +NTSTATUS ldap_result_n(struct ldap_request *req, int n, struct ldap_message **msg) { - DATA_BLOB blob; - char *val; - int errno_save; - BOOL res; - - if (!ldap_find_single_value(msg, attr, &blob)) - return False; - - val = malloc(blob.length+1); - if (val == NULL) - return False; + *msg = NULL; - memcpy(val, blob.data, blob.length); - val[blob.length] = '\0'; - - errno_save = errno; - errno = 0; - - *value = strtol(val, NULL, 10); + while (req->state != LDAP_REQUEST_DONE && n >= req->num_replies) { + if (event_loop_once(req->conn->event.event_ctx) != 0) { + return NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + } - res = (errno == 0); + if (n < req->num_replies) { + *msg = req->replies[n]; + return NT_STATUS_OK; + } - free(val); - errno = errno_save; + if (!NT_STATUS_IS_OK(req->status)) { + return req->status; + } - return res; + return NT_STATUS_NO_MORE_ENTRIES; } -int ldap_error(struct ldap_connection *conn) -{ - return 0; -} -NTSTATUS ldap2nterror(int ldaperror) +/* + return a single result message, checking if it is of the expected LDAP type +*/ +NTSTATUS ldap_result_one(struct ldap_request *req, struct ldap_message **msg, int type) { - return NT_STATUS_OK; + NTSTATUS status; + status = ldap_result_n(req, 0, msg); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + if ((*msg)->type != type) { + *msg = NULL; + return NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + return status; } diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h new file mode 100644 index 0000000000..719c3639c1 --- /dev/null +++ b/source4/libcli/ldap/ldap_client.h @@ -0,0 +1,86 @@ +/* + Unix SMB/CIFS Implementation. + + ldap client side header + + Copyright (C) Andrew Tridgell 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. +*/ + + +enum ldap_request_state {LDAP_REQUEST_SEND, LDAP_REQUEST_PENDING, LDAP_REQUEST_DONE}; + +/* this is the handle that the caller gets when an async ldap message + is sent */ +struct ldap_request { + struct ldap_request *next, *prev; + struct ldap_connection *conn; + + enum ldap_request_tag type; + int messageid; + enum ldap_request_state state; + + int num_replies; + struct ldap_message **replies; + + NTSTATUS status; + DATA_BLOB data; + struct { + void (*fn)(struct ldap_request *); + void *private; + } async; +}; + + +/* main context for a ldap client connection */ +struct ldap_connection { + struct socket_context *sock; + char *host; + uint16_t port; + BOOL ldaps; + + const char *auth_dn; + const char *simple_pw; + + /* next message id to assign */ + unsigned next_messageid; + + /* outgoing send queue */ + struct ldap_request *send_queue; + + /* Outstanding LDAP requests that have not yet been replied to */ + struct ldap_request *pending; + + /* Let's support SASL */ + struct gensec_security *gensec; + + /* set if we are wrapping requests */ + BOOL enable_wrap; + + /* partially received packet */ + DATA_BLOB partial; + + /* the default timeout for messages */ + int timeout; + + /* last error message */ + char *last_error; + + struct { + struct event_context *event_ctx; + struct fd_event *fde; + } event; +}; diff --git a/source4/libcli/ldap/ldap_ldif.c b/source4/libcli/ldap/ldap_ldif.c deleted file mode 100644 index 55e902ecad..0000000000 --- a/source4/libcli/ldap/ldap_ldif.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - Unix SMB/CIFS mplementation. - LDAP protocol helper functions for SAMBA - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Volker Lendecke 2004 - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Simo Sorce 2004 - - 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/ldap/ldap.h" - -BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, - struct ldb_message_element *attrib) -{ - attrib->values = talloc_realloc(mem_ctx, - attrib->values, - DATA_BLOB, - attrib->num_values+1); - if (attrib->values == NULL) - return False; - - attrib->values[attrib->num_values] = - data_blob_talloc(mem_ctx, value->data, value->length); - attrib->num_values += 1; - return True; -} - -BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, - const struct ldb_message_element *attrib, - struct ldb_message_element **attribs, - int *num_attribs) -{ - *attribs = talloc_realloc(mem_ctx, - *attribs, - struct ldb_message_element, - *num_attribs+1); - - if (*attribs == NULL) - return False; - - (*attribs)[*num_attribs] = *attrib; - *num_attribs += 1; - return True; -} - -BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, - struct ldap_mod *mod, - struct ldap_mod **mods, - int *num_mods) -{ - *mods = talloc_realloc(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1); - - if (*mods == NULL) - return False; - - (*mods)[*num_mods] = *mod; - *num_mods += 1; - return True; -} - diff --git a/source4/libcli/ldap/ldap_msg.c b/source4/libcli/ldap/ldap_msg.c new file mode 100644 index 0000000000..5ac44a5226 --- /dev/null +++ b/source4/libcli/ldap/ldap_msg.c @@ -0,0 +1,84 @@ +/* + Unix SMB/CIFS mplementation. + + LDAP protocol helper functions for SAMBA + + Copyright (C) Andrew Tridgell 2005 + Copyright (C) Volker Lendecke 2004 + + 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 "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); +} + + +BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, + struct ldb_message_element *attrib) +{ + attrib->values = talloc_realloc(mem_ctx, + attrib->values, + DATA_BLOB, + attrib->num_values+1); + if (attrib->values == NULL) + return False; + + attrib->values[attrib->num_values] = + data_blob_talloc(mem_ctx, value->data, value->length); + attrib->num_values += 1; + return True; +} + +BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, + const struct ldb_message_element *attrib, + struct ldb_message_element **attribs, + int *num_attribs) +{ + *attribs = talloc_realloc(mem_ctx, + *attribs, + struct ldb_message_element, + *num_attribs+1); + + if (*attribs == NULL) + return False; + + (*attribs)[*num_attribs] = *attrib; + *num_attribs += 1; + return True; +} + +BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, + struct ldap_mod *mod, + struct ldap_mod **mods, + int *num_mods) +{ + *mods = talloc_realloc(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1); + + if (*mods == NULL) + return False; + + (*mods)[*num_mods] = *mod; + *num_mods += 1; + return True; +} + -- cgit From af237084ecd4f9928c6c282b9c5c73598d5c73d6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 16 Jun 2005 11:36:09 +0000 Subject: r7633: this patch started as an attempt to make the dcerpc code use a given event_context for the socket_connect() call, so that when things that use dcerpc are running alongside anything else it doesn't block the whole process during a connect. Then of course I needed to change any code that created a dcerpc connection (such as the auth code) to also take an event context, and anything that called that and so on .... thus the size of the patch. There were 3 places where I punted: - abartlet wanted me to add a gensec_set_event_context() call instead of adding it to the gensec init calls. Andrew, my apologies for not doing this. I didn't do it as adding a new parameter allowed me to catch all the callers with the compiler. Now that its done, we could go back and use gensec_set_event_context() - the ejs code calls auth initialisation, which means it should pass in the event context from the web server. I punted on that. Needs fixing. - I used a NULL event context in dcom_get_pipe(). This is equivalent to what we did already, but should be fixed to use a callers event context. Jelmer, can you think of a clean way to do that? I also cleaned up a couple of things: - libnet_context_destroy() makes no sense. I removed it. - removed some unused vars in various places (This used to be commit 3a3025485bdb8f600ab528c0b4b4eef0c65e3fc9) --- source4/libcli/ldap/ldap_bind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 11a6997fb2..ea97798261 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -144,7 +144,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr DATA_BLOB input = data_blob(NULL, 0); DATA_BLOB output = data_blob(NULL, 0); - status = gensec_client_start(conn, &conn->gensec); + status = gensec_client_start(conn, &conn->gensec, NULL); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); goto failed; -- cgit From ab1e121b76a953f89592df8ec471603715b57dfc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 17 Jun 2005 02:45:40 +0000 Subject: r7665: - added a ildap_*() interface to our internal ldap library. This interface is very similar to the traditional ldap interface, and will be used as part of a ldb backend based on the current ldb_ldap backend - fixed some allocation issues in ldb_msg.c (This used to be commit b34a29dcf26f68a2f47380a6c74a4095fdfd2fbe) --- source4/libcli/ldap/config.mk | 4 +- source4/libcli/ldap/ldap.h | 1 + source4/libcli/ldap/ldap_client.c | 25 +++++ source4/libcli/ldap/ldap_ildap.c | 209 ++++++++++++++++++++++++++++++++++++++ source4/libcli/ldap/ldap_msg.c | 4 +- 5 files changed, 241 insertions(+), 2 deletions(-) create mode 100644 source4/libcli/ldap/ldap_ildap.c (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index ca33581043..210fb112d3 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -5,6 +5,8 @@ ADD_OBJ_FILES = libcli/ldap/ldap.o \ libcli/ldap/ldap_client.o \ libcli/ldap/ldap_bind.o \ libcli/ldap/ldap_msg.o \ - libcli/ldap/ldap_ndr.o + libcli/ldap/ldap_ndr.o \ + libcli/ldap/ldap_ildap.o +REQUIRED_SUBSYSTEMS = LIBCLI_UTILS LIBBASIC LIBEVENTS GENSEC SOCKET RPC_NDR_SAMR # End SUBSYSTEM LIBCLI_LDAP ################################# diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 072070f723..4f2dbc0787 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -217,6 +217,7 @@ struct ldap_ExtendedResponse { }; union ldap_Request { + struct ldap_Result GeneralResult; struct ldap_BindRequest BindRequest; struct ldap_BindResponse BindResponse; struct ldap_UnbindRequest UnbindRequest; diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index f3a7f104d4..7ad45f4eea 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -573,6 +573,8 @@ NTSTATUS ldap_result_n(struct ldap_request *req, int n, struct ldap_message **ms { *msg = NULL; + NT_STATUS_HAVE_NO_MEMORY(req); + while (req->state != LDAP_REQUEST_DONE && n >= req->num_replies) { if (event_loop_once(req->conn->event.event_ctx) != 0) { return NT_STATUS_UNEXPECTED_NETWORK_ERROR; @@ -608,3 +610,26 @@ NTSTATUS ldap_result_one(struct ldap_request *req, struct ldap_message **msg, in } return status; } + +/* + a simple ldap transaction, for single result requests that only need a status code + this relies on single valued requests having the response type == request type + 1 +*/ +NTSTATUS ldap_transaction(struct ldap_connection *conn, struct ldap_message *msg) +{ + struct ldap_request *req = ldap_request_send(conn, msg); + struct ldap_message *res; + NTSTATUS status; + status = ldap_result_n(req, 0, &res); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return status; + } + if (res->type != msg->type + 1) { + talloc_free(req); + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + status = ldap_check_response(conn, &res->r.GeneralResult); + talloc_free(req); + return status; +} diff --git a/source4/libcli/ldap/ldap_ildap.c b/source4/libcli/ldap/ldap_ildap.c new file mode 100644 index 0000000000..cfcb79f64f --- /dev/null +++ b/source4/libcli/ldap/ldap_ildap.c @@ -0,0 +1,209 @@ +/* + Unix SMB/CIFS mplementation. + + ildap api - an api similar to the traditional ldap api + + Copyright (C) Andrew Tridgell 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 "libcli/ldap/ldap.h" +#include "libcli/ldap/ldap_client.h" + +/* + delete a record + */ +NTSTATUS ildap_delete(struct ldap_connection *conn, const char *dn) +{ + struct ldap_message *msg; + NTSTATUS status; + + msg = new_ldap_message(conn); + NT_STATUS_HAVE_NO_MEMORY(msg); + + msg->type = LDAP_TAG_DelRequest; + msg->r.DelRequest.dn = dn; + + status = ldap_transaction(conn, msg); + + talloc_free(msg); + + return status; +} + +/* + add a record + */ +NTSTATUS ildap_add(struct ldap_connection *conn, const char *dn, struct ldap_mod **mods) +{ + struct ldap_message *msg; + int n, i; + NTSTATUS status; + + msg = new_ldap_message(conn); + NT_STATUS_HAVE_NO_MEMORY(msg); + + for (n=0;mods[n];n++) /* noop */ ; + + msg->type = LDAP_TAG_AddRequest; + msg->r.AddRequest.dn = dn; + msg->r.AddRequest.num_attributes = n; + msg->r.AddRequest.attributes = talloc_array(msg, struct ldb_message_element, n); + if (msg->r.AddRequest.attributes == NULL) { + talloc_free(msg); + return NT_STATUS_NO_MEMORY; + } + for (i=0;ir.AddRequest.attributes[i] = mods[i]->attrib; + } + + status = ldap_transaction(conn, msg); + + talloc_free(msg); + + return status; +} + + +/* + modify a record + */ +NTSTATUS ildap_modify(struct ldap_connection *conn, const char *dn, struct ldap_mod **mods) +{ + struct ldap_message *msg; + int n, i; + NTSTATUS status; + + msg = new_ldap_message(conn); + NT_STATUS_HAVE_NO_MEMORY(msg); + + for (n=0;mods[n];n++) /* noop */ ; + + msg->type = LDAP_TAG_ModifyRequest; + msg->r.ModifyRequest.dn = dn; + msg->r.ModifyRequest.num_mods = n; + msg->r.ModifyRequest.mods = talloc_array(msg, struct ldap_mod, n); + if (msg->r.ModifyRequest.mods == NULL) { + talloc_free(msg); + return NT_STATUS_NO_MEMORY; + } + for (i=0;ir.ModifyRequest.mods[i] = *mods[i]; + } + + status = ldap_transaction(conn, msg); + + talloc_free(msg); + + return status; +} + + +/* + rename a record + */ +NTSTATUS ildap_rename(struct ldap_connection *conn, const char *dn, const char *newrdn, + const char *parentdn, BOOL deleteolddn) +{ + struct ldap_message *msg; + NTSTATUS status; + + msg = new_ldap_message(conn); + NT_STATUS_HAVE_NO_MEMORY(msg); + + msg->type = LDAP_TAG_ModifyDNRequest; + msg->r.ModifyDNRequest.dn = dn; + msg->r.ModifyDNRequest.newrdn = newrdn; + msg->r.ModifyDNRequest.deleteolddn = deleteolddn; + msg->r.ModifyDNRequest.newsuperior = parentdn; + + status = ldap_transaction(conn, msg); + + talloc_free(msg); + + return status; +} + + +/* + count the returned search entries +*/ +int ildap_count_entries(struct ldap_connection *conn, struct ldap_message **res) +{ + int i; + for (i=0;res && res[i];i++) /* noop */ ; + return i; +} + + +/* + perform a ldap search +*/ +NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn, + int scope, const char *expression, + const char * const *attrs, BOOL attributesonly, + struct ldap_message ***results) +{ + struct ldap_message *msg; + int n, i; + NTSTATUS status; + struct ldap_request *req; + + *results = NULL; + + msg = new_ldap_message(conn); + NT_STATUS_HAVE_NO_MEMORY(msg); + + for (n=0;attrs && attrs[n];n++) /* noop */ ; + + msg->type = LDAP_TAG_SearchRequest; + msg->r.SearchRequest.basedn = basedn; + msg->r.SearchRequest.scope = scope; + msg->r.SearchRequest.deref = LDAP_DEREFERENCE_NEVER; + msg->r.SearchRequest.timelimit = 0; + msg->r.SearchRequest.sizelimit = 0; + msg->r.SearchRequest.attributesonly = attributesonly; + msg->r.SearchRequest.tree = ldb_parse_tree(msg, expression); + msg->r.SearchRequest.num_attributes = n; + msg->r.SearchRequest.attributes = attrs; + + req = ldap_request_send(conn, msg); + talloc_steal(msg, req); + + for (i=n=0;True;i++) { + struct ldap_message *res; + status = ldap_result_n(req, i, &res); + if (!NT_STATUS_IS_OK(status)) break; + if (res->type != LDAP_TAG_SearchResultEntry) continue; + + (*results) = talloc_realloc(conn, *results, struct ldap_message *, n+2); + if (*results == NULL) { + talloc_free(msg); + return NT_STATUS_NO_MEMORY; + } + (*results)[n] = talloc_steal(*results, res); + (*results)[n+1] = NULL; + n++; + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) { + status = NT_STATUS_OK; + } + + return status; +} diff --git a/source4/libcli/ldap/ldap_msg.c b/source4/libcli/ldap/ldap_msg.c index 5ac44a5226..901c42a62a 100644 --- a/source4/libcli/ldap/ldap_msg.c +++ b/source4/libcli/ldap/ldap_msg.c @@ -44,7 +44,7 @@ BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, return False; attrib->values[attrib->num_values] = - data_blob_talloc(mem_ctx, value->data, value->length); + data_blob_talloc(attrib->values, value->data, value->length); attrib->num_values += 1; return True; } @@ -63,6 +63,8 @@ BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, return False; (*attribs)[*num_attribs] = *attrib; + talloc_steal(*attribs, attrib->values); + talloc_steal(*attribs, attrib->name); *num_attribs += 1; return True; } -- cgit From 56b79e945f1e28d1ba7296e44a9802c140b942ef Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Jun 2005 07:54:14 +0000 Subject: r7713: fixed error display in ildap_search() (This used to be commit abc9f4bd89d0eda655f7de01db49cbbb64682bf4) --- source4/libcli/ldap/ldap_ildap.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_ildap.c b/source4/libcli/ldap/ldap_ildap.c index cfcb79f64f..541797c25c 100644 --- a/source4/libcli/ldap/ldap_ildap.c +++ b/source4/libcli/ldap/ldap_ildap.c @@ -189,6 +189,12 @@ NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn, struct ldap_message *res; status = ldap_result_n(req, i, &res); if (!NT_STATUS_IS_OK(status)) break; + + if (res->type == LDAP_TAG_SearchResultDone) { + status = ldap_check_response(conn, &res->r.GeneralResult); + break; + } + if (res->type != LDAP_TAG_SearchResultEntry) continue; (*results) = talloc_realloc(conn, *results, struct ldap_message *, n+2); -- cgit From 90cf33953dcfab988162f9ee53cdc0eb6ff87c28 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Jun 2005 09:01:51 +0000 Subject: r7715: ensure we don't print null strings in ldap_errstr() (This used to be commit dc419fc89973c2d7fa333df389b75cb218e8a848) --- source4/libcli/ldap/ldap_client.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 7ad45f4eea..e392002a19 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -549,7 +549,9 @@ NTSTATUS ldap_check_response(struct ldap_connection *conn, struct ldap_Result *r } conn->last_error = talloc_asprintf(conn, "LDAP error %u - %s <%s> <%s>", r->resultcode, - r->dn, r->errormessage, r->referral); + r->dn?r->dn:"(NULL)", + r->errormessage?r->errormessage:"", + r->referral?r->referral:""); return NT_STATUS_LDAP(r->resultcode); } -- cgit From 1e99722d020f38eaad7fe2010f43c23586a19410 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Jun 2005 09:08:08 +0000 Subject: r7716: a single wrapped ldap blob can contain multiple ldap messages (This used to be commit de5f265b6c586335965a6de844c203206261cc3b) --- source4/libcli/ldap/ldap_client.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index e392002a19..bc70cd56aa 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -213,12 +213,12 @@ static void ldap_try_decode_wrapped(struct ldap_connection *conn) return; } - if (ldap_decode(&asn1, msg)) { + while (ldap_decode(&asn1, msg)) { ldap_match_message(conn, msg); - } else { - talloc_free(msg); + msg = talloc(conn, struct ldap_message); } + talloc_free(msg); asn1_free(&asn1); if (conn->partial.length == len + 4) { -- cgit From ca91a8a6919b9bc1b6016310c6b30447723b08d6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Jun 2005 09:09:27 +0000 Subject: r7717: fixed some typos (This used to be commit fc8feee56034fe165359c804d111f80e5b3ebb65) --- source4/libcli/ldap/ldap_bind.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index ea97798261..7e4fa10fe4 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -154,28 +154,28 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr status = gensec_set_credentials(conn->gensec, creds); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC creds: %s\n", + DEBUG(1, ("Failed to set GENSEC creds: %s\n", nt_errstr(status))); goto failed; } status = gensec_set_target_hostname(conn->gensec, conn->host); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", + DEBUG(1, ("Failed to set GENSEC target hostname: %s\n", nt_errstr(status))); goto failed; } status = gensec_set_target_service(conn->gensec, "ldap"); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC target service: %s\n", + DEBUG(1, ("Failed to set GENSEC target service: %s\n", nt_errstr(status))); goto failed; } status = gensec_start_mech_by_sasl_name(conn->gensec, "NTLM"); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism: %s\n", + DEBUG(1, ("Failed to set GENSEC client SPNEGO mechanism: %s\n", nt_errstr(status))); goto failed; } -- cgit From b4eee348c4d36e67ba83651c250366e84e7125dd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Jun 2005 10:38:06 +0000 Subject: r7720: - simplify the asn1 decode of ldap_search() a lot, taking advantage of the fact that the ldap data structures now use ldb_message_element. - fixed null termination of elements in ildap (This used to be commit 09060994c1ed12073ae6e1131d7074db8fdc523c) --- source4/libcli/ldap/ldap.c | 4 +++- source4/libcli/ldap/ldap_msg.c | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index c642fc3e4b..83858b1768 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -98,6 +98,9 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree asn1_pop_tag(data); break; + case LDB_OP_NOT: + #warning "OP_NOT missing" + default: return False; } @@ -605,7 +608,6 @@ static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, DATA_BLOB blob; asn1_read_OctetString(data, &blob); add_value_to_attrib(mem_ctx, &blob, attrib); - data_blob_free(&blob); } asn1_end_tag(data); asn1_end_tag(data); diff --git a/source4/libcli/ldap/ldap_msg.c b/source4/libcli/ldap/ldap_msg.c index 901c42a62a..9b531f3138 100644 --- a/source4/libcli/ldap/ldap_msg.c +++ b/source4/libcli/ldap/ldap_msg.c @@ -43,8 +43,9 @@ BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, if (attrib->values == NULL) return False; - attrib->values[attrib->num_values] = - data_blob_talloc(attrib->values, value->data, value->length); + attrib->values[attrib->num_values].data = talloc_steal(attrib->values, + value->data); + attrib->values[attrib->num_values].length = value->length; attrib->num_values += 1; return True; } -- cgit From 91a79f2b24b62d9b78ecb52ff593672acc6f971a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Jun 2005 12:44:36 +0000 Subject: r7722: when we get a zero read, the connection is dead (This used to be commit 060323530454edf21b217550b373513e5860146c) --- source4/libcli/ldap/ldap_client.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index bc70cd56aa..f2b09e89e3 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -243,8 +243,7 @@ static void ldap_recv_handler(struct ldap_connection *conn) /* work out how much data is pending */ status = socket_pending(conn->sock, &npending); if (!NT_STATUS_IS_OK(status) || npending == 0) { - DEBUG(0,("ldap_recv_handler - pending=%d - %s\n", - (int)npending, nt_errstr(status))); + ldap_connection_dead(conn); return; } -- cgit From 2a0a0f2551b03e4792cab37455b094d21819dc87 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Jun 2005 12:45:28 +0000 Subject: r7723: - fix a mismatched asn1 push/pop on bind - add error checking to ldap_encode() - fixed the asn1 codes for extended search - use asn1 context macros (This used to be commit 25d500b6e559b9a530ae65a21046cfde0f8c41af) --- source4/libcli/ldap/ldap.c | 55 ++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 29 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 83858b1768..81e659d3e8 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -38,7 +38,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree if ((tree->u.simple.value.length == 1) && (((char *)(tree->u.simple.value.data))[0] == '*')) { /* Just a presence test */ - asn1_push_tag(data, 0x87); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7)); asn1_write(data, tree->u.simple.attr, strlen(tree->u.simple.attr)); asn1_pop_tag(data); @@ -46,7 +46,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree } /* equality test */ - asn1_push_tag(data, 0xa3); + asn1_push_tag(data, ASN1_CONTEXT(3)); asn1_write_OctetString(data, tree->u.simple.attr, strlen(tree->u.simple.attr)); asn1_write_OctetString(data, tree->u.simple.value.data, @@ -63,37 +63,34 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree dnAttributes [4] BOOLEAN DEFAULT FALSE } */ - asn1_push_tag(data, 0xa9); + asn1_push_tag(data, ASN1_CONTEXT(9)); if (tree->u.extended.rule_id) { - asn1_push_tag(data, 1); - asn1_write_OctetString(data, tree->u.extended.rule_id, - strlen(tree->u.extended.rule_id)); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); + asn1_write_LDAPString(data, tree->u.extended.rule_id); asn1_pop_tag(data); } if (tree->u.extended.attr) { - asn1_push_tag(data, 2); - asn1_write_OctetString(data, tree->u.extended.attr, - strlen(tree->u.extended.attr)); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(2)); + asn1_write_LDAPString(data, tree->u.extended.attr); asn1_pop_tag(data); } - asn1_push_tag(data, 3); - asn1_write_OctetString(data, tree->u.extended.value.data, - tree->u.extended.value.length); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3)); + asn1_write_LDAPString(data, tree->u.extended.value.data); + asn1_pop_tag(data); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4)); + asn1_write_uint8(data, tree->u.extended.dnAttributes); asn1_pop_tag(data); - if (tree->u.extended.dnAttributes) { - asn1_push_tag(data, 4); - asn1_write_BOOLEAN(data, True); - asn1_pop_tag(data); - } asn1_pop_tag(data); break; case LDB_OP_AND: case LDB_OP_OR: - asn1_push_tag(data, 0xa0 | (tree->operation==LDB_OP_AND?0:1)); + asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1)); for (i=0; iu.list.num_elements; i++) { - ldap_push_filter(data, tree->u.list.elements[i]); + if (!ldap_push_filter(data, tree->u.list.elements[i])) { + return False; + } } asn1_pop_tag(data); break; @@ -161,7 +158,6 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) return False; } - asn1_pop_tag(&data); asn1_pop_tag(&data); break; } @@ -187,7 +183,9 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) asn1_write_Integer(&data, r->timelimit); asn1_write_BOOLEAN(&data, r->attributesonly); - ldap_push_filter(&data, r->tree); + if (!ldap_push_filter(&data, r->tree)) { + return False; + } asn1_push_tag(&data, ASN1_SEQUENCE(0)); for (i=0; inum_attributes; i++) { @@ -389,6 +387,12 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) } asn1_pop_tag(&data); + + if (data.has_error) { + asn1_free(&data); + return False; + } + *result = data_blob(data.data, data.length); asn1_free(&data); return True; @@ -438,16 +442,14 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, struct asn1_data *data) { - uint8_t filter_tag, tag_desc; + uint8_t filter_tag; struct ldb_parse_tree *ret; if (!asn1_peek_uint8(data, &filter_tag)) { return NULL; } - tag_desc = filter_tag; filter_tag &= 0x1f; /* strip off the asn1 stuff */ - tag_desc &= 0xe0; ret = talloc(mem_ctx, struct ldb_parse_tree); if (ret == NULL) return NULL; @@ -460,11 +462,6 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, ret->u.list.num_elements = 0; ret->u.list.elements = NULL; - if (tag_desc != 0xa0) { - /* context compount */ - goto failed; - } - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { goto failed; } -- cgit From be19641f30f9a13a38dd08216e1fd22aaaffa9bd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Jun 2005 12:48:42 +0000 Subject: r7724: added encoding of LDB_OP_NOT search components (This used to be commit 82b1feeafea57ca1b8d7bf79f777eebcc703769c) --- source4/libcli/ldap/ldap.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 81e659d3e8..2514e10117 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -96,7 +96,12 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree break; case LDB_OP_NOT: - #warning "OP_NOT missing" + asn1_push_tag(data, ASN1_CONTEXT(2)); + if (!ldap_push_filter(data, tree->u.not.child)) { + return False; + } + asn1_pop_tag(data); + break; default: return False; -- cgit From e2bb0d0ba75265101cefd7325d705a7bf63ec585 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Jun 2005 13:15:09 +0000 Subject: r7725: fixed a bug with partial asn1 frames in the ldap client (This used to be commit 0f22306a9c61c1b00aeb0f3bf7e875d9b7b4606d) --- source4/libcli/ldap/ldap_client.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index f2b09e89e3..41764b9a37 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -156,6 +156,8 @@ static void ldap_try_decode_plain(struct ldap_connection *conn) /* try and decode - this will fail if we don't have a full packet yet */ while (asn1.ofs < asn1.length) { struct ldap_message *msg = talloc(conn, struct ldap_message); + off_t saved_ofs = asn1.ofs; + if (msg == NULL) { ldap_connection_dead(conn); return; @@ -164,6 +166,7 @@ static void ldap_try_decode_plain(struct ldap_connection *conn) if (ldap_decode(&asn1, msg)) { ldap_match_message(conn, msg); } else { + asn1.ofs = saved_ofs; talloc_free(msg); break; } -- cgit From c7496c6cdb7bdcdd483868c21457350f567ec054 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 19 Jun 2005 09:31:34 +0000 Subject: r7747: - simplified the ldap server buffer handling - got rid of the special cases for sasl buffers - added a tls_socket_pending() call to determine how much data is waiting on a tls connection - removed the attempt at async handling of ldap calls. The buffers/sockets are all async, but the calls themselves are sync. (This used to be commit 73cb4aad229d08e17e22d5792580bd43a61b142a) --- source4/libcli/ldap/ldap_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 41764b9a37..c9915ae140 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -174,7 +174,7 @@ static void ldap_try_decode_plain(struct ldap_connection *conn) /* keep any remaining data in conn->partial */ data_blob_free(&conn->partial); - if (asn1.ofs != conn->partial.length) { + if (asn1.ofs != asn1.length) { conn->partial = data_blob_talloc(conn, asn1.data + asn1.ofs, asn1.length - asn1.ofs); -- cgit From 7267cb3312f148be8cd00eb76b8e137cd4b2a314 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 19 Jun 2005 10:37:45 +0000 Subject: r7749: some bug fixes from testing with socket:testnonblock - fixed some infinite loops in asn1.c - ensure asn1 callers know if an error is end of buffer or bad data - handle npending 0 in ldap server (This used to be commit f22c3b84c8912ccd36e676a782b58f1841be8875) --- source4/libcli/ldap/ldap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 2514e10117..d7a230a77f 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -501,7 +501,9 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, ret->operation = LDB_OP_NOT; ret->u.not.child = ldap_decode_filter_tree(ret, data); - + if (ret->u.not.child == NULL) { + goto failed; + } if (!asn1_end_tag(data)) { goto failed; } @@ -595,7 +597,6 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, failed: talloc_free(ret); - DEBUG(0,("Failed to parse ASN.1 LDAP filter\n")); return NULL; } -- cgit From a40d966ff592436be7014c8a83144c0a5901c1fb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 19 Jun 2005 22:29:40 +0000 Subject: r7763: fixed some circular dependencies (This used to be commit 3bdf89b0f7521ca39d48dc4c32fe96971d4d60fd) --- source4/libcli/ldap/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 210fb112d3..93665c5152 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -7,6 +7,6 @@ ADD_OBJ_FILES = libcli/ldap/ldap.o \ libcli/ldap/ldap_msg.o \ libcli/ldap/ldap_ndr.o \ libcli/ldap/ldap_ildap.o -REQUIRED_SUBSYSTEMS = LIBCLI_UTILS LIBBASIC LIBEVENTS GENSEC SOCKET RPC_NDR_SAMR +REQUIRED_SUBSYSTEMS = LIBCLI_UTILS LIBEVENTS GENSEC SOCKET RPC_NDR_SAMR # End SUBSYSTEM LIBCLI_LDAP ################################# -- cgit From 5eccf719fba324e9f1ce4a5b425b29a25125d4f1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 20 Jun 2005 01:17:29 +0000 Subject: r7770: added ldaps support to our ldap client library (This used to be commit 8f5c2e8682795258a6361b9516a38a8fabdef150) --- source4/libcli/ldap/config.mk | 2 +- source4/libcli/ldap/ldap_client.c | 25 +++++++++++++++++-------- source4/libcli/ldap/ldap_client.h | 1 + 3 files changed, 19 insertions(+), 9 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 93665c5152..a92e733493 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -7,6 +7,6 @@ ADD_OBJ_FILES = libcli/ldap/ldap.o \ libcli/ldap/ldap_msg.o \ libcli/ldap/ldap_ndr.o \ libcli/ldap/ldap_ildap.o -REQUIRED_SUBSYSTEMS = LIBCLI_UTILS LIBEVENTS GENSEC SOCKET RPC_NDR_SAMR +REQUIRED_SUBSYSTEMS = LIBCLI_UTILS LIBEVENTS GENSEC SOCKET RPC_NDR_SAMR LIBTLS # End SUBSYSTEM LIBCLI_LDAP ################################# diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index c9915ae140..32bd6656d6 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 "lib/tls/tls.h" #include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" @@ -90,8 +91,8 @@ static void ldap_connection_dead(struct ldap_connection *conn) } } - talloc_free(conn->sock); - conn->sock = NULL; + talloc_free(conn->tls); + conn->tls = NULL; } @@ -244,7 +245,7 @@ static void ldap_recv_handler(struct ldap_connection *conn) size_t npending=0, nread; /* work out how much data is pending */ - status = socket_pending(conn->sock, &npending); + status = tls_socket_pending(conn->tls, &npending); if (!NT_STATUS_IS_OK(status) || npending == 0) { ldap_connection_dead(conn); return; @@ -258,8 +259,8 @@ static void ldap_recv_handler(struct ldap_connection *conn) } /* receive the pending data */ - status = socket_recv(conn->sock, conn->partial.data + conn->partial.length, - npending, &nread, 0); + status = tls_socket_recv(conn->tls, conn->partial.data + conn->partial.length, + npending, &nread); if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { return; } @@ -288,7 +289,7 @@ static void ldap_send_handler(struct ldap_connection *conn) size_t nsent; NTSTATUS status; - status = socket_send(conn->sock, &req->data, &nsent, 0); + status = tls_socket_send(conn->tls, &req->data, &nsent); if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { break; } @@ -331,7 +332,7 @@ static void ldap_io_handler(struct event_context *ev, struct fd_event *fde, struct ldap_connection *conn = talloc_get_type(private, struct ldap_connection); if (flags & EVENT_FD_WRITE) { ldap_send_handler(conn); - if (conn->sock == NULL) return; + if (conn->tls == NULL) return; } if (flags & EVENT_FD_READ) { ldap_recv_handler(conn); @@ -416,6 +417,14 @@ NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url) return NT_STATUS_INTERNAL_ERROR; } + conn->tls = tls_init_client(conn->sock, conn->event.fde, conn->ldaps); + if (conn->tls == NULL) { + talloc_free(conn->sock); + return NT_STATUS_INTERNAL_ERROR; + } + talloc_steal(conn, conn->tls); + talloc_steal(conn->tls, conn->sock); + return NT_STATUS_OK; } @@ -460,7 +469,7 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, { struct ldap_request *req; - if (conn->sock == NULL) { + if (conn->tls == NULL) { return NULL; } diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h index 719c3639c1..b61f765b40 100644 --- a/source4/libcli/ldap/ldap_client.h +++ b/source4/libcli/ldap/ldap_client.h @@ -47,6 +47,7 @@ struct ldap_request { /* main context for a ldap client connection */ struct ldap_connection { + struct tls_context *tls; struct socket_context *sock; char *host; uint16_t port; -- cgit From bec00581247c9062ea0acce6037ef75ab188548c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 21 Jun 2005 13:42:47 +0000 Subject: r7810: don't give errors when the ldap server sends us reference replies (This used to be commit f2b2d2626f5eb4fbd7d7c5cdcde486d00fc19447) --- source4/libcli/ldap/ldap_client.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 32bd6656d6..a8463f7872 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -130,7 +130,8 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message req->replies[req->num_replies] = talloc_steal(req->replies, msg); req->num_replies++; - if (msg->type != LDAP_TAG_SearchResultEntry) { + if (msg->type != LDAP_TAG_SearchResultEntry && + msg->type != LDAP_TAG_SearchResultReference) { /* currently only search results expect multiple replies */ req->state = LDAP_REQUEST_DONE; -- cgit From acd04c9281252f4fe47c7127da13ea25be703c7c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 24 Jun 2005 00:03:47 +0000 Subject: r7855: fixed a typo (This used to be commit a1155651e722e28496be02b729c950afae5db9a9) --- source4/libcli/ldap/ldap_bind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 7e4fa10fe4..e70a56779b 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -234,7 +234,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr } if (NT_STATUS_IS_OK(status) && - (gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) || + (gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL) || gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN))) { conn->enable_wrap = True; } -- cgit From bdee131f30e1bef31498b08bb648ddee35ea4892 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 24 Jun 2005 00:18:20 +0000 Subject: r7860: switch our ldb storage format to use a NDR encoded objectSid. This is quite a large change as we had lots of code that assumed that objectSid was a string in S- format. metze and simo tried to convince me to use NDR format months ago, but I didn't listen, so its fair that I have the pain of fixing all the code now :-) This builds on the ldb_register_samba_handlers() and ldif handlers code I did earlier this week. There are still three parts of this conversion I have not finished: - the ltdb index records need to use the string form of the objectSid (to keep the DNs sane). Until that it done I have disabled indexing on objectSid, which is a big performance hit, but allows us to pass all our tests while I rejig the indexing system to use a externally supplied conversion function - I haven't yet put in place the code that allows client to use the "S-xxx-yyy" form for objectSid in ldap search expressions. w2k3 supports this, presumably by looking for the "S-" prefix to determine what type of objectSid form is being used by the client. I have been working on ways to handle this, but am not happy with them yet so they aren't part of this patch - I need to change pidl to generate push functions that take a "const void *" instead of a "void*" for the data pointer. That will fix the couple of new warnings this code generates. Luckily it many places the conversion to NDR formatted records actually simplified the code, as it means we no longer need as many calls to dom_sid_parse_talloc(). In some places it got more complex, but not many. (This used to be commit d40bc2fa8ddd43560315688eebdbe98bdd02756c) --- source4/libcli/ldap/ldap_ndr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index 88ca1ece77..f490b9983d 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -41,7 +41,7 @@ const char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value) /* encode a NDR dom_sid as a ldap filter element */ -const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, struct dom_sid *sid) +const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) { DATA_BLOB blob; NTSTATUS status; -- cgit From 52bef30fd48393fa7b24ade7622c758373bd6dbe Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 13 Jul 2005 05:55:28 +0000 Subject: r8414: Some C++ friendlyness fixes - 'not' is apparently a keyword in C++. (This used to be commit bcfb3a45e4a5962fe763f8071d4458f4bd11605b) --- source4/libcli/ldap/ldap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index d7a230a77f..5a45e6524e 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -97,7 +97,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree case LDB_OP_NOT: asn1_push_tag(data, ASN1_CONTEXT(2)); - if (!ldap_push_filter(data, tree->u.not.child)) { + if (!ldap_push_filter(data, tree->u.isnot.child)) { return False; } asn1_pop_tag(data); @@ -500,8 +500,8 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, } ret->operation = LDB_OP_NOT; - ret->u.not.child = ldap_decode_filter_tree(ret, data); - if (ret->u.not.child == NULL) { + ret->u.isnot.child = ldap_decode_filter_tree(ret, data); + if (ret->u.isnot.child == NULL) { goto failed; } if (!asn1_end_tag(data)) { -- cgit From 039393d6620816789b4ebd131974b23b6420f4dc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 17 Jul 2005 10:52:31 +0000 Subject: r8523: match a zero message id in ldap replies to the last request sent. Thanks to simo for noticing that this is needed to catch the server sending a "can't decode request" error reply (This used to be commit 6e81e866dc7a5dc014d2d9f2e09803c6adfd1830) --- source4/libcli/ldap/ldap_client.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index a8463f7872..97b75602aa 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -106,6 +106,11 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message for (req=conn->pending; req; req=req->next) { if (req->messageid == msg->messageid) break; } + /* match a zero message id to the last request sent. + It seems that servers send 0 if unable to parse */ + if (req == NULL && msg->messageid == 0) { + req = conn->pending; + } if (req == NULL) { DEBUG(0,("ldap: no matching message id for %u\n", msg->messageid)); @@ -480,6 +485,9 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, req->state = LDAP_REQUEST_SEND; req->conn = conn; req->messageid = conn->next_messageid++; + if (conn->next_messageid == 0) { + conn->next_messageid = 1; + } req->type = msg->type; if (req->messageid == -1) { goto failed; -- cgit From f4576157edab9d3e39a88342312fc42ba6e59469 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 17 Jul 2005 14:16:41 +0000 Subject: r8530: Now our ldap server is able to fullfill present and substring searches (This used to be commit a910671bd8c6d2d8d5b6ff30fc07ead244e696f1) --- source4/libcli/ldap/ldap.c | 220 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 184 insertions(+), 36 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 5a45e6524e..b5e142ff6c 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -34,17 +34,26 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree int i; switch (tree->operation) { - case LDB_OP_SIMPLE: - if ((tree->u.simple.value.length == 1) && - (((char *)(tree->u.simple.value.data))[0] == '*')) { - /* Just a presence test */ - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7)); - asn1_write(data, tree->u.simple.attr, - strlen(tree->u.simple.attr)); - asn1_pop_tag(data); - return !data->has_error; + case LDB_OP_AND: + case LDB_OP_OR: + asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1)); + for (i=0; iu.list.num_elements; i++) { + if (!ldap_push_filter(data, tree->u.list.elements[i])) { + return False; + } } + asn1_pop_tag(data); + break; + case LDB_OP_NOT: + asn1_push_tag(data, ASN1_CONTEXT(2)); + if (!ldap_push_filter(data, tree->u.isnot.child)) { + return False; + } + asn1_pop_tag(data); + break; + + case LDB_OP_SIMPLE: /* equality test */ asn1_push_tag(data, ASN1_CONTEXT(3)); asn1_write_OctetString(data, tree->u.simple.attr, @@ -54,6 +63,51 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree asn1_pop_tag(data); break; + case LDB_OP_SUBSTRING: + /* + SubstringFilter ::= SEQUENCE { + type AttributeDescription, + -- at least one must be present + substrings SEQUENCE OF CHOICE { + initial [0] LDAPString, + any [1] LDAPString, + final [2] LDAPString } } + */ + asn1_push_tag(data, ASN1_CONTEXT(4)); + asn1_write_OctetString(data, tree->u.substring.attr, strlen(tree->u.substring.attr)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + i = 0; + if ( ! tree->u.substring.start_with_wildcard) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write_LDAPString(data, tree->u.substring.chunks[i]->data); + asn1_pop_tag(data); + i++; + } + while (tree->u.substring.chunks[i]) { + int ctx; + + if (( ! tree->u.substring.chunks[i + 1]) && + (tree->u.substring.end_with_wildcard == 0)) { + ctx = 2; + } else { + ctx = 1; + } + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(ctx)); + asn1_write_LDAPString(data, tree->u.substring.chunks[i]->data); + asn1_pop_tag(data); + i++; + } + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + + case LDB_OP_PRESENT: + /* present test */ + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7)); + asn1_write_LDAPString(data, tree->u.present.attr); + asn1_pop_tag(data); + return !data->has_error; + case LDB_OP_EXTENDED: /* MatchingRuleAssertion ::= SEQUENCE { @@ -82,26 +136,6 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree asn1_pop_tag(data); asn1_pop_tag(data); break; - - - case LDB_OP_AND: - case LDB_OP_OR: - asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1)); - for (i=0; iu.list.num_elements; i++) { - if (!ldap_push_filter(data, tree->u.list.elements[i])) { - return False; - } - } - asn1_pop_tag(data); - break; - - case LDB_OP_NOT: - asn1_push_tag(data, ASN1_CONTEXT(2)); - if (!ldap_push_filter(data, tree->u.isnot.child)) { - return False; - } - asn1_pop_tag(data); - break; default: return False; @@ -440,6 +474,30 @@ static void ldap_decode_response(TALLOC_CTX *mem_ctx, } } +static struct ldb_val **ldap_decode_substring(TALLOC_CTX *mem_ctx, struct ldb_val **chunks, int chunk_num, char *value) +{ + + chunks = talloc_realloc(mem_ctx, chunks, struct ldb_val *, chunk_num + 2); + if (chunks == NULL) { + return NULL; + } + + chunks[chunk_num] = talloc(mem_ctx, struct ldb_val); + if (chunks[chunk_num] == NULL) { + return NULL; + } + + chunks[chunk_num]->data = talloc_strdup(mem_ctx, value); + if (chunks[chunk_num]->data == NULL) { + return NULL; + } + chunks[chunk_num]->length = strlen(value) + 1; + + chunks[chunk_num + 1] = NULL; + + return chunks; +} + /* parse the ASN.1 formatted search string into a ldb_parse_tree @@ -528,6 +586,100 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, ret->u.simple.value.length = value.length; break; } + case 4: { + /* substrings */ + DATA_BLOB attr; + uint8_t subs_tag; + char *value; + int chunk_num = 0; + + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } + if (!asn1_read_OctetString(data, &attr)) { + goto failed; + } + + ret->operation = LDB_OP_SUBSTRING; + ret->u.substring.attr = talloc_memdup(ret, attr.data, attr.length + 1); + ret->u.substring.attr[attr.length] = '\0'; + ret->u.substring.chunks = NULL; + ret->u.substring.start_with_wildcard = 1; + ret->u.substring.end_with_wildcard = 1; + + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { + goto failed; + } + + while (asn1_tag_remaining(data)) { + asn1_peek_uint8(data, &subs_tag); + subs_tag &= 0x1f; /* strip off the asn1 stuff */ + if (subs_tag > 2) goto failed; + + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(subs_tag)); + asn1_read_LDAPString(data, &value); + asn1_end_tag(data); + + switch (subs_tag) { + case 0: + if (ret->u.substring.chunks != NULL) { + /* initial value found in the middle */ + goto failed; + } + + ret->u.substring.chunks = ldap_decode_substring(ret, NULL, 0, value); + if (ret->u.substring.chunks == NULL) { + goto failed; + } + + ret->u.substring.start_with_wildcard = 0; + chunk_num = 1; + break; + + case 1: + if (ret->u.substring.end_with_wildcard == 0) { + /* "any" value found after a "final" value */ + goto failed; + } + + ret->u.substring.chunks = ldap_decode_substring(ret, + ret->u.substring.chunks, + chunk_num, + value); + if (ret->u.substring.chunks == NULL) { + goto failed; + } + + chunk_num++; + break; + + case 2: + ret->u.substring.chunks = ldap_decode_substring(ret, + ret->u.substring.chunks, + chunk_num, + value); + if (ret->u.substring.chunks == NULL) { + goto failed; + } + + ret->u.substring.end_with_wildcard = 0; + break; + + default: + goto failed; + } + + } + + if (!asn1_end_tag(data)) { /* SEQUENCE */ + goto failed; + } + + if (!asn1_end_tag(data)) { + goto failed; + } + break; + } case 7: { /* Normal presence, "attribute=*" */ char *attr; @@ -539,13 +691,9 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, goto failed; } - ret->operation = LDB_OP_SIMPLE; - ret->u.simple.attr = talloc_steal(ret, attr); - ret->u.simple.value.data = talloc_strdup(ret, "*"); - if (ret->u.simple.value.data == NULL) { - goto failed; - } - ret->u.simple.value.length = 1; + ret->operation = LDB_OP_PRESENT; + ret->u.present.attr = talloc_steal(ret, attr); + if (!asn1_end_tag(data)) { goto failed; } -- cgit From bfb11862698743ee36bc6050269378321e6e577c Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 19 Jul 2005 09:09:00 +0000 Subject: r8585: add to ldb and ldap comparison functionality better pares filters Approx is currently only a stub need to dig more info to understand what it really means and how it works exactly (This used to be commit a9e8cd0bad27ed2b3c6a12302e787ba3c9a70a3c) --- source4/libcli/ldap/ldap.c | 105 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 96 insertions(+), 9 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index b5e142ff6c..b71c4a6dff 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -53,13 +53,13 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree asn1_pop_tag(data); break; - case LDB_OP_SIMPLE: + case LDB_OP_EQUALITY: /* equality test */ asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, tree->u.simple.attr, - strlen(tree->u.simple.attr)); - asn1_write_OctetString(data, tree->u.simple.value.data, - tree->u.simple.value.length); + asn1_write_OctetString(data, tree->u.equality.attr, + strlen(tree->u.equality.attr)); + asn1_write_OctetString(data, tree->u.equality.value.data, + tree->u.equality.value.length); asn1_pop_tag(data); break; @@ -101,6 +101,26 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree asn1_pop_tag(data); break; + case LDB_OP_GREATER: + /* greaterOrEqual test */ + asn1_push_tag(data, ASN1_CONTEXT(5)); + asn1_write_OctetString(data, tree->u.comparison.attr, + strlen(tree->u.comparison.attr)); + asn1_write_OctetString(data, tree->u.comparison.value.data, + tree->u.comparison.value.length); + asn1_pop_tag(data); + break; + + case LDB_OP_LESS: + /* lessOrEqual test */ + asn1_push_tag(data, ASN1_CONTEXT(6)); + asn1_write_OctetString(data, tree->u.comparison.attr, + strlen(tree->u.comparison.attr)); + asn1_write_OctetString(data, tree->u.comparison.value.data, + tree->u.comparison.value.length); + asn1_pop_tag(data); + break; + case LDB_OP_PRESENT: /* present test */ asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7)); @@ -108,6 +128,16 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree asn1_pop_tag(data); return !data->has_error; + case LDB_OP_APPROX: + /* approx test */ + asn1_push_tag(data, ASN1_CONTEXT(8)); + asn1_write_OctetString(data, tree->u.comparison.attr, + strlen(tree->u.comparison.attr)); + asn1_write_OctetString(data, tree->u.comparison.value.data, + tree->u.comparison.value.length); + asn1_pop_tag(data); + break; + case LDB_OP_EXTENDED: /* MatchingRuleAssertion ::= SEQUENCE { @@ -580,10 +610,10 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, goto failed; } - ret->operation = LDB_OP_SIMPLE; - ret->u.simple.attr = talloc_steal(ret, attrib); - ret->u.simple.value.data = talloc_steal(ret, value.data); - ret->u.simple.value.length = value.length; + ret->operation = LDB_OP_EQUALITY; + ret->u.equality.attr = talloc_steal(ret, attrib); + ret->u.equality.value.data = talloc_steal(ret, value.data); + ret->u.equality.value.length = value.length; break; } case 4: { @@ -680,6 +710,44 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, } break; } + case 5: { + /* greaterOrEqual */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_GREATER; + ret->u.comparison.attr = talloc_steal(ret, attrib); + ret->u.comparison.value.data = talloc_steal(ret, value.data); + ret->u.comparison.value.length = value.length; + break; + } + case 6: { + /* lessOrEqual */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_LESS; + ret->u.comparison.attr = talloc_steal(ret, attrib); + ret->u.comparison.value.data = talloc_steal(ret, value.data); + ret->u.comparison.value.length = value.length; + break; + } case 7: { /* Normal presence, "attribute=*" */ char *attr; @@ -699,6 +767,25 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, } break; } + case 8: { + /* approx */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_APPROX; + ret->u.comparison.attr = talloc_steal(ret, attrib); + ret->u.comparison.value.data = talloc_steal(ret, value.data); + ret->u.comparison.value.length = value.length; + break; + } case 9: { char *oid, *attr, *value; uint8_t dnAttributes; -- cgit From 6553dd0c60e922f42de347a02c8f792f087c393c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 28 Jul 2005 00:27:28 +0000 Subject: r8811: Fix the build.. (This used to be commit fac77f5fa267da57a55e88cad8993897e80741a0) --- source4/libcli/ldap/ldap_ndr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index f490b9983d..bc19e49535 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -24,6 +24,7 @@ #include "includes.h" #include "libcli/ldap/ldap.h" #include "librpc/gen_ndr/ndr_security.h" +#include "librpc/gen_ndr/ndr_misc.h" /* encode a NDR uint32 as a ldap filter element -- cgit From f297f82398d77e5d2fe5faf5de8b581ad5a6acd1 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 2 Aug 2005 14:04:22 +0000 Subject: r8917: Better support for extended ldap search operations Try to follow the RFC where possible and adapt to openLdap and AD way of handling this structure (This used to be commit d844d45d87b4114bc1b9af2e40f8c27ba3e219de) --- source4/libcli/ldap/ldap.c | 66 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 17 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index b71c4a6dff..f7f6feea38 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -787,36 +787,68 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, break; } case 9: { - char *oid, *attr, *value; + char *oid = NULL, *attr = NULL, *value; uint8_t dnAttributes; /* an extended search */ if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { goto failed; } - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1)); - asn1_read_LDAPString(data, &oid); - asn1_end_tag(data); - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2)); - asn1_read_LDAPString(data, &attr); - asn1_end_tag(data); + /* FIXME: read carefully rfc2251.txt there are a number of 'MUST's + we need to check we properly implement --SSS */ + /* either oid or type must be defined */ + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { /* optional */ + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1)); + asn1_read_LDAPString(data, &oid); + asn1_end_tag(data); + } + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(2))) { /* optional */ + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2)); + asn1_read_LDAPString(data, &attr); + asn1_end_tag(data); + } asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(3)); asn1_read_LDAPString(data, &value); asn1_end_tag(data); - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(4)); - asn1_read_uint8(data, &dnAttributes); - asn1_end_tag(data); - if ((data->has_error) || (oid == NULL) || (value == NULL)) { + /* dnAttributes is marked as BOOLEAN DEFAULT FALSE + it is not marked as OPTIONAL but openldap tools + do not set this unless it is to be set as TRUE + NOTE: openldap tools do not work with AD as it + seems that AD always requires the dnAttributes + boolean value to be set */ + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(4))) { + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(4)); + asn1_read_uint8(data, &dnAttributes); + asn1_end_tag(data); + } else { + dnAttributes = 0; + } + if ((oid == NULL && attr == NULL) || (value == NULL)) { goto failed; } - ret->operation = LDB_OP_EXTENDED; - ret->u.extended.attr = talloc_steal(ret, attr); - ret->u.extended.rule_id = talloc_steal(ret, oid); - ret->u.extended.value.data = talloc_steal(ret, value); - ret->u.extended.value.length = strlen(value); - ret->u.extended.dnAttributes = dnAttributes; + if (oid) { + ret->operation = LDB_OP_EXTENDED; + /* From the RFC2251: If the type field is + absent and matchingRule is present, the matchValue is compared + against all attributes in an entry which support that matchingRule + */ + if (attr) { + ret->u.extended.attr = talloc_steal(ret, attr); + } else { + ret->u.extended.attr = talloc_strdup(ret, "*"); + } + ret->u.extended.rule_id = talloc_steal(ret, oid); + ret->u.extended.value.data = talloc_steal(ret, value); + ret->u.extended.value.length = strlen(value); + ret->u.extended.dnAttributes = dnAttributes; + } else { + ret->operation = LDB_OP_EQUALITY; + ret->u.equality.attr = talloc_steal(ret, attr); + ret->u.equality.value.data = talloc_steal(ret, value); + ret->u.equality.value.length = strlen(value); + } if (!asn1_end_tag(data)) { goto failed; } -- cgit From 3be75a4c6d4b9d86f1b85c75fb2f41c6c0eeec94 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 11 Aug 2005 13:12:45 +0000 Subject: r9240: - move struct security_token to the idl file, with this we can the ndr_pull/push/print functions for it in the ntacl-lsm module - fix compiler warnings in the ldap_encode_ndr_* code metze (This used to be commit 83d65d0d7ed9c240ad44aa2c881c1f07212bfda4) --- source4/libcli/ldap/ldap_ndr.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index bc19e49535..0cccdbe971 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -29,7 +29,7 @@ /* encode a NDR uint32 as a ldap filter element */ -const char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value) +char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value) { uint8_t buf[4]; struct ldb_val val; @@ -42,11 +42,11 @@ const char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value) /* encode a NDR dom_sid as a ldap filter element */ -const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) +char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) { DATA_BLOB blob; NTSTATUS status; - const char *ret; + char *ret; status = ndr_push_struct_blob(&blob, mem_ctx, sid, (ndr_push_flags_fn_t)ndr_push_dom_sid); if (!NT_STATUS_IS_OK(status)) { @@ -61,11 +61,11 @@ const char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *s /* encode a NDR GUID as a ldap filter element */ -const char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) +char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) { DATA_BLOB blob; NTSTATUS status; - const char *ret; + char *ret; status = ndr_push_struct_blob(&blob, mem_ctx, guid, (ndr_push_flags_fn_t)ndr_push_GUID); if (!NT_STATUS_IS_OK(status)) { -- cgit From ba90b652d918fb34f1e43083f8283f669c73c340 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 23 Aug 2005 05:29:37 +0000 Subject: r9505: Work on GENSEC and the code that calls it, for tighter interface requirements, and for better error reporting. In particular, the composite session setup (extended security/SPNEGO) code now returns errors, rather than NT_STATUS_NO_MEMORY. This is seen particularly when GENSEC fails to start. The tighter interface rules apply to NTLMSSP, which must be called exactly the right number of times. This is to match some of our other less-tested modules, where adding flexablity is harder. (and this is security code, so let's just get it right). As such, the DCE/RPC and LDAP clients have been updated. Andrew Bartlett (This used to be commit 134550cf752b9edad66c3368750bfb4bbd9d55d1) --- source4/libcli/ldap/ldap_bind.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index e70a56779b..738222da86 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -141,6 +141,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr { NTSTATUS status; TALLOC_CTX *tmp_ctx = NULL; + DATA_BLOB input = data_blob(NULL, 0); DATA_BLOB output = data_blob(NULL, 0); @@ -183,21 +184,35 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr tmp_ctx = talloc_new(conn); if (tmp_ctx == NULL) goto failed; - status = gensec_update(conn->gensec, tmp_ctx, input, &output); - while (1) { + NTSTATUS gensec_status; struct ldap_message *response; struct ldap_message *msg; struct ldap_request *req; int result = LDAP_OTHER; - if (NT_STATUS_IS_OK(status) && output.length == 0) { - break; - } + status = gensec_update(conn->gensec, tmp_ctx, + input, + &output); + /* The status value here, from GENSEC is vital to the security + * of the system. Even if the other end accepts, if GENSEC + * claims 'MORE_PROCESSING_REQUIRED' then you must keep + * feeding it blobs, or else the remote host/attacker might + * avoid mutal authentication requirements. + * + * Likewise, you must not feed GENSEC too much (after the OK), + * it doesn't like that either + */ + + gensec_status = status; + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) { break; } + if (output.length == 0) { + break; + } msg = new_ldap_sasl_bind_msg(tmp_ctx, "GSS-SPNEGO", &output); if (msg == NULL) { @@ -225,12 +240,15 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr result = response->r.BindResponse.response.resultcode; if (result != LDAP_SUCCESS && result != LDAP_SASL_BIND_IN_PROGRESS) { + status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; break; } - status = gensec_update(conn->gensec, tmp_ctx, - response->r.BindResponse.SASL.secblob, - &output); + /* This is where we check if GENSEC wanted to be fed more data */ + if (!NT_STATUS_EQUAL(gensec_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + break; + } + input = response->r.BindResponse.SASL.secblob; } if (NT_STATUS_IS_OK(status) && -- cgit From a129ad36eb34bbeda80c75b2f8d771bdaca8451e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 13 Sep 2005 22:05:45 +0000 Subject: r10213: fixed a memory leak in the ldap client and server code spotted by Karl Melcher. ldap_encode() now takes a memory context to use for the data blob (This used to be commit 09948a59336a7f02bf2b4605f2d4d886e65b85f2) --- source4/libcli/ldap/ldap.c | 4 ++-- source4/libcli/ldap/ldap_client.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index f7f6feea38..815d543038 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -189,7 +189,7 @@ static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *res } } -BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) +BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) { struct asn1_data data; int i, j; @@ -462,7 +462,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result) return False; } - *result = data_blob(data.data, data.length); + *result = data_blob_talloc(mem_ctx, data.data, data.length); asn1_free(&data); return True; } diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 97b75602aa..800e523eb4 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -497,7 +497,7 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, msg->messageid = req->messageid; - if (!ldap_encode(msg, &req->data)) { + if (!ldap_encode(msg, &req->data, req)) { goto failed; } -- cgit From 6812c73534001d2dd05a9a74358d2b6d0029f1a7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 20 Sep 2005 11:59:03 +0000 Subject: r10348: Add scons scripts for remaining subsystems. Most subsystems build now, but final linking still fails (as does generating files asn1, et, idl and proto files) (This used to be commit 4f0d7f75b99c7f4388d8acb0838577d86baf68b5) --- source4/libcli/ldap/SConscript | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 source4/libcli/ldap/SConscript (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/SConscript b/source4/libcli/ldap/SConscript new file mode 100644 index 0000000000..eef9a9f41c --- /dev/null +++ b/source4/libcli/ldap/SConscript @@ -0,0 +1,5 @@ +Import('hostenv') + +hostenv.StaticLibrary('cli_ldap', + ['ldap.c','ldap_client.c','ldap_bind.c','ldap_msg.c','ldap_ndr.c', + 'ldap_ildap.c']) -- cgit From 3d4ea18d4dd9031adc16348c16595d6c216b2d84 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 24 Sep 2005 16:23:41 +0000 Subject: r10478: More work on proto headers; we now generate a couple of smaller ones that are then included by include/proto.h (This used to be commit 703ffbaaaca11f3d8781cfe9e7542fcaa626d991) --- source4/libcli/ldap/SConscript | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 source4/libcli/ldap/SConscript (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/SConscript b/source4/libcli/ldap/SConscript deleted file mode 100644 index eef9a9f41c..0000000000 --- a/source4/libcli/ldap/SConscript +++ /dev/null @@ -1,5 +0,0 @@ -Import('hostenv') - -hostenv.StaticLibrary('cli_ldap', - ['ldap.c','ldap_client.c','ldap_bind.c','ldap_msg.c','ldap_ndr.c', - 'ldap_ildap.c']) -- cgit From 67762d7965d74e4534a9dcb06276786fa9a37713 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 30 Sep 2005 23:56:54 +0000 Subject: r10668: added a ildap_search_bytree() function (This used to be commit fd6d895ebdb201ac6afaf5c8ec84d003765cdff6) --- source4/libcli/ldap/ldap_ildap.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_ildap.c b/source4/libcli/ldap/ldap_ildap.c index 541797c25c..d85585bce8 100644 --- a/source4/libcli/ldap/ldap_ildap.c +++ b/source4/libcli/ldap/ldap_ildap.c @@ -154,10 +154,10 @@ int ildap_count_entries(struct ldap_connection *conn, struct ldap_message **res) /* perform a ldap search */ -NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn, - int scope, const char *expression, - const char * const *attrs, BOOL attributesonly, - struct ldap_message ***results) +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_message ***results) { struct ldap_message *msg; int n, i; @@ -178,7 +178,7 @@ NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn, msg->r.SearchRequest.timelimit = 0; msg->r.SearchRequest.sizelimit = 0; msg->r.SearchRequest.attributesonly = attributesonly; - msg->r.SearchRequest.tree = ldb_parse_tree(msg, expression); + msg->r.SearchRequest.tree = tree; msg->r.SearchRequest.num_attributes = n; msg->r.SearchRequest.attributes = attrs; @@ -213,3 +213,18 @@ NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn, return status; } + +/* + perform a ldap search +*/ +NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn, + int scope, const char *expression, + const char * const *attrs, BOOL attributesonly, + struct ldap_message ***results) +{ + struct ldb_parse_tree *tree = ldb_parse_tree(conn, expression); + NTSTATUS status; + status = ildap_search(conn, basedn, scope, tree, attrs, attributesonly, results); + talloc_free(tree); + return status; +} -- cgit From a599edf04cbdeef9014923ba0d3713b8ff84f266 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 12 Oct 2005 06:10:23 +0000 Subject: r10913: This patch isn't as big as it looks ... most of the changes are fixes to make all the ldb code compile without warnings on gcc4. Unfortunately That required a lot of casts :-( I have also added the start of an 'operational' module, which will replace the timestamp module, plus add support for some other operational attributes In ldb_msg_*() I added some new utility functions to make the operational module sane, and remove the 'ldb' argument from the ldb_msg_add_*() functions. That argument was only needed back in the early days of ldb when we didn't use the hierarchical talloc and thus needed a place to get the allocation function from. Now its just a pain to pass around everywhere. Also added a ldb_debug_set() function that calls ldb_debug() plus sets the result using ldb_set_errstring(). That saves on some awkward coding in a few places. (This used to be commit f6818daecca95760c12f79fd307770cbe3346f57) --- source4/libcli/ldap/ldap.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 815d543038..043faabf2f 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -79,7 +79,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree i = 0; if ( ! tree->u.substring.start_with_wildcard) { asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write_LDAPString(data, tree->u.substring.chunks[i]->data); + asn1_write_LDAPString(data, (char *)tree->u.substring.chunks[i]->data); asn1_pop_tag(data); i++; } @@ -93,7 +93,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree ctx = 1; } asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(ctx)); - asn1_write_LDAPString(data, tree->u.substring.chunks[i]->data); + asn1_write_LDAPString(data, (char *)tree->u.substring.chunks[i]->data); asn1_pop_tag(data); i++; } @@ -159,7 +159,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree asn1_pop_tag(data); } asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3)); - asn1_write_LDAPString(data, tree->u.extended.value.data); + asn1_write_LDAPString(data, (char *)tree->u.extended.value.data); asn1_pop_tag(data); asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4)); asn1_write_uint8(data, tree->u.extended.dnAttributes); @@ -517,7 +517,7 @@ static struct ldb_val **ldap_decode_substring(TALLOC_CTX *mem_ctx, struct ldb_va return NULL; } - chunks[chunk_num]->data = talloc_strdup(mem_ctx, value); + chunks[chunk_num]->data = (uint8_t *)talloc_strdup(mem_ctx, value); if (chunks[chunk_num]->data == NULL) { return NULL; } @@ -631,8 +631,7 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, } ret->operation = LDB_OP_SUBSTRING; - ret->u.substring.attr = talloc_memdup(ret, attr.data, attr.length + 1); - ret->u.substring.attr[attr.length] = '\0'; + ret->u.substring.attr = talloc_strndup(ret, (char *)attr.data, attr.length); ret->u.substring.chunks = NULL; ret->u.substring.start_with_wildcard = 1; ret->u.substring.end_with_wildcard = 1; -- cgit From 2ecb46d595b880c533e2dafea43baf02f009bec6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 14 Oct 2005 12:54:52 +0000 Subject: r11037: (This used to be commit 6913e338405a5aca5c70cf6e022532c596ed0a36) --- source4/libcli/ldap/SConscript | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 source4/libcli/ldap/SConscript (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/SConscript b/source4/libcli/ldap/SConscript new file mode 100644 index 0000000000..eef9a9f41c --- /dev/null +++ b/source4/libcli/ldap/SConscript @@ -0,0 +1,5 @@ +Import('hostenv') + +hostenv.StaticLibrary('cli_ldap', + ['ldap.c','ldap_client.c','ldap_bind.c','ldap_msg.c','ldap_ndr.c', + 'ldap_ildap.c']) -- cgit From cffd522b5c806508dfacfb10234e4c0a115c0a98 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 14 Oct 2005 14:02:47 +0000 Subject: r11052: bring samba4 uptodate with the samba4-winsrepl branch, before the bad merge metze (This used to be commit 471c0ca4abb17fb5f73c0efed195c67628c1c06e) --- source4/libcli/ldap/SConscript | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/SConscript b/source4/libcli/ldap/SConscript index eef9a9f41c..e69de29bb2 100644 --- a/source4/libcli/ldap/SConscript +++ b/source4/libcli/ldap/SConscript @@ -1,5 +0,0 @@ -Import('hostenv') - -hostenv.StaticLibrary('cli_ldap', - ['ldap.c','ldap_client.c','ldap_bind.c','ldap_msg.c','ldap_ndr.c', - 'ldap_ildap.c']) -- cgit From d73bd8f01aefe97f007a59f49698a5c7c9e97c29 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 17 Oct 2005 11:50:34 +0000 Subject: r11114: - fixed error handling on bad bind in ildap client - added nicer error display, giving a string version of the error code (This used to be commit 5ec486bb81536b38a5f40cae7555cbcbbfa52263) --- source4/libcli/ldap/ldap_bind.c | 3 +- source4/libcli/ldap/ldap_client.c | 63 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 738222da86..c08ffabc22 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -240,7 +240,8 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr result = response->r.BindResponse.response.resultcode; if (result != LDAP_SUCCESS && result != LDAP_SASL_BIND_IN_PROGRESS) { - status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + status = ldap_check_response(conn, + &response->r.BindResponse.response); break; } diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 800e523eb4..6b4e73d44b 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -555,11 +555,63 @@ NTSTATUS ldap_request_wait(struct ldap_request *req) } +/* + a mapping of ldap response code to strings +*/ +static const struct { + enum ldap_result_code code; + const char *str; +} ldap_code_map[] = { +#define _LDAP_MAP_CODE(c) { c, #c } + _LDAP_MAP_CODE(LDAP_SUCCESS), + _LDAP_MAP_CODE(LDAP_OPERATIONS_ERROR), + _LDAP_MAP_CODE(LDAP_PROTOCOL_ERROR), + _LDAP_MAP_CODE(LDAP_TIME_LIMIT_EXCEEDED), + _LDAP_MAP_CODE(LDAP_SIZE_LIMIT_EXCEEDED), + _LDAP_MAP_CODE(LDAP_COMPARE_FALSE), + _LDAP_MAP_CODE(LDAP_COMPARE_TRUE), + _LDAP_MAP_CODE(LDAP_AUTH_METHOD_NOT_SUPPORTED), + _LDAP_MAP_CODE(LDAP_STRONG_AUTH_REQUIRED), + _LDAP_MAP_CODE(LDAP_REFERRAL), + _LDAP_MAP_CODE(LDAP_ADMIN_LIMIT_EXCEEDED), + _LDAP_MAP_CODE(LDAP_UNAVAILABLE_CRITICAL_EXTENSION), + _LDAP_MAP_CODE(LDAP_CONFIDENTIALITY_REQUIRED), + _LDAP_MAP_CODE(LDAP_SASL_BIND_IN_PROGRESS), + _LDAP_MAP_CODE(LDAP_NO_SUCH_ATTRIBUTE), + _LDAP_MAP_CODE(LDAP_UNDEFINED_ATTRIBUTE_TYPE), + _LDAP_MAP_CODE(LDAP_INAPPROPRIATE_MATCHING), + _LDAP_MAP_CODE(LDAP_CONSTRAINT_VIOLATION), + _LDAP_MAP_CODE(LDAP_ATTRIBUTE_OR_VALUE_EXISTS), + _LDAP_MAP_CODE(LDAP_INVALID_ATTRIBUTE_SYNTAX), + _LDAP_MAP_CODE(LDAP_NO_SUCH_OBJECT), + _LDAP_MAP_CODE(LDAP_ALIAS_PROBLEM), + _LDAP_MAP_CODE(LDAP_INVALID_DN_SYNTAX), + _LDAP_MAP_CODE(LDAP_ALIAS_DEREFERENCING_PROBLEM), + _LDAP_MAP_CODE(LDAP_INAPPROPRIATE_AUTHENTICATION), + _LDAP_MAP_CODE(LDAP_INVALID_CREDENTIALS), + _LDAP_MAP_CODE(LDAP_INSUFFICIENT_ACCESS_RIGHTs), + _LDAP_MAP_CODE(LDAP_BUSY), + _LDAP_MAP_CODE(LDAP_UNAVAILABLE), + _LDAP_MAP_CODE(LDAP_UNWILLING_TO_PERFORM), + _LDAP_MAP_CODE(LDAP_LOOP_DETECT), + _LDAP_MAP_CODE(LDAP_NAMING_VIOLATION), + _LDAP_MAP_CODE(LDAP_OBJECT_CLASS_VIOLATION), + _LDAP_MAP_CODE(LDAP_NOT_ALLOWED_ON_NON_LEAF), + _LDAP_MAP_CODE(LDAP_NOT_ALLOWED_ON_RDN), + _LDAP_MAP_CODE(LDAP_ENTRY_ALREADY_EXISTS), + _LDAP_MAP_CODE(LDAP_OBJECT_CLASS_MODS_PROHIBITED), + _LDAP_MAP_CODE(LDAP_AFFECTS_MULTIPLE_DSAS), + _LDAP_MAP_CODE(LDAP_OTHER) +}; + /* used to setup the status code from a ldap response */ NTSTATUS ldap_check_response(struct ldap_connection *conn, struct ldap_Result *r) { + int i; + const char *codename = "unknown"; + if (r->resultcode == LDAP_SUCCESS) { return NT_STATUS_OK; } @@ -567,8 +619,17 @@ NTSTATUS ldap_check_response(struct ldap_connection *conn, struct ldap_Result *r if (conn->last_error) { talloc_free(conn->last_error); } - conn->last_error = talloc_asprintf(conn, "LDAP error %u - %s <%s> <%s>", + + for (i=0;iresultcode == ldap_code_map[i].code) { + codename = ldap_code_map[i].str; + break; + } + } + + conn->last_error = talloc_asprintf(conn, "LDAP error %u %s - %s <%s> <%s>", r->resultcode, + codename, r->dn?r->dn:"(NULL)", r->errormessage?r->errormessage:"", r->referral?r->referral:""); -- cgit From f4d590662effeb80c2b55ae5ad869b4b7810cf08 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 20 Oct 2005 10:04:57 +0000 Subject: r11214: Remove scons files (see http://lists.samba.org/archive/samba-technical/2005-October/043443.html) (This used to be commit 7fffc5c9178158249be632ac0ca179c13bd1f98f) --- source4/libcli/ldap/SConscript | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 source4/libcli/ldap/SConscript (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/SConscript b/source4/libcli/ldap/SConscript deleted file mode 100644 index e69de29bb2..0000000000 -- cgit From 4c5a4a7e0288e9ac0b2f795befd5684059e4c429 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 21 Oct 2005 16:29:54 +0000 Subject: r11244: Relative path names in .mk files (This used to be commit 24e10300906c380919d2d631bfb3b8fd6b3f54ba) --- source4/libcli/ldap/config.mk | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index a92e733493..face7caa66 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,12 +1,12 @@ ################################# # Start SUBSYSTEM LIBCLI_LDAP [SUBSYSTEM::LIBCLI_LDAP] -ADD_OBJ_FILES = libcli/ldap/ldap.o \ - libcli/ldap/ldap_client.o \ - libcli/ldap/ldap_bind.o \ - libcli/ldap/ldap_msg.o \ - libcli/ldap/ldap_ndr.o \ - libcli/ldap/ldap_ildap.o +ADD_OBJ_FILES = ldap.o \ + ldap_client.o \ + ldap_bind.o \ + ldap_msg.o \ + ldap_ndr.o \ + ldap_ildap.o REQUIRED_SUBSYSTEMS = LIBCLI_UTILS LIBEVENTS GENSEC SOCKET RPC_NDR_SAMR LIBTLS # End SUBSYSTEM LIBCLI_LDAP ################################# -- cgit From ca40d0a6fea0dbf2a9962ed125f420bea3ca0269 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 24 Oct 2005 04:19:27 +0000 Subject: r11271: Fix a warning and an infinite recursion (This used to be commit 7bc855359a82010fefa9fd1d4c719292bfc83528) --- source4/libcli/ldap/ldap_ildap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_ildap.c b/source4/libcli/ldap/ldap_ildap.c index d85585bce8..666cc02536 100644 --- a/source4/libcli/ldap/ldap_ildap.c +++ b/source4/libcli/ldap/ldap_ildap.c @@ -180,7 +180,7 @@ NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn, msg->r.SearchRequest.attributesonly = attributesonly; msg->r.SearchRequest.tree = tree; msg->r.SearchRequest.num_attributes = n; - msg->r.SearchRequest.attributes = attrs; + msg->r.SearchRequest.attributes = discard_const(attrs); req = ldap_request_send(conn, msg); talloc_steal(msg, req); @@ -224,7 +224,8 @@ NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn, { struct ldb_parse_tree *tree = ldb_parse_tree(conn, expression); NTSTATUS status; - status = ildap_search(conn, basedn, scope, tree, attrs, attributesonly, results); + status = ildap_search_bytree(conn, basedn, scope, tree, attrs, + attributesonly, results); talloc_free(tree); return status; } -- cgit From d6e070b74af8891c5e6ee15d57f8c0db3aac2f14 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 24 Oct 2005 09:34:12 +0000 Subject: r11274: Start a connection attempt to the DC's port 389. To do this properly, make socket_connect and ldap_connect properly async. Volker (This used to be commit bcc71fc1deeed443d7cf00220ce264011ddf588d) --- source4/libcli/ldap/ldap_client.c | 97 +++++++++++++++++++++++++++++++-------- 1 file changed, 79 insertions(+), 18 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 6b4e73d44b..d7cfd7c7e5 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -31,6 +31,7 @@ #include "lib/tls/tls.h" #include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" +#include "libcli/composite/composite.h" /* @@ -393,45 +394,105 @@ static NTSTATUS ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, /* connect to a ldap server */ -NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url) + +struct ldap_connect_state { + struct composite_context *ctx; + struct ldap_connection *conn; +}; + +static void ldap_connect_recv_conn(struct composite_context *ctx); + +struct composite_context *ldap_connect_send(struct ldap_connection *conn, + const char *url) { - NTSTATUS status; + struct composite_context *result, *ctx; + struct ldap_connect_state *state; - status = ldap_parse_basic_url(conn, url, &conn->host, - &conn->port, &conn->ldaps); - NT_STATUS_NOT_OK_RETURN(status); + result = talloc_zero(NULL, struct composite_context); + if (result == NULL) goto failed; + result->state = COMPOSITE_STATE_IN_PROGRESS; + result->async.fn = NULL; + result->event_ctx = conn->event.event_ctx; - status = socket_create("ipv4", SOCKET_TYPE_STREAM, &conn->sock, 0); - NT_STATUS_NOT_OK_RETURN(status); + state = talloc(result, struct ldap_connect_state); + if (state == NULL) goto failed; + state->ctx = result; + result->private_data = state; - talloc_steal(conn, conn->sock); + state->conn = conn; - /* connect in a event friendly way */ - status = socket_connect_ev(conn->sock, NULL, 0, conn->host, conn->port, 0, - conn->event.event_ctx); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(conn->sock); - return status; + state->ctx->status = ldap_parse_basic_url(conn, url, &conn->host, + &conn->port, &conn->ldaps); + if (!NT_STATUS_IS_OK(state->ctx->status)) { + composite_trigger_error(state->ctx); + return result; } + state->ctx->status = socket_create("ipv4", SOCKET_TYPE_STREAM, + &conn->sock, 0); + if (!NT_STATUS_IS_OK(state->ctx->status)) { + composite_trigger_error(state->ctx); + return result; + } + + talloc_steal(conn, conn->sock); + + ctx = socket_connect_send(conn->sock, NULL, 0, conn->host, + conn->port, 0, conn->event.event_ctx); + if (ctx == NULL) goto failed; + + ctx->async.fn = ldap_connect_recv_conn; + ctx->async.private_data = state; + return result; + + failed: + talloc_free(result); + return NULL; +} + +static void ldap_connect_recv_conn(struct composite_context *ctx) +{ + struct ldap_connect_state *state = + talloc_get_type(ctx->async.private_data, + struct ldap_connect_state); + struct ldap_connection *conn = state->conn; + + state->ctx->status = socket_connect_recv(ctx); + if (!composite_is_ok(state->ctx)) return; + /* setup a handler for events on this socket */ conn->event.fde = event_add_fd(conn->event.event_ctx, conn->sock, socket_get_fd(conn->sock), EVENT_FD_READ, ldap_io_handler, conn); if (conn->event.fde == NULL) { - talloc_free(conn->sock); - return NT_STATUS_INTERNAL_ERROR; + composite_error(state->ctx, NT_STATUS_INTERNAL_ERROR); + return; } conn->tls = tls_init_client(conn->sock, conn->event.fde, conn->ldaps); if (conn->tls == NULL) { talloc_free(conn->sock); - return NT_STATUS_INTERNAL_ERROR; + return; } talloc_steal(conn, conn->tls); talloc_steal(conn->tls, conn->sock); - return NT_STATUS_OK; + composite_done(state->ctx); + + return; +} + +NTSTATUS ldap_connect_recv(struct composite_context *ctx) +{ + NTSTATUS status = composite_wait(ctx); + talloc_free(ctx); + return status; +} + +NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url) +{ + struct composite_context *ctx = ldap_connect_send(conn, url); + return ldap_connect_recv(ctx); } /* destroy an open ldap request */ -- cgit From 134b2488c82ae13392121f71e4960178a38f3e01 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 28 Oct 2005 11:02:42 +0000 Subject: r11369: Implement socket_connect_multi: Connect to multiple ipv4 tcp ports in sequence, with a 2-millisecond timeout between firing the syn packets. Build smbcli_sock_connect_send upon that. Volker (This used to be commit 5718df44d90d113304c5deed1e2e7f82ff9e928f) --- source4/libcli/ldap/ldap_client.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index d7cfd7c7e5..3b801ca225 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -428,17 +428,8 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, return result; } - state->ctx->status = socket_create("ipv4", SOCKET_TYPE_STREAM, - &conn->sock, 0); - if (!NT_STATUS_IS_OK(state->ctx->status)) { - composite_trigger_error(state->ctx); - return result; - } - - talloc_steal(conn, conn->sock); - - ctx = socket_connect_send(conn->sock, NULL, 0, conn->host, - conn->port, 0, conn->event.event_ctx); + ctx = socket_connect_multi_send(state, conn->host, 1, &conn->port, + conn->event.event_ctx); if (ctx == NULL) goto failed; ctx->async.fn = ldap_connect_recv_conn; @@ -456,8 +447,10 @@ static void ldap_connect_recv_conn(struct composite_context *ctx) talloc_get_type(ctx->async.private_data, struct ldap_connect_state); struct ldap_connection *conn = state->conn; + uint16_t port; - state->ctx->status = socket_connect_recv(ctx); + state->ctx->status = socket_connect_multi_recv(ctx, state, &conn->sock, + &port); if (!composite_is_ok(state->ctx)) return; /* setup a handler for events on this socket */ -- cgit From 72820aaf9281acc2acec869793a95f3353c1034c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 5 Nov 2005 11:02:37 +0000 Subject: r11521: Add in client support for checking supportedSASLmechanisms, and then determining a mechanism to use. Currently it doesn't to fallbacks like SPNEGO does, but this could be added (to GENSEC, not to here). This also adds a new function to GENSEC, which returns a list of SASL names in our preference order (currently determined by the build system of all things...). Also make the similar function used for OIDs in SPNEGO do the same. This is all a very long-winded way of moving from a hard-coded NTLM to GSS-SPNEGO in our SASL client... Andrew Bartlett (This used to be commit 130eb9bb9a37957614c87e0e6846a812abb51e00) --- source4/libcli/ldap/ldap_bind.c | 57 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index c08ffabc22..81e0c8b4e6 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -145,6 +145,18 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr DATA_BLOB input = data_blob(NULL, 0); DATA_BLOB output = data_blob(NULL, 0); + struct ldap_message **sasl_mechs_msgs; + struct ldap_SearchResEntry *search; + int count, i; + + const char **sasl_names; + const struct gensec_security_ops **mechs; + + static const char *supported_sasl_mech_attrs[] = { + "supportedSASLMechanisms", + NULL + }; + status = gensec_client_start(conn, &conn->gensec, NULL); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); @@ -174,16 +186,57 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr goto failed; } - status = gensec_start_mech_by_sasl_name(conn->gensec, "NTLM"); + status = ildap_search(conn, "", LDAP_SEARCH_SCOPE_BASE, "", supported_sasl_mech_attrs, + False, &sasl_mechs_msgs); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to set GENSEC client SPNEGO mechanism: %s\n", + DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: %s\n", nt_errstr(status))); goto failed; } + + count = ildap_count_entries(conn, sasl_mechs_msgs); + if (count != 1) { + DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of replies: %d\n", + count)); + goto failed; + } tmp_ctx = talloc_new(conn); if (tmp_ctx == NULL) goto failed; + search = &sasl_mechs_msgs[0]->r.SearchResultEntry; + if (search->num_attributes != 1) { + DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of attributes: %d\n", + search->num_attributes)); + goto failed; + } + + sasl_names = talloc_array(tmp_ctx, const char *, search->attributes[0].num_values + 1); + if (!sasl_names) { + DEBUG(1, ("talloc_arry(char *, %d) failed\n", + count)); + goto failed; + } + + for (i=0; iattributes[0].num_values; i++) { + sasl_names[i] = (const char *)search->attributes[0].values[i].data; + } + sasl_names[i] = NULL; + + mechs = gensec_security_by_sasl(tmp_ctx, sasl_names); + if (!mechs || !mechs[0]) { + DEBUG(1, ("None of the %d proposed SASL mechs were acceptable\n", + count)); + goto failed; + } + + status = gensec_start_mech_by_ops(conn->gensec, mechs[0]); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to set GENSEC client mechanism: %s/%s %s\n", + mechs[0]->name, mechs[0]->sasl_name, nt_errstr(status))); + goto failed; + } + while (1) { NTSTATUS gensec_status; struct ldap_message *response; -- cgit From 75ec65597cd9b0008876bbb5967f822f65985d0c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 5 Nov 2005 11:24:10 +0000 Subject: r11523: Working towards having Samba3 join Samba4, this allows the SASL credentials to be NULL, where the client is requesting a CIFS style server-first negTokenInit. Andrew Bartlett (This used to be commit eba652ecc89766304fdad14463072dc311693701) --- source4/libcli/ldap/ldap.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 043faabf2f..7d1758a8fa 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -933,9 +933,13 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_start_tag(data, ASN1_CONTEXT(3)); r->mechanism = LDAP_AUTH_MECH_SASL; asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism); - asn1_read_OctetString(data, &r->creds.SASL.secblob); - if (r->creds.SASL.secblob.data) { - talloc_steal(msg, r->creds.SASL.secblob.data); + if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { /* optional */ + asn1_read_OctetString(data, &r->creds.SASL.secblob); + if (r->creds.SASL.secblob.data) { + talloc_steal(msg, r->creds.SASL.secblob.data); + } + } else { + r->creds.SASL.secblob = data_blob(NULL, 0); } asn1_end_tag(data); } -- cgit From 69307693dc47cdaa931551c99914e85273037886 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 5 Nov 2005 23:46:57 +0000 Subject: r11528: Separate finding dcs from initializing a domain. Makes it easier to possibly support cldap and other stuff in the future. This temporarily disables wbinfo -t, but that will come back soon. Try an ldap bind using gss-spnego. This got me krb5 binds against "our" w2k3 and a trusted w2k, although with some memleaks from krb5 and a BAD_OPTION tgs-rep error. Volker (This used to be commit d14948fdf687c8f70ef9ec35445b7eb04da84253) --- source4/libcli/ldap/ldap_client.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h index b61f765b40..38e043da1f 100644 --- a/source4/libcli/ldap/ldap_client.h +++ b/source4/libcli/ldap/ldap_client.h @@ -21,6 +21,8 @@ */ +#include "libcli/ldap/ldap.h" + enum ldap_request_state {LDAP_REQUEST_SEND, LDAP_REQUEST_PENDING, LDAP_REQUEST_DONE}; /* this is the handle that the caller gets when an async ldap message -- cgit From 65baaafc34b2befac50541c5aef86e5d906d2797 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Nov 2005 00:28:02 +0000 Subject: r11620: switch the ldap client code over to using the generic packet code (This used to be commit 1d29ad2a27d89454e5e3c4a3cf05cc5edde0208c) --- source4/libcli/ldap/ldap.c | 8 ++ source4/libcli/ldap/ldap_client.c | 286 ++++++++++++++++---------------------- source4/libcli/ldap/ldap_client.h | 8 +- 3 files changed, 129 insertions(+), 173 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 7d1758a8fa..3cfbe3a1e1 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1289,3 +1289,11 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) } +/* + return NT_STATUS_OK if a blob has enough bytes in it to be a full + ldap packet. Set packet_size if true. +*/ +NTSTATUS ldap_full_packet(void *private, DATA_BLOB blob, size_t *packet_size) +{ + return asn1_full_tag(blob, ASN1_SEQUENCE(0), packet_size); +} diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 3b801ca225..503016e896 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -32,6 +32,7 @@ #include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" #include "libcli/composite/composite.h" +#include "lib/stream/packet.h" /* @@ -82,20 +83,20 @@ static void ldap_connection_dead(struct ldap_connection *conn) } } - while (conn->send_queue) { - req = conn->send_queue; - DLIST_REMOVE(req->conn->send_queue, req); - req->state = LDAP_REQUEST_DONE; - req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; - if (req->async.fn) { - req->async.fn(req); - } - } - talloc_free(conn->tls); conn->tls = NULL; } +/* + handle packet errors +*/ +static void ldap_error_handler(void *private, NTSTATUS status) +{ + struct ldap_connection *conn = talloc_get_type(private, + struct ldap_connection); + ldap_connection_dead(conn); +} + /* match up with a pending message, adding to the replies list @@ -149,184 +150,99 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message } } + /* - try and decode/process plain data + check if a blob is a complete ldap packet + handle wrapper or unwrapped connections */ -static void ldap_try_decode_plain(struct ldap_connection *conn) +NTSTATUS ldap_complete_packet(void *private, DATA_BLOB blob, size_t *size) { - struct asn1_data asn1; - - if (!asn1_load(&asn1, conn->partial)) { - ldap_connection_dead(conn); - return; - } - - /* try and decode - this will fail if we don't have a full packet yet */ - while (asn1.ofs < asn1.length) { - struct ldap_message *msg = talloc(conn, struct ldap_message); - off_t saved_ofs = asn1.ofs; - - if (msg == NULL) { - ldap_connection_dead(conn); - return; - } - - if (ldap_decode(&asn1, msg)) { - ldap_match_message(conn, msg); - } else { - asn1.ofs = saved_ofs; - talloc_free(msg); - break; - } - } - - /* keep any remaining data in conn->partial */ - data_blob_free(&conn->partial); - if (asn1.ofs != asn1.length) { - conn->partial = data_blob_talloc(conn, - asn1.data + asn1.ofs, - asn1.length - asn1.ofs); + struct ldap_connection *conn = talloc_get_type(private, + struct ldap_connection); + if (conn->enable_wrap) { + return packet_full_request_u32(private, blob, size); } - asn1_free(&asn1); + return ldap_full_packet(private, blob, size); } /* - try and decode/process wrapped data + decode/process plain data */ -static void ldap_try_decode_wrapped(struct ldap_connection *conn) +static NTSTATUS ldap_decode_plain(struct ldap_connection *conn, DATA_BLOB blob) { - uint32_t len; - - /* keep decoding while we have a full wrapped packet */ - while (conn->partial.length >= 4 && - (len=RIVAL(conn->partial.data, 0)) <= conn->partial.length-4) { - DATA_BLOB wrapped, unwrapped; - struct asn1_data asn1; - struct ldap_message *msg = talloc(conn, struct ldap_message); - NTSTATUS status; - - if (msg == NULL) { - ldap_connection_dead(conn); - return; - } + struct asn1_data asn1; + struct ldap_message *msg = talloc(conn, struct ldap_message); - wrapped.data = conn->partial.data+4; - wrapped.length = len; + if (msg == NULL) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } - status = gensec_unwrap(conn->gensec, msg, &wrapped, &unwrapped); - if (!NT_STATUS_IS_OK(status)) { - ldap_connection_dead(conn); - return; - } + if (!asn1_load(&asn1, blob)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + + if (!ldap_decode(&asn1, msg)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } - if (!asn1_load(&asn1, unwrapped)) { - ldap_connection_dead(conn); - return; - } + ldap_match_message(conn, msg); - while (ldap_decode(&asn1, msg)) { - ldap_match_message(conn, msg); - msg = talloc(conn, struct ldap_message); - } - - talloc_free(msg); - asn1_free(&asn1); - - if (conn->partial.length == len + 4) { - data_blob_free(&conn->partial); - } else { - memmove(conn->partial.data, conn->partial.data+len+4, - conn->partial.length - (len+4)); - conn->partial.length -= len + 4; - } - } + data_blob_free(&blob); + asn1_free(&asn1); + return NT_STATUS_OK; } - /* - handle ldap recv events + decode/process wrapped data */ -static void ldap_recv_handler(struct ldap_connection *conn) +static NTSTATUS ldap_decode_wrapped(struct ldap_connection *conn, DATA_BLOB blob) { + DATA_BLOB wrapped, unwrapped; + struct asn1_data asn1; + struct ldap_message *msg = talloc(conn, struct ldap_message); NTSTATUS status; - size_t npending=0, nread; - /* work out how much data is pending */ - status = tls_socket_pending(conn->tls, &npending); - if (!NT_STATUS_IS_OK(status) || npending == 0) { - ldap_connection_dead(conn); - return; + if (msg == NULL) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } - conn->partial.data = talloc_realloc_size(conn, conn->partial.data, - conn->partial.length + npending); - if (conn->partial.data == NULL) { - ldap_connection_dead(conn); - return; - } + wrapped = data_blob_const(blob.data+4, blob.length-4); - /* receive the pending data */ - status = tls_socket_recv(conn->tls, conn->partial.data + conn->partial.length, - npending, &nread); - if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { - return; - } + status = gensec_unwrap(conn->gensec, msg, &wrapped, &unwrapped); if (!NT_STATUS_IS_OK(status)) { - ldap_connection_dead(conn); - return; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } - conn->partial.length += nread; - /* see if we can decode what we have */ - if (conn->enable_wrap) { - ldap_try_decode_wrapped(conn); - } else { - ldap_try_decode_plain(conn); + data_blob_free(&blob); + + if (!asn1_load(&asn1, unwrapped)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } + + while (ldap_decode(&asn1, msg)) { + ldap_match_message(conn, msg); + msg = talloc(conn, struct ldap_message); + } + + talloc_free(msg); + asn1_free(&asn1); + + return NT_STATUS_OK; } /* - handle ldap send events + handle ldap recv events */ -static void ldap_send_handler(struct ldap_connection *conn) +static NTSTATUS ldap_recv_handler(void *private, DATA_BLOB blob) { - while (conn->send_queue) { - struct ldap_request *req = conn->send_queue; - size_t nsent; - NTSTATUS status; - - status = tls_socket_send(conn->tls, &req->data, &nsent); - if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { - break; - } - if (!NT_STATUS_IS_OK(status)) { - ldap_connection_dead(conn); - return; - } - - req->data.data += nsent; - req->data.length -= nsent; - if (req->data.length == 0) { - req->state = LDAP_REQUEST_PENDING; - DLIST_REMOVE(conn->send_queue, req); - - /* some types of requests don't expect a reply */ - if (req->type == LDAP_TAG_AbandonRequest || - req->type == LDAP_TAG_UnbindRequest) { - req->status = NT_STATUS_OK; - req->state = LDAP_REQUEST_DONE; - if (req->async.fn) { - req->async.fn(req); - } - } else { - DLIST_ADD(conn->pending, req); - } - } - } - if (conn->send_queue == NULL) { - EVENT_FD_NOT_WRITEABLE(conn->event.fde); + struct ldap_connection *conn = talloc_get_type(private, + struct ldap_connection); + if (conn->enable_wrap) { + return ldap_decode_wrapped(conn, blob); } + + return ldap_decode_plain(conn, blob); } @@ -336,13 +252,14 @@ static void ldap_send_handler(struct ldap_connection *conn) static void ldap_io_handler(struct event_context *ev, struct fd_event *fde, uint16_t flags, void *private) { - struct ldap_connection *conn = talloc_get_type(private, struct ldap_connection); + struct ldap_connection *conn = talloc_get_type(private, + struct ldap_connection); if (flags & EVENT_FD_WRITE) { - ldap_send_handler(conn); + packet_queue_run(conn->packet); if (conn->tls == NULL) return; } if (flags & EVENT_FD_READ) { - ldap_recv_handler(conn); + packet_recv(conn->packet); } } @@ -470,6 +387,19 @@ static void ldap_connect_recv_conn(struct composite_context *ctx) talloc_steal(conn, conn->tls); talloc_steal(conn->tls, conn->sock); + conn->packet = packet_init(conn); + if (conn->packet == NULL) { + talloc_free(conn->sock); + return; + } + packet_set_private(conn->packet, conn); + packet_set_tls(conn->packet, conn->tls); + packet_set_callback(conn->packet, ldap_recv_handler); + packet_set_full_request(conn->packet, ldap_complete_packet); + packet_set_error_handler(conn->packet, ldap_error_handler); + packet_set_event_context(conn->packet, conn->event.event_ctx); + packet_set_serialise(conn->packet, conn->event.fde); + composite_done(state->ctx); return; @@ -492,9 +422,6 @@ NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url) static int ldap_request_destructor(void *ptr) { struct ldap_request *req = talloc_get_type(ptr, struct ldap_request); - if (req->state == LDAP_REQUEST_SEND) { - DLIST_REMOVE(req->conn->send_queue, req); - } if (req->state == LDAP_REQUEST_PENDING) { DLIST_REMOVE(req->conn->pending, req); } @@ -509,9 +436,6 @@ static void ldap_request_timeout(struct event_context *ev, struct timed_event *t { struct ldap_request *req = talloc_get_type(private, struct ldap_request); req->status = NT_STATUS_IO_TIMEOUT; - if (req->state == LDAP_REQUEST_SEND) { - DLIST_REMOVE(req->conn->send_queue, req); - } if (req->state == LDAP_REQUEST_PENDING) { DLIST_REMOVE(req->conn->pending, req); } @@ -521,6 +445,19 @@ static void ldap_request_timeout(struct event_context *ev, struct timed_event *t } } + +/* + called on completion of a one-way ldap request +*/ +static void ldap_request_complete(struct event_context *ev, struct timed_event *te, + struct timeval t, void *private) +{ + struct ldap_request *req = talloc_get_type(private, struct ldap_request); + if (req->async.fn) { + req->async.fn(req); + } +} + /* send a ldap message - async interface */ @@ -528,6 +465,7 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, struct ldap_message *msg) { struct ldap_request *req; + NTSTATUS status; if (conn->tls == NULL) { return NULL; @@ -558,7 +496,6 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, /* possibly encrypt/sign the request */ if (conn->enable_wrap) { DATA_BLOB wrapped; - NTSTATUS status; status = gensec_wrap(conn->gensec, req, &req->data, &wrapped); if (!NT_STATUS_IS_OK(status)) { @@ -574,11 +511,26 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, data_blob_free(&wrapped); } + status = packet_send(conn->packet, req->data); + if (!NT_STATUS_IS_OK(status)) { + goto failed; + } - if (conn->send_queue == NULL) { - EVENT_FD_WRITEABLE(conn->event.fde); + /* some requests don't expect a reply, so don't add those to the + pending queue */ + if (req->type == LDAP_TAG_AbandonRequest || + req->type == LDAP_TAG_UnbindRequest) { + req->status = NT_STATUS_OK; + req->state = LDAP_REQUEST_DONE; + /* we can't call the async callback now, as it isn't setup, so + call it as next event */ + event_add_timed(conn->event.event_ctx, req, timeval_zero(), + ldap_request_complete, req); + return req; } - DLIST_ADD_END(conn->send_queue, req, struct ldap_request *); + + req->state = LDAP_REQUEST_PENDING; + DLIST_ADD(conn->pending, req); /* put a timeout on the request */ event_add_timed(conn->event.event_ctx, req, diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h index 38e043da1f..ee458dc5b0 100644 --- a/source4/libcli/ldap/ldap_client.h +++ b/source4/libcli/ldap/ldap_client.h @@ -61,9 +61,6 @@ struct ldap_connection { /* next message id to assign */ unsigned next_messageid; - /* outgoing send queue */ - struct ldap_request *send_queue; - /* Outstanding LDAP requests that have not yet been replied to */ struct ldap_request *pending; @@ -73,9 +70,6 @@ struct ldap_connection { /* set if we are wrapping requests */ BOOL enable_wrap; - /* partially received packet */ - DATA_BLOB partial; - /* the default timeout for messages */ int timeout; @@ -86,4 +80,6 @@ struct ldap_connection { struct event_context *event_ctx; struct fd_event *fde; } event; + + struct packet_context *packet; }; -- cgit From 614950aed35353854019db5cccec5b3154643ca3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 Nov 2005 03:45:57 +0000 Subject: r11713: separate out the setting of the fde in the packet context from the enabling of packet serialisation (This used to be commit 6a47cd65a8b588f9ddd375c57caaba08281e7cbb) --- source4/libcli/ldap/ldap_client.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 503016e896..a5f647939f 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -398,7 +398,8 @@ static void ldap_connect_recv_conn(struct composite_context *ctx) packet_set_full_request(conn->packet, ldap_complete_packet); packet_set_error_handler(conn->packet, ldap_error_handler); packet_set_event_context(conn->packet, conn->event.event_ctx); - packet_set_serialise(conn->packet, conn->event.fde); + packet_set_fde(conn->packet, conn->event.fde); + packet_set_serialise(conn->packet); composite_done(state->ctx); -- cgit From 687545e94e0cb4f2bac0596f7f78797cca312e73 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Dec 2005 04:10:13 +0000 Subject: r12062: SASL negotiation now requires a gensec_security context, so that we only try permitted mechanims. Andrew Bartlett (This used to be commit 0f50239dc40ee128e4985f8aec5bb5f440a4f3f0) --- source4/libcli/ldap/ldap_bind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 81e0c8b4e6..766416f575 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -223,7 +223,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr } sasl_names[i] = NULL; - mechs = gensec_security_by_sasl(tmp_ctx, sasl_names); + mechs = gensec_security_by_sasl(conn->gensec, tmp_ctx, sasl_names); if (!mechs || !mechs[0]) { DEBUG(1, ("None of the %d proposed SASL mechs were acceptable\n", count)); -- cgit From 111a920fdb92ccef32f89b2f992bdd3051e5ac54 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 8 Dec 2005 01:13:45 +0000 Subject: r12116: got rid of composite_trigger_done() and composite_trigger_error(), and instead make the normal composite_done() and composite_error() functions automatically trigger a delayed callback if the caller has had no opportunity to setup a async callback this removes one of the common mistakes in writing a composite function (This used to be commit f9413ce792ded682e05134b66d433eeec293e6f1) --- source4/libcli/ldap/ldap_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index a5f647939f..0a787bbf57 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -341,7 +341,7 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, state->ctx->status = ldap_parse_basic_url(conn, url, &conn->host, &conn->port, &conn->ldaps); if (!NT_STATUS_IS_OK(state->ctx->status)) { - composite_trigger_error(state->ctx); + composite_error(state->ctx, state->ctx->status); return result; } -- cgit From d8e35f882879e189f55b3bca818dd44cc5f0c6fa Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 26 Dec 2005 18:03:50 +0000 Subject: r12498: Eliminate INIT_OBJ_FILES and ADD_OBJ_FILES. We were not using the difference between these at all, and in the future the fact that INIT_OBJ_FILES include smb_build.h will be sufficient to have recompiles at the right time. (This used to be commit b24f2583edee38abafa58578d8b5c4b43e517def) --- source4/libcli/ldap/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index face7caa66..243de79fce 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,7 +1,7 @@ ################################# # Start SUBSYSTEM LIBCLI_LDAP [SUBSYSTEM::LIBCLI_LDAP] -ADD_OBJ_FILES = ldap.o \ +OBJ_FILES = ldap.o \ ldap_client.o \ ldap_bind.o \ ldap_msg.o \ -- cgit From 2cd5ca7d25f12aa9198bf8c2deb6aea282f573ee Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 28 Dec 2005 15:38:36 +0000 Subject: r12542: Move some more prototypes out to seperate headers (This used to be commit 0aca5fd5130d980d07398f3291d294202aefe3c2) --- source4/libcli/ldap/config.mk | 1 + source4/libcli/ldap/ldap.h | 2 ++ source4/libcli/ldap/ldap_client.c | 1 + 3 files changed, 4 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 243de79fce..b9fcb20038 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,6 +1,7 @@ ################################# # Start SUBSYSTEM LIBCLI_LDAP [SUBSYSTEM::LIBCLI_LDAP] +PRIVATE_PROTO_HEADER = ldap_proto.h OBJ_FILES = ldap.o \ ldap_client.o \ ldap_bind.o \ diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 4f2dbc0787..b6e69ff8e6 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -254,4 +254,6 @@ struct ldap_message { struct ldap_Control *controls; }; +#include "libcli/ldap/ldap_proto.h" + #endif diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 0a787bbf57..1ce86f7f85 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -33,6 +33,7 @@ #include "libcli/ldap/ldap_client.h" #include "libcli/composite/composite.h" #include "lib/stream/packet.h" +#include "auth/gensec/gensec.h" /* -- cgit From 46aa296cc94933082dbb4b9b2b1ed210a600ad2d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 29 Dec 2005 23:14:33 +0000 Subject: r12592: Remove some useless dependencies (This used to be commit ca8db1a0cd77682ac2c6dc4718f5d753a4fcc4db) --- source4/libcli/ldap/config.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index b9fcb20038..912cb133bf 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -8,6 +8,7 @@ OBJ_FILES = ldap.o \ ldap_msg.o \ ldap_ndr.o \ ldap_ildap.o -REQUIRED_SUBSYSTEMS = LIBCLI_UTILS LIBEVENTS GENSEC SOCKET RPC_NDR_SAMR LIBTLS +REQUIRED_SUBSYSTEMS = LIBCLI_UTILS LIBEVENTS GENSEC SOCKET NDR_SAMR LIBTLS \ + LIBPACKET # End SUBSYSTEM LIBCLI_LDAP ################################# -- cgit From d4de4c2d210d2e8c9b5aedf70695594809ad6a0b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 30 Dec 2005 13:16:54 +0000 Subject: r12608: Remove some unused #include lines. (This used to be commit 70e7449318aa0e9d2639c76730a7d1683b2f4981) --- source4/libcli/ldap/ldap_bind.c | 1 - source4/libcli/ldap/ldap_client.c | 2 -- source4/libcli/ldap/ldap_ildap.c | 1 - source4/libcli/ldap/ldap_msg.c | 1 - source4/libcli/ldap/ldap_ndr.c | 1 - 5 files changed, 6 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 766416f575..6b1c321d49 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -23,7 +23,6 @@ */ #include "includes.h" -#include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" #include "auth/auth.h" diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 1ce86f7f85..77fc7db049 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -28,8 +28,6 @@ #include "dlinklist.h" #include "lib/events/events.h" #include "lib/socket/socket.h" -#include "lib/tls/tls.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_ildap.c b/source4/libcli/ldap/ldap_ildap.c index 666cc02536..f29685a67c 100644 --- a/source4/libcli/ldap/ldap_ildap.c +++ b/source4/libcli/ldap/ldap_ildap.c @@ -22,7 +22,6 @@ */ #include "includes.h" -#include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" /* diff --git a/source4/libcli/ldap/ldap_msg.c b/source4/libcli/ldap/ldap_msg.c index 9b531f3138..c77d9eb356 100644 --- a/source4/libcli/ldap/ldap_msg.c +++ b/source4/libcli/ldap/ldap_msg.c @@ -23,7 +23,6 @@ */ #include "includes.h" -#include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index 0cccdbe971..1d5e4ccf20 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -23,7 +23,6 @@ #include "includes.h" #include "libcli/ldap/ldap.h" -#include "librpc/gen_ndr/ndr_security.h" #include "librpc/gen_ndr/ndr_misc.h" /* -- cgit From 78c50015bb8bd5a1d831a6e7ec796b3367c73145 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 3 Jan 2006 15:40:05 +0000 Subject: r12694: Move some headers to the directory of the subsystem they belong to. (This used to be commit c722f665c90103f3ed57621c460e32ad33e7a8a3) --- source4/libcli/ldap/ldap.c | 2 +- source4/libcli/ldap/ldap_client.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 3cfbe3a1e1..c699820cea 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -25,7 +25,7 @@ #include "includes.h" #include "system/iconv.h" -#include "asn_1.h" +#include "libcli/util/asn_1.h" #include "libcli/ldap/ldap.h" diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 77fc7db049..9b1a4ef9d5 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -24,7 +24,7 @@ */ #include "includes.h" -#include "asn_1.h" +#include "libcli/util/asn_1.h" #include "dlinklist.h" #include "lib/events/events.h" #include "lib/socket/socket.h" -- cgit From c908d0b2aa111659e57a73efb8c33c413965c846 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 6 Jan 2006 04:01:23 +0000 Subject: 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) --- source4/libcli/ldap/config.mk | 3 +- source4/libcli/ldap/ldap.c | 39 +-- source4/libcli/ldap/ldap.h | 7 +- source4/libcli/ldap/ldap_bind.c | 5 +- source4/libcli/ldap/ldap_client.c | 1 + source4/libcli/ldap/ldap_controls.c | 470 ++++++++++++++++++++++++++++++++++++ source4/libcli/ldap/ldap_ildap.c | 14 +- source4/libcli/ldap/ldap_msg.c | 3 +- source4/libcli/ldap/ldap_ndr.c | 1 + 9 files changed, 518 insertions(+), 25 deletions(-) create mode 100644 source4/libcli/ldap/ldap_controls.c (limited to 'source4/libcli/ldap') 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" /* -- cgit From eed0a95128714b93b9ff484780e5d74fc301be6d Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 13 Jan 2006 22:48:08 +0000 Subject: r12917: fix decoding of ldap controls some more work on timeouts (This used to be commit a7e2fe3cb33be2effff7eb764047567f2da3cd55) --- source4/libcli/ldap/ldap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index d021fc3bd6..b281f62ed0 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1264,7 +1264,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) 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)); + /* asn1_start_tag(data, ASN1_SEQUENCE(0)); */ ctrl = talloc_realloc(msg, ctrl, struct ldap_Control *, i+2); if (!ctrl) { -- cgit From 5db0c6b3042292e0f343ced3d45f2f7a8f97de12 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 14 Jan 2006 01:06:16 +0000 Subject: r12925: implement client side of ASQ control (This used to be commit dd386bdc6ca6fe0b25705d5a375d29e6940b437f) --- source4/libcli/ldap/ldap_controls.c | 99 +++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 55e7a94aa7..2a48d401c9 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -225,6 +225,67 @@ static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out return True; } +/* seem that this controls has 2 forms one in case it is used with + * a Search Request and another when used ina Search Response + */ +static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) +{ + DATA_BLOB source_attribute; + struct asn1_data data; + struct ldb_asq_control *lac; + + if (!asn1_load(&data, in)) { + return False; + } + + lac = talloc(mem_ctx, struct ldb_asq_control); + if (!lac) { + return False; + } + + if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) { + + if (!asn1_read_OctetString(&data, &source_attribute)) { + return False; + } + lac->src_attr_len = source_attribute.length; + if (lac->src_attr_len) { + lac->source_attribute = talloc_memdup(lac, source_attribute.data, source_attribute.length); + + if (!(lac->source_attribute)) { + return False; + } + } else { + lac->source_attribute = NULL; + } + + lac->request = 1; + + } else if (asn1_peek_tag(&data, ASN1_ENUMERATED)) { + + if (!asn1_read_enumerated(&data, &(lac->result))) { + return False; + } + + lac->request = 0; + + } else { + return False; + } + + if (!asn1_end_tag(&data)) { + return False; + } + + *out = lac; + + 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); @@ -366,11 +427,49 @@ static BOOL encode_paged_results_request(void *mem_ctx, void *in, DATA_BLOB *out return True; } +/* seem that this controls has 2 forms one in case it is used with + * a Search Request and another when used ina Search Response + */ +static BOOL encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out) +{ + struct ldb_asq_control *lac = talloc_get_type(in, struct ldb_asq_control); + struct asn1_data data; + + ZERO_STRUCT(data); + + if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (lac->request) { + + if (!asn1_write_OctetString(&data, lac->source_attribute, lac->src_attr_len)) { + return False; + } + } else { + if (!asn1_write_enumerated(&data, lac->result)) { + 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 }, + { "1.2.840.113556.1.4.1504", decode_asq_control, encode_asq_control }, { NULL, NULL, NULL } }; -- cgit From 3b447ab4a131509491b42a1843c52ba69bab5e11 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 17 Jan 2006 04:04:57 +0000 Subject: r12977: Some code to implement the client side of the Dirsync control Still investigating how it works. Simo. (This used to be commit bebd403523e581606505e05e7cb621efbc22fa36) --- source4/libcli/ldap/ldap_controls.c | 86 +++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 2a48d401c9..744f21fed1 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -225,6 +225,56 @@ static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out return True; } +static BOOL decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out) +{ + DATA_BLOB cookie; + struct asn1_data data; + struct ldb_dirsync_control *ldc; + + if (!asn1_load(&data, in)) { + return False; + } + + ldc = talloc(mem_ctx, struct ldb_dirsync_control); + if (!ldc) { + return False; + } + + if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_read_Integer(&data, &(ldc->flags))) { + return False; + } + + if (!asn1_read_Integer(&data, &(ldc->max_attributes))) { + return False; + } + + if (!asn1_read_OctetString(&data, &cookie)) { + return False; + } + ldc->cookie_len = cookie.length; + if (ldc->cookie_len) { + ldc->cookie = talloc_memdup(ldc, cookie.data, cookie.length); + + if (!(ldc->cookie)) { + return False; + } + } else { + ldc->cookie = NULL; + } + + if (!asn1_end_tag(&data)) { + return False; + } + + *out = ldc; + + return True; +} + /* seem that this controls has 2 forms one in case it is used with * a Search Request and another when used ina Search Response */ @@ -464,12 +514,48 @@ static BOOL encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out) return True; } +static BOOL encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out) +{ + struct ldb_dirsync_control *ldc = talloc_get_type(in, struct ldb_dirsync_control); + struct asn1_data data; + + ZERO_STRUCT(data); + + if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_write_Integer(&data, ldc->flags)) { + return False; + } + + if (!asn1_write_Integer(&data, ldc->max_attributes)) { + return False; + } + + if (!asn1_write_OctetString(&data, ldc->cookie, ldc->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 }, { "1.2.840.113556.1.4.1504", decode_asq_control, encode_asq_control }, + { "1.2.840.113556.1.4.841", decode_dirsync_request, encode_dirsync_request }, { NULL, NULL, NULL } }; -- cgit From 828ee2bc6fa4f757c63a31054a0046fe09f8c26e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Jan 2006 18:56:04 +0000 Subject: r12984: add parse code and ldbsearch cmdline code for NOTIFICATION LDAP Controls http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ldap/ldap/ldap_server_notification_oid.asp this doesn't work yet, but it shows that we need to extend ldb to correctly handle async requests... metze (This used to be commit 1fe67189490c9faf499b68a28071a6294a53db0e) --- source4/libcli/ldap/ldap_controls.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 744f21fed1..1f7a415e8e 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -60,7 +60,7 @@ static BOOL decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void **out) if (!asn1_read_OctetString(&data, &attr)) { return False; } - lsrc->attr_desc = talloc_strndup(lsrc, attr.data, attr.length); + lsrc->attr_desc = talloc_strndup(lsrc, (const char *)attr.data, attr.length); if (!lsrc->attr_desc) { return False; } @@ -111,7 +111,7 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) return False; } - lssc[num]->attributeName = talloc_strndup(lssc[num], attr.data, attr.length); + lssc[num]->attributeName = talloc_strndup(lssc[num], (const char *)attr.data, attr.length); if (!lssc [num]->attributeName) { return False; } @@ -120,7 +120,7 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) if (!asn1_read_OctetString(&data, &rule)) { return False; } - lssc[num]->orderingRule = talloc_strndup(lssc[num], rule.data, rule.length); + lssc[num]->orderingRule = talloc_strndup(lssc[num], (const char *)rule.data, rule.length); if (!lssc[num]->orderingRule) { return False; } @@ -336,6 +336,15 @@ static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) return True; } +static BOOL decode_notification_request(void *mem_ctx, DATA_BLOB in, void **out) +{ + if (in.length != 0) { + return False; + } + + 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); @@ -549,6 +558,16 @@ static BOOL encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out) return True; } +static BOOL encode_notification_request(void *mem_ctx, void *in, DATA_BLOB *out) +{ + if (in) { + return False; + } + + *out = data_blob(NULL, 0); + 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 }, @@ -556,6 +575,7 @@ struct control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.474", decode_server_sort_response, encode_server_sort_response }, { "1.2.840.113556.1.4.1504", decode_asq_control, encode_asq_control }, { "1.2.840.113556.1.4.841", decode_dirsync_request, encode_dirsync_request }, + { "1.2.840.113556.1.4.528", decode_notification_request, encode_notification_request }, { NULL, NULL, NULL } }; -- cgit From f256a9c55e4785e4383a0546e75bba355a51fa04 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 4 Feb 2006 09:53:50 +0000 Subject: r13342: Make the GSSAPI SASL mech actually work, by (shock horror) reading the spec. GSSAPI differs from GSS-SPNEGO in an additional 3 packets, negotiating a buffer size and what integrity protection/privacy should be used. I worked off draft-ietf-sasl-gssapi-03, and this works against Win2k3. I'm doing this in the hope that Apple clients as well as SASL-based LDAP tools may get a bit further. I still can't get ldapsearch to work, it fails with the ever-helpful 'Local error'. Andrew Bartlett (This used to be commit 3e462897754b30306c1983af2d137329dd937ad6) --- source4/libcli/ldap/ldap_bind.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 1f6ef77631..2880298dd5 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -152,7 +152,6 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr int count, i; const char **sasl_names; - const struct gensec_security_ops **mechs; static const char *supported_sasl_mech_attrs[] = { "supportedSASLMechanisms", @@ -225,17 +224,10 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr } sasl_names[i] = NULL; - mechs = gensec_security_by_sasl(conn->gensec, tmp_ctx, sasl_names); - if (!mechs || !mechs[0]) { - DEBUG(1, ("None of the %d proposed SASL mechs were acceptable\n", - count)); - goto failed; - } - - status = gensec_start_mech_by_ops(conn->gensec, mechs[0]); + status = gensec_start_mech_by_sasl_list(conn->gensec, sasl_names); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to set GENSEC client mechanism: %s/%s %s\n", - mechs[0]->name, mechs[0]->sasl_name, nt_errstr(status))); + DEBUG(1, ("None of the %d proposed SASL mechs were acceptable: %s\n", + count, nt_errstr(status))); goto failed; } @@ -265,11 +257,12 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr !NT_STATUS_IS_OK(status)) { break; } - if (output.length == 0) { + if (NT_STATUS_IS_OK(status) && output.length == 0) { break; } - msg = new_ldap_sasl_bind_msg(tmp_ctx, "GSS-SPNEGO", &output); + /* Perhaps we should make gensec_start_mech_by_sasl_list() return the name we got? */ + msg = new_ldap_sasl_bind_msg(tmp_ctx, conn->gensec->ops->sasl_name, &output); if (msg == NULL) { status = NT_STATUS_NO_MEMORY; goto failed; -- cgit From 2e7f35f88faedb5b6e2302c5dacf62709dee12a9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 4 Feb 2006 11:19:09 +0000 Subject: r13344: Trust SASL to have subtle distinctions between NULL and zero-length responses... Also trust OpenLDAP to be pedantic about it, breaking connections to AD. In any case, we now get this 'right' (by nasty overloading hacks, but hey), and we can now use system-supplied OpenLDAP libs and SASL/GSSAPI to talk to Samba4. Andrew Bartlett (This used to be commit 0cbe18211a95f811b51865bc0e8729e9a302ad25) --- source4/libcli/ldap/ldap.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index b281f62ed0..496fec527f 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -219,8 +219,15 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct asn1_push_tag(&data, ASN1_CONTEXT(3)); asn1_write_OctetString(&data, r->creds.SASL.mechanism, strlen(r->creds.SASL.mechanism)); - asn1_write_OctetString(&data, r->creds.SASL.secblob.data, - r->creds.SASL.secblob.length); + /* The value of data indicates if this + * optional element exists at all. In SASL + * there is a difference between NULL and + * zero-legnth, but our APIs don't express it + * well */ + if (r->creds.SASL.secblob.data) { + asn1_write_OctetString(&data, r->creds.SASL.secblob.data, + r->creds.SASL.secblob.length); + } asn1_pop_tag(&data); break; default: @@ -234,7 +241,14 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct struct ldap_BindResponse *r = &msg->r.BindResponse; asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); ldap_encode_response(&data, &r->response); - asn1_write_ContextSimple(&data, 7, &r->SASL.secblob); + /* The value of data indicates if this + * optional element exists at all. In SASL + * there is a difference between NULL and + * zero-legnth, but our APIs don't express it + * well */ + if (r->SASL.secblob.data) { + asn1_write_ContextSimple(&data, 7, &r->SASL.secblob); + } asn1_pop_tag(&data); break; } -- cgit From ad5e8bbe9d5c2250092bb3a83098c3af46304a82 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 5 Feb 2006 17:28:27 +0000 Subject: r13352: Integrate Patch to support the ManageDSAIT control from Pete Rowley (This used to be commit bf20a848fda1607ca1b0d84791c299c0035793a1) --- source4/libcli/ldap/ldap_controls.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 1f7a415e8e..cb7b52d423 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -345,6 +345,15 @@ static BOOL decode_notification_request(void *mem_ctx, DATA_BLOB in, void **out) return True; } +static BOOL decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void **out) +{ + if (in.length != 0) { + return False; + } + + 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); @@ -568,6 +577,16 @@ static BOOL encode_notification_request(void *mem_ctx, void *in, DATA_BLOB *out) return True; } +static BOOL encode_manageDSAIT_request(void *mem_ctx, void *in, DATA_BLOB *out) +{ + if (in) { + return False; + } + + *out = data_blob(NULL, 0); + 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 }, @@ -576,6 +595,7 @@ struct control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.1504", decode_asq_control, encode_asq_control }, { "1.2.840.113556.1.4.841", decode_dirsync_request, encode_dirsync_request }, { "1.2.840.113556.1.4.528", decode_notification_request, encode_notification_request }, + { "2.16.840.1.113730.3.4.2", decode_manageDSAIT_request, encode_manageDSAIT_request }, { NULL, NULL, NULL } }; -- cgit From 3721bca79dc6ff409085a2fc40cbd060d25191d4 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 5 Feb 2006 20:48:27 +0000 Subject: r13354: Add tests to check that controls work properly Fix asq module, add a second_stage_init to register with rootdse Fix asq control ldap parsing routines (this was nasty to find out) (This used to be commit 933a80397d137f7d5b79c82a068d62bb6928ef47) --- source4/libcli/ldap/ldap_controls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index cb7b52d423..e02efdee2c 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -304,7 +304,7 @@ static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) } lac->src_attr_len = source_attribute.length; if (lac->src_attr_len) { - lac->source_attribute = talloc_memdup(lac, source_attribute.data, source_attribute.length); + lac->source_attribute = talloc_strndup(lac, source_attribute.data, source_attribute.length); if (!(lac->source_attribute)) { return False; -- cgit From 338c410fec8dbd902485e56567f6aecf256cdba2 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 6 Feb 2006 01:21:17 +0000 Subject: r13361: initial implementation of the vlv control seem still buggy, can't make w2k3 to like it yet (This used to be commit e1318383e91f6f6db39e3e3c9946fbb089753947) --- source4/libcli/ldap/ldap_controls.c | 245 +++++++++++++++++++++++++++++++++++- 1 file changed, 244 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index e02efdee2c..222b4a3358 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -304,7 +304,7 @@ static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) } lac->src_attr_len = source_attribute.length; if (lac->src_attr_len) { - lac->source_attribute = talloc_strndup(lac, source_attribute.data, source_attribute.length); + lac->source_attribute = talloc_strndup(lac, (char *)source_attribute.data, source_attribute.length); if (!(lac->source_attribute)) { return False; @@ -354,6 +354,154 @@ static BOOL decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void **out) return True; } +static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) +{ + DATA_BLOB assertion_value, context_id; + struct asn1_data data; + struct ldb_vlv_req_control *lvrc; + + if (!asn1_load(&data, in)) { + return False; + } + + lvrc = talloc(mem_ctx, struct ldb_vlv_req_control); + if (!lvrc) { + return False; + } + + if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_read_Integer(&data, &(lvrc->beforeCount))) { + return False; + } + + if (!asn1_read_Integer(&data, &(lvrc->afterCount))) { + return False; + } + + if (asn1_peek_tag(&data, ASN1_SEQUENCE(0))) { + + lvrc->type = 0; + + if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_read_Integer(&data, &(lvrc->match.byOffset.offset))) { + return False; + } + + if (!asn1_read_Integer(&data, &(lvrc->match.byOffset.contentCount))) { + return False; + } + + if (!asn1_end_tag(&data)) { + return False; + } + + } else { + + lvrc->type = 1; + + if (!asn1_read_OctetString(&data, &assertion_value)) { + return False; + } + lvrc->match.gtOrEq.value_len = assertion_value.length; + if (lvrc->match.gtOrEq.value_len) { + lvrc->match.gtOrEq.value = talloc_memdup(lvrc, assertion_value.data, assertion_value.length); + + if (!(lvrc->match.gtOrEq.value)) { + return False; + } + } else { + lvrc->match.gtOrEq.value = NULL; + } + } + + if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) { + if (!asn1_read_OctetString(&data, &context_id)) { + return False; + } + lvrc->ctxid_len = context_id.length; + if (lvrc->ctxid_len) { + lvrc->contextId = talloc_memdup(lvrc, context_id.data, context_id.length); + + if (!(lvrc->contextId)) { + return False; + } + } else { + lvrc->contextId = NULL; + } + } else { + lvrc->contextId = NULL; + lvrc->ctxid_len = 0; + } + + if (!asn1_end_tag(&data)) { + return False; + } + + *out = lvrc; + + return True; +} + +static BOOL decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out) +{ + DATA_BLOB context_id; + struct asn1_data data; + struct ldb_vlv_resp_control *lvrc; + + if (!asn1_load(&data, in)) { + return False; + } + + lvrc = talloc(mem_ctx, struct ldb_vlv_resp_control); + if (!lvrc) { + return False; + } + + if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_read_Integer(&data, &(lvrc->targetPosition))) { + return False; + } + + if (!asn1_read_Integer(&data, &(lvrc->contentCount))) { + return False; + } + + if (!asn1_read_enumerated(&data, &(lvrc->vlv_result))) { + return False; + } + + if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) { + if (!asn1_read_OctetString(&data, &context_id)) { + return False; + } + lvrc->contextId = talloc_strndup(lvrc, (const char *)context_id.data, context_id.length); + if (!lvrc->contextId) { + return False; + } + lvrc->ctxid_len = context_id.length; + } else { + lvrc->contextId = NULL; + lvrc->ctxid_len = 0; + } + + if (!asn1_end_tag(&data)) { + return False; + } + + *out = lvrc; + + 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); @@ -587,6 +735,99 @@ static BOOL encode_manageDSAIT_request(void *mem_ctx, void *in, DATA_BLOB *out) return True; } +static BOOL encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out) +{ + struct ldb_vlv_req_control *lvrc = talloc_get_type(in, struct ldb_vlv_req_control); + struct asn1_data data; + + ZERO_STRUCT(data); + + if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_write_Integer(&data, lvrc->beforeCount)) { + return False; + } + + if (!asn1_write_Integer(&data, lvrc->afterCount)) { + return False; + } + + if (lvrc->type == 0) { + if (!asn1_write_Integer(&data, lvrc->match.byOffset.offset)) { + return False; + } + + if (!asn1_write_Integer(&data, lvrc->match.byOffset.contentCount)) { + return False; + } + } else { + + if (!asn1_write_OctetString(&data, lvrc->match.gtOrEq.value, lvrc->match.gtOrEq.value_len)) { + return False; + } + } + + if (lvrc->ctxid_len) { + if (!asn1_write_OctetString(&data, lvrc->contextId, lvrc->ctxid_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; +} + +static BOOL encode_vlv_response(void *mem_ctx, void *in, DATA_BLOB *out) +{ + struct ldb_vlv_resp_control *lvrc = talloc_get_type(in, struct ldb_vlv_resp_control); + struct asn1_data data; + + ZERO_STRUCT(data); + + if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_write_Integer(&data, lvrc->targetPosition)) { + return False; + } + + if (!asn1_write_Integer(&data, lvrc->contentCount)) { + return False; + } + + if (!asn1_write_enumerated(&data, lvrc->vlv_result)) { + return False; + } + + if (lvrc->ctxid_len) { + if (!asn1_write_OctetString(&data, lvrc->contextId, lvrc->ctxid_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 }, @@ -596,6 +837,8 @@ struct control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.841", decode_dirsync_request, encode_dirsync_request }, { "1.2.840.113556.1.4.528", decode_notification_request, encode_notification_request }, { "2.16.840.1.113730.3.4.2", decode_manageDSAIT_request, encode_manageDSAIT_request }, + { "2.16.840.1.113730.3.4.9", decode_vlv_request, encode_vlv_request }, + { "2.16.840.1.113730.3.4.10", decode_vlv_response, encode_vlv_response }, { NULL, NULL, NULL } }; -- cgit From f7def09a1ec105294b189c0d933f59977a252057 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 6 Feb 2006 22:55:34 +0000 Subject: r13372: fixes ... still no joy (This used to be commit 0e2cca9153619d646b90f32620905ab66b017c6a) --- source4/libcli/ldap/ldap_controls.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 222b4a3358..f85e4843c1 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -755,6 +755,10 @@ static BOOL encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out) } if (lvrc->type == 0) { + if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + if (!asn1_write_Integer(&data, lvrc->match.byOffset.offset)) { return False; } @@ -762,6 +766,10 @@ static BOOL encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out) if (!asn1_write_Integer(&data, lvrc->match.byOffset.contentCount)) { return False; } + + if (!asn1_pop_tag(&data)) { + return False; + } } else { if (!asn1_write_OctetString(&data, lvrc->match.gtOrEq.value, lvrc->match.gtOrEq.value_len)) { -- cgit From f2e88ab7cf2010ffeae2f16762f88285d1a77fd8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Feb 2006 13:33:33 +0000 Subject: r13506: zero memory as some ASN.1 elements are optional, and we should initialize them for the internal use... found by 'make valgrindtest' metze (This used to be commit 1db9501c5261a974c6da1938537c7991ff6cfefd) --- source4/libcli/ldap/ldap_controls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index f85e4843c1..4a28fa510b 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -98,7 +98,7 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) if (!lssc) { return False; } - lssc[num] = talloc(lssc, struct ldb_server_sort_control); + lssc[num] = talloc_zero(lssc, struct ldb_server_sort_control); if (!lssc[num]) { return False; } -- cgit From 7449f4d8030e7d4a14c75d35af5ea68cf682d24f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Feb 2006 15:19:10 +0000 Subject: r13508: some ASN.1 element in LDAP are optional, make it possible to code the difference between a zero length and a NULL DATA_BLOB... metze (This used to be commit 54f0b19c55df8ad3882f31a114e2ea0e4cf940ae) --- source4/libcli/ldap/ldap.c | 102 ++++++++++++++++++++++++------------ source4/libcli/ldap/ldap.h | 12 ++--- source4/libcli/ldap/ldap_bind.c | 19 +++++-- source4/libcli/ldap/ldap_controls.c | 34 +++++++----- 4 files changed, 112 insertions(+), 55 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 496fec527f..55f1361e16 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -219,14 +219,9 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct asn1_push_tag(&data, ASN1_CONTEXT(3)); asn1_write_OctetString(&data, r->creds.SASL.mechanism, strlen(r->creds.SASL.mechanism)); - /* The value of data indicates if this - * optional element exists at all. In SASL - * there is a difference between NULL and - * zero-legnth, but our APIs don't express it - * well */ - if (r->creds.SASL.secblob.data) { - asn1_write_OctetString(&data, r->creds.SASL.secblob.data, - r->creds.SASL.secblob.length); + if (r->creds.SASL.secblob) { + asn1_write_OctetString(&data, r->creds.SASL.secblob->data, + r->creds.SASL.secblob->length); } asn1_pop_tag(&data); break; @@ -241,13 +236,8 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct struct ldap_BindResponse *r = &msg->r.BindResponse; asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); ldap_encode_response(&data, &r->response); - /* The value of data indicates if this - * optional element exists at all. In SASL - * there is a difference between NULL and - * zero-legnth, but our APIs don't express it - * well */ - if (r->SASL.secblob.data) { - asn1_write_ContextSimple(&data, 7, &r->SASL.secblob); + if (r->SASL.secblob) { + asn1_write_ContextSimple(&data, 7, r->SASL.secblob); } asn1_pop_tag(&data); break; @@ -396,7 +386,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct asn1_write_OctetString(&data, r->dn, strlen(r->dn)); asn1_write_OctetString(&data, r->newrdn, strlen(r->newrdn)); asn1_write_BOOLEAN(&data, r->deleteolddn); - if (r->newsuperior != NULL) { + if (r->newsuperior) { asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(0)); asn1_write(&data, r->newsuperior, strlen(r->newsuperior)); @@ -452,9 +442,11 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(0)); asn1_write(&data, r->oid, strlen(r->oid)); asn1_pop_tag(&data); - asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(1)); - asn1_write(&data, r->value.data, r->value.length); - asn1_pop_tag(&data); + if (r->value) { + asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(1)); + asn1_write(&data, r->value->data, r->value->length); + asn1_pop_tag(&data); + } asn1_pop_tag(&data); break; } @@ -462,6 +454,16 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); ldap_encode_response(&data, &r->response); + if (r->oid) { + asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(10)); + asn1_write(&data, r->oid, strlen(r->oid)); + asn1_pop_tag(&data); + } + if (r->value) { + asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(11)); + asn1_write(&data, r->value->data, r->value->length); + asn1_pop_tag(&data); + } asn1_pop_tag(&data); break; } @@ -960,12 +962,17 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) r->mechanism = LDAP_AUTH_MECH_SASL; asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism); if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { /* optional */ - asn1_read_OctetString(data, &r->creds.SASL.secblob); - if (r->creds.SASL.secblob.data) { - talloc_steal(msg, r->creds.SASL.secblob.data); + DATA_BLOB tmp_blob = data_blob(NULL, 0); + asn1_read_OctetString(data, &tmp_blob); + r->creds.SASL.secblob = talloc(msg, DATA_BLOB); + if (!r->creds.SASL.secblob) { + return False; } + *r->creds.SASL.secblob = data_blob_talloc(r->creds.SASL.secblob, + tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); } else { - r->creds.SASL.secblob = data_blob(NULL, 0); + r->creds.SASL.secblob = NULL; } asn1_end_tag(data); } @@ -981,10 +988,15 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) { DATA_BLOB tmp_blob = data_blob(NULL, 0); asn1_read_ContextSimple(data, 7, &tmp_blob); - r->SASL.secblob = data_blob_talloc(msg, tmp_blob.data, tmp_blob.length); + r->SASL.secblob = talloc(msg, DATA_BLOB); + if (!r->SASL.secblob) { + return False; + } + *r->SASL.secblob = data_blob_talloc(r->SASL.secblob, + tmp_blob.data, tmp_blob.length); data_blob_free(&tmp_blob); } else { - r->SASL.secblob = data_blob(NULL, 0); + r->SASL.secblob = NULL; } asn1_end_tag(data); break; @@ -1241,10 +1253,14 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { asn1_read_ContextSimple(data, 1, &tmp_blob); - r->value = data_blob_talloc(msg, tmp_blob.data, tmp_blob.length); + r->value = talloc(msg, DATA_BLOB); + if (!r->value) { + return False; + } + *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); data_blob_free(&tmp_blob); } else { - r->value = data_blob(NULL, 0); + r->value = NULL; } asn1_end_tag(data); @@ -1253,15 +1269,35 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_ExtendedResponse): { struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; + DATA_BLOB tmp_blob = data_blob(NULL, 0); + msg->type = LDAP_TAG_ExtendedResponse; asn1_start_tag(data, tag); ldap_decode_response(msg, data, &r->response); - /* I have to come across an operation that actually sends - * something back to really see what's going on. The currently - * needed pwdchange does not send anything back. */ - r->name = NULL; - r->value.data = NULL; - r->value.length = 0; + + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(10))) { + asn1_read_ContextSimple(data, 1, &tmp_blob); + r->oid = blob2string_talloc(msg, tmp_blob); + data_blob_free(&tmp_blob); + if (!r->oid) { + return False; + } + } else { + r->oid = NULL; + } + + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(11))) { + asn1_read_ContextSimple(data, 1, &tmp_blob); + r->value = talloc(msg, DATA_BLOB); + if (!r->value) { + return False; + } + *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->value = NULL; + } + asn1_end_tag(data); break; } diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 5283553f13..de284d23d1 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -109,7 +109,7 @@ struct ldap_BindRequest { const char *password; struct { const char *mechanism; - DATA_BLOB secblob; + DATA_BLOB *secblob;/* optional */ } SASL; } creds; }; @@ -117,7 +117,7 @@ struct ldap_BindRequest { struct ldap_BindResponse { struct ldap_Result response; union { - DATA_BLOB secblob; + DATA_BLOB *secblob;/* optional */ } SASL; }; @@ -192,7 +192,7 @@ struct ldap_ModifyDNRequest { const char *dn; const char *newrdn; BOOL deleteolddn; - const char *newsuperior; + const char *newsuperior;/* optional */ }; struct ldap_CompareRequest { @@ -207,13 +207,13 @@ struct ldap_AbandonRequest { struct ldap_ExtendedRequest { const char *oid; - DATA_BLOB value; + DATA_BLOB *value;/* optional */ }; struct ldap_ExtendedResponse { struct ldap_Result response; - const char *name; - DATA_BLOB value; + const char *oid;/* optional */ + DATA_BLOB *value;/* optional */ }; union ldap_Request { diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 2880298dd5..cacb0d150e 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -129,7 +129,16 @@ static struct ldap_message *new_ldap_sasl_bind_msg(struct ldap_connection *conn, res->r.BindRequest.dn = ""; 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; + if (secblob) { + res->r.BindRequest.creds.SASL.secblob = talloc(res, DATA_BLOB); + if (!res->r.BindRequest.creds.SASL.secblob) { + talloc_free(res); + return NULL; + } + *res->r.BindRequest.creds.SASL.secblob = *secblob; + } else { + res->r.BindRequest.creds.SASL.secblob = NULL; + } res->controls = NULL; return res; @@ -262,7 +271,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr } /* Perhaps we should make gensec_start_mech_by_sasl_list() return the name we got? */ - msg = new_ldap_sasl_bind_msg(tmp_ctx, conn->gensec->ops->sasl_name, &output); + msg = new_ldap_sasl_bind_msg(tmp_ctx, conn->gensec->ops->sasl_name, (output.data?&output:NULL)); if (msg == NULL) { status = NT_STATUS_NO_MEMORY; goto failed; @@ -297,7 +306,11 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr if (!NT_STATUS_EQUAL(gensec_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { break; } - input = response->r.BindResponse.SASL.secblob; + if (response->r.BindResponse.SASL.secblob) { + input = *response->r.BindResponse.SASL.secblob; + } else { + input = data_blob(NULL, 0); + } } if (NT_STATUS_IS_OK(status) && diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 4a28fa510b..5bd46cf7a9 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -304,7 +304,7 @@ static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) } lac->src_attr_len = source_attribute.length; if (lac->src_attr_len) { - lac->source_attribute = talloc_strndup(lac, (char *)source_attribute.data, source_attribute.length); + lac->source_attribute = talloc_strndup(lac, (const char *)source_attribute.data, source_attribute.length); if (!(lac->source_attribute)) { return False; @@ -864,7 +864,7 @@ BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Cont return False; } ctrl->oid = talloc_strndup(mem_ctx, (char *)oid.data, oid.length); - if (!(ctrl->oid)) { + if (!ctrl->oid) { return False; } @@ -878,13 +878,17 @@ BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Cont ctrl->value = NULL; + if (!asn1_peek_tag(data, ASN1_OCTET_STRING)) { + goto end_tag; + } + + if (!asn1_read_OctetString(data, &value)) { + return False; + } + 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))) { + if (!ldap_known_controls[i].decode(mem_ctx, value, &ctrl->value)) { return False; } break; @@ -894,6 +898,7 @@ BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Cont return False; } +end_tag: if (!asn1_end_tag(data)) { return False; } @@ -909,17 +914,21 @@ BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Cont 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; } } + if (!ctrl->value) { + goto pop_tag; + } + 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)) { @@ -932,12 +941,11 @@ BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Cont return False; } - if (value.length != 0) { - if (!asn1_write_OctetString(data, value.data, value.length)) { - return False; - } + if (!asn1_write_OctetString(data, value.data, value.length)) { + return False; } +pop_tag: if (!asn1_pop_tag(data)) { return False; } -- cgit From 00fe70e5b917769418f68eaa255d3a06a9a08ce7 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 22 Feb 2006 01:31:35 +0000 Subject: r13609: Get in the initial work on making ldb async Currently only ldb_ildap is async, the plan is to first make all backend support the async calls, and then remove the sync functions from backends and keep the only in the API. Modules will need to be transformed along the way. Simo (This used to be commit 1e2c13b2d52de7c534493dd79a2c0596a3e8c1f5) --- source4/libcli/ldap/ldap.c | 8 +++--- source4/libcli/ldap/ldap.h | 8 +----- source4/libcli/ldap/ldap_client.c | 34 ++++++++++++------------- source4/libcli/ldap/ldap_client.h | 4 ++- source4/libcli/ldap/ldap_controls.c | 49 ++++++++++++++++++++++++++++++------- source4/libcli/ldap/ldap_ildap.c | 14 ++++++----- 6 files changed, 73 insertions(+), 44 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 55f1361e16..42cad3a63e 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1309,19 +1309,19 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { int i; - struct ldap_Control **ctrl = NULL; + struct ldb_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+2); + ctrl = talloc_realloc(msg, ctrl, struct ldb_control *, i+2); if (!ctrl) { return False; } - ctrl[i] = talloc(ctrl, struct ldap_Control); + ctrl[i] = talloc(ctrl, struct ldb_control); if (!ctrl[i]) { return False; } @@ -1348,7 +1348,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) return NT_STATUS_OK if a blob has enough bytes in it to be a full ldap packet. Set packet_size if true. */ -NTSTATUS ldap_full_packet(void *private, DATA_BLOB blob, size_t *packet_size) +NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size) { return asn1_full_tag(blob, ASN1_SEQUENCE(0), packet_size); } diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index de284d23d1..1deabf0b10 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -240,17 +240,11 @@ union ldap_Request { struct ldap_ExtendedResponse ExtendedResponse; }; -struct ldap_Control { - const char *oid; - BOOL critical; - void *value; -}; - struct ldap_message { int messageid; enum ldap_request_tag type; union ldap_Request r; - struct ldap_Control **controls; + struct ldb_control **controls; }; #include "libcli/ldap/ldap_proto.h" diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 9103e939e7..364961cf47 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -90,9 +90,9 @@ static void ldap_connection_dead(struct ldap_connection *conn) /* handle packet errors */ -static void ldap_error_handler(void *private, NTSTATUS status) +static void ldap_error_handler(void *private_data, NTSTATUS status) { - struct ldap_connection *conn = talloc_get_type(private, + struct ldap_connection *conn = talloc_get_type(private_data, struct ldap_connection); ldap_connection_dead(conn); } @@ -155,14 +155,14 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message check if a blob is a complete ldap packet handle wrapper or unwrapped connections */ -NTSTATUS ldap_complete_packet(void *private, DATA_BLOB blob, size_t *size) +NTSTATUS ldap_complete_packet(void *private_data, DATA_BLOB blob, size_t *size) { - struct ldap_connection *conn = talloc_get_type(private, + struct ldap_connection *conn = talloc_get_type(private_data, struct ldap_connection); if (conn->enable_wrap) { - return packet_full_request_u32(private, blob, size); + return packet_full_request_u32(private_data, blob, size); } - return ldap_full_packet(private, blob, size); + return ldap_full_packet(private_data, blob, size); } /* @@ -234,9 +234,9 @@ static NTSTATUS ldap_decode_wrapped(struct ldap_connection *conn, DATA_BLOB blob /* handle ldap recv events */ -static NTSTATUS ldap_recv_handler(void *private, DATA_BLOB blob) +static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob) { - struct ldap_connection *conn = talloc_get_type(private, + struct ldap_connection *conn = talloc_get_type(private_data, struct ldap_connection); if (conn->enable_wrap) { return ldap_decode_wrapped(conn, blob); @@ -250,9 +250,9 @@ static NTSTATUS ldap_recv_handler(void *private, DATA_BLOB blob) handle ldap socket events */ static void ldap_io_handler(struct event_context *ev, struct fd_event *fde, - uint16_t flags, void *private) + uint16_t flags, void *private_data) { - struct ldap_connection *conn = talloc_get_type(private, + struct ldap_connection *conn = talloc_get_type(private_data, struct ldap_connection); if (flags & EVENT_FD_WRITE) { packet_queue_run(conn->packet); @@ -433,9 +433,9 @@ static int ldap_request_destructor(void *ptr) called on timeout of a ldap request */ static void ldap_request_timeout(struct event_context *ev, struct timed_event *te, - struct timeval t, void *private) + struct timeval t, void *private_data) { - struct ldap_request *req = talloc_get_type(private, struct ldap_request); + struct ldap_request *req = talloc_get_type(private_data, struct ldap_request); req->status = NT_STATUS_IO_TIMEOUT; if (req->state == LDAP_REQUEST_PENDING) { DLIST_REMOVE(req->conn->pending, req); @@ -451,9 +451,9 @@ static void ldap_request_timeout(struct event_context *ev, struct timed_event *t called on completion of a one-way ldap request */ static void ldap_request_complete(struct event_context *ev, struct timed_event *te, - struct timeval t, void *private) + struct timeval t, void *private_data) { - struct ldap_request *req = talloc_get_type(private, struct ldap_request); + struct ldap_request *req = talloc_get_type(private_data, struct ldap_request); if (req->async.fn) { req->async.fn(req); } @@ -534,9 +534,9 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, DLIST_ADD(conn->pending, req); /* put a timeout on the request */ - event_add_timed(conn->event.event_ctx, req, - timeval_current_ofs(conn->timeout, 0), - ldap_request_timeout, req); + req->time_event = event_add_timed(conn->event.event_ctx, req, + timeval_current_ofs(conn->timeout, 0), + ldap_request_timeout, req); return req; diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h index ee458dc5b0..3f71c42f22 100644 --- a/source4/libcli/ldap/ldap_client.h +++ b/source4/libcli/ldap/ldap_client.h @@ -42,8 +42,10 @@ struct ldap_request { DATA_BLOB data; struct { void (*fn)(struct ldap_request *); - void *private; + void *private_data; } async; + + struct timed_event *time_event; }; diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 5bd46cf7a9..373b71d370 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -381,10 +381,14 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) return False; } - if (asn1_peek_tag(&data, ASN1_SEQUENCE(0))) { + if (asn1_peek_tag(&data, ASN1_CONTEXT(0))) { lvrc->type = 0; + if (!asn1_start_tag(&data, ASN1_CONTEXT(0))) { + return False; + } + if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { return False; } @@ -397,7 +401,11 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) return False; } - if (!asn1_end_tag(&data)) { + if (!asn1_end_tag(&data)) { /*SEQUENCE*/ + return False; + } + + if (!asn1_end_tag(&data)) { /*CONTEXT*/ return False; } @@ -405,6 +413,10 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) lvrc->type = 1; + if (!asn1_start_tag(&data, ASN1_CONTEXT(1))) { + return False; + } + if (!asn1_read_OctetString(&data, &assertion_value)) { return False; } @@ -418,6 +430,10 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) } else { lvrc->match.gtOrEq.value = NULL; } + + if (!asn1_end_tag(&data)) { /*CONTEXT*/ + return False; + } } if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) { @@ -755,6 +771,10 @@ static BOOL encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out) } if (lvrc->type == 0) { + if (!asn1_push_tag(&data, ASN1_CONTEXT(0))) { + return False; + } + if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { return False; } @@ -767,14 +787,25 @@ static BOOL encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out) return False; } - if (!asn1_pop_tag(&data)) { + if (!asn1_pop_tag(&data)) { /*SEQUENCE*/ + return False; + } + + if (!asn1_pop_tag(&data)) { /*CONTEXT*/ return False; } } else { + if (!asn1_push_tag(&data, ASN1_CONTEXT(1))) { + return False; + } if (!asn1_write_OctetString(&data, lvrc->match.gtOrEq.value, lvrc->match.gtOrEq.value_len)) { return False; } + + if (!asn1_pop_tag(&data)) { /*CONTEXT*/ + return False; + } } if (lvrc->ctxid_len) { @@ -850,7 +881,7 @@ struct control_handler ldap_known_controls[] = { { NULL, NULL, NULL } }; -BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Control *ctrl) +BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldb_control *ctrl) { int i; DATA_BLOB oid; @@ -876,7 +907,7 @@ BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Cont ctrl->critical = False; } - ctrl->value = NULL; + ctrl->data = NULL; if (!asn1_peek_tag(data, ASN1_OCTET_STRING)) { goto end_tag; @@ -888,7 +919,7 @@ BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Cont 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].decode(mem_ctx, value, &ctrl->value)) { + if (!ldap_known_controls[i].decode(mem_ctx, value, &ctrl->data)) { return False; } break; @@ -906,7 +937,7 @@ end_tag: return True; } -BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Control *ctrl) +BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldb_control *ctrl) { DATA_BLOB value; int i; @@ -925,13 +956,13 @@ BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldap_Cont } } - if (!ctrl->value) { + if (!ctrl->data) { goto pop_tag; } 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)) { + if (!ldap_known_controls[i].encode(mem_ctx, ctrl->data, &value)) { return False; } break; diff --git a/source4/libcli/ldap/ldap_ildap.c b/source4/libcli/ldap/ldap_ildap.c index a5227ec37f..f26fb7db78 100644 --- a/source4/libcli/ldap/ldap_ildap.c +++ b/source4/libcli/ldap/ldap_ildap.c @@ -152,13 +152,13 @@ int ildap_count_entries(struct ldap_connection *conn, struct ldap_message **res) /* - perform a ldap search + perform a synchronous ldap search */ 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 ldb_control **control_req, + struct ldb_control ***control_res, struct ldap_message ***results) { struct ldap_message *msg; @@ -203,7 +203,9 @@ NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn, break; } - if (res->type != LDAP_TAG_SearchResultEntry) continue; + if (res->type != LDAP_TAG_SearchResultEntry && + res->type != LDAP_TAG_SearchResultReference) + continue; (*results) = talloc_realloc(conn, *results, struct ldap_message *, n+2); if (*results == NULL) { @@ -228,8 +230,8 @@ 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 ldb_control **control_req, + struct ldb_control ***control_res, struct ldap_message ***results) { struct ldb_parse_tree *tree = ldb_parse_tree(conn, expression); -- cgit From ceb6e9717bf8ea5c83a01e159a7006fd8651620c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 7 Mar 2006 16:41:04 +0000 Subject: r13960: Generate makefile rules for installing/removing shared modules. (This used to be commit 2c746980328431ab04852dc668899e3eb042da99) --- source4/libcli/ldap/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 59d2d1ea30..c0ad8d157f 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -9,7 +9,7 @@ OBJ_FILES = ldap.o \ ldap_ndr.o \ ldap_ildap.o \ ldap_controls.o -REQUIRED_SUBSYSTEMS = LIBCLI_UTILS LIBEVENTS GENSEC SOCKET NDR_SAMR LIBTLS \ +REQUIRED_SUBSYSTEMS = LIBCLI_UTILS LIBEVENTS gensec SOCKET NDR_SAMR LIBTLS \ LIBPACKET # End SUBSYSTEM LIBCLI_LDAP ################################# -- cgit From f9827c2ad157b9a5d26028ea6f3e7e1cec871ca1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 15 Mar 2006 05:30:39 +0000 Subject: r14423: don't die on no controls (This used to be commit 9787fb8e917c22ffe910062630dc4f32473a9fab) --- source4/libcli/ldap/ldap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 42cad3a63e..c1fc461b5f 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1332,7 +1332,9 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) } - ctrl[i] = NULL; + if (ctrl != NULL) { + ctrl[i] = NULL; + } msg->controls = ctrl; -- cgit From 07fd3bd5121aa9b81b6c7a14910f09f64ab4bad9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 15 Mar 2006 05:31:51 +0000 Subject: r14424: another empty controls case (This used to be commit 7d0eb678bf3649fb4e09da039dd1b716ea3df2cc) --- source4/libcli/ldap/ldap_controls.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 373b71d370..ccb1b74a55 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -137,7 +137,9 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) } } - lssc[num] = NULL; + if (lssc != NULL) { + lssc[num] = NULL; + } if (!asn1_end_tag(&data)) { return False; -- cgit From 5b0051e0325aea7e46715aa61bba0a1dc025132c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 17 Mar 2006 13:55:10 +0000 Subject: r14511: Install more headers (This used to be commit e1f896948fad8cf5a1aec300865c250c5721ee7d) --- source4/libcli/ldap/config.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index c0ad8d157f..624b2603ec 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,7 +1,8 @@ ################################# # Start SUBSYSTEM LIBCLI_LDAP [SUBSYSTEM::LIBCLI_LDAP] -PRIVATE_PROTO_HEADER = ldap_proto.h +PUBLIC_PROTO_HEADER = ldap_proto.h +PUBLIC_HEADERS = ldap.h OBJ_FILES = ldap.o \ ldap_client.o \ ldap_bind.o \ -- cgit From 35349a58df5b69446607fbd742a05f57f3515319 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 18 Mar 2006 15:42:57 +0000 Subject: r14542: Remove librpc, libndr and libnbt from includes.h (This used to be commit 51b4270513752d2eafbe77f9de598de16ef84a1f) --- source4/libcli/ldap/ldap.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 1deabf0b10..ba0f801832 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -247,6 +247,10 @@ struct ldap_message { struct ldb_control **controls; }; +struct event_context; +struct cli_credentials; +struct dom_sid; + #include "libcli/ldap/ldap_proto.h" #endif -- cgit From 935af3eb1963761b4c8fd9e0e9902ad592f948bf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 25 Mar 2006 18:47:47 +0000 Subject: r14724: Rearrange some source files, install more headers. (This used to be commit 7146c1600f29c349e5bb78f810e7e170b535dd37) --- source4/libcli/ldap/config.mk | 4 ++-- source4/libcli/ldap/ldap.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 624b2603ec..f59da733eb 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -10,7 +10,7 @@ OBJ_FILES = ldap.o \ ldap_ndr.o \ ldap_ildap.o \ ldap_controls.o -REQUIRED_SUBSYSTEMS = LIBCLI_UTILS LIBEVENTS gensec SOCKET NDR_SAMR LIBTLS \ - LIBPACKET +REQUIRED_SUBSYSTEMS = LIBSAMBA-ERRORS LIBEVENTS gensec SOCKET NDR_SAMR LIBTLS \ + LIBPACKET ASN1_UTIL # End SUBSYSTEM LIBCLI_LDAP ################################# diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index ba0f801832..30c5acc6fb 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -250,6 +250,7 @@ struct ldap_message { struct event_context; struct cli_credentials; struct dom_sid; +struct asn1_data; #include "libcli/ldap/ldap_proto.h" -- cgit From 60f3ef505238aaceb40101d5e839d2e303c9c7bd Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 23 Apr 2006 17:22:32 +0000 Subject: r15181: Don't try kerberos sign/seal when in SSL (This used to be commit 3be3b1130c41e8e372531c137c46f91c5c0acf98) --- source4/libcli/ldap/ldap_bind.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index cacb0d150e..585bdbb234 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -25,6 +25,7 @@ #include "includes.h" #include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" +#include "lib/tls/tls.h" #include "auth/auth.h" static struct ldap_message *new_ldap_simple_bind_msg(struct ldap_connection *conn, @@ -173,7 +174,11 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr goto failed; } - gensec_want_feature(conn->gensec, 0 | GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL); + /* require Kerberos SIGN/SEAL only if we don't use SSL + * Windows seem not to like double encryption */ + if (conn->tls == NULL || (! tls_enabled(conn->tls))) { + gensec_want_feature(conn->gensec, 0 | GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL); + } status = gensec_set_credentials(conn->gensec, creds); if (!NT_STATUS_IS_OK(status)) { -- cgit From 69b51f702af1ded825d5c17bdb97014cac12e752 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 24 Apr 2006 15:47:59 +0000 Subject: r15207: Introduce PRIVATE_DEPENDENCIES and PUBLIC_DEPENDENCIES as replacement for REQUIRED_SUBSYSTEMS. (This used to be commit adc8a019b6da256f104abed1b82bfde6998a2ac9) --- source4/libcli/ldap/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index f59da733eb..26f230d7ef 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -10,7 +10,7 @@ OBJ_FILES = ldap.o \ ldap_ndr.o \ ldap_ildap.o \ ldap_controls.o -REQUIRED_SUBSYSTEMS = LIBSAMBA-ERRORS LIBEVENTS gensec SOCKET NDR_SAMR LIBTLS \ +PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS gensec SOCKET NDR_SAMR LIBTLS \ LIBPACKET ASN1_UTIL # End SUBSYSTEM LIBCLI_LDAP ################################# -- cgit From 8f164299473553ee28f4fbf1d9a120840c5e5feb Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 25 Apr 2006 11:50:32 +0000 Subject: r15238: Add some code to automatically reconnect if we want to. (This used to be commit e2102999e26566543162455b34adbd2b0486b74d) --- source4/libcli/ldap/ldap_bind.c | 53 ++++++++++++++++++++++++++ source4/libcli/ldap/ldap_client.c | 78 ++++++++++++++++++++++++++++++++++----- source4/libcli/ldap/ldap_client.h | 14 ++++++- 3 files changed, 134 insertions(+), 11 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 585bdbb234..c33d53f775 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -28,6 +28,39 @@ #include "lib/tls/tls.h" #include "auth/auth.h" +struct ldap_simple_creds { + const char *dn; + const char *pw; +}; + +NTSTATUS ldap_rebind(struct ldap_connection *conn) +{ + NTSTATUS status; + struct ldap_simple_creds *creds; + + switch (conn->bind.type) { + case LDAP_BIND_SASL: + status = ldap_bind_sasl(conn, (struct cli_credentials *)conn->bind.creds); + break; + + case LDAP_BIND_SIMPLE: + creds = (struct ldap_simple_creds *)conn->bind.creds; + + if (creds == NULL) { + return NT_STATUS_UNSUCCESSFUL; + } + + status = ldap_bind_simple(conn, creds->dn, creds->pw); + break; + + default: + return NT_STATUS_UNSUCCESSFUL; + } + + return status; +} + + static struct ldap_message *new_ldap_simple_bind_msg(struct ldap_connection *conn, const char *dn, const char *pw) { @@ -110,6 +143,20 @@ NTSTATUS ldap_bind_simple(struct ldap_connection *conn, talloc_free(req); + if (NT_STATUS_IS_OK(status)) { + struct ldap_simple_creds *creds = talloc(conn, struct ldap_simple_creds); + if (creds == NULL) { + return NT_STATUS_NO_MEMORY; + } + creds->dn = talloc_strdup(creds, dn); + creds->pw = talloc_strdup(creds, pw); + if (creds->dn == NULL || creds->pw == NULL) { + return NT_STATUS_NO_MEMORY; + } + conn->bind.type = LDAP_BIND_SIMPLE; + conn->bind.creds = creds; + } + return status; } @@ -325,6 +372,12 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr } talloc_free(tmp_ctx); + + if (NT_STATUS_IS_OK(status)) { + conn->bind.type = LDAP_BIND_SASL; + conn->bind.creds = creds; + } + return status; failed: diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 364961cf47..344605f4ec 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -33,6 +33,7 @@ #include "libcli/composite/composite.h" #include "lib/stream/packet.h" #include "auth/gensec/gensec.h" +#include "system/time.h" /* @@ -62,10 +63,12 @@ struct ldap_connection *ldap_new_connection(TALLOC_CTX *mem_ctx, /* set a reasonable request timeout */ conn->timeout = 60; + /* explicitly avoid reconnections by default */ + conn->reconnect.max_retries = 0; + return conn; } - /* the connection is dead */ @@ -73,6 +76,7 @@ static void ldap_connection_dead(struct ldap_connection *conn) { struct ldap_request *req; + /* return an error for any pending request ... */ while (conn->pending) { req = conn->pending; DLIST_REMOVE(req->conn->pending, req); @@ -84,9 +88,16 @@ static void ldap_connection_dead(struct ldap_connection *conn) } talloc_free(conn->tls); + talloc_free(conn->sock); /* this will also free event.fde */ + talloc_free(conn->packet); conn->tls = NULL; + conn->sock = NULL; + conn->event.fde = NULL; + conn->packet = NULL; } +static void ldap_reconnect(struct ldap_connection *conn); + /* handle packet errors */ @@ -95,6 +106,9 @@ static void ldap_error_handler(void *private_data, NTSTATUS status) struct ldap_connection *conn = talloc_get_type(private_data, struct ldap_connection); ldap_connection_dead(conn); + + /* but try to reconnect so that the ldb client can go on */ + ldap_reconnect(conn); } @@ -325,6 +339,11 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, struct composite_context *result, *ctx; struct ldap_connect_state *state; + if (conn->reconnect.url == NULL) { + conn->reconnect.url = talloc_strdup(conn, url); + if (conn->reconnect.url == NULL) goto failed; + } + result = talloc_zero(NULL, struct composite_context); if (result == NULL) goto failed; result->state = COMPOSITE_STATE_IN_PROGRESS; @@ -419,6 +438,40 @@ NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url) return ldap_connect_recv(ctx); } +/* Actually this function is NOT ASYNC safe, FIXME? */ +static void ldap_reconnect(struct ldap_connection *conn) +{ + NTSTATUS status; + time_t now = time(NULL); + + /* do we have set up reconnect ? */ + if (conn->reconnect.max_retries == 0) return; + + /* is the retry time expired ? */ + if (now > conn->reconnect.previous + 30) { + conn->reconnect.retries = 0; + conn->reconnect.previous = now; + } + + /* are we reconnectind too often and too fast? */ + if (conn->reconnect.retries > conn->reconnect.max_retries) return; + + /* keep track of the number of reconnections */ + conn->reconnect.retries++; + + /* reconnect */ + status = ldap_connect(conn, conn->reconnect.url); + if ( ! NT_STATUS_IS_OK(status)) { + return; + } + + /* rebind */ + status = ldap_rebind(conn); + if ( ! NT_STATUS_IS_OK(status)) { + ldap_connection_dead(conn); + } +} + /* destroy an open ldap request */ static int ldap_request_destructor(void *ptr) { @@ -466,15 +519,16 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, struct ldap_message *msg) { struct ldap_request *req; - NTSTATUS status; + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + + req = talloc_zero(conn, struct ldap_request); + if (req == NULL) return NULL; if (conn->tls == NULL) { - return NULL; + status = NT_STATUS_INVALID_CONNECTION; + goto failed; } - req = talloc_zero(conn, struct ldap_request); - if (req == NULL) goto failed; - req->state = LDAP_REQUEST_SEND; req->conn = conn; req->messageid = conn->next_messageid++; @@ -541,8 +595,12 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, return req; failed: - talloc_free(req); - return NULL; + req->status = status; + req->state = LDAP_REQUEST_ERROR; + event_add_timed(conn->event.event_ctx, req, timeval_zero(), + ldap_request_complete, req); + + return req; } @@ -552,7 +610,7 @@ failed: */ NTSTATUS ldap_request_wait(struct ldap_request *req) { - while (req->state != LDAP_REQUEST_DONE) { + while (req->state <= LDAP_REQUEST_DONE) { if (event_loop_once(req->conn->event.event_ctx) != 0) { req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; break; @@ -665,7 +723,7 @@ NTSTATUS ldap_result_n(struct ldap_request *req, int n, struct ldap_message **ms NT_STATUS_HAVE_NO_MEMORY(req); - while (req->state != LDAP_REQUEST_DONE && n >= req->num_replies) { + while (req->state <= LDAP_REQUEST_DONE && n >= req->num_replies) { if (event_loop_once(req->conn->event.event_ctx) != 0) { return NT_STATUS_UNEXPECTED_NETWORK_ERROR; } diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h index 3f71c42f22..7801f8b6bc 100644 --- a/source4/libcli/ldap/ldap_client.h +++ b/source4/libcli/ldap/ldap_client.h @@ -23,7 +23,7 @@ #include "libcli/ldap/ldap.h" -enum ldap_request_state {LDAP_REQUEST_SEND, LDAP_REQUEST_PENDING, LDAP_REQUEST_DONE}; +enum ldap_request_state { LDAP_REQUEST_SEND=1, LDAP_REQUEST_PENDING=2, LDAP_REQUEST_DONE=3, LDAP_REQUEST_ERROR=4 }; /* this is the handle that the caller gets when an async ldap message is sent */ @@ -60,6 +60,18 @@ struct ldap_connection { const char *auth_dn; const char *simple_pw; + struct { + char *url; + int max_retries; + int retries; + time_t previous; + } reconnect; + + struct { + enum { LDAP_BIND_SIMPLE, LDAP_BIND_SASL } type; + void *creds; + } bind; + /* next message id to assign */ unsigned next_messageid; -- cgit From 13f17436ea98544315dcf119b0a395a8359fb3e9 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 25 Apr 2006 12:34:13 +0000 Subject: r15241: Add helper function to set reconnect status defaults (This used to be commit 6fff8f871a607e561531e2aabef37f3469aa85e9) --- source4/libcli/ldap/ldap_client.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 344605f4ec..74ac64a68d 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -438,6 +438,17 @@ NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url) return ldap_connect_recv(ctx); } +/* set reconnect parameters */ + +void ldap_set_reconn_params(struct ldap_connection *conn, int max_retries) +{ + if (conn) { + conn->reconnect.max_retries = max_retries; + conn->reconnect.retries = 0; + conn->reconnect.previous = time(NULL); + } +} + /* Actually this function is NOT ASYNC safe, FIXME? */ static void ldap_reconnect(struct ldap_connection *conn) { -- cgit From 886329898c3e6184642a6e454fd10802c388dc7e Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 26 Apr 2006 16:52:45 +0000 Subject: r15288: fix some problems (This used to be commit d448389be88b3bb9d6f9a3b8a1e1597c4988a0ff) --- source4/libcli/ldap/ldap_client.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 74ac64a68d..27cab38916 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -88,7 +88,7 @@ static void ldap_connection_dead(struct ldap_connection *conn) } talloc_free(conn->tls); - talloc_free(conn->sock); /* this will also free event.fde */ +/* talloc_free(conn->sock); this will also free event.fde */ talloc_free(conn->packet); conn->tls = NULL; conn->sock = NULL; @@ -621,7 +621,7 @@ failed: */ NTSTATUS ldap_request_wait(struct ldap_request *req) { - while (req->state <= LDAP_REQUEST_DONE) { + while (req->state < LDAP_REQUEST_DONE) { if (event_loop_once(req->conn->event.event_ctx) != 0) { req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; break; @@ -734,7 +734,7 @@ NTSTATUS ldap_result_n(struct ldap_request *req, int n, struct ldap_message **ms NT_STATUS_HAVE_NO_MEMORY(req); - while (req->state <= LDAP_REQUEST_DONE && n >= req->num_replies) { + while (req->state < LDAP_REQUEST_DONE && n >= req->num_replies) { if (event_loop_once(req->conn->event.event_ctx) != 0) { return NT_STATUS_UNEXPECTED_NETWORK_ERROR; } -- cgit From 710ea949886dd57c66dc6d397e0ea41c89736107 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 27 Apr 2006 16:09:17 +0000 Subject: r15297: Move create_security_token() to samdb as it requires SAMDB (and the rest of LIBSECURITY doesn't) Make the ldb password_hash module only depend on some keys manipulation code, not full heimdal Some other dependency fixes (This used to be commit 5b3ab728edfc9cdd9eee16ad0fe6dfd4b5ced630) --- source4/libcli/ldap/config.mk | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 26f230d7ef..ec5c48b48c 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -10,7 +10,8 @@ OBJ_FILES = ldap.o \ ldap_ndr.o \ ldap_ildap.o \ ldap_controls.o -PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS gensec SOCKET NDR_SAMR LIBTLS \ - LIBPACKET ASN1_UTIL +PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET +PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE SOCKET NDR_SAMR LIBTLS ASN1_UTIL +#PRIVATE_DEPENDENCIES = gensec # End SUBSYSTEM LIBCLI_LDAP ################################# -- cgit From 9220144604e0050cd823fd107c311bf9013cd5a5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 29 Apr 2006 02:45:34 +0000 Subject: r15313: Fix some dependencies in dso mode (This used to be commit f0afe9e2ff16515df1b3226b479b19ea3e9c3d0c) --- source4/libcli/ldap/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index ec5c48b48c..167a07eddd 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -11,7 +11,7 @@ OBJ_FILES = ldap.o \ ldap_ildap.o \ ldap_controls.o PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET -PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE SOCKET NDR_SAMR LIBTLS ASN1_UTIL +PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE SOCKET LIBCLI_RESOLVE NDR_SAMR LIBTLS ASN1_UTIL #PRIVATE_DEPENDENCIES = gensec # End SUBSYSTEM LIBCLI_LDAP ################################# -- cgit From cf0f4ec073b694e43daeeddf9aab51cd3e51fd2b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 30 Apr 2006 13:54:03 +0000 Subject: r15358: Fix some compiler warnings / type safety. Found by tcc (This used to be commit 12ba42de5886f9f4f9b1698476557e0c217d06f3) --- source4/libcli/ldap/ldap_controls.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index ccb1b74a55..47b1262aea 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -127,9 +127,11 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) } if (asn1_peek_tag(&data, ASN1_BOOLEAN)) { - if (!asn1_read_BOOLEAN(&data, &(lssc[num]->reverse))) { + bool reverse; + if (!asn1_read_BOOLEAN(&data, &reverse)) { return False; } + lssc[num]->reverse = reverse; } if (!asn1_end_tag(&data)) { @@ -902,9 +904,11 @@ BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldb_contr } if (asn1_peek_tag(data, ASN1_BOOLEAN)) { - if (!asn1_read_BOOLEAN(data, &(ctrl->critical))) { + bool critical; + if (!asn1_read_BOOLEAN(data, &critical)) { return False; } + critical = ctrl->critical; } else { ctrl->critical = False; } -- cgit From 37e94956e0a976b6d144b5885b2ef18bb8e4b39b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 30 Apr 2006 20:00:37 +0000 Subject: r15365: Fix error in my previous commit, caught by metze. (This used to be commit 0d99397007960e555f562f1498a202407e235f36) --- source4/libcli/ldap/ldap_controls.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 47b1262aea..f4f54ec2e2 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -127,7 +127,7 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) } if (asn1_peek_tag(&data, ASN1_BOOLEAN)) { - bool reverse; + BOOL reverse; if (!asn1_read_BOOLEAN(&data, &reverse)) { return False; } @@ -904,11 +904,11 @@ BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldb_contr } if (asn1_peek_tag(data, ASN1_BOOLEAN)) { - bool critical; + BOOL critical; if (!asn1_read_BOOLEAN(data, &critical)) { return False; } - critical = ctrl->critical; + ctrl->critical = critical; } else { ctrl->critical = False; } -- cgit From 6275553baee5593f9e13a0635755b2deb275c3be Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 1 May 2006 12:54:36 +0000 Subject: r15373: Rename SOCKET to LIBSAMBA-SOCKET to prevent name clashes with -lsocket on SUN boxes. (This used to be commit c95ad11307dc89384c10bd5919817bf12d9c1ed9) --- source4/libcli/ldap/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 167a07eddd..c1c74cd168 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -11,7 +11,7 @@ OBJ_FILES = ldap.o \ ldap_ildap.o \ ldap_controls.o PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET -PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE SOCKET LIBCLI_RESOLVE NDR_SAMR LIBTLS ASN1_UTIL +PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE LIBSAMBA-SOCKET LIBCLI_RESOLVE NDR_SAMR LIBTLS ASN1_UTIL #PRIVATE_DEPENDENCIES = gensec # End SUBSYSTEM LIBCLI_LDAP ################################# -- cgit From 46f627ea7afb0ad006efadf593bf202cea05194e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 1 May 2006 22:07:12 +0000 Subject: r15384: Improve naming of socket library, disable Requires(.private)? fields in pkg-config files for now as they break external projects. (This used to be commit f919fd6655f00361691e676d260bd40e0b8ddcc7) --- source4/libcli/ldap/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index c1c74cd168..88ebc3256f 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -11,7 +11,7 @@ OBJ_FILES = ldap.o \ ldap_ildap.o \ ldap_controls.o PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET -PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE LIBSAMBA-SOCKET LIBCLI_RESOLVE NDR_SAMR LIBTLS ASN1_UTIL +PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket LIBCLI_RESOLVE NDR_SAMR LIBTLS ASN1_UTIL #PRIVATE_DEPENDENCIES = gensec # End SUBSYSTEM LIBCLI_LDAP ################################# -- cgit From 742c110cd67f4995639822981e8bfcb1f652f2c4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 2 May 2006 20:15:47 +0000 Subject: r15400: Move the TLS code behind the socket interface. This reduces caller complexity, because the TLS code is now called just like any other socket. (A new socket context is returned by the tls_init_server and tls_init_client routines). When TLS is not available, the original socket is returned. Andrew Bartlett (This used to be commit 09b2f30dfa7a640f5187b4933204e9680be61497) --- source4/libcli/ldap/ldap_bind.c | 2 +- source4/libcli/ldap/ldap_client.c | 39 +++++++++++++++++++++------------------ source4/libcli/ldap/ldap_client.h | 1 - 3 files changed, 22 insertions(+), 20 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index c33d53f775..6714d68b0e 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -223,7 +223,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr /* require Kerberos SIGN/SEAL only if we don't use SSL * Windows seem not to like double encryption */ - if (conn->tls == NULL || (! tls_enabled(conn->tls))) { + if (!tls_enabled(conn->sock)) { gensec_want_feature(conn->gensec, 0 | GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL); } diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 27cab38916..8d815c7103 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -32,6 +32,7 @@ #include "libcli/ldap/ldap_client.h" #include "libcli/composite/composite.h" #include "lib/stream/packet.h" +#include "lib/tls/tls.h" #include "auth/gensec/gensec.h" #include "system/time.h" @@ -85,12 +86,10 @@ static void ldap_connection_dead(struct ldap_connection *conn) if (req->async.fn) { req->async.fn(req); } - } + } - talloc_free(conn->tls); -/* talloc_free(conn->sock); this will also free event.fde */ + talloc_free(conn->sock); /* this will also free event.fde */ talloc_free(conn->packet); - conn->tls = NULL; conn->sock = NULL; conn->event.fde = NULL; conn->packet = NULL; @@ -270,7 +269,7 @@ static void ldap_io_handler(struct event_context *ev, struct fd_event *fde, struct ldap_connection); if (flags & EVENT_FD_WRITE) { packet_queue_run(conn->packet); - if (conn->tls == NULL) return; + if (!tls_enabled(conn->sock)) return; } if (flags & EVENT_FD_READ) { packet_recv(conn->packet); @@ -339,11 +338,6 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, struct composite_context *result, *ctx; struct ldap_connect_state *state; - if (conn->reconnect.url == NULL) { - conn->reconnect.url = talloc_strdup(conn, url); - if (conn->reconnect.url == NULL) goto failed; - } - result = talloc_zero(NULL, struct composite_context); if (result == NULL) goto failed; result->state = COMPOSITE_STATE_IN_PROGRESS; @@ -357,6 +351,11 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, state->conn = conn; + if (conn->reconnect.url == NULL) { + conn->reconnect.url = talloc_strdup(conn, url); + if (conn->reconnect.url == NULL) goto failed; + } + state->ctx->status = ldap_parse_basic_url(conn, url, &conn->host, &conn->port, &conn->ldaps); if (!NT_STATUS_IS_OK(state->ctx->status)) { @@ -379,6 +378,7 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, static void ldap_connect_recv_conn(struct composite_context *ctx) { + struct socket_context *initial_socket; struct ldap_connect_state *state = talloc_get_type(ctx->async.private_data, struct ldap_connect_state); @@ -398,21 +398,24 @@ static void ldap_connect_recv_conn(struct composite_context *ctx) return; } - conn->tls = tls_init_client(conn->sock, conn->event.fde, conn->ldaps); - if (conn->tls == NULL) { - talloc_free(conn->sock); - return; + talloc_steal(conn, conn->sock); + initial_socket = conn->sock; + if (conn->ldaps) { + conn->sock = tls_init_client(conn->sock, conn->event.fde); + if (conn->sock == NULL) { + talloc_free(initial_socket); + return; + } } - talloc_steal(conn, conn->tls); - talloc_steal(conn->tls, conn->sock); conn->packet = packet_init(conn); if (conn->packet == NULL) { talloc_free(conn->sock); return; } + packet_set_private(conn->packet, conn); - packet_set_tls(conn->packet, conn->tls); + packet_set_socket(conn->packet, conn->sock); packet_set_callback(conn->packet, ldap_recv_handler); packet_set_full_request(conn->packet, ldap_complete_packet); packet_set_error_handler(conn->packet, ldap_error_handler); @@ -535,7 +538,7 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, req = talloc_zero(conn, struct ldap_request); if (req == NULL) return NULL; - if (conn->tls == NULL) { + if (conn->sock == NULL) { status = NT_STATUS_INVALID_CONNECTION; goto failed; } diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h index 7801f8b6bc..28b9f2763c 100644 --- a/source4/libcli/ldap/ldap_client.h +++ b/source4/libcli/ldap/ldap_client.h @@ -51,7 +51,6 @@ struct ldap_request { /* main context for a ldap client connection */ struct ldap_connection { - struct tls_context *tls; struct socket_context *sock; char *host; uint16_t port; -- cgit From 172a83d72491f90f6191be1040ef8b2e1789bd2e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 13 May 2006 19:14:12 +0000 Subject: r15573: Fix build of systems that have iconv headers in non-standard locations Split of system/locale.h header from system/iconv.h Previously, iconv wasn't being used on these systems (This used to be commit aa6d66fda69779d1c2948a1aca85dbd5208f1cba) --- source4/libcli/ldap/ldap.c | 1 - source4/libcli/ldap/ldap_controls.c | 1 - 2 files changed, 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index c1fc461b5f..6f475478b1 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -24,7 +24,6 @@ */ #include "includes.h" -#include "system/iconv.h" #include "libcli/util/asn_1.h" #include "libcli/ldap/ldap.h" diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index f4f54ec2e2..ee8f9d4bb1 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -21,7 +21,6 @@ */ #include "includes.h" -#include "system/iconv.h" #include "libcli/util/asn_1.h" #include "libcli/ldap/ldap.h" #include "lib/ldb/include/ldb.h" -- cgit From 971d30bb201f5c3faff5f575d26882eb79f7955a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 24 May 2006 07:34:11 +0000 Subject: r15854: more talloc_set_destructor() typesafe fixes (This used to be commit 61c6100617589ac6df4f527877241464cacbf8b3) --- source4/libcli/ldap/ldap_client.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 8d815c7103..07b7f2b412 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -487,9 +487,8 @@ static void ldap_reconnect(struct ldap_connection *conn) } /* destroy an open ldap request */ -static int ldap_request_destructor(void *ptr) +static int ldap_request_destructor(struct ldap_request *req) { - struct ldap_request *req = talloc_get_type(ptr, struct ldap_request); if (req->state == LDAP_REQUEST_PENDING) { DLIST_REMOVE(req->conn->pending, req); } -- cgit From c38f24b0210cb98b5062f3e0c92be9a9177e1bb7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 7 Jun 2006 04:23:42 +0000 Subject: r16073: On an incoming wildcard search, it is critical that the size be correct, or we try and do a memcmp on the trailing '\0'. This happens because we now use memcmp for the prefix matching. I just wish I had a test other than a particular invocation of the OSX client. (I've tried and failed so far) Andrew Bartlett (This used to be commit 36aa8390807581442c68ac3ee9dd6eb05d89b86d) --- source4/libcli/ldap/ldap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 6f475478b1..6a0b86f78b 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -548,9 +548,9 @@ static struct ldb_val **ldap_decode_substring(TALLOC_CTX *mem_ctx, struct ldb_va if (chunks[chunk_num]->data == NULL) { return NULL; } - chunks[chunk_num]->length = strlen(value) + 1; + chunks[chunk_num]->length = strlen(value); - chunks[chunk_num + 1] = NULL; + chunks[chunk_num + 1] = '\0'; return chunks; } -- cgit From ba07fa43d0b0090f5e686d8c1822468049f52416 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 23 Jul 2006 02:50:08 +0000 Subject: r17197: This patch moves the encryption of bulk data on SASL negotiated security contexts from the application layer into the socket layer. This improves a number of correctness aspects, as we now allow LDAP packets to cross multiple SASL packets. It should also make it much easier to write async LDAP tests from windows clients, as they use SASL by default. It is also vital to allowing OpenLDAP clients to use GSSAPI against Samba4, as it negotiates a rather small SASL buffer size. This patch mirrors the earlier work done to move TLS into the socket layer. Unusual in this pstch is the extra read callback argument I take. As SASL is a layer on top of a socket, it is entirely possible for the SASL layer to drain a socket dry, but for the caller not to have read all the decrypted data. This would leave the system without an event to restart the read (as the socket is dry). As such, I re-invoke the read handler from a timed callback, which should trigger on the next running of the event loop. I believe that the TLS code does require a similar callback. In trying to understand why this is required, imagine a SASL-encrypted LDAP packet in the following formation: +-----------------+---------------------+ | SASL Packet #1 | SASL Packet #2 | ----------------------------------------+ | LDAP Packet #1 | LDAP Packet #2 | ----------------------------------------+ In the old code, this was illegal, but it is perfectly standard SASL-encrypted LDAP. Without the callback, we would read and process the first LDAP packet, and the SASL code would have read the second SASL packet (to decrypt enough data for the LDAP packet), and no data would remain on the socket. Without data on the socket, read events stop. That is why I add timed events, until the SASL buffer is drained. Another approach would be to add a hack to the event system, to have it pretend there remained data to read off the network (but that is ugly). In improving the code, to handle more real-world cases, I've been able to remove almost all the special-cases in the testnonblock code. The only special case is that we must use a deterministic partial packet when calling send, rather than a random length. (1 + n/2). This is needed because of the way the SASL and TLS code works, and the 'resend on failure' requirements. Andrew Bartlett (This used to be commit 5d7c9c12cb2b39673172a357092b80cd814850b0) --- source4/libcli/ldap/config.mk | 2 +- source4/libcli/ldap/ldap_bind.c | 22 ++++++--- source4/libcli/ldap/ldap_client.c | 94 ++++----------------------------------- source4/libcli/ldap/ldap_client.h | 3 -- 4 files changed, 26 insertions(+), 95 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 88ebc3256f..e5a7133cfa 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -11,7 +11,7 @@ OBJ_FILES = ldap.o \ ldap_ildap.o \ ldap_controls.o PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET -PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket LIBCLI_RESOLVE NDR_SAMR LIBTLS ASN1_UTIL +PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket LIBCLI_RESOLVE NDR_SAMR LIBTLS ASN1_UTIL GENSEC_SOCKET #PRIVATE_DEPENDENCIES = gensec # End SUBSYSTEM LIBCLI_LDAP ################################# diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 6714d68b0e..2b209c3871 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -27,6 +27,8 @@ #include "libcli/ldap/ldap_client.h" #include "lib/tls/tls.h" #include "auth/auth.h" +#include "auth/gensec/socket.h" +#include "lib/stream/packet.h" struct ldap_simple_creds { const char *dn; @@ -365,15 +367,23 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr } } - if (NT_STATUS_IS_OK(status) && - (gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL) || - gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN))) { - conn->enable_wrap = True; - } - talloc_free(tmp_ctx); if (NT_STATUS_IS_OK(status)) { + struct socket_context *socket = gensec_socket_init(conn->gensec, + conn->sock, + conn->event.event_ctx, + ldap_read_io_handler, + conn); + if (socket) { + conn->sock = socket; + talloc_steal(conn->sock, socket); + packet_set_socket(conn->packet, socket); + } else { + status = NT_STATUS_NO_MEMORY; + goto failed; + } + conn->bind.type = LDAP_BIND_SASL; conn->bind.creds = creds; } diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 07b7f2b412..2e834b5244 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -165,25 +165,13 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message /* - check if a blob is a complete ldap packet - handle wrapper or unwrapped connections + decode/process LDAP data */ -NTSTATUS ldap_complete_packet(void *private_data, DATA_BLOB blob, size_t *size) -{ - struct ldap_connection *conn = talloc_get_type(private_data, - struct ldap_connection); - if (conn->enable_wrap) { - return packet_full_request_u32(private_data, blob, size); - } - return ldap_full_packet(private_data, blob, size); -} - -/* - decode/process plain data -*/ -static NTSTATUS ldap_decode_plain(struct ldap_connection *conn, DATA_BLOB blob) +static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob) { struct asn1_data asn1; + struct ldap_connection *conn = talloc_get_type(private_data, + struct ldap_connection); struct ldap_message *msg = talloc(conn, struct ldap_message); if (msg == NULL) { @@ -205,60 +193,14 @@ static NTSTATUS ldap_decode_plain(struct ldap_connection *conn, DATA_BLOB blob) return NT_STATUS_OK; } -/* - decode/process wrapped data -*/ -static NTSTATUS ldap_decode_wrapped(struct ldap_connection *conn, DATA_BLOB blob) -{ - DATA_BLOB wrapped, unwrapped; - struct asn1_data asn1; - struct ldap_message *msg = talloc(conn, struct ldap_message); - NTSTATUS status; - - if (msg == NULL) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - wrapped = data_blob_const(blob.data+4, blob.length-4); - - status = gensec_unwrap(conn->gensec, msg, &wrapped, &unwrapped); - if (!NT_STATUS_IS_OK(status)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - data_blob_free(&blob); - - if (!asn1_load(&asn1, unwrapped)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - while (ldap_decode(&asn1, msg)) { - ldap_match_message(conn, msg); - msg = talloc(conn, struct ldap_message); - } - - talloc_free(msg); - asn1_free(&asn1); - - return NT_STATUS_OK; -} - - -/* - handle ldap recv events -*/ -static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob) +/* Handle read events, from the GENSEC socket callback, or real events */ +void ldap_read_io_handler(void *private_data, uint16_t flags) { struct ldap_connection *conn = talloc_get_type(private_data, struct ldap_connection); - if (conn->enable_wrap) { - return ldap_decode_wrapped(conn, blob); - } - - return ldap_decode_plain(conn, blob); + packet_recv(conn->packet); } - /* handle ldap socket events */ @@ -272,7 +214,7 @@ static void ldap_io_handler(struct event_context *ev, struct fd_event *fde, if (!tls_enabled(conn->sock)) return; } if (flags & EVENT_FD_READ) { - packet_recv(conn->packet); + ldap_read_io_handler(private_data, flags); } } @@ -417,7 +359,7 @@ static void ldap_connect_recv_conn(struct composite_context *ctx) packet_set_private(conn->packet, conn); packet_set_socket(conn->packet, conn->sock); packet_set_callback(conn->packet, ldap_recv_handler); - packet_set_full_request(conn->packet, ldap_complete_packet); + packet_set_full_request(conn->packet, ldap_full_packet); packet_set_error_handler(conn->packet, ldap_error_handler); packet_set_event_context(conn->packet, conn->event.event_ctx); packet_set_fde(conn->packet, conn->event.fde); @@ -561,24 +503,6 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, goto failed; } - /* possibly encrypt/sign the request */ - if (conn->enable_wrap) { - DATA_BLOB wrapped; - - status = gensec_wrap(conn->gensec, req, &req->data, &wrapped); - if (!NT_STATUS_IS_OK(status)) { - goto failed; - } - data_blob_free(&req->data); - req->data = data_blob_talloc(req, NULL, wrapped.length + 4); - if (req->data.data == NULL) { - goto failed; - } - RSIVAL(req->data.data, 0, wrapped.length); - memcpy(req->data.data+4, wrapped.data, wrapped.length); - data_blob_free(&wrapped); - } - status = packet_send(conn->packet, req->data); if (!NT_STATUS_IS_OK(status)) { goto failed; diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h index 28b9f2763c..849737d8a9 100644 --- a/source4/libcli/ldap/ldap_client.h +++ b/source4/libcli/ldap/ldap_client.h @@ -80,9 +80,6 @@ struct ldap_connection { /* Let's support SASL */ struct gensec_security *gensec; - /* set if we are wrapping requests */ - BOOL enable_wrap; - /* the default timeout for messages */ int timeout; -- cgit From 9d6f2767179fad2f9a067c67c09afddb6304e4eb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 25 Jul 2006 00:57:27 +0000 Subject: r17222: Change the function prototypes for the GENSEc and TLS socket creation routines to return an NTSTATUS. This should help track down errors. Use a bit of talloc_steal and talloc_unlink to get the real socket to be a child of the GENSEC or TLS socket. Always return a new socket, even for the 'pass-though' case. Andrew Bartlett (This used to be commit 003e2ab93c87267ba28cd67bd85975bad62a8ea2) --- source4/libcli/ldap/ldap_bind.c | 21 ++++++++++++--------- source4/libcli/ldap/ldap_client.c | 11 ++++++----- 2 files changed, 18 insertions(+), 14 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 2b209c3871..f1f7872455 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -370,15 +370,18 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr talloc_free(tmp_ctx); if (NT_STATUS_IS_OK(status)) { - struct socket_context *socket = gensec_socket_init(conn->gensec, - conn->sock, - conn->event.event_ctx, - ldap_read_io_handler, - conn); - if (socket) { - conn->sock = socket; - talloc_steal(conn->sock, socket); - packet_set_socket(conn->packet, socket); + struct socket_context *sasl_socket; + status = gensec_socket_init(conn->gensec, + conn->sock, + conn->event.event_ctx, + ldap_read_io_handler, + conn, + &sasl_socket); + if (NT_STATUS_IS_OK(status)) { + talloc_steal(conn->sock, sasl_socket); + talloc_unlink(conn, conn->sock); + conn->sock = sasl_socket; + packet_set_socket(conn->packet, conn->sock); } else { status = NT_STATUS_NO_MEMORY; goto failed; diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 2e834b5244..eb7b9c6327 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -320,7 +320,6 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, static void ldap_connect_recv_conn(struct composite_context *ctx) { - struct socket_context *initial_socket; struct ldap_connect_state *state = talloc_get_type(ctx->async.private_data, struct ldap_connect_state); @@ -341,13 +340,15 @@ static void ldap_connect_recv_conn(struct composite_context *ctx) } talloc_steal(conn, conn->sock); - initial_socket = conn->sock; if (conn->ldaps) { - conn->sock = tls_init_client(conn->sock, conn->event.fde); - if (conn->sock == NULL) { - talloc_free(initial_socket); + struct socket_context *tls_socket = tls_init_client(conn->sock, conn->event.fde); + if (tls_socket == NULL) { + talloc_free(conn->sock); return; } + talloc_unlink(conn, conn->sock); + conn->sock = tls_socket; + talloc_steal(conn, conn->sock); } conn->packet = packet_init(conn); -- cgit From ec8d486e267b60ebad3eac937580986155b75914 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 25 Jul 2006 12:48:40 +0000 Subject: r17230: don't overwrite the error with NT_STATUS_NO_MEMORY metze (This used to be commit f2196bf9b662d3f38d59eceb8c54f9d2e3f7b505) --- source4/libcli/ldap/ldap_bind.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index f1f7872455..4fdd87a25b 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -377,16 +377,13 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr ldap_read_io_handler, conn, &sasl_socket); - if (NT_STATUS_IS_OK(status)) { - talloc_steal(conn->sock, sasl_socket); - talloc_unlink(conn, conn->sock); - conn->sock = sasl_socket; - packet_set_socket(conn->packet, conn->sock); - } else { - status = NT_STATUS_NO_MEMORY; - goto failed; - } - + if (!NT_STATUS_IS_OK(status)) goto failed; + + talloc_steal(conn->sock, sasl_socket); + talloc_unlink(conn, conn->sock); + conn->sock = sasl_socket; + packet_set_socket(conn->packet, conn->sock); + conn->bind.type = LDAP_BIND_SASL; conn->bind.creds = creds; } -- cgit From b4028ca1041fc8e0266de2f5c858dd40e660aafb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 5 Aug 2006 10:26:23 +0000 Subject: r17418: add client support for the LDAP_SERVER_SD_FLAGS control metze (This used to be commit 23759a1e9b05c4fde475a9016cb0b7447656d7e7) --- source4/libcli/ldap/ldap_controls.c | 59 +++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index ee8f9d4bb1..445b5f8086 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -182,6 +182,37 @@ static BOOL decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out) return True; } +static BOOL decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out) +{ + struct asn1_data data; + struct ldb_sd_flags_control *lsdfc; + + if (!asn1_load(&data, in)) { + return False; + } + + lsdfc = talloc(mem_ctx, struct ldb_sd_flags_control); + if (!lsdfc) { + return False; + } + + if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_read_Integer(&data, &(lsdfc->secinfo_flags))) { + return False; + } + + if (!asn1_end_tag(&data)) { + return False; + } + + *out = lsdfc; + + return True; +} + static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB cookie; @@ -631,6 +662,33 @@ static BOOL encode_extended_dn_request(void *mem_ctx, void *in, DATA_BLOB *out) return True; } +static BOOL encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out) +{ + struct ldb_sd_flags_control *lsdfc = talloc_get_type(in, struct ldb_sd_flags_control); + struct asn1_data data; + + ZERO_STRUCT(data); + + if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_write_Integer(&data, lsdfc->secinfo_flags)) { + 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); @@ -878,6 +936,7 @@ struct control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.1504", decode_asq_control, encode_asq_control }, { "1.2.840.113556.1.4.841", decode_dirsync_request, encode_dirsync_request }, { "1.2.840.113556.1.4.528", decode_notification_request, encode_notification_request }, + { "1.2.840.113556.1.4.801", decode_sd_flags_request, encode_sd_flags_request }, { "2.16.840.1.113730.3.4.2", decode_manageDSAIT_request, encode_manageDSAIT_request }, { "2.16.840.1.113730.3.4.9", decode_vlv_request, encode_vlv_request }, { "2.16.840.1.113730.3.4.10", decode_vlv_response, encode_vlv_response }, -- cgit From 817610f38540fb99595f6e3b77b9f6696f9e3b3f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 5 Aug 2006 11:18:14 +0000 Subject: r17419: add client support for the LDAP_SERVER_SEARCH_OPTIONS support. with this you can limit a search to a specific partitions or a search over all partitions without getting referrals. (Witch is the default behavior on the Global Catalog Port) metze (This used to be commit 4ccd0f8171f3748ee6efe1abd3f894d2cdf46bf4) --- source4/libcli/ldap/ldap_controls.c | 59 +++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 445b5f8086..4c5d214a8f 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -213,6 +213,37 @@ static BOOL decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out) return True; } +static BOOL decode_search_options_request(void *mem_ctx, DATA_BLOB in, void **out) +{ + struct asn1_data data; + struct ldb_search_options_control *lsoc; + + if (!asn1_load(&data, in)) { + return False; + } + + lsoc = talloc(mem_ctx, struct ldb_search_options_control); + if (!lsoc) { + return False; + } + + if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_read_Integer(&data, &(lsoc->search_options))) { + return False; + } + + if (!asn1_end_tag(&data)) { + return False; + } + + *out = lsoc; + + return True; +} + static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB cookie; @@ -689,6 +720,33 @@ static BOOL encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out) return True; } +static BOOL encode_search_options_request(void *mem_ctx, void *in, DATA_BLOB *out) +{ + struct ldb_search_options_control *lsoc = talloc_get_type(in, struct ldb_search_options_control); + struct asn1_data data; + + ZERO_STRUCT(data); + + if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + return False; + } + + if (!asn1_write_Integer(&data, lsoc->search_options)) { + 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); @@ -937,6 +995,7 @@ struct control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.841", decode_dirsync_request, encode_dirsync_request }, { "1.2.840.113556.1.4.528", decode_notification_request, encode_notification_request }, { "1.2.840.113556.1.4.801", decode_sd_flags_request, encode_sd_flags_request }, + { "1.2.840.113556.1.4.1340", decode_search_options_request, encode_search_options_request }, { "2.16.840.1.113730.3.4.2", decode_manageDSAIT_request, encode_manageDSAIT_request }, { "2.16.840.1.113730.3.4.9", decode_vlv_request, encode_vlv_request }, { "2.16.840.1.113730.3.4.10", decode_vlv_response, encode_vlv_response }, -- cgit From 8ac0237eba1831c8ba6d01c2b9d8402636a21bb2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 5 Aug 2006 11:38:50 +0000 Subject: r17420: add client support for the LDAP_SERVER_DOMAIN_SCOPE control metze (This used to be commit 84e74a759cfa49ebc8b4ba1b8e729d6d920fc55a) --- source4/libcli/ldap/ldap_controls.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 4c5d214a8f..395c4eb836 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -401,6 +401,15 @@ static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) return True; } +static BOOL decode_domain_scope_request(void *mem_ctx, DATA_BLOB in, void **out) +{ + if (in.length != 0) { + return False; + } + + return True; +} + static BOOL decode_notification_request(void *mem_ctx, DATA_BLOB in, void **out) { if (in.length != 0) { @@ -850,6 +859,16 @@ static BOOL encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out) return True; } +static BOOL encode_domain_scope_request(void *mem_ctx, void *in, DATA_BLOB *out) +{ + if (in) { + return False; + } + + *out = data_blob(NULL, 0); + return True; +} + static BOOL encode_notification_request(void *mem_ctx, void *in, DATA_BLOB *out) { if (in) { @@ -995,6 +1014,7 @@ struct control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.841", decode_dirsync_request, encode_dirsync_request }, { "1.2.840.113556.1.4.528", decode_notification_request, encode_notification_request }, { "1.2.840.113556.1.4.801", decode_sd_flags_request, encode_sd_flags_request }, + { "1.2.840.113556.1.4.1339", decode_domain_scope_request, encode_domain_scope_request }, { "1.2.840.113556.1.4.1340", decode_search_options_request, encode_search_options_request }, { "2.16.840.1.113730.3.4.2", decode_manageDSAIT_request, encode_manageDSAIT_request }, { "2.16.840.1.113730.3.4.9", decode_vlv_request, encode_vlv_request }, -- cgit From 12050962f6dd37819e58e1e0b572c159f0406f7a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 5 Aug 2006 19:35:00 +0000 Subject: r17429: implement the LDAP_SERVER_SHOW_DELETED control in the client metze (This used to be commit 40dc7c1787c16bfc15ac87fee81d2d2d1f3d2fde) --- source4/libcli/ldap/ldap_controls.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 395c4eb836..75af597c33 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -419,6 +419,15 @@ static BOOL decode_notification_request(void *mem_ctx, DATA_BLOB in, void **out) return True; } +static BOOL decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void **out) +{ + if (in.length != 0) { + return False; + } + + return True; +} + static BOOL decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void **out) { if (in.length != 0) { @@ -879,6 +888,16 @@ static BOOL encode_notification_request(void *mem_ctx, void *in, DATA_BLOB *out) return True; } +static BOOL encode_show_deleted_request(void *mem_ctx, void *in, DATA_BLOB *out) +{ + if (in) { + return False; + } + + *out = data_blob(NULL, 0); + return True; +} + static BOOL encode_manageDSAIT_request(void *mem_ctx, void *in, DATA_BLOB *out) { if (in) { @@ -1013,6 +1032,7 @@ struct control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.1504", decode_asq_control, encode_asq_control }, { "1.2.840.113556.1.4.841", decode_dirsync_request, encode_dirsync_request }, { "1.2.840.113556.1.4.528", decode_notification_request, encode_notification_request }, + { "1.2.840.113556.1.4.417", decode_show_deleted_request, encode_show_deleted_request }, { "1.2.840.113556.1.4.801", decode_sd_flags_request, encode_sd_flags_request }, { "1.2.840.113556.1.4.1339", decode_domain_scope_request, encode_domain_scope_request }, { "1.2.840.113556.1.4.1340", decode_search_options_request, encode_search_options_request }, -- cgit From 3a083f8f53b998b6aabf69e845fd0fbdf86b6499 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 5 Aug 2006 19:50:58 +0000 Subject: r17430: implement the LDAP_SERVER_PERMISSIVE_MODIFY control in the client metze (This used to be commit 96259f0f24b114e505241c9d2deb702a8b40f1b6) --- source4/libcli/ldap/ldap_controls.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 75af597c33..5cd0451136 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -428,6 +428,15 @@ static BOOL decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void **out) return True; } +static BOOL decode_permissive_modify_request(void *mem_ctx, DATA_BLOB in, void **out) +{ + if (in.length != 0) { + return False; + } + + return True; +} + static BOOL decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void **out) { if (in.length != 0) { @@ -898,6 +907,16 @@ static BOOL encode_show_deleted_request(void *mem_ctx, void *in, DATA_BLOB *out) return True; } +static BOOL encode_permissive_modify_request(void *mem_ctx, void *in, DATA_BLOB *out) +{ + if (in) { + return False; + } + + *out = data_blob(NULL, 0); + return True; +} + static BOOL encode_manageDSAIT_request(void *mem_ctx, void *in, DATA_BLOB *out) { if (in) { @@ -1033,6 +1052,7 @@ struct control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.841", decode_dirsync_request, encode_dirsync_request }, { "1.2.840.113556.1.4.528", decode_notification_request, encode_notification_request }, { "1.2.840.113556.1.4.417", decode_show_deleted_request, encode_show_deleted_request }, + { "1.2.840.113556.1.4.1413", decode_permissive_modify_request, encode_permissive_modify_request }, { "1.2.840.113556.1.4.801", decode_sd_flags_request, encode_sd_flags_request }, { "1.2.840.113556.1.4.1339", decode_domain_scope_request, encode_domain_scope_request }, { "1.2.840.113556.1.4.1340", decode_search_options_request, encode_search_options_request }, -- cgit From 0329d755a7611ba3897fc1ee9bdce410cc33d7f8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 30 Aug 2006 11:29:34 +0000 Subject: r17930: Merge noinclude branch: * Move dlinklist.h, smb.h to subsystem-specific directories * Clean up ads.h and move what is left of it to dsdb/ (only place where it's used) (This used to be commit f7afa1cb77f3cfa7020b57de12e6003db7cfcc42) --- source4/libcli/ldap/ldap_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index eb7b9c6327..efc6f7b4e5 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -25,7 +25,7 @@ #include "includes.h" #include "libcli/util/asn_1.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" #include "lib/events/events.h" #include "lib/socket/socket.h" #include "libcli/ldap/ldap.h" -- cgit From 22ced36791da7de99afb799deb30b934ccbd902e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 4 Sep 2006 00:26:10 +0000 Subject: r18021: Add ldapi support to our LDAP client. To be used for testing an OpenLDAP backend. Andrew Bartlett (This used to be commit da66b53e6ac39c5f020781830ee69d460aa0cae5) --- source4/libcli/ldap/ldap_client.c | 127 ++++++++++++++++++++++++++++---------- 1 file changed, 93 insertions(+), 34 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index efc6f7b4e5..4fa8cc0146 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -226,19 +226,13 @@ static NTSTATUS ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, { int tmp_port = 0; char protocol[11]; - char tmp_host[255]; - const char *p = url; + char tmp_host[1025]; int ret; - /* skip leading "URL:" (if any) */ - if (strncasecmp(p, "URL:", 4) == 0) { - p += 4; - } - /* Paranoia check */ SMB_ASSERT(sizeof(protocol)>10 && sizeof(tmp_host)>254); - ret = sscanf(p, "%10[^:]://%254[^:/]:%d", protocol, tmp_host, &tmp_port); + ret = sscanf(url, "%10[^:]://%254[^:/]:%d", protocol, tmp_host, &tmp_port); if (ret < 2) { return NT_STATUS_INVALID_PARAMETER; } @@ -272,13 +266,16 @@ struct ldap_connect_state { struct ldap_connection *conn; }; -static void ldap_connect_recv_conn(struct composite_context *ctx); +static void ldap_connect_recv_unix_conn(struct composite_context *ctx); +static void ldap_connect_recv_tcp_conn(struct composite_context *ctx); struct composite_context *ldap_connect_send(struct ldap_connection *conn, const char *url) { struct composite_context *result, *ctx; struct ldap_connect_state *state; + char protocol[11]; + int ret; result = talloc_zero(NULL, struct composite_context); if (result == NULL) goto failed; @@ -298,44 +295,73 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, if (conn->reconnect.url == NULL) goto failed; } - state->ctx->status = ldap_parse_basic_url(conn, url, &conn->host, - &conn->port, &conn->ldaps); - if (!NT_STATUS_IS_OK(state->ctx->status)) { - composite_error(state->ctx, state->ctx->status); - return result; + /* Paranoia check */ + SMB_ASSERT(sizeof(protocol)>10); + + ret = sscanf(url, "%10[^:]://", protocol); + if (ret < 1) { + return NULL; } - ctx = socket_connect_multi_send(state, conn->host, 1, &conn->port, - conn->event.event_ctx); - if (ctx == NULL) goto failed; + if (strequal(protocol, "ldapi")) { + struct socket_address *unix_addr; + char path[1025]; + + NTSTATUS status = socket_create("unix", SOCKET_TYPE_STREAM, &conn->sock, 0); + if (!NT_STATUS_IS_OK(status)) { + return NULL; + } + SMB_ASSERT(sizeof(protocol)>10); + SMB_ASSERT(sizeof(path)>1024); + + ret = sscanf(url, "%10[^:]://%1025c", protocol, path); + if (ret < 2) { + composite_error(state->ctx, NT_STATUS_INVALID_PARAMETER); + return result; + } - ctx->async.fn = ldap_connect_recv_conn; - ctx->async.private_data = state; - return result; + rfc1738_unescape(path); + + unix_addr = socket_address_from_strings(conn, conn->sock->backend_name, + path, 0); + if (!unix_addr) { + return NULL; + } + + ctx = socket_connect_send(conn->sock, NULL, unix_addr, + 0, conn->event.event_ctx); + ctx->async.fn = ldap_connect_recv_unix_conn; + ctx->async.private_data = state; + return result; + } else { + NTSTATUS status = ldap_parse_basic_url(conn, url, &conn->host, + &conn->port, &conn->ldaps); + if (!NT_STATUS_IS_OK(state->ctx->status)) { + composite_error(state->ctx, status); + return result; + } + + ctx = socket_connect_multi_send(state, conn->host, 1, &conn->port, + conn->event.event_ctx); + if (ctx == NULL) goto failed; + ctx->async.fn = ldap_connect_recv_tcp_conn; + ctx->async.private_data = state; + return result; + } failed: talloc_free(result); return NULL; } -static void ldap_connect_recv_conn(struct composite_context *ctx) +static void ldap_connect_got_sock(struct composite_context *ctx, struct ldap_connection *conn) { - struct ldap_connect_state *state = - talloc_get_type(ctx->async.private_data, - struct ldap_connect_state); - struct ldap_connection *conn = state->conn; - uint16_t port; - - state->ctx->status = socket_connect_multi_recv(ctx, state, &conn->sock, - &port); - if (!composite_is_ok(state->ctx)) return; - /* setup a handler for events on this socket */ conn->event.fde = event_add_fd(conn->event.event_ctx, conn->sock, socket_get_fd(conn->sock), EVENT_FD_READ, ldap_io_handler, conn); if (conn->event.fde == NULL) { - composite_error(state->ctx, NT_STATUS_INTERNAL_ERROR); + composite_error(ctx, NT_STATUS_INTERNAL_ERROR); return; } @@ -366,9 +392,42 @@ static void ldap_connect_recv_conn(struct composite_context *ctx) packet_set_fde(conn->packet, conn->event.fde); packet_set_serialise(conn->packet); - composite_done(state->ctx); + composite_done(ctx); +} + +static void ldap_connect_recv_tcp_conn(struct composite_context *ctx) +{ + struct ldap_connect_state *state = + talloc_get_type(ctx->async.private_data, + struct ldap_connect_state); + struct ldap_connection *conn = state->conn; + uint16_t port; + + NTSTATUS status = socket_connect_multi_recv(ctx, state, &conn->sock, + &port); + if (!NT_STATUS_IS_OK(state->ctx->status)) { + composite_error(state->ctx, status); + return; + } + + ldap_connect_got_sock(state->ctx, conn); +} + +static void ldap_connect_recv_unix_conn(struct composite_context *ctx) +{ + struct ldap_connect_state *state = + talloc_get_type(ctx->async.private_data, + struct ldap_connect_state); + struct ldap_connection *conn = state->conn; + + NTSTATUS status = socket_connect_recv(ctx); + + if (!NT_STATUS_IS_OK(state->ctx->status)) { + composite_error(state->ctx, status); + return; + } - return; + ldap_connect_got_sock(state->ctx, conn); } NTSTATUS ldap_connect_recv(struct composite_context *ctx) -- cgit From e21e8379a2ce9f3ca70227889c5c11a719516980 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 4 Sep 2006 01:59:23 +0000 Subject: r18024: The %c sscanf format I'm using doesn't null terminate. Andrew Bartlett (This used to be commit 1920cb8b3978f745cba7e854410deb9174de2dc0) --- source4/libcli/ldap/ldap_client.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 4fa8cc0146..bc230879fc 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -311,9 +311,12 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, if (!NT_STATUS_IS_OK(status)) { return NULL; } + talloc_steal(conn, conn->sock); SMB_ASSERT(sizeof(protocol)>10); SMB_ASSERT(sizeof(path)>1024); + /* The %c specifier doesn't null terminate :-( */ + ZERO_STRUCT(path); ret = sscanf(url, "%10[^:]://%1025c", protocol, path); if (ret < 2) { composite_error(state->ctx, NT_STATUS_INVALID_PARAMETER); -- cgit From 556aab78a0ff18505f7c8561586abc977adf8e43 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 4 Sep 2006 03:59:04 +0000 Subject: r18025: Don't try to set a target host if there isn't one (such as with ldapi://). Andrew Bartlett (This used to be commit 556a21faeed0b6e3cc6efcfa8e0939b151a802de) --- source4/libcli/ldap/ldap_bind.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 4fdd87a25b..f617cbe102 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -236,11 +236,13 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr goto failed; } - status = gensec_set_target_hostname(conn->gensec, conn->host); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to set GENSEC target hostname: %s\n", - nt_errstr(status))); - goto failed; + if (conn->host) { + status = gensec_set_target_hostname(conn->gensec, conn->host); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to set GENSEC target hostname: %s\n", + nt_errstr(status))); + goto failed; + } } status = gensec_set_target_service(conn->gensec, "ldap"); -- cgit From d7534e0cc772b9aa0b7cdeb0ed4469e44173348f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 8 Sep 2006 06:04:10 +0000 Subject: r18256: use the right status variable (This used to be commit f4b4bd945f5c3955aab0c3cf89ad6cdda7529dac) --- source4/libcli/ldap/ldap_client.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index bc230879fc..da1ffcd317 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -405,10 +405,9 @@ static void ldap_connect_recv_tcp_conn(struct composite_context *ctx) struct ldap_connect_state); struct ldap_connection *conn = state->conn; uint16_t port; - NTSTATUS status = socket_connect_multi_recv(ctx, state, &conn->sock, &port); - if (!NT_STATUS_IS_OK(state->ctx->status)) { + if (!NT_STATUS_IS_OK(status)) { composite_error(state->ctx, status); return; } -- cgit From e91cee468eceb6ff8843bafc7fbb22a21b52a00c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 9 Sep 2006 12:57:45 +0000 Subject: r18309: FreeBSD 6.1 has a symbol ldap_new_connection() in the system ldap library. Even though we don't like to that library, it gets loaded via nss-ldap, which means nss-ldap calls into the samba ldap lib with the wrong parameters, and crashes. We really need to use a completely different namespace in libcli/ldap/ (This used to be commit c440e0eed9afae5fe69995a7416971e7c8560779) --- source4/libcli/ldap/ldap_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index da1ffcd317..7bb4d0c79a 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -40,7 +40,7 @@ /* create a new ldap_connection stucture. The event context is optional */ -struct ldap_connection *ldap_new_connection(TALLOC_CTX *mem_ctx, +struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx, struct event_context *ev) { struct ldap_connection *conn; -- cgit From 31454d2e8b70f7aca87099dba25abe790781c7a7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 29 Sep 2006 04:45:15 +0000 Subject: r18989: Fixes found by these two LDAP testsuites: - http://www.ee.oulu.fi/research/ouspg/protos/testing/c06/ldapv3/ - http://gleg.net/protover_ldap_sample.shtml Also fixes found by a subsequent audit of the code for similar issues. (This used to be commit 441a4f6262459dabfefd9bb12622ada9c007a60c) --- source4/libcli/ldap/ldap.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 6a0b86f78b..5a7174b41d 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -949,8 +949,14 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) r->mechanism = LDAP_AUTH_MECH_SIMPLE; asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); pwlen = asn1_tag_remaining(data); + if (pwlen == -1) { + return False; + } if (pwlen != 0) { char *pw = talloc_size(msg, pwlen+1); + if (!pw) { + return False; + } asn1_read(data, pw, pwlen); pw[pwlen] = '\0'; r->creds.password = pw; @@ -974,6 +980,9 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) r->creds.SASL.secblob = NULL; } asn1_end_tag(data); + } else { + /* Neither Simple nor SASL bind */ + return False; } asn1_end_tag(data); break; @@ -1096,8 +1105,9 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) ldap_decode_attrib(msg, data, &mod.attrib); asn1_end_tag(data); if (!add_mod_to_array_talloc(msg, &mod, - &r->mods, &r->num_mods)) - break; + &r->mods, &r->num_mods)) { + return False; + } } asn1_end_tag(data); @@ -1146,6 +1156,9 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_start_tag(data, ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); len = asn1_tag_remaining(data); + if (len == -1) { + return False; + } dn = talloc_size(msg, len+1); if (dn == NULL) break; @@ -1179,9 +1192,13 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) char *newsup; asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); len = asn1_tag_remaining(data); + if (len == -1) { + return False; + } newsup = talloc_size(msg, len+1); - if (newsup == NULL) - break; + if (newsup == NULL) { + return False; + } asn1_read(data, newsup, len); newsup[len] = '\0'; r->newsuperior = newsup; -- cgit From 4fa24df98ded939c68bdc95e9f09334caeeb84af Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 29 Oct 2006 17:40:19 +0000 Subject: r19507: Merge my DSO fixes branch. Building Samba's libraries as shared libraries works again now, by specifying --enable-dso to configure. (This used to be commit 7a01235067a4800b07b8919a6a475954bfb0b04c) --- source4/libcli/ldap/ldap_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 7bb4d0c79a..2c2cd0dd66 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -432,7 +432,7 @@ static void ldap_connect_recv_unix_conn(struct composite_context *ctx) ldap_connect_got_sock(state->ctx, conn); } -NTSTATUS ldap_connect_recv(struct composite_context *ctx) +_PUBLIC_ NTSTATUS ldap_connect_recv(struct composite_context *ctx) { NTSTATUS status = composite_wait(ctx); talloc_free(ctx); -- cgit From 13dbee3ffea6065a826f010e50c9b4eb2c6ad109 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 7 Nov 2006 00:48:36 +0000 Subject: r19598: Ahead of a merge to current lorikeet-heimdal: Break up auth/auth.h not to include the world. Add credentials_krb5.h with the kerberos dependent prototypes. Andrew Bartlett (This used to be commit 2b569c42e0fbb596ea82484d0e1cb22e193037b9) --- source4/libcli/ldap/ldap_bind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index f617cbe102..c4c731e4f5 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -26,7 +26,7 @@ #include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" #include "lib/tls/tls.h" -#include "auth/auth.h" +#include "auth/gensec/gensec.h" #include "auth/gensec/socket.h" #include "lib/stream/packet.h" -- cgit From b236d54c42a01343c4b0ec68d70a47a48531e71d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 12 Dec 2006 22:43:35 +0000 Subject: r20141: use the gensec_features of the cli_credentials for ildap connections, instead of hardcoded GENSEC_FEATURE_SEAL. That means plain LDAP is now the default. metze (This used to be commit b69471866c2a6c61002147938f233f2f63963ba4) --- source4/libcli/ldap/ldap_bind.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index c4c731e4f5..addc8cf91e 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -28,6 +28,7 @@ #include "lib/tls/tls.h" #include "auth/gensec/gensec.h" #include "auth/gensec/socket.h" +#include "auth/credentials/credentials.h" #include "lib/stream/packet.h" struct ldap_simple_creds { @@ -211,7 +212,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr int count, i; const char **sasl_names; - + uint32_t old_gensec_features; static const char *supported_sasl_mech_attrs[] = { "supportedSASLMechanisms", NULL @@ -225,10 +226,12 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr /* require Kerberos SIGN/SEAL only if we don't use SSL * Windows seem not to like double encryption */ - if (!tls_enabled(conn->sock)) { - gensec_want_feature(conn->gensec, 0 | GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL); + old_gensec_features = cli_credentials_get_gensec_features(creds); + if (tls_enabled(conn->sock)) { + cli_credentials_set_gensec_features(creds, 0); } + /* this call also sets the gensec_want_features */ status = gensec_set_credentials(conn->gensec, creds); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to set GENSEC creds: %s\n", @@ -236,6 +239,9 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr goto failed; } + /* reset the original gensec_features */ + cli_credentials_set_gensec_features(creds, old_gensec_features); + if (conn->host) { status = gensec_set_target_hostname(conn->gensec, conn->host); if (!NT_STATUS_IS_OK(status)) { -- cgit From 31d6d8c45735bef52a14b922667a036245df8061 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Feb 2007 14:29:04 +0000 Subject: r21501: ugly but the windows 2000 mmc deturns decoding error without this metze (This used to be commit f17da75754f8cc79b60e04b54a4bc99191e71ff3) --- source4/libcli/ldap/ldap.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 5a7174b41d..bdcea0962d 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -237,6 +237,10 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct ldap_encode_response(&data, &r->response); if (r->SASL.secblob) { asn1_write_ContextSimple(&data, 7, r->SASL.secblob); + } else { + /* ugly but the windows 2000 mmc deturns decoding error without this */ + DATA_BLOB zero = data_blob(NULL, 0); + asn1_write_ContextSimple(&data, 7, &zero); } asn1_pop_tag(&data); break; -- cgit From bf772399bf38b16567b68e7fde102431e5a28135 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 23 Feb 2007 07:46:51 +0000 Subject: r21511: this seems to be the nicer fix for the problem with the windows 2000 LDAP client metze (This used to be commit d40465470fa09827ea529e1f2c80bca9efc152a8) --- source4/libcli/ldap/ldap.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index bdcea0962d..5a7174b41d 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -237,10 +237,6 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct ldap_encode_response(&data, &r->response); if (r->SASL.secblob) { asn1_write_ContextSimple(&data, 7, r->SASL.secblob); - } else { - /* ugly but the windows 2000 mmc deturns decoding error without this */ - DATA_BLOB zero = data_blob(NULL, 0); - asn1_write_ContextSimple(&data, 7, &zero); } asn1_pop_tag(&data); break; -- cgit From 3370f2f2d7e5296e8f54f721003c07fac111d1ad Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 8 Mar 2007 06:23:39 +0000 Subject: r21761: - Give more detail on LDAP client library failures (make it clear where the error is from) - Make default error string more consistant Andrew Bartlett (This used to be commit 7f115579d20a3112efd11444fafcbf78698fc9a1) --- source4/libcli/ldap/ldap_client.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 2c2cd0dd66..82cafd721a 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -562,6 +562,7 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn, msg->messageid = req->messageid; if (!ldap_encode(msg, &req->data, req)) { + status = NT_STATUS_INTERNAL_ERROR; goto failed; } @@ -704,12 +705,14 @@ NTSTATUS ldap_check_response(struct ldap_connection *conn, struct ldap_Result *r /* return error string representing the last error */ -const char *ldap_errstr(struct ldap_connection *conn, NTSTATUS status) +const char *ldap_errstr(struct ldap_connection *conn, + TALLOC_CTX *mem_ctx, + NTSTATUS status) { if (NT_STATUS_IS_LDAP(status) && conn->last_error != NULL) { - return conn->last_error; + return talloc_strdup(mem_ctx, conn->last_error); } - return nt_errstr(status); + return talloc_asprintf(mem_ctx, "LDAP client internal error: %s", nt_errstr(status)); } -- cgit From 9b03286b32a916dbef59f1459eefa01f0ebfeed3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 13 Mar 2007 00:59:06 +0000 Subject: r21806: I've been working over the last week to fix up the LDAP backend for Samba4. This only broke on global catalog queries, which turned out to be due to changes in the partitions module that metze needed for his DRSUAPI work. I've reworked partitions.c to always include the 'problematic' control, and therefore demonstrated that this is the issue. This ensures consistency, and should help with finding issues like this in future. As this control (DSDB_CONTROL_CURRENT_PARTITION_OID) is not intended to be linearised, I've added logic to allow it to be skipped when creating network packets. I've likewise make our LDAP server skip unknown controls, when marked 'not critical' on it's input, rather than just dropping the entire request. I need some help to generate a correct error packet when it is marked critical. Further work could perhaps be to have the ldap_encode routine return a textual description of what failed to encode, as that would have saved me a lot of time... Andrew Bartlett (This used to be commit eef710668f91d1bbaa2d834d9e653e11c8aac817) --- source4/libcli/ldap/ldap.c | 75 +++++++++++++++++++++++-------------- source4/libcli/ldap/ldap_client.c | 7 +++- source4/libcli/ldap/ldap_controls.c | 71 ++++++++++++++++++++++------------- 3 files changed, 95 insertions(+), 58 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 5a7174b41d..1e308d5847 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -925,7 +925,9 @@ static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, asn1_end_tag(data); } -BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) +/* This routine returns LDAP status codes */ + +NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) { uint8_t tag; @@ -933,7 +935,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_read_Integer(data, &msg->messageid); if (!asn1_peek_uint8(data, &tag)) - return False; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); switch(tag) { @@ -950,12 +952,12 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); pwlen = asn1_tag_remaining(data); if (pwlen == -1) { - return False; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } if (pwlen != 0) { char *pw = talloc_size(msg, pwlen+1); if (!pw) { - return False; + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } asn1_read(data, pw, pwlen); pw[pwlen] = '\0'; @@ -971,7 +973,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_read_OctetString(data, &tmp_blob); r->creds.SASL.secblob = talloc(msg, DATA_BLOB); if (!r->creds.SASL.secblob) { - return False; + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } *r->creds.SASL.secblob = data_blob_talloc(r->creds.SASL.secblob, tmp_blob.data, tmp_blob.length); @@ -982,7 +984,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_end_tag(data); } else { /* Neither Simple nor SASL bind */ - return False; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } asn1_end_tag(data); break; @@ -998,7 +1000,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_read_ContextSimple(data, 7, &tmp_blob); r->SASL.secblob = talloc(msg, DATA_BLOB); if (!r->SASL.secblob) { - return False; + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } *r->SASL.secblob = data_blob_talloc(r->SASL.secblob, tmp_blob.data, tmp_blob.length); @@ -1030,7 +1032,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) r->tree = ldap_decode_filter_tree(msg, data); if (r->tree == NULL) { - return False; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } asn1_start_tag(data, ASN1_SEQUENCE(0)); @@ -1038,15 +1040,16 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) r->num_attributes = 0; r->attributes = NULL; - while (asn1_tag_remaining(data) > 0) { + while (asn1_tag_remaining(data) > 0) { + const char *attr; if (!asn1_read_OctetString_talloc(msg, data, &attr)) - return False; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); if (!add_string_to_array(msg, attr, &r->attributes, &r->num_attributes)) - return False; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } asn1_end_tag(data); @@ -1106,7 +1109,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_end_tag(data); if (!add_mod_to_array_talloc(msg, &mod, &r->mods, &r->num_mods)) { - return False; + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } } @@ -1157,7 +1160,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); len = asn1_tag_remaining(data); if (len == -1) { - return False; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } dn = talloc_size(msg, len+1); if (dn == NULL) @@ -1193,11 +1196,11 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); len = asn1_tag_remaining(data); if (len == -1) { - return False; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } newsup = talloc_size(msg, len+1); if (newsup == NULL) { - return False; + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } asn1_read(data, newsup, len); newsup[len] = '\0'; @@ -1259,19 +1262,19 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) msg->type = LDAP_TAG_ExtendedRequest; asn1_start_tag(data,tag); if (!asn1_read_ContextSimple(data, 0, &tmp_blob)) { - return False; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } r->oid = blob2string_talloc(msg, tmp_blob); data_blob_free(&tmp_blob); if (!r->oid) { - return False; + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { asn1_read_ContextSimple(data, 1, &tmp_blob); r->value = talloc(msg, DATA_BLOB); if (!r->value) { - return False; + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); data_blob_free(&tmp_blob); @@ -1296,7 +1299,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) r->oid = blob2string_talloc(msg, tmp_blob); data_blob_free(&tmp_blob); if (!r->oid) { - return False; + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } } else { r->oid = NULL; @@ -1306,7 +1309,7 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_read_ContextSimple(data, 1, &tmp_blob); r->value = talloc(msg, DATA_BLOB); if (!r->value) { - return False; + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); data_blob_free(&tmp_blob); @@ -1318,34 +1321,45 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) break; } default: - return False; + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } msg->controls = NULL; if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { - int i; + int i = 0; struct ldb_control **ctrl = NULL; asn1_start_tag(data, ASN1_CONTEXT(0)); - for (i=0; asn1_peek_tag(data, ASN1_SEQUENCE(0)); i++) { + while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { + DATA_BLOB value; /* asn1_start_tag(data, ASN1_SEQUENCE(0)); */ ctrl = talloc_realloc(msg, ctrl, struct ldb_control *, i+2); if (!ctrl) { - return False; + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } ctrl[i] = talloc(ctrl, struct ldb_control); if (!ctrl[i]) { - return False; + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } - if (!ldap_decode_control(ctrl, data, ctrl[i])) { - return False; + if (!ldap_decode_control_wrapper(ctrl, data, ctrl[i], &value)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + + if (!ldap_decode_control_value(ctrl, value, ctrl[i])) { + if (ctrl[i]->critical) { + return NT_STATUS_LDAP(LDAP_UNAVAILABLE_CRITICAL_EXTENSION); + } else { + talloc_free(ctrl[i]); + ctrl[i] = NULL; + } + } else { + i++; } - } if (ctrl != NULL) { @@ -1358,7 +1372,10 @@ BOOL ldap_decode(struct asn1_data *data, struct ldap_message *msg) } asn1_end_tag(data); - return ((!data->has_error) && (data->nesting == NULL)); + if ((data->has_error) || (data->nesting != NULL)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + return NT_STATUS_OK; } diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 82cafd721a..8852fd5427 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -169,6 +169,8 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message */ static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob) { + int ret; + NTSTATUS status; struct asn1_data asn1; struct ldap_connection *conn = talloc_get_type(private_data, struct ldap_connection); @@ -182,8 +184,9 @@ static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob) return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } - if (!ldap_decode(&asn1, msg)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + status = ldap_decode(&asn1, msg); + if (!NT_STATUS_IS_OK(status)) { + return status; } ldap_match_message(conn, msg); diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 5cd0451136..bbb0cb1aa5 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -1059,14 +1059,35 @@ struct control_handler ldap_known_controls[] = { { "2.16.840.1.113730.3.4.2", decode_manageDSAIT_request, encode_manageDSAIT_request }, { "2.16.840.1.113730.3.4.9", decode_vlv_request, encode_vlv_request }, { "2.16.840.1.113730.3.4.10", decode_vlv_response, encode_vlv_response }, +/* DSDB_CONTROL_CURRENT_PARTITION_OID is internal only, and has no network representation */ + { "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 }, { NULL, NULL, NULL } }; -BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldb_control *ctrl) +BOOL ldap_decode_control_value(void *mem_ctx, DATA_BLOB value, struct ldb_control *ctrl) { int i; + + 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].decode || !ldap_known_controls[i].decode(mem_ctx, value, &ctrl->data)) { + return False; + } + break; + } + } + if (ldap_known_controls[i].oid == NULL) { + return False; + } + + return True; +} + +BOOL ldap_decode_control_wrapper(void *mem_ctx, struct asn1_data *data, struct ldb_control *ctrl, DATA_BLOB *value) +{ DATA_BLOB oid; - DATA_BLOB value; if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; @@ -1096,19 +1117,7 @@ BOOL ldap_decode_control(void *mem_ctx, struct asn1_data *data, struct ldb_contr goto end_tag; } - if (!asn1_read_OctetString(data, &value)) { - 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].decode(mem_ctx, value, &ctrl->data)) { - return False; - } - break; - } - } - if (ldap_known_controls[i].oid == NULL) { + if (!asn1_read_OctetString(data, value)) { return False; } @@ -1125,6 +1134,26 @@ BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldb_contr DATA_BLOB value; int i; + 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) { + if (ctrl->critical) { + return False; + } else { + /* not encoding this control */ + return True; + } + } + if (!ldap_known_controls[i].encode(mem_ctx, ctrl->data, &value)) { + return False; + } + break; + } + } + if (ldap_known_controls[i].oid == NULL) { + return False; + } + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } @@ -1143,18 +1172,6 @@ BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldb_contr goto pop_tag; } - 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->data, &value)) { - return False; - } - break; - } - } - if (ldap_known_controls[i].oid == NULL) { - return False; - } - if (!asn1_write_OctetString(data, value.data, value.length)) { return False; } -- cgit From 1c8b46bb7236edac23de83d1d8de7244e4044a81 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Apr 2007 11:02:45 +0000 Subject: r22405: fix memory leak in error path metze (This used to be commit d19195bfa5405822613d5236cd76547f0ac77bde) --- source4/libcli/ldap/ldap_client.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 8852fd5427..39f265015a 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -186,6 +186,7 @@ static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob) status = ldap_decode(&asn1, msg); if (!NT_STATUS_IS_OK(status)) { + asn1_free(&asn1); return status; } -- cgit From cb00a33c672ce78dc58a722804013e5b567fdf45 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 15 May 2007 07:16:04 +0000 Subject: r22884: Be consistant with the case of these constants. Andrew Bartlett (This used to be commit 7b086eebd6af21674ca18c7d9b35cb2c6b57514a) --- source4/libcli/ldap/ldap.h | 2 +- source4/libcli/ldap/ldap_client.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 30c5acc6fb..faf6815390 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -79,7 +79,7 @@ enum ldap_result_code { LDAP_ALIAS_DEREFERENCING_PROBLEM = 36, LDAP_INAPPROPRIATE_AUTHENTICATION = 48, LDAP_INVALID_CREDENTIALS = 49, - LDAP_INSUFFICIENT_ACCESS_RIGHTs = 50, + LDAP_INSUFFICIENT_ACCESS_RIGHTS = 50, LDAP_BUSY = 51, LDAP_UNAVAILABLE = 52, LDAP_UNWILLING_TO_PERFORM = 53, diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 39f265015a..c819122dd2 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -658,7 +658,7 @@ static const struct { _LDAP_MAP_CODE(LDAP_ALIAS_DEREFERENCING_PROBLEM), _LDAP_MAP_CODE(LDAP_INAPPROPRIATE_AUTHENTICATION), _LDAP_MAP_CODE(LDAP_INVALID_CREDENTIALS), - _LDAP_MAP_CODE(LDAP_INSUFFICIENT_ACCESS_RIGHTs), + _LDAP_MAP_CODE(LDAP_INSUFFICIENT_ACCESS_RIGHTS), _LDAP_MAP_CODE(LDAP_BUSY), _LDAP_MAP_CODE(LDAP_UNAVAILABLE), _LDAP_MAP_CODE(LDAP_UNWILLING_TO_PERFORM), -- cgit From 7bb939b1cb2b39a8271cf16d9f5fce5312a9af10 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 21 May 2007 06:12:06 +0000 Subject: r23030: finally fixed up our asn1 code to use better memory allocation. This should allow us to fix some long standing memory leaks. (This used to be commit 3db49c2ec9968221c1361785b94061046ecd159d) --- source4/libcli/ldap/ldap.c | 297 ++++++++++++++++--------------- source4/libcli/ldap/ldap_client.c | 11 +- source4/libcli/ldap/ldap_controls.c | 344 +++++++++++++++++------------------- 3 files changed, 320 insertions(+), 332 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 1e308d5847..70ba9335db 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -190,55 +190,54 @@ static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *res BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) { - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); int i, j; - ZERO_STRUCT(data); - asn1_push_tag(&data, ASN1_SEQUENCE(0)); - asn1_write_Integer(&data, msg->messageid); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_Integer(data, msg->messageid); switch (msg->type) { case LDAP_TAG_BindRequest: { struct ldap_BindRequest *r = &msg->r.BindRequest; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - asn1_write_Integer(&data, r->version); - asn1_write_OctetString(&data, r->dn, + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_Integer(data, r->version); + asn1_write_OctetString(data, r->dn, (r->dn != NULL) ? strlen(r->dn) : 0); switch (r->mechanism) { case LDAP_AUTH_MECH_SIMPLE: /* context, primitive */ - asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write(&data, r->creds.password, + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(data, r->creds.password, strlen(r->creds.password)); - asn1_pop_tag(&data); + asn1_pop_tag(data); break; case LDAP_AUTH_MECH_SASL: /* context, constructed */ - asn1_push_tag(&data, ASN1_CONTEXT(3)); - asn1_write_OctetString(&data, r->creds.SASL.mechanism, + asn1_push_tag(data, ASN1_CONTEXT(3)); + asn1_write_OctetString(data, r->creds.SASL.mechanism, strlen(r->creds.SASL.mechanism)); if (r->creds.SASL.secblob) { - asn1_write_OctetString(&data, r->creds.SASL.secblob->data, + asn1_write_OctetString(data, r->creds.SASL.secblob->data, r->creds.SASL.secblob->length); } - asn1_pop_tag(&data); + asn1_pop_tag(data); break; default: return False; } - asn1_pop_tag(&data); + asn1_pop_tag(data); break; } case LDAP_TAG_BindResponse: { struct ldap_BindResponse *r = &msg->r.BindResponse; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(&data, &r->response); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, &r->response); if (r->SASL.secblob) { - asn1_write_ContextSimple(&data, 7, r->SASL.secblob); + asn1_write_ContextSimple(data, 7, r->SASL.secblob); } - asn1_pop_tag(&data); + asn1_pop_tag(data); break; } case LDAP_TAG_UnbindRequest: { @@ -247,223 +246,223 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct } case LDAP_TAG_SearchRequest: { struct ldap_SearchRequest *r = &msg->r.SearchRequest; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(&data, r->basedn, strlen(r->basedn)); - asn1_write_enumerated(&data, r->scope); - asn1_write_enumerated(&data, r->deref); - asn1_write_Integer(&data, r->sizelimit); - asn1_write_Integer(&data, r->timelimit); - asn1_write_BOOLEAN(&data, r->attributesonly); - - if (!ldap_push_filter(&data, r->tree)) { + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->basedn, strlen(r->basedn)); + asn1_write_enumerated(data, r->scope); + asn1_write_enumerated(data, r->deref); + asn1_write_Integer(data, r->sizelimit); + asn1_write_Integer(data, r->timelimit); + asn1_write_BOOLEAN(data, r->attributesonly); + + if (!ldap_push_filter(data, r->tree)) { return False; } - asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); for (i=0; inum_attributes; i++) { - asn1_write_OctetString(&data, r->attributes[i], + asn1_write_OctetString(data, r->attributes[i], strlen(r->attributes[i])); } - asn1_pop_tag(&data); - asn1_pop_tag(&data); + asn1_pop_tag(data); + asn1_pop_tag(data); break; } case LDAP_TAG_SearchResultEntry: { struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(&data, r->dn, strlen(r->dn)); - asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); for (i=0; inum_attributes; i++) { struct ldb_message_element *attr = &r->attributes[i]; - asn1_push_tag(&data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(&data, attr->name, + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, attr->name, strlen(attr->name)); - asn1_push_tag(&data, ASN1_SEQUENCE(1)); + asn1_push_tag(data, ASN1_SEQUENCE(1)); for (j=0; jnum_values; j++) { - asn1_write_OctetString(&data, + asn1_write_OctetString(data, attr->values[j].data, attr->values[j].length); } - asn1_pop_tag(&data); - asn1_pop_tag(&data); + asn1_pop_tag(data); + asn1_pop_tag(data); } - asn1_pop_tag(&data); - asn1_pop_tag(&data); + asn1_pop_tag(data); + asn1_pop_tag(data); break; } case LDAP_TAG_SearchResultDone: { struct ldap_Result *r = &msg->r.SearchResultDone; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(&data, r); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); break; } case LDAP_TAG_ModifyRequest: { struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(&data, r->dn, strlen(r->dn)); - asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); for (i=0; inum_mods; i++) { struct ldb_message_element *attrib = &r->mods[i].attrib; - asn1_push_tag(&data, ASN1_SEQUENCE(0)); - asn1_write_enumerated(&data, r->mods[i].type); - asn1_push_tag(&data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(&data, attrib->name, + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_enumerated(data, r->mods[i].type); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, attrib->name, strlen(attrib->name)); - asn1_push_tag(&data, ASN1_SET); + asn1_push_tag(data, ASN1_SET); for (j=0; jnum_values; j++) { - asn1_write_OctetString(&data, + asn1_write_OctetString(data, attrib->values[j].data, attrib->values[j].length); } - asn1_pop_tag(&data); - asn1_pop_tag(&data); - asn1_pop_tag(&data); + asn1_pop_tag(data); + asn1_pop_tag(data); + asn1_pop_tag(data); } - asn1_pop_tag(&data); - asn1_pop_tag(&data); + asn1_pop_tag(data); + asn1_pop_tag(data); break; } case LDAP_TAG_ModifyResponse: { struct ldap_Result *r = &msg->r.ModifyResponse; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(&data, r); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); break; } case LDAP_TAG_AddRequest: { struct ldap_AddRequest *r = &msg->r.AddRequest; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(&data, r->dn, strlen(r->dn)); - asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); for (i=0; inum_attributes; i++) { struct ldb_message_element *attrib = &r->attributes[i]; - asn1_push_tag(&data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(&data, attrib->name, + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, attrib->name, strlen(attrib->name)); - asn1_push_tag(&data, ASN1_SET); + asn1_push_tag(data, ASN1_SET); for (j=0; jattributes[i].num_values; j++) { - asn1_write_OctetString(&data, + asn1_write_OctetString(data, attrib->values[j].data, attrib->values[j].length); } - asn1_pop_tag(&data); - asn1_pop_tag(&data); + asn1_pop_tag(data); + asn1_pop_tag(data); } - asn1_pop_tag(&data); - asn1_pop_tag(&data); + asn1_pop_tag(data); + asn1_pop_tag(data); break; } case LDAP_TAG_AddResponse: { struct ldap_Result *r = &msg->r.AddResponse; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(&data, r); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); break; } case LDAP_TAG_DelRequest: { struct ldap_DelRequest *r = &msg->r.DelRequest; - asn1_push_tag(&data, ASN1_APPLICATION_SIMPLE(msg->type)); - asn1_write(&data, r->dn, strlen(r->dn)); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); + asn1_write(data, r->dn, strlen(r->dn)); + asn1_pop_tag(data); break; } case LDAP_TAG_DelResponse: { struct ldap_Result *r = &msg->r.DelResponse; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(&data, r); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); break; } case LDAP_TAG_ModifyDNRequest: { struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(&data, r->dn, strlen(r->dn)); - asn1_write_OctetString(&data, r->newrdn, strlen(r->newrdn)); - asn1_write_BOOLEAN(&data, r->deleteolddn); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_write_OctetString(data, r->newrdn, strlen(r->newrdn)); + asn1_write_BOOLEAN(data, r->deleteolddn); if (r->newsuperior) { - asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write(&data, r->newsuperior, + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(data, r->newsuperior, strlen(r->newsuperior)); - asn1_pop_tag(&data); + asn1_pop_tag(data); } - asn1_pop_tag(&data); + asn1_pop_tag(data); break; } case LDAP_TAG_ModifyDNResponse: { struct ldap_Result *r = &msg->r.ModifyDNResponse; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(&data, r); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); break; } case LDAP_TAG_CompareRequest: { struct ldap_CompareRequest *r = &msg->r.CompareRequest; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(&data, r->dn, strlen(r->dn)); - asn1_push_tag(&data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(&data, r->attribute, + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, r->attribute, strlen(r->attribute)); - asn1_write_OctetString(&data, r->value.data, + asn1_write_OctetString(data, r->value.data, r->value.length); - asn1_pop_tag(&data); - asn1_pop_tag(&data); + asn1_pop_tag(data); + asn1_pop_tag(data); break; } case LDAP_TAG_CompareResponse: { struct ldap_Result *r = &msg->r.ModifyDNResponse; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(&data, r); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); break; } case LDAP_TAG_AbandonRequest: { struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; - asn1_push_tag(&data, ASN1_APPLICATION_SIMPLE(msg->type)); - asn1_write_implicit_Integer(&data, r->messageid); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); + asn1_write_implicit_Integer(data, r->messageid); + asn1_pop_tag(data); break; } case LDAP_TAG_SearchResultReference: { struct ldap_SearchResRef *r = &msg->r.SearchResultReference; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(&data, r->referral, strlen(r->referral)); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->referral, strlen(r->referral)); + asn1_pop_tag(data); break; } case LDAP_TAG_ExtendedRequest: { struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write(&data, r->oid, strlen(r->oid)); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(data, r->oid, strlen(r->oid)); + asn1_pop_tag(data); if (r->value) { - asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(1)); - asn1_write(&data, r->value->data, r->value->length); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); + asn1_write(data, r->value->data, r->value->length); + asn1_pop_tag(data); } - asn1_pop_tag(&data); + asn1_pop_tag(data); break; } case LDAP_TAG_ExtendedResponse: { struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; - asn1_push_tag(&data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(&data, &r->response); + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, &r->response); if (r->oid) { - asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(10)); - asn1_write(&data, r->oid, strlen(r->oid)); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(10)); + asn1_write(data, r->oid, strlen(r->oid)); + asn1_pop_tag(data); } if (r->value) { - asn1_push_tag(&data, ASN1_CONTEXT_SIMPLE(11)); - asn1_write(&data, r->value->data, r->value->length); - asn1_pop_tag(&data); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(11)); + asn1_write(data, r->value->data, r->value->length); + asn1_pop_tag(data); } - asn1_pop_tag(&data); + asn1_pop_tag(data); break; } default: @@ -471,26 +470,26 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct } if (msg->controls != NULL) { - asn1_push_tag(&data, ASN1_CONTEXT(0)); + 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])) { + if (!ldap_encode_control(mem_ctx, data, msg->controls[i])) { return False; } } - asn1_pop_tag(&data); + asn1_pop_tag(data); } - asn1_pop_tag(&data); + asn1_pop_tag(data); - if (data.has_error) { - asn1_free(&data); + if (data->has_error) { + asn1_free(data); return False; } - *result = data_blob_talloc(mem_ctx, data.data, data.length); - asn1_free(&data); + *result = data_blob_talloc(mem_ctx, data->data, data->length); + asn1_free(data); return True; } @@ -508,7 +507,7 @@ static BOOL asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, const char **result) { DATA_BLOB string; - if (!asn1_read_OctetString(data, &string)) + if (!asn1_read_OctetString(data, mem_ctx, &string)) return False; *result = blob2string_talloc(mem_ctx, string); data_blob_free(&string); @@ -631,7 +630,7 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, &value); + asn1_read_OctetString(data, mem_ctx, &value); asn1_end_tag(data); if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { goto failed; @@ -653,7 +652,7 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { goto failed; } - if (!asn1_read_OctetString(data, &attr)) { + if (!asn1_read_OctetString(data, mem_ctx, &attr)) { goto failed; } @@ -673,7 +672,7 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, if (subs_tag > 2) goto failed; asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(subs_tag)); - asn1_read_LDAPString(data, &value); + asn1_read_LDAPString(data, mem_ctx, &value); asn1_end_tag(data); switch (subs_tag) { @@ -743,7 +742,7 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, &value); + asn1_read_OctetString(data, mem_ctx, &value); asn1_end_tag(data); if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { goto failed; @@ -762,7 +761,7 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, &value); + asn1_read_OctetString(data, mem_ctx, &value); asn1_end_tag(data); if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { goto failed; @@ -781,7 +780,7 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(filter_tag))) { goto failed; } - if (!asn1_read_LDAPString(data, &attr)) { + if (!asn1_read_LDAPString(data, ret, &attr)) { goto failed; } @@ -800,7 +799,7 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, &value); + asn1_read_OctetString(data, mem_ctx, &value); asn1_end_tag(data); if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { goto failed; @@ -825,16 +824,16 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, /* either oid or type must be defined */ if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { /* optional */ asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1)); - asn1_read_LDAPString(data, &oid); + asn1_read_LDAPString(data, ret, &oid); asn1_end_tag(data); } if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(2))) { /* optional */ asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2)); - asn1_read_LDAPString(data, &attr); + asn1_read_LDAPString(data, ret, &attr); asn1_end_tag(data); } asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(3)); - asn1_read_LDAPString(data, &value); + asn1_read_LDAPString(data, ret, &value); asn1_end_tag(data); /* dnAttributes is marked as BOOLEAN DEFAULT FALSE it is not marked as OPTIONAL but openldap tools @@ -902,7 +901,7 @@ static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, asn1_start_tag(data, ASN1_SET); while (asn1_peek_tag(data, ASN1_OCTET_STRING)) { DATA_BLOB blob; - asn1_read_OctetString(data, &blob); + asn1_read_OctetString(data, mem_ctx, &blob); add_value_to_attrib(mem_ctx, &blob, attrib); } asn1_end_tag(data); @@ -970,7 +969,7 @@ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism); if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { /* optional */ DATA_BLOB tmp_blob = data_blob(NULL, 0); - asn1_read_OctetString(data, &tmp_blob); + asn1_read_OctetString(data, msg, &tmp_blob); r->creds.SASL.secblob = talloc(msg, DATA_BLOB); if (!r->creds.SASL.secblob) { return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); @@ -1228,7 +1227,7 @@ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) asn1_read_OctetString_talloc(msg, data, &r->dn); asn1_start_tag(data, ASN1_SEQUENCE(0)); asn1_read_OctetString_talloc(msg, data, &r->attribute); - asn1_read_OctetString(data, &r->value); + asn1_read_OctetString(data, msg, &r->value); if (r->value.data) { talloc_steal(msg, r->value.data); } diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index c819122dd2..5e4eddee92 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -169,31 +169,30 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message */ static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob) { - int ret; NTSTATUS status; - struct asn1_data asn1; struct ldap_connection *conn = talloc_get_type(private_data, struct ldap_connection); struct ldap_message *msg = talloc(conn, struct ldap_message); + struct asn1_data *asn1 = asn1_init(conn); if (msg == NULL) { return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } - if (!asn1_load(&asn1, blob)) { + if (!asn1_load(asn1, blob)) { return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } - status = ldap_decode(&asn1, msg); + status = ldap_decode(asn1, msg); if (!NT_STATUS_IS_OK(status)) { - asn1_free(&asn1); + asn1_free(asn1); return status; } ldap_match_message(conn, msg); data_blob_free(&blob); - asn1_free(&asn1); + asn1_free(asn1); return NT_STATUS_OK; } diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index bbb0cb1aa5..180e6eeb62 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -34,10 +34,10 @@ struct control_handler { static BOOL decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB attr; - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); struct ldb_sort_resp_control *lsrc; - if (!asn1_load(&data, in)) { + if (!asn1_load(data, in)) { return False; } @@ -46,17 +46,17 @@ static BOOL decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void **out) return False; } - if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_read_enumerated(&data, &(lsrc->result))) { + 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)) { + if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { + if (!asn1_read_OctetString(data, mem_ctx, &attr)) { return False; } lsrc->attr_desc = talloc_strndup(lsrc, (const char *)attr.data, attr.length); @@ -65,7 +65,7 @@ static BOOL decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void **out) } } - if (!asn1_end_tag(&data)) { + if (!asn1_end_tag(data)) { return False; } @@ -78,21 +78,21 @@ 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 asn1_data *data = asn1_init(mem_ctx); struct ldb_server_sort_control **lssc; int num; - if (!asn1_load(&data, in)) { + if (!asn1_load(data, in)) { return False; } - if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; } lssc = NULL; - for (num = 0; asn1_peek_tag(&data, ASN1_SEQUENCE(0)); num++) { + 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; @@ -102,11 +102,11 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) return False; } - if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_read_OctetString(&data, &attr)) { + if (!asn1_read_OctetString(data, mem_ctx, &attr)) { return False; } @@ -115,8 +115,8 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) return False; } - if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) { - if (!asn1_read_OctetString(&data, &rule)) { + if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { + if (!asn1_read_OctetString(data, mem_ctx, &rule)) { return False; } lssc[num]->orderingRule = talloc_strndup(lssc[num], (const char *)rule.data, rule.length); @@ -125,15 +125,15 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) } } - if (asn1_peek_tag(&data, ASN1_BOOLEAN)) { + if (asn1_peek_tag(data, ASN1_BOOLEAN)) { BOOL reverse; - if (!asn1_read_BOOLEAN(&data, &reverse)) { + if (!asn1_read_BOOLEAN(data, &reverse)) { return False; } lssc[num]->reverse = reverse; } - if (!asn1_end_tag(&data)) { + if (!asn1_end_tag(data)) { return False; } } @@ -142,7 +142,7 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) lssc[num] = NULL; } - if (!asn1_end_tag(&data)) { + if (!asn1_end_tag(data)) { return False; } @@ -153,10 +153,10 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) static BOOL decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out) { - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); struct ldb_extended_dn_control *ledc; - if (!asn1_load(&data, in)) { + if (!asn1_load(data, in)) { return False; } @@ -165,15 +165,15 @@ static BOOL decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out) return False; } - if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_read_Integer(&data, &(ledc->type))) { + if (!asn1_read_Integer(data, &(ledc->type))) { return False; } - if (!asn1_end_tag(&data)) { + if (!asn1_end_tag(data)) { return False; } @@ -184,10 +184,10 @@ static BOOL decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out) static BOOL decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out) { - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); struct ldb_sd_flags_control *lsdfc; - if (!asn1_load(&data, in)) { + if (!asn1_load(data, in)) { return False; } @@ -196,15 +196,15 @@ static BOOL decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out) return False; } - if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_read_Integer(&data, &(lsdfc->secinfo_flags))) { + if (!asn1_read_Integer(data, &(lsdfc->secinfo_flags))) { return False; } - if (!asn1_end_tag(&data)) { + if (!asn1_end_tag(data)) { return False; } @@ -215,10 +215,10 @@ static BOOL decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out) static BOOL decode_search_options_request(void *mem_ctx, DATA_BLOB in, void **out) { - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); struct ldb_search_options_control *lsoc; - if (!asn1_load(&data, in)) { + if (!asn1_load(data, in)) { return False; } @@ -227,15 +227,15 @@ static BOOL decode_search_options_request(void *mem_ctx, DATA_BLOB in, void **ou return False; } - if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_read_Integer(&data, &(lsoc->search_options))) { + if (!asn1_read_Integer(data, &(lsoc->search_options))) { return False; } - if (!asn1_end_tag(&data)) { + if (!asn1_end_tag(data)) { return False; } @@ -247,10 +247,10 @@ static BOOL decode_search_options_request(void *mem_ctx, DATA_BLOB in, void **ou static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB cookie; - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); struct ldb_paged_control *lprc; - if (!asn1_load(&data, in)) { + if (!asn1_load(data, in)) { return False; } @@ -259,15 +259,15 @@ static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out return False; } - if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_read_Integer(&data, &(lprc->size))) { + if (!asn1_read_Integer(data, &(lprc->size))) { return False; } - if (!asn1_read_OctetString(&data, &cookie)) { + if (!asn1_read_OctetString(data, mem_ctx, &cookie)) { return False; } lprc->cookie_len = cookie.length; @@ -281,7 +281,7 @@ static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out lprc->cookie = NULL; } - if (!asn1_end_tag(&data)) { + if (!asn1_end_tag(data)) { return False; } @@ -293,10 +293,10 @@ static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out static BOOL decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB cookie; - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); struct ldb_dirsync_control *ldc; - if (!asn1_load(&data, in)) { + if (!asn1_load(data, in)) { return False; } @@ -305,19 +305,19 @@ static BOOL decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out) return False; } - if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_read_Integer(&data, &(ldc->flags))) { + if (!asn1_read_Integer(data, &(ldc->flags))) { return False; } - if (!asn1_read_Integer(&data, &(ldc->max_attributes))) { + if (!asn1_read_Integer(data, &(ldc->max_attributes))) { return False; } - if (!asn1_read_OctetString(&data, &cookie)) { + if (!asn1_read_OctetString(data, mem_ctx, &cookie)) { return False; } ldc->cookie_len = cookie.length; @@ -331,7 +331,7 @@ static BOOL decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out) ldc->cookie = NULL; } - if (!asn1_end_tag(&data)) { + if (!asn1_end_tag(data)) { return False; } @@ -346,10 +346,10 @@ static BOOL decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out) static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB source_attribute; - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); struct ldb_asq_control *lac; - if (!asn1_load(&data, in)) { + if (!asn1_load(data, in)) { return False; } @@ -358,13 +358,13 @@ static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) return False; } - if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) { + if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { - if (!asn1_read_OctetString(&data, &source_attribute)) { + if (!asn1_read_OctetString(data, mem_ctx, &source_attribute)) { return False; } lac->src_attr_len = source_attribute.length; @@ -380,9 +380,9 @@ static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) lac->request = 1; - } else if (asn1_peek_tag(&data, ASN1_ENUMERATED)) { + } else if (asn1_peek_tag(data, ASN1_ENUMERATED)) { - if (!asn1_read_enumerated(&data, &(lac->result))) { + if (!asn1_read_enumerated(data, &(lac->result))) { return False; } @@ -392,7 +392,7 @@ static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) return False; } - if (!asn1_end_tag(&data)) { + if (!asn1_end_tag(data)) { return False; } @@ -449,10 +449,10 @@ static BOOL decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void **out) static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB assertion_value, context_id; - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); struct ldb_vlv_req_control *lvrc; - if (!asn1_load(&data, in)) { + if (!asn1_load(data, in)) { return False; } @@ -461,43 +461,43 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) return False; } - if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_read_Integer(&data, &(lvrc->beforeCount))) { + if (!asn1_read_Integer(data, &(lvrc->beforeCount))) { return False; } - if (!asn1_read_Integer(&data, &(lvrc->afterCount))) { + if (!asn1_read_Integer(data, &(lvrc->afterCount))) { return False; } - if (asn1_peek_tag(&data, ASN1_CONTEXT(0))) { + if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { lvrc->type = 0; - if (!asn1_start_tag(&data, ASN1_CONTEXT(0))) { + if (!asn1_start_tag(data, ASN1_CONTEXT(0))) { return False; } - if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_read_Integer(&data, &(lvrc->match.byOffset.offset))) { + if (!asn1_read_Integer(data, &(lvrc->match.byOffset.offset))) { return False; } - if (!asn1_read_Integer(&data, &(lvrc->match.byOffset.contentCount))) { + if (!asn1_read_Integer(data, &(lvrc->match.byOffset.contentCount))) { return False; } - if (!asn1_end_tag(&data)) { /*SEQUENCE*/ + if (!asn1_end_tag(data)) { /*SEQUENCE*/ return False; } - if (!asn1_end_tag(&data)) { /*CONTEXT*/ + if (!asn1_end_tag(data)) { /*CONTEXT*/ return False; } @@ -505,11 +505,11 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) lvrc->type = 1; - if (!asn1_start_tag(&data, ASN1_CONTEXT(1))) { + if (!asn1_start_tag(data, ASN1_CONTEXT(1))) { return False; } - if (!asn1_read_OctetString(&data, &assertion_value)) { + if (!asn1_read_OctetString(data, mem_ctx, &assertion_value)) { return False; } lvrc->match.gtOrEq.value_len = assertion_value.length; @@ -523,13 +523,13 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) lvrc->match.gtOrEq.value = NULL; } - if (!asn1_end_tag(&data)) { /*CONTEXT*/ + if (!asn1_end_tag(data)) { /*CONTEXT*/ return False; } } - if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) { - if (!asn1_read_OctetString(&data, &context_id)) { + if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { + if (!asn1_read_OctetString(data, mem_ctx, &context_id)) { return False; } lvrc->ctxid_len = context_id.length; @@ -547,7 +547,7 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) lvrc->ctxid_len = 0; } - if (!asn1_end_tag(&data)) { + if (!asn1_end_tag(data)) { return False; } @@ -559,10 +559,10 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) static BOOL decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB context_id; - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); struct ldb_vlv_resp_control *lvrc; - if (!asn1_load(&data, in)) { + if (!asn1_load(data, in)) { return False; } @@ -571,24 +571,24 @@ static BOOL decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out) return False; } - if (!asn1_start_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_read_Integer(&data, &(lvrc->targetPosition))) { + if (!asn1_read_Integer(data, &(lvrc->targetPosition))) { return False; } - if (!asn1_read_Integer(&data, &(lvrc->contentCount))) { + if (!asn1_read_Integer(data, &(lvrc->contentCount))) { return False; } - if (!asn1_read_enumerated(&data, &(lvrc->vlv_result))) { + if (!asn1_read_enumerated(data, &(lvrc->vlv_result))) { return False; } - if (asn1_peek_tag(&data, ASN1_OCTET_STRING)) { - if (!asn1_read_OctetString(&data, &context_id)) { + if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { + if (!asn1_read_OctetString(data, mem_ctx, &context_id)) { return False; } lvrc->contextId = talloc_strndup(lvrc, (const char *)context_id.data, context_id.length); @@ -601,7 +601,7 @@ static BOOL decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out) lvrc->ctxid_len = 0; } - if (!asn1_end_tag(&data)) { + if (!asn1_end_tag(data)) { return False; } @@ -613,32 +613,31 @@ static BOOL decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out) 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); + struct asn1_data *data = asn1_init(mem_ctx); - if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_write_enumerated(&data, lsrc->result)) { + 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))) { + if (!asn1_write_OctetString(data, lsrc->attr_desc, strlen(lsrc->attr_desc))) { return False; } } - if (!asn1_pop_tag(&data)) { + if (!asn1_pop_tag(data)) { return False; } - *out = data_blob_talloc(mem_ctx, data.data, data.length); + *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { return False; } + talloc_free(data); return True; } @@ -646,49 +645,48 @@ static BOOL encode_server_sort_response(void *mem_ctx, void *in, DATA_BLOB *out) 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; + struct asn1_data *data = asn1_init(mem_ctx); int num; - ZERO_STRUCT(data); - - if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } for (num = 0; lssc[num]; num++) { - if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_write_OctetString(&data, lssc[num]->attributeName, strlen(lssc[num]->attributeName))) { + 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))) { + 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)) { + if (!asn1_write_BOOLEAN(data, lssc[num]->reverse)) { return False; } } - if (!asn1_pop_tag(&data)) { + if (!asn1_pop_tag(data)) { return False; } } - if (!asn1_pop_tag(&data)) { + if (!asn1_pop_tag(data)) { return False; } - *out = data_blob_talloc(mem_ctx, data.data, data.length); + *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { return False; } + talloc_free(data); return True; } @@ -696,26 +694,25 @@ static BOOL encode_server_sort_request(void *mem_ctx, void *in, DATA_BLOB *out) 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); + struct asn1_data *data = asn1_init(mem_ctx); - if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_write_Integer(&data, ledc->type)) { + if (!asn1_write_Integer(data, ledc->type)) { return False; } - if (!asn1_pop_tag(&data)) { + if (!asn1_pop_tag(data)) { return False; } - *out = data_blob_talloc(mem_ctx, data.data, data.length); + *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { return False; } + talloc_free(data); return True; } @@ -723,26 +720,25 @@ static BOOL encode_extended_dn_request(void *mem_ctx, void *in, DATA_BLOB *out) static BOOL encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_sd_flags_control *lsdfc = talloc_get_type(in, struct ldb_sd_flags_control); - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); - ZERO_STRUCT(data); - - if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_write_Integer(&data, lsdfc->secinfo_flags)) { + if (!asn1_write_Integer(data, lsdfc->secinfo_flags)) { return False; } - if (!asn1_pop_tag(&data)) { + if (!asn1_pop_tag(data)) { return False; } - *out = data_blob_talloc(mem_ctx, data.data, data.length); + *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { return False; } + talloc_free(data); return True; } @@ -750,26 +746,25 @@ static BOOL encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out) static BOOL encode_search_options_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_search_options_control *lsoc = talloc_get_type(in, struct ldb_search_options_control); - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); - ZERO_STRUCT(data); - - if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_write_Integer(&data, lsoc->search_options)) { + if (!asn1_write_Integer(data, lsoc->search_options)) { return False; } - if (!asn1_pop_tag(&data)) { + if (!asn1_pop_tag(data)) { return False; } - *out = data_blob_talloc(mem_ctx, data.data, data.length); + *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { return False; } + talloc_free(data); return True; } @@ -777,30 +772,29 @@ static BOOL encode_search_options_request(void *mem_ctx, void *in, DATA_BLOB *ou 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; + struct asn1_data *data = asn1_init(mem_ctx); - ZERO_STRUCT(data); - - if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_write_Integer(&data, lprc->size)) { + if (!asn1_write_Integer(data, lprc->size)) { return False; } - if (!asn1_write_OctetString(&data, lprc->cookie, lprc->cookie_len)) { + if (!asn1_write_OctetString(data, lprc->cookie, lprc->cookie_len)) { return False; } - if (!asn1_pop_tag(&data)) { + if (!asn1_pop_tag(data)) { return False; } - *out = data_blob_talloc(mem_ctx, data.data, data.length); + *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { return False; } + talloc_free(data); return True; } @@ -811,33 +805,32 @@ static BOOL encode_paged_results_request(void *mem_ctx, void *in, DATA_BLOB *out static BOOL encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_asq_control *lac = talloc_get_type(in, struct ldb_asq_control); - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); - ZERO_STRUCT(data); - - if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } if (lac->request) { - if (!asn1_write_OctetString(&data, lac->source_attribute, lac->src_attr_len)) { + if (!asn1_write_OctetString(data, lac->source_attribute, lac->src_attr_len)) { return False; } } else { - if (!asn1_write_enumerated(&data, lac->result)) { + if (!asn1_write_enumerated(data, lac->result)) { return False; } } - if (!asn1_pop_tag(&data)) { + if (!asn1_pop_tag(data)) { return False; } - *out = data_blob_talloc(mem_ctx, data.data, data.length); + *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { return False; } + talloc_free(data); return True; } @@ -845,34 +838,33 @@ static BOOL encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out) static BOOL encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_dirsync_control *ldc = talloc_get_type(in, struct ldb_dirsync_control); - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); - ZERO_STRUCT(data); - - if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_write_Integer(&data, ldc->flags)) { + if (!asn1_write_Integer(data, ldc->flags)) { return False; } - if (!asn1_write_Integer(&data, ldc->max_attributes)) { + if (!asn1_write_Integer(data, ldc->max_attributes)) { return False; } - if (!asn1_write_OctetString(&data, ldc->cookie, ldc->cookie_len)) { + if (!asn1_write_OctetString(data, ldc->cookie, ldc->cookie_len)) { return False; } - if (!asn1_pop_tag(&data)) { + if (!asn1_pop_tag(data)) { return False; } - *out = data_blob_talloc(mem_ctx, data.data, data.length); + *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { return False; } + talloc_free(data); return True; } @@ -930,74 +922,73 @@ static BOOL encode_manageDSAIT_request(void *mem_ctx, void *in, DATA_BLOB *out) static BOOL encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_vlv_req_control *lvrc = talloc_get_type(in, struct ldb_vlv_req_control); - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); - ZERO_STRUCT(data); - - if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_write_Integer(&data, lvrc->beforeCount)) { + if (!asn1_write_Integer(data, lvrc->beforeCount)) { return False; } - if (!asn1_write_Integer(&data, lvrc->afterCount)) { + if (!asn1_write_Integer(data, lvrc->afterCount)) { return False; } if (lvrc->type == 0) { - if (!asn1_push_tag(&data, ASN1_CONTEXT(0))) { + if (!asn1_push_tag(data, ASN1_CONTEXT(0))) { return False; } - if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_write_Integer(&data, lvrc->match.byOffset.offset)) { + if (!asn1_write_Integer(data, lvrc->match.byOffset.offset)) { return False; } - if (!asn1_write_Integer(&data, lvrc->match.byOffset.contentCount)) { + if (!asn1_write_Integer(data, lvrc->match.byOffset.contentCount)) { return False; } - if (!asn1_pop_tag(&data)) { /*SEQUENCE*/ + if (!asn1_pop_tag(data)) { /*SEQUENCE*/ return False; } - if (!asn1_pop_tag(&data)) { /*CONTEXT*/ + if (!asn1_pop_tag(data)) { /*CONTEXT*/ return False; } } else { - if (!asn1_push_tag(&data, ASN1_CONTEXT(1))) { + if (!asn1_push_tag(data, ASN1_CONTEXT(1))) { return False; } - if (!asn1_write_OctetString(&data, lvrc->match.gtOrEq.value, lvrc->match.gtOrEq.value_len)) { + if (!asn1_write_OctetString(data, lvrc->match.gtOrEq.value, lvrc->match.gtOrEq.value_len)) { return False; } - if (!asn1_pop_tag(&data)) { /*CONTEXT*/ + if (!asn1_pop_tag(data)) { /*CONTEXT*/ return False; } } if (lvrc->ctxid_len) { - if (!asn1_write_OctetString(&data, lvrc->contextId, lvrc->ctxid_len)) { + if (!asn1_write_OctetString(data, lvrc->contextId, lvrc->ctxid_len)) { return False; } } - if (!asn1_pop_tag(&data)) { + if (!asn1_pop_tag(data)) { return False; } - *out = data_blob_talloc(mem_ctx, data.data, data.length); + *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { return False; } + talloc_free(data); return True; } @@ -1005,40 +996,39 @@ static BOOL encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out) static BOOL encode_vlv_response(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_vlv_resp_control *lvrc = talloc_get_type(in, struct ldb_vlv_resp_control); - struct asn1_data data; + struct asn1_data *data = asn1_init(mem_ctx); - ZERO_STRUCT(data); - - if (!asn1_push_tag(&data, ASN1_SEQUENCE(0))) { + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } - if (!asn1_write_Integer(&data, lvrc->targetPosition)) { + if (!asn1_write_Integer(data, lvrc->targetPosition)) { return False; } - if (!asn1_write_Integer(&data, lvrc->contentCount)) { + if (!asn1_write_Integer(data, lvrc->contentCount)) { return False; } - if (!asn1_write_enumerated(&data, lvrc->vlv_result)) { + if (!asn1_write_enumerated(data, lvrc->vlv_result)) { return False; } if (lvrc->ctxid_len) { - if (!asn1_write_OctetString(&data, lvrc->contextId, lvrc->ctxid_len)) { + if (!asn1_write_OctetString(data, lvrc->contextId, lvrc->ctxid_len)) { return False; } } - if (!asn1_pop_tag(&data)) { + if (!asn1_pop_tag(data)) { return False; } - *out = data_blob_talloc(mem_ctx, data.data, data.length); + *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { return False; } + talloc_free(data); return True; } @@ -1093,7 +1083,7 @@ BOOL ldap_decode_control_wrapper(void *mem_ctx, struct asn1_data *data, struct l return False; } - if (!asn1_read_OctetString(data, &oid)) { + if (!asn1_read_OctetString(data, mem_ctx, &oid)) { return False; } ctrl->oid = talloc_strndup(mem_ctx, (char *)oid.data, oid.length); @@ -1117,7 +1107,7 @@ BOOL ldap_decode_control_wrapper(void *mem_ctx, struct asn1_data *data, struct l goto end_tag; } - if (!asn1_read_OctetString(data, value)) { + if (!asn1_read_OctetString(data, mem_ctx, value)) { return False; } -- cgit From 931f594cf16b8c7f9f416d7a8831432b783a0ec8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 21 May 2007 12:47:18 +0000 Subject: r23036: error checking on asn1_init() failure (This used to be commit 26cf8494084c0106ef0e1c9b6ef40eeadf945ef2) --- source4/libcli/ldap/ldap.c | 2 ++ source4/libcli/ldap/ldap_client.c | 4 +++- source4/libcli/ldap/ldap_controls.c | 40 +++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 70ba9335db..55988b8eb4 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -193,6 +193,8 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct struct asn1_data *data = asn1_init(mem_ctx); int i, j; + if (!data) return False; + asn1_push_tag(data, ASN1_SEQUENCE(0)); asn1_write_Integer(data, msg->messageid); diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 5e4eddee92..ce15b39271 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -175,11 +175,13 @@ static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob) struct ldap_message *msg = talloc(conn, struct ldap_message); struct asn1_data *asn1 = asn1_init(conn); - if (msg == NULL) { + if (asn1 == NULL || msg == NULL) { return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } if (!asn1_load(asn1, blob)) { + talloc_free(msg); + talloc_free(asn1); return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 180e6eeb62..79c16afc95 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -37,6 +37,8 @@ static BOOL decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void **out) struct asn1_data *data = asn1_init(mem_ctx); struct ldb_sort_resp_control *lsrc; + if (!data) return False; + if (!asn1_load(data, in)) { return False; } @@ -82,6 +84,8 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) struct ldb_server_sort_control **lssc; int num; + if (!data) return False; + if (!asn1_load(data, in)) { return False; } @@ -156,6 +160,8 @@ static BOOL decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out) struct asn1_data *data = asn1_init(mem_ctx); struct ldb_extended_dn_control *ledc; + if (!data) return False; + if (!asn1_load(data, in)) { return False; } @@ -187,6 +193,8 @@ static BOOL decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out) struct asn1_data *data = asn1_init(mem_ctx); struct ldb_sd_flags_control *lsdfc; + if (!data) return False; + if (!asn1_load(data, in)) { return False; } @@ -218,6 +226,8 @@ static BOOL decode_search_options_request(void *mem_ctx, DATA_BLOB in, void **ou struct asn1_data *data = asn1_init(mem_ctx); struct ldb_search_options_control *lsoc; + if (!data) return False; + if (!asn1_load(data, in)) { return False; } @@ -250,6 +260,8 @@ static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out struct asn1_data *data = asn1_init(mem_ctx); struct ldb_paged_control *lprc; + if (!data) return False; + if (!asn1_load(data, in)) { return False; } @@ -296,6 +308,8 @@ static BOOL decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out) struct asn1_data *data = asn1_init(mem_ctx); struct ldb_dirsync_control *ldc; + if (!data) return False; + if (!asn1_load(data, in)) { return False; } @@ -349,6 +363,8 @@ static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) struct asn1_data *data = asn1_init(mem_ctx); struct ldb_asq_control *lac; + if (!data) return False; + if (!asn1_load(data, in)) { return False; } @@ -452,6 +468,8 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) struct asn1_data *data = asn1_init(mem_ctx); struct ldb_vlv_req_control *lvrc; + if (!data) return False; + if (!asn1_load(data, in)) { return False; } @@ -562,6 +580,8 @@ static BOOL decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out) struct asn1_data *data = asn1_init(mem_ctx); struct ldb_vlv_resp_control *lvrc; + if (!data) return False; + if (!asn1_load(data, in)) { return False; } @@ -615,6 +635,8 @@ 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 = asn1_init(mem_ctx); + if (!data) return False; + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } @@ -648,6 +670,8 @@ static BOOL encode_server_sort_request(void *mem_ctx, void *in, DATA_BLOB *out) struct asn1_data *data = asn1_init(mem_ctx); int num; + if (!data) return False; + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } @@ -696,6 +720,8 @@ 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 = asn1_init(mem_ctx); + if (!data) return False; + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } @@ -722,6 +748,8 @@ static BOOL encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out) struct ldb_sd_flags_control *lsdfc = talloc_get_type(in, struct ldb_sd_flags_control); struct asn1_data *data = asn1_init(mem_ctx); + if (!data) return False; + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } @@ -748,6 +776,8 @@ static BOOL encode_search_options_request(void *mem_ctx, void *in, DATA_BLOB *ou struct ldb_search_options_control *lsoc = talloc_get_type(in, struct ldb_search_options_control); struct asn1_data *data = asn1_init(mem_ctx); + if (!data) return False; + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } @@ -774,6 +804,8 @@ 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 = asn1_init(mem_ctx); + if (!data) return False; + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } @@ -807,6 +839,8 @@ static BOOL encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out) struct ldb_asq_control *lac = talloc_get_type(in, struct ldb_asq_control); struct asn1_data *data = asn1_init(mem_ctx); + if (!data) return False; + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } @@ -840,6 +874,8 @@ static BOOL encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out) struct ldb_dirsync_control *ldc = talloc_get_type(in, struct ldb_dirsync_control); struct asn1_data *data = asn1_init(mem_ctx); + if (!data) return False; + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } @@ -924,6 +960,8 @@ static BOOL encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out) struct ldb_vlv_req_control *lvrc = talloc_get_type(in, struct ldb_vlv_req_control); struct asn1_data *data = asn1_init(mem_ctx); + if (!data) return False; + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } @@ -998,6 +1036,8 @@ static BOOL encode_vlv_response(void *mem_ctx, void *in, DATA_BLOB *out) struct ldb_vlv_resp_control *lvrc = talloc_get_type(in, struct ldb_vlv_resp_control); struct asn1_data *data = asn1_init(mem_ctx); + if (!data) return False; + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { return False; } -- cgit From 0479a2f1cbae51fcd8dbdc3c148c808421fb4d25 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 02:07:03 +0000 Subject: r23792: convert Samba4 to GPLv3 There are still a few tidyups of old FSF addresses to come (in both s3 and s4). More commits soon. (This used to be commit fcf38a38ac691abd0fa51b89dc951a08e89fdafa) --- source4/libcli/ldap/ldap.c | 5 ++--- source4/libcli/ldap/ldap.h | 5 ++--- source4/libcli/ldap/ldap_bind.c | 5 ++--- source4/libcli/ldap/ldap_client.c | 5 ++--- source4/libcli/ldap/ldap_client.h | 5 ++--- source4/libcli/ldap/ldap_controls.c | 5 ++--- source4/libcli/ldap/ldap_ildap.c | 5 ++--- source4/libcli/ldap/ldap_msg.c | 5 ++--- source4/libcli/ldap/ldap_ndr.c | 5 ++--- 9 files changed, 18 insertions(+), 27 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 55988b8eb4..64f6f90d31 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -9,7 +9,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -18,8 +18,7 @@ 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. + along with this program. If not, see . */ diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index faf6815390..fd622de449 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -5,7 +5,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ 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. + along with this program. If not, see . */ diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index addc8cf91e..cbe8772414 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -8,7 +8,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ 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. + along with this program. If not, see . */ diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index ce15b39271..8476a4977b 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -9,7 +9,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -18,8 +18,7 @@ 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. + along with this program. If not, see . */ diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h index 849737d8a9..0850e8ff64 100644 --- a/source4/libcli/ldap/ldap_client.h +++ b/source4/libcli/ldap/ldap_client.h @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 79c16afc95..4f76c7315b 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -6,7 +6,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ 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. + along with this program. If not, see . */ diff --git a/source4/libcli/ldap/ldap_ildap.c b/source4/libcli/ldap/ldap_ildap.c index f26fb7db78..5366e325cb 100644 --- a/source4/libcli/ldap/ldap_ildap.c +++ b/source4/libcli/ldap/ldap_ildap.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ diff --git a/source4/libcli/ldap/ldap_msg.c b/source4/libcli/ldap/ldap_msg.c index d74aa500ca..c9643dafda 100644 --- a/source4/libcli/ldap/ldap_msg.c +++ b/source4/libcli/ldap/ldap_msg.c @@ -8,7 +8,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ 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. + along with this program. If not, see . */ diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index 0cccdbe971..a5f90cf82b 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -7,7 +7,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ 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. + along with this program. If not, see . */ -- cgit From a87dea2a0894015cf4a3140995791f5468c40038 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 10 Jul 2007 11:37:30 +0000 Subject: r23810: Make things static, and remove unsued code. This includes some of the original ildap ldap client API. ldb provides a much easier abstraction on this to use, and doesn't use these functions. Andrew Bartlett (This used to be commit dc27a7e41c297472675e8c251bb14327a1af3902) --- source4/libcli/ldap/ldap_ildap.c | 114 --------------------------------------- 1 file changed, 114 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_ildap.c b/source4/libcli/ldap/ldap_ildap.c index 5366e325cb..62019b8cc1 100644 --- a/source4/libcli/ldap/ldap_ildap.c +++ b/source4/libcli/ldap/ldap_ildap.c @@ -24,120 +24,6 @@ #include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" -/* - delete a record - */ -NTSTATUS ildap_delete(struct ldap_connection *conn, const char *dn) -{ - struct ldap_message *msg; - NTSTATUS status; - - msg = new_ldap_message(conn); - NT_STATUS_HAVE_NO_MEMORY(msg); - - msg->type = LDAP_TAG_DelRequest; - msg->r.DelRequest.dn = dn; - - status = ldap_transaction(conn, msg); - - talloc_free(msg); - - return status; -} - -/* - add a record - */ -NTSTATUS ildap_add(struct ldap_connection *conn, const char *dn, struct ldap_mod **mods) -{ - struct ldap_message *msg; - int n, i; - NTSTATUS status; - - msg = new_ldap_message(conn); - NT_STATUS_HAVE_NO_MEMORY(msg); - - for (n=0;mods[n];n++) /* noop */ ; - - msg->type = LDAP_TAG_AddRequest; - msg->r.AddRequest.dn = dn; - msg->r.AddRequest.num_attributes = n; - msg->r.AddRequest.attributes = talloc_array(msg, struct ldb_message_element, n); - if (msg->r.AddRequest.attributes == NULL) { - talloc_free(msg); - return NT_STATUS_NO_MEMORY; - } - for (i=0;ir.AddRequest.attributes[i] = mods[i]->attrib; - } - - status = ldap_transaction(conn, msg); - - talloc_free(msg); - - return status; -} - - -/* - modify a record - */ -NTSTATUS ildap_modify(struct ldap_connection *conn, const char *dn, struct ldap_mod **mods) -{ - struct ldap_message *msg; - int n, i; - NTSTATUS status; - - msg = new_ldap_message(conn); - NT_STATUS_HAVE_NO_MEMORY(msg); - - for (n=0;mods[n];n++) /* noop */ ; - - msg->type = LDAP_TAG_ModifyRequest; - msg->r.ModifyRequest.dn = dn; - msg->r.ModifyRequest.num_mods = n; - msg->r.ModifyRequest.mods = talloc_array(msg, struct ldap_mod, n); - if (msg->r.ModifyRequest.mods == NULL) { - talloc_free(msg); - return NT_STATUS_NO_MEMORY; - } - for (i=0;ir.ModifyRequest.mods[i] = *mods[i]; - } - - status = ldap_transaction(conn, msg); - - talloc_free(msg); - - return status; -} - - -/* - rename a record - */ -NTSTATUS ildap_rename(struct ldap_connection *conn, const char *dn, const char *newrdn, - const char *parentdn, BOOL deleteolddn) -{ - struct ldap_message *msg; - NTSTATUS status; - - msg = new_ldap_message(conn); - NT_STATUS_HAVE_NO_MEMORY(msg); - - msg->type = LDAP_TAG_ModifyDNRequest; - msg->r.ModifyDNRequest.dn = dn; - msg->r.ModifyDNRequest.newrdn = newrdn; - msg->r.ModifyDNRequest.deleteolddn = deleteolddn; - msg->r.ModifyDNRequest.newsuperior = parentdn; - - status = ldap_transaction(conn, msg); - - talloc_free(msg); - - return status; -} - /* count the returned search entries -- cgit From 210971d092e908e1ec482646b3ceb2f579d89440 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 6 Aug 2007 04:07:05 +0000 Subject: r24248: Attempt to fix bug #4830 by . If there is no payload to the control, we still need to inialise *value, as otherwise we read uninitialised data later. Andrew Bartlett (This used to be commit f6566480b7f1b4036b38284aa539f3a69f5c4573) --- source4/libcli/ldap/ldap_controls.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 4f76c7315b..3a5d14c0c9 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -1143,6 +1143,7 @@ BOOL ldap_decode_control_wrapper(void *mem_ctx, struct asn1_data *data, struct l ctrl->data = NULL; if (!asn1_peek_tag(data, ASN1_OCTET_STRING)) { + *value = data_blob(NULL, 0); goto end_tag; } -- cgit From 61ffa08f4c95e29d301de9fbabd6e71c2dbc1056 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 27 Aug 2007 18:10:19 +0000 Subject: r24712: No longer expose the 'BOOL' data type in any interfaces. (This used to be commit 1ce32673d960c8b05b6c1b1b99e1976a402417ae) --- source4/libcli/ldap/ldap.h | 4 ++-- source4/libcli/ldap/ldap_client.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index fd622de449..022c70e36a 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -143,7 +143,7 @@ struct ldap_SearchRequest { enum ldap_deref deref; uint32_t timelimit; uint32_t sizelimit; - BOOL attributesonly; + bool attributesonly; struct ldb_parse_tree *tree; int num_attributes; const char **attributes; @@ -190,7 +190,7 @@ struct ldap_DelRequest { struct ldap_ModifyDNRequest { const char *dn; const char *newrdn; - BOOL deleteolddn; + bool deleteolddn; const char *newsuperior;/* optional */ }; diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h index 0850e8ff64..d2a12ee8b5 100644 --- a/source4/libcli/ldap/ldap_client.h +++ b/source4/libcli/ldap/ldap_client.h @@ -53,7 +53,7 @@ struct ldap_connection { struct socket_context *sock; char *host; uint16_t port; - BOOL ldaps; + bool ldaps; const char *auth_dn; const char *simple_pw; -- cgit From cd962355abad90a2161765a7be7d26e63572cab7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 Sep 2007 15:08:14 +0000 Subject: r25000: Fix some more C++ compatibility warnings. (This used to be commit 08bb1ef643ab906f1645cf6f32763dc73b1884e4) --- source4/libcli/ldap/ldap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 64f6f90d31..06ff000acf 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -497,7 +497,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct static const char *blob2string_talloc(TALLOC_CTX *mem_ctx, DATA_BLOB blob) { - char *result = talloc_size(mem_ctx, blob.length+1); + char *result = talloc_array(mem_ctx, char, blob.length+1); memcpy(result, blob.data, blob.length); result[blob.length] = '\0'; return result; @@ -955,7 +955,7 @@ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } if (pwlen != 0) { - char *pw = talloc_size(msg, pwlen+1); + char *pw = talloc_array(msg, char, pwlen+1); if (!pw) { return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } @@ -1162,7 +1162,7 @@ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) if (len == -1) { return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } - dn = talloc_size(msg, len+1); + dn = talloc_array(msg, char, len+1); if (dn == NULL) break; asn1_read(data, dn, len); @@ -1198,7 +1198,7 @@ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) if (len == -1) { return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } - newsup = talloc_size(msg, len+1); + newsup = talloc_array(msg, char, len+1); if (newsup == NULL) { return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } -- cgit From 9b009c900987517359485799be8be4167494b376 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 23 Sep 2007 21:35:03 +0000 Subject: r25301: Merge my includes.h cleanups. (This used to be commit 37425495f392a2d0122a93aa2c42758eab7dab5a) --- source4/libcli/ldap/ldap.h | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 022c70e36a..e89322213a 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -22,6 +22,7 @@ #define _SMB_LDAP_H #include "lib/ldb/include/ldb.h" +#include "librpc/gen_ndr/misc.h" enum ldap_request_tag { LDAP_TAG_BindRequest = 0, -- cgit From 2151cde58014ea2e822c13d2f8a369b45dc19ca8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 6 Oct 2007 22:28:14 +0000 Subject: r25554: Convert last instances of BOOL, True and False to the standard types. (This used to be commit 566aa14139510788548a874e9213d91317f83ca9) --- source4/libcli/ldap/ldap.c | 30 +- source4/libcli/ldap/ldap_bind.c | 2 +- source4/libcli/ldap/ldap_client.c | 6 +- source4/libcli/ldap/ldap_controls.c | 530 ++++++++++++++++++------------------ source4/libcli/ldap/ldap_ildap.c | 6 +- source4/libcli/ldap/ldap_msg.c | 18 +- 6 files changed, 296 insertions(+), 296 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 06ff000acf..11689fbd79 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -27,7 +27,7 @@ #include "libcli/ldap/ldap.h" -static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree) +static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree) { int i; @@ -37,7 +37,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1)); for (i=0; iu.list.num_elements; i++) { if (!ldap_push_filter(data, tree->u.list.elements[i])) { - return False; + return false; } } asn1_pop_tag(data); @@ -46,7 +46,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree case LDB_OP_NOT: asn1_push_tag(data, ASN1_CONTEXT(2)); if (!ldap_push_filter(data, tree->u.isnot.child)) { - return False; + return false; } asn1_pop_tag(data); break; @@ -166,7 +166,7 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree break; default: - return False; + return false; } return !data->has_error; } @@ -187,12 +187,12 @@ static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *res } } -BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) +bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) { struct asn1_data *data = asn1_init(mem_ctx); int i, j; - if (!data) return False; + if (!data) return false; asn1_push_tag(data, ASN1_SEQUENCE(0)); asn1_write_Integer(data, msg->messageid); @@ -225,7 +225,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct asn1_pop_tag(data); break; default: - return False; + return false; } asn1_pop_tag(data); @@ -256,7 +256,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct asn1_write_BOOLEAN(data, r->attributesonly); if (!ldap_push_filter(data, r->tree)) { - return False; + return false; } asn1_push_tag(data, ASN1_SEQUENCE(0)); @@ -467,7 +467,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct break; } default: - return False; + return false; } if (msg->controls != NULL) { @@ -475,7 +475,7 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct for (i = 0; msg->controls[i] != NULL; i++) { if (!ldap_encode_control(mem_ctx, data, msg->controls[i])) { - return False; + return false; } } @@ -486,12 +486,12 @@ BOOL ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ct if (data->has_error) { asn1_free(data); - return False; + return false; } *result = data_blob_talloc(mem_ctx, data->data, data->length); asn1_free(data); - return True; + return true; } static const char *blob2string_talloc(TALLOC_CTX *mem_ctx, @@ -503,16 +503,16 @@ static const char *blob2string_talloc(TALLOC_CTX *mem_ctx, return result; } -static BOOL asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, +static 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)) - return False; + return false; *result = blob2string_talloc(mem_ctx, string); data_blob_free(&string); - return True; + return true; } static void ldap_decode_response(TALLOC_CTX *mem_ctx, diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index cbe8772414..d285735d4e 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -258,7 +258,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, NULL, NULL, &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 8476a4977b..aea95de161 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -226,7 +226,7 @@ static void ldap_io_handler(struct event_context *ev, struct fd_event *fde, parse a ldap URL */ static NTSTATUS ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, - char **host, uint16_t *port, BOOL *ldaps) + char **host, uint16_t *port, bool *ldaps) { int tmp_port = 0; char protocol[11]; @@ -243,10 +243,10 @@ static NTSTATUS ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url, if (strequal(protocol, "ldap")) { *port = 389; - *ldaps = False; + *ldaps = false; } else if (strequal(protocol, "ldaps")) { *port = 636; - *ldaps = True; + *ldaps = true; } else { DEBUG(0, ("unrecognised ldap protocol (%s)!\n", protocol)); return NT_STATUS_PROTOCOL_UNREACHABLE; diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 3a5d14c0c9..b7fd1ce178 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -26,56 +26,56 @@ 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); + 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) +static bool decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB attr; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_sort_resp_control *lsrc; - if (!data) return False; + if (!data) return false; if (!asn1_load(data, in)) { - return False; + return false; } lsrc = talloc(mem_ctx, struct ldb_sort_resp_control); if (!lsrc) { - return False; + return false; } if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_read_enumerated(data, &(lsrc->result))) { - return False; + return false; } lsrc->attr_desc = NULL; if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { if (!asn1_read_OctetString(data, mem_ctx, &attr)) { - return False; + return false; } lsrc->attr_desc = talloc_strndup(lsrc, (const char *)attr.data, attr.length); if (!lsrc->attr_desc) { - return False; + return false; } } if (!asn1_end_tag(data)) { - return False; + return false; } *out = lsrc; - return True; + return true; } -static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB attr; DATA_BLOB rule; @@ -83,14 +83,14 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) struct ldb_server_sort_control **lssc; int num; - if (!data) return False; + if (!data) return false; if (!asn1_load(data, in)) { - return False; + return false; } if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } lssc = NULL; @@ -98,46 +98,46 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) 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; + return false; } lssc[num] = talloc_zero(lssc, struct ldb_server_sort_control); if (!lssc[num]) { - return False; + return false; } if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_read_OctetString(data, mem_ctx, &attr)) { - return False; + return false; } lssc[num]->attributeName = talloc_strndup(lssc[num], (const char *)attr.data, attr.length); if (!lssc [num]->attributeName) { - return False; + return false; } if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { if (!asn1_read_OctetString(data, mem_ctx, &rule)) { - return False; + return false; } lssc[num]->orderingRule = talloc_strndup(lssc[num], (const char *)rule.data, rule.length); if (!lssc[num]->orderingRule) { - return False; + return false; } } if (asn1_peek_tag(data, ASN1_BOOLEAN)) { - BOOL reverse; + bool reverse; if (!asn1_read_BOOLEAN(data, &reverse)) { - return False; + return false; } lssc[num]->reverse = reverse; } if (!asn1_end_tag(data)) { - return False; + return false; } } @@ -146,248 +146,248 @@ static BOOL decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) } if (!asn1_end_tag(data)) { - return False; + return false; } *out = lssc; - return True; + return true; } -static BOOL decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out) { struct asn1_data *data = asn1_init(mem_ctx); struct ldb_extended_dn_control *ledc; - if (!data) return False; + if (!data) return false; if (!asn1_load(data, in)) { - return False; + return false; } ledc = talloc(mem_ctx, struct ldb_extended_dn_control); if (!ledc) { - return False; + return false; } if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_read_Integer(data, &(ledc->type))) { - return False; + return false; } if (!asn1_end_tag(data)) { - return False; + return false; } *out = ledc; - return True; + return true; } -static BOOL decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out) { struct asn1_data *data = asn1_init(mem_ctx); struct ldb_sd_flags_control *lsdfc; - if (!data) return False; + if (!data) return false; if (!asn1_load(data, in)) { - return False; + return false; } lsdfc = talloc(mem_ctx, struct ldb_sd_flags_control); if (!lsdfc) { - return False; + return false; } if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_read_Integer(data, &(lsdfc->secinfo_flags))) { - return False; + return false; } if (!asn1_end_tag(data)) { - return False; + return false; } *out = lsdfc; - return True; + return true; } -static BOOL decode_search_options_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_search_options_request(void *mem_ctx, DATA_BLOB in, void **out) { struct asn1_data *data = asn1_init(mem_ctx); struct ldb_search_options_control *lsoc; - if (!data) return False; + if (!data) return false; if (!asn1_load(data, in)) { - return False; + return false; } lsoc = talloc(mem_ctx, struct ldb_search_options_control); if (!lsoc) { - return False; + return false; } if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_read_Integer(data, &(lsoc->search_options))) { - return False; + return false; } if (!asn1_end_tag(data)) { - return False; + return false; } *out = lsoc; - return True; + return true; } -static BOOL decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB cookie; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_paged_control *lprc; - if (!data) return False; + if (!data) return false; if (!asn1_load(data, in)) { - return False; + return false; } lprc = talloc(mem_ctx, struct ldb_paged_control); if (!lprc) { - return False; + return false; } if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_read_Integer(data, &(lprc->size))) { - return False; + return false; } if (!asn1_read_OctetString(data, mem_ctx, &cookie)) { - return False; + 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; + return false; } } else { lprc->cookie = NULL; } if (!asn1_end_tag(data)) { - return False; + return false; } *out = lprc; - return True; + return true; } -static BOOL decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB cookie; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_dirsync_control *ldc; - if (!data) return False; + if (!data) return false; if (!asn1_load(data, in)) { - return False; + return false; } ldc = talloc(mem_ctx, struct ldb_dirsync_control); if (!ldc) { - return False; + return false; } if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_read_Integer(data, &(ldc->flags))) { - return False; + return false; } if (!asn1_read_Integer(data, &(ldc->max_attributes))) { - return False; + return false; } if (!asn1_read_OctetString(data, mem_ctx, &cookie)) { - return False; + return false; } ldc->cookie_len = cookie.length; if (ldc->cookie_len) { ldc->cookie = talloc_memdup(ldc, cookie.data, cookie.length); if (!(ldc->cookie)) { - return False; + return false; } } else { ldc->cookie = NULL; } if (!asn1_end_tag(data)) { - return False; + return false; } *out = ldc; - return True; + return true; } /* seem that this controls has 2 forms one in case it is used with * a Search Request and another when used ina Search Response */ -static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB source_attribute; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_asq_control *lac; - if (!data) return False; + if (!data) return false; if (!asn1_load(data, in)) { - return False; + return false; } lac = talloc(mem_ctx, struct ldb_asq_control); if (!lac) { - return False; + return false; } if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { if (!asn1_read_OctetString(data, mem_ctx, &source_attribute)) { - return False; + return false; } lac->src_attr_len = source_attribute.length; if (lac->src_attr_len) { lac->source_attribute = talloc_strndup(lac, (const char *)source_attribute.data, source_attribute.length); if (!(lac->source_attribute)) { - return False; + return false; } } else { lac->source_attribute = NULL; @@ -398,96 +398,96 @@ static BOOL decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) } else if (asn1_peek_tag(data, ASN1_ENUMERATED)) { if (!asn1_read_enumerated(data, &(lac->result))) { - return False; + return false; } lac->request = 0; } else { - return False; + return false; } if (!asn1_end_tag(data)) { - return False; + return false; } *out = lac; - return True; + return true; } -static BOOL decode_domain_scope_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_domain_scope_request(void *mem_ctx, DATA_BLOB in, void **out) { if (in.length != 0) { - return False; + return false; } - return True; + return true; } -static BOOL decode_notification_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_notification_request(void *mem_ctx, DATA_BLOB in, void **out) { if (in.length != 0) { - return False; + return false; } - return True; + return true; } -static BOOL decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void **out) { if (in.length != 0) { - return False; + return false; } - return True; + return true; } -static BOOL decode_permissive_modify_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_permissive_modify_request(void *mem_ctx, DATA_BLOB in, void **out) { if (in.length != 0) { - return False; + return false; } - return True; + return true; } -static BOOL decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void **out) { if (in.length != 0) { - return False; + return false; } - return True; + return true; } -static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB assertion_value, context_id; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_vlv_req_control *lvrc; - if (!data) return False; + if (!data) return false; if (!asn1_load(data, in)) { - return False; + return false; } lvrc = talloc(mem_ctx, struct ldb_vlv_req_control); if (!lvrc) { - return False; + return false; } if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_read_Integer(data, &(lvrc->beforeCount))) { - return False; + return false; } if (!asn1_read_Integer(data, &(lvrc->afterCount))) { - return False; + return false; } if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { @@ -495,27 +495,27 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) lvrc->type = 0; if (!asn1_start_tag(data, ASN1_CONTEXT(0))) { - return False; + return false; } if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_read_Integer(data, &(lvrc->match.byOffset.offset))) { - return False; + return false; } if (!asn1_read_Integer(data, &(lvrc->match.byOffset.contentCount))) { - return False; + return false; } if (!asn1_end_tag(data)) { /*SEQUENCE*/ - return False; + return false; } if (!asn1_end_tag(data)) { /*CONTEXT*/ - return False; + return false; } } else { @@ -523,38 +523,38 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) lvrc->type = 1; if (!asn1_start_tag(data, ASN1_CONTEXT(1))) { - return False; + return false; } if (!asn1_read_OctetString(data, mem_ctx, &assertion_value)) { - return False; + return false; } lvrc->match.gtOrEq.value_len = assertion_value.length; if (lvrc->match.gtOrEq.value_len) { lvrc->match.gtOrEq.value = talloc_memdup(lvrc, assertion_value.data, assertion_value.length); if (!(lvrc->match.gtOrEq.value)) { - return False; + return false; } } else { lvrc->match.gtOrEq.value = NULL; } if (!asn1_end_tag(data)) { /*CONTEXT*/ - return False; + return false; } } if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { if (!asn1_read_OctetString(data, mem_ctx, &context_id)) { - return False; + return false; } lvrc->ctxid_len = context_id.length; if (lvrc->ctxid_len) { lvrc->contextId = talloc_memdup(lvrc, context_id.data, context_id.length); if (!(lvrc->contextId)) { - return False; + return false; } } else { lvrc->contextId = NULL; @@ -565,54 +565,54 @@ static BOOL decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) } if (!asn1_end_tag(data)) { - return False; + return false; } *out = lvrc; - return True; + return true; } -static BOOL decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out) { DATA_BLOB context_id; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_vlv_resp_control *lvrc; - if (!data) return False; + if (!data) return false; if (!asn1_load(data, in)) { - return False; + return false; } lvrc = talloc(mem_ctx, struct ldb_vlv_resp_control); if (!lvrc) { - return False; + return false; } if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_read_Integer(data, &(lvrc->targetPosition))) { - return False; + return false; } if (!asn1_read_Integer(data, &(lvrc->contentCount))) { - return False; + return false; } if (!asn1_read_enumerated(data, &(lvrc->vlv_result))) { - return False; + return false; } if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { if (!asn1_read_OctetString(data, mem_ctx, &context_id)) { - return False; + return false; } lvrc->contextId = talloc_strndup(lvrc, (const char *)context_id.data, context_id.length); if (!lvrc->contextId) { - return False; + return false; } lvrc->ctxid_len = context_id.length; } else { @@ -621,455 +621,455 @@ static BOOL decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out) } if (!asn1_end_tag(data)) { - return False; + return false; } *out = lvrc; - return True; + return true; } -static BOOL encode_server_sort_response(void *mem_ctx, void *in, DATA_BLOB *out) +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 = asn1_init(mem_ctx); - if (!data) return False; + if (!data) return false; if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_write_enumerated(data, lsrc->result)) { - return False; + return false; } if (lsrc->attr_desc) { if (!asn1_write_OctetString(data, lsrc->attr_desc, strlen(lsrc->attr_desc))) { - return False; + return false; } } if (!asn1_pop_tag(data)) { - return False; + return false; } *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { - return False; + return false; } talloc_free(data); - return True; + return true; } -static BOOL encode_server_sort_request(void *mem_ctx, void *in, DATA_BLOB *out) +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 = asn1_init(mem_ctx); int num; - if (!data) return False; + if (!data) return false; if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } for (num = 0; lssc[num]; num++) { if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_write_OctetString(data, lssc[num]->attributeName, strlen(lssc[num]->attributeName))) { - return False; + return false; } if (lssc[num]->orderingRule) { if (!asn1_write_OctetString(data, lssc[num]->orderingRule, strlen(lssc[num]->orderingRule))) { - return False; + return false; } } if (lssc[num]->reverse) { if (!asn1_write_BOOLEAN(data, lssc[num]->reverse)) { - return False; + return false; } } if (!asn1_pop_tag(data)) { - return False; + return false; } } if (!asn1_pop_tag(data)) { - return False; + return false; } *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { - return False; + return false; } talloc_free(data); - return True; + return true; } -static BOOL encode_extended_dn_request(void *mem_ctx, void *in, DATA_BLOB *out) +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 = asn1_init(mem_ctx); - if (!data) return False; + if (!data) return false; if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_write_Integer(data, ledc->type)) { - return False; + return false; } if (!asn1_pop_tag(data)) { - return False; + return false; } *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { - return False; + return false; } talloc_free(data); - return True; + return true; } -static BOOL encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_sd_flags_control *lsdfc = talloc_get_type(in, struct ldb_sd_flags_control); struct asn1_data *data = asn1_init(mem_ctx); - if (!data) return False; + if (!data) return false; if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_write_Integer(data, lsdfc->secinfo_flags)) { - return False; + return false; } if (!asn1_pop_tag(data)) { - return False; + return false; } *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { - return False; + return false; } talloc_free(data); - return True; + return true; } -static BOOL encode_search_options_request(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_search_options_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_search_options_control *lsoc = talloc_get_type(in, struct ldb_search_options_control); struct asn1_data *data = asn1_init(mem_ctx); - if (!data) return False; + if (!data) return false; if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_write_Integer(data, lsoc->search_options)) { - return False; + return false; } if (!asn1_pop_tag(data)) { - return False; + return false; } *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { - return False; + return false; } talloc_free(data); - return True; + return true; } -static BOOL encode_paged_results_request(void *mem_ctx, void *in, DATA_BLOB *out) +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 = asn1_init(mem_ctx); - if (!data) return False; + if (!data) return false; if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_write_Integer(data, lprc->size)) { - return False; + return false; } if (!asn1_write_OctetString(data, lprc->cookie, lprc->cookie_len)) { - return False; + return false; } if (!asn1_pop_tag(data)) { - return False; + return false; } *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { - return False; + return false; } talloc_free(data); - return True; + return true; } /* seem that this controls has 2 forms one in case it is used with * a Search Request and another when used ina Search Response */ -static BOOL encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_asq_control *lac = talloc_get_type(in, struct ldb_asq_control); struct asn1_data *data = asn1_init(mem_ctx); - if (!data) return False; + if (!data) return false; if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (lac->request) { if (!asn1_write_OctetString(data, lac->source_attribute, lac->src_attr_len)) { - return False; + return false; } } else { if (!asn1_write_enumerated(data, lac->result)) { - return False; + return false; } } if (!asn1_pop_tag(data)) { - return False; + return false; } *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { - return False; + return false; } talloc_free(data); - return True; + return true; } -static BOOL encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_dirsync_control *ldc = talloc_get_type(in, struct ldb_dirsync_control); struct asn1_data *data = asn1_init(mem_ctx); - if (!data) return False; + if (!data) return false; if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_write_Integer(data, ldc->flags)) { - return False; + return false; } if (!asn1_write_Integer(data, ldc->max_attributes)) { - return False; + return false; } if (!asn1_write_OctetString(data, ldc->cookie, ldc->cookie_len)) { - return False; + return false; } if (!asn1_pop_tag(data)) { - return False; + return false; } *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { - return False; + return false; } talloc_free(data); - return True; + return true; } -static BOOL encode_domain_scope_request(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_domain_scope_request(void *mem_ctx, void *in, DATA_BLOB *out) { if (in) { - return False; + return false; } *out = data_blob(NULL, 0); - return True; + return true; } -static BOOL encode_notification_request(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_notification_request(void *mem_ctx, void *in, DATA_BLOB *out) { if (in) { - return False; + return false; } *out = data_blob(NULL, 0); - return True; + return true; } -static BOOL encode_show_deleted_request(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_show_deleted_request(void *mem_ctx, void *in, DATA_BLOB *out) { if (in) { - return False; + return false; } *out = data_blob(NULL, 0); - return True; + return true; } -static BOOL encode_permissive_modify_request(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_permissive_modify_request(void *mem_ctx, void *in, DATA_BLOB *out) { if (in) { - return False; + return false; } *out = data_blob(NULL, 0); - return True; + return true; } -static BOOL encode_manageDSAIT_request(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_manageDSAIT_request(void *mem_ctx, void *in, DATA_BLOB *out) { if (in) { - return False; + return false; } *out = data_blob(NULL, 0); - return True; + return true; } -static BOOL encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_vlv_req_control *lvrc = talloc_get_type(in, struct ldb_vlv_req_control); struct asn1_data *data = asn1_init(mem_ctx); - if (!data) return False; + if (!data) return false; if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_write_Integer(data, lvrc->beforeCount)) { - return False; + return false; } if (!asn1_write_Integer(data, lvrc->afterCount)) { - return False; + return false; } if (lvrc->type == 0) { if (!asn1_push_tag(data, ASN1_CONTEXT(0))) { - return False; + return false; } if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_write_Integer(data, lvrc->match.byOffset.offset)) { - return False; + return false; } if (!asn1_write_Integer(data, lvrc->match.byOffset.contentCount)) { - return False; + return false; } if (!asn1_pop_tag(data)) { /*SEQUENCE*/ - return False; + return false; } if (!asn1_pop_tag(data)) { /*CONTEXT*/ - return False; + return false; } } else { if (!asn1_push_tag(data, ASN1_CONTEXT(1))) { - return False; + return false; } if (!asn1_write_OctetString(data, lvrc->match.gtOrEq.value, lvrc->match.gtOrEq.value_len)) { - return False; + return false; } if (!asn1_pop_tag(data)) { /*CONTEXT*/ - return False; + return false; } } if (lvrc->ctxid_len) { if (!asn1_write_OctetString(data, lvrc->contextId, lvrc->ctxid_len)) { - return False; + return false; } } if (!asn1_pop_tag(data)) { - return False; + return false; } *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { - return False; + return false; } talloc_free(data); - return True; + return true; } -static BOOL encode_vlv_response(void *mem_ctx, void *in, DATA_BLOB *out) +static bool encode_vlv_response(void *mem_ctx, void *in, DATA_BLOB *out) { struct ldb_vlv_resp_control *lvrc = talloc_get_type(in, struct ldb_vlv_resp_control); struct asn1_data *data = asn1_init(mem_ctx); - if (!data) return False; + if (!data) return false; if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_write_Integer(data, lvrc->targetPosition)) { - return False; + return false; } if (!asn1_write_Integer(data, lvrc->contentCount)) { - return False; + return false; } if (!asn1_write_enumerated(data, lvrc->vlv_result)) { - return False; + return false; } if (lvrc->ctxid_len) { if (!asn1_write_OctetString(data, lvrc->contextId, lvrc->ctxid_len)) { - return False; + return false; } } if (!asn1_pop_tag(data)) { - return False; + return false; } *out = data_blob_talloc(mem_ctx, data->data, data->length); if (out->data == NULL) { - return False; + return false; } talloc_free(data); - return True; + return true; } struct control_handler ldap_known_controls[] = { @@ -1095,49 +1095,49 @@ struct control_handler ldap_known_controls[] = { { NULL, NULL, NULL } }; -BOOL ldap_decode_control_value(void *mem_ctx, DATA_BLOB value, struct ldb_control *ctrl) +bool ldap_decode_control_value(void *mem_ctx, DATA_BLOB value, struct ldb_control *ctrl) { int i; 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].decode || !ldap_known_controls[i].decode(mem_ctx, value, &ctrl->data)) { - return False; + return false; } break; } } if (ldap_known_controls[i].oid == NULL) { - return False; + return false; } - return True; + return true; } -BOOL ldap_decode_control_wrapper(void *mem_ctx, struct asn1_data *data, struct ldb_control *ctrl, DATA_BLOB *value) +bool ldap_decode_control_wrapper(void *mem_ctx, struct asn1_data *data, struct ldb_control *ctrl, DATA_BLOB *value) { DATA_BLOB oid; if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_read_OctetString(data, mem_ctx, &oid)) { - return False; + return false; } ctrl->oid = talloc_strndup(mem_ctx, (char *)oid.data, oid.length); if (!ctrl->oid) { - return False; + return false; } if (asn1_peek_tag(data, ASN1_BOOLEAN)) { - BOOL critical; + bool critical; if (!asn1_read_BOOLEAN(data, &critical)) { - return False; + return false; } ctrl->critical = critical; } else { - ctrl->critical = False; + ctrl->critical = false; } ctrl->data = NULL; @@ -1148,18 +1148,18 @@ BOOL ldap_decode_control_wrapper(void *mem_ctx, struct asn1_data *data, struct l } if (!asn1_read_OctetString(data, mem_ctx, value)) { - return False; + return false; } end_tag: if (!asn1_end_tag(data)) { - return False; + return false; } - return True; + return true; } -BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldb_control *ctrl) +bool ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldb_control *ctrl) { DATA_BLOB value; int i; @@ -1168,33 +1168,33 @@ BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldb_contr if (strcmp(ldap_known_controls[i].oid, ctrl->oid) == 0) { if (!ldap_known_controls[i].encode) { if (ctrl->critical) { - return False; + return false; } else { /* not encoding this control */ - return True; + return true; } } if (!ldap_known_controls[i].encode(mem_ctx, ctrl->data, &value)) { - return False; + return false; } break; } } if (ldap_known_controls[i].oid == NULL) { - return False; + return false; } if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return False; + return false; } if (!asn1_write_OctetString(data, ctrl->oid, strlen(ctrl->oid))) { - return False; + return false; } if (ctrl->critical) { if (!asn1_write_BOOLEAN(data, ctrl->critical)) { - return False; + return false; } } @@ -1203,13 +1203,13 @@ BOOL ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldb_contr } if (!asn1_write_OctetString(data, value.data, value.length)) { - return False; + return false; } pop_tag: if (!asn1_pop_tag(data)) { - return False; + return false; } - return True; + return true; } diff --git a/source4/libcli/ldap/ldap_ildap.c b/source4/libcli/ldap/ldap_ildap.c index 62019b8cc1..7b592c65ae 100644 --- a/source4/libcli/ldap/ldap_ildap.c +++ b/source4/libcli/ldap/ldap_ildap.c @@ -41,7 +41,7 @@ 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, + const char * const *attrs, bool attributesonly, struct ldb_control **control_req, struct ldb_control ***control_res, struct ldap_message ***results) @@ -75,7 +75,7 @@ NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn, req = ldap_request_send(conn, msg); talloc_steal(msg, req); - for (i=n=0;True;i++) { + for (i=n=0;true;i++) { struct ldap_message *res; status = ldap_result_n(req, i, &res); if (!NT_STATUS_IS_OK(status)) break; @@ -114,7 +114,7 @@ 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, + const char * const *attrs, bool attributesonly, struct ldb_control **control_req, struct ldb_control ***control_res, struct ldap_message ***results) diff --git a/source4/libcli/ldap/ldap_msg.c b/source4/libcli/ldap/ldap_msg.c index c9643dafda..12832b8ec4 100644 --- a/source4/libcli/ldap/ldap_msg.c +++ b/source4/libcli/ldap/ldap_msg.c @@ -32,7 +32,7 @@ struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) } -BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, +bool add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, struct ldb_message_element *attrib) { attrib->values = talloc_realloc(mem_ctx, @@ -40,16 +40,16 @@ BOOL add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, DATA_BLOB, attrib->num_values+1); if (attrib->values == NULL) - return False; + return false; attrib->values[attrib->num_values].data = talloc_steal(attrib->values, value->data); attrib->values[attrib->num_values].length = value->length; attrib->num_values += 1; - return True; + return true; } -BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, +bool add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, const struct ldb_message_element *attrib, struct ldb_message_element **attribs, int *num_attribs) @@ -60,16 +60,16 @@ BOOL add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, *num_attribs+1); if (*attribs == NULL) - return False; + return false; (*attribs)[*num_attribs] = *attrib; talloc_steal(*attribs, attrib->values); talloc_steal(*attribs, attrib->name); *num_attribs += 1; - return True; + return true; } -BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, +bool add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, struct ldap_mod *mod, struct ldap_mod **mods, int *num_mods) @@ -77,10 +77,10 @@ BOOL add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, *mods = talloc_realloc(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1); if (*mods == NULL) - return False; + return false; (*mods)[*num_mods] = *mod; *num_mods += 1; - return True; + return true; } -- cgit From 5861a17042d1dfb9ae77a519b7e0da9484c2074c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 18 Oct 2007 03:32:07 +0200 Subject: r25692: fixed another example where the free of fde and the free of the socket causes the fd to be closed before epoll is told (This used to be commit d19686cf8a3aba0c6601c5fa58cbf74461055c1c) --- source4/libcli/ldap/ldap_client.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index aea95de161..fcb2d92214 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -366,12 +366,14 @@ static void ldap_connect_got_sock(struct composite_context *ctx, struct ldap_con /* setup a handler for events on this socket */ conn->event.fde = event_add_fd(conn->event.event_ctx, conn->sock, socket_get_fd(conn->sock), - EVENT_FD_READ, ldap_io_handler, conn); + EVENT_FD_READ | EVENT_FD_AUTOCLOSE, ldap_io_handler, conn); if (conn->event.fde == NULL) { composite_error(ctx, NT_STATUS_INTERNAL_ERROR); return; } + socket_set_flags(conn->sock, SOCKET_FLAG_NOCLOSE); + talloc_steal(conn, conn->sock); if (conn->ldaps) { struct socket_context *tls_socket = tls_init_client(conn->sock, conn->event.fde); -- cgit From 529763a9aa192a6785ba878aceeb1683c2510913 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 9 Nov 2007 19:24:51 +0100 Subject: r25920: ndr: change NTSTAUS into enum ndr_err_code (samba4 callers) lib/messaging/ lib/registry/ lib/ldb-samba/ librpc/rpc/ auth/auth_winbind.c auth/gensec/ auth/kerberos/ dsdb/repl/ dsdb/samdb/ dsdb/schema/ torture/ cluster/ctdb/ kdc/ ntvfs/ipc/ torture/rap/ ntvfs/ utils/getntacl.c ntptr/ smb_server/ libcli/wrepl/ wrepl_server/ libcli/cldap/ libcli/dgram/ libcli/ldap/ libcli/raw/ libcli/nbt/ libnet/ winbind/ rpc_server/ metze (This used to be commit 6223c7fddc972687eb577e04fc1c8e0604c35435) --- source4/libcli/ldap/ldap_ndr.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index a5f90cf82b..468c366c85 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -44,11 +44,11 @@ char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value) char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) { DATA_BLOB blob; - NTSTATUS status; + enum ndr_err_code ndr_err; char *ret; - status = ndr_push_struct_blob(&blob, mem_ctx, sid, - (ndr_push_flags_fn_t)ndr_push_dom_sid); - if (!NT_STATUS_IS_OK(status)) { + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, sid, + (ndr_push_flags_fn_t)ndr_push_dom_sid); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return NULL; } ret = ldb_binary_encode(mem_ctx, blob); @@ -63,11 +63,11 @@ char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) { DATA_BLOB blob; - NTSTATUS status; + enum ndr_err_code ndr_err; char *ret; - status = ndr_push_struct_blob(&blob, mem_ctx, guid, - (ndr_push_flags_fn_t)ndr_push_GUID); - if (!NT_STATUS_IS_OK(status)) { + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, guid, + (ndr_push_flags_fn_t)ndr_push_GUID); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return NULL; } ret = ldb_binary_encode(mem_ctx, blob); @@ -81,12 +81,15 @@ char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GUID *guid) { DATA_BLOB blob; - NTSTATUS status; + enum ndr_err_code ndr_err; blob.data = val.data; blob.length = val.length; - status = ndr_pull_struct_blob(&blob, mem_ctx, guid, - (ndr_pull_flags_fn_t)ndr_pull_GUID); + ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, guid, + (ndr_pull_flags_fn_t)ndr_pull_GUID); talloc_free(val.data); - return status; + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } + return NT_STATUS_OK; } -- cgit From 0ac6bffdf46003517127fbd9763f74e09e96c21a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 27 Nov 2007 02:04:38 +0100 Subject: r26136: Attempt to fix dependencies for auth. (This used to be commit abf2600a044cdbab6c5d7880d18217bff3d15c39) --- source4/libcli/ldap/config.mk | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index e5a7133cfa..adccd23eb1 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,5 +1,3 @@ -################################# -# Start SUBSYSTEM LIBCLI_LDAP [SUBSYSTEM::LIBCLI_LDAP] PUBLIC_PROTO_HEADER = ldap_proto.h PUBLIC_HEADERS = ldap.h @@ -12,6 +10,4 @@ OBJ_FILES = ldap.o \ ldap_controls.o PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket LIBCLI_RESOLVE NDR_SAMR LIBTLS ASN1_UTIL GENSEC_SOCKET -#PRIVATE_DEPENDENCIES = gensec -# End SUBSYSTEM LIBCLI_LDAP -################################# +#FIXME: PRIVATE_DEPENDENCIES = gensec -- cgit From 364266e22a08e730f2442cf87ec385620cff2700 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 29 Nov 2007 08:00:04 +0100 Subject: r26192: Handle, test and implement the style of extended_dn requiest that MMC uses. It appears that the control value is optional, implying type 0 responses. Failing to parse this was causing LDAP disconnects with 'unavailable critical extension'. Andrew Bartlett (This used to be commit 833dfc2f2af84c45f954e428c9ea6babf100ba92) --- source4/libcli/ldap/ldap.c | 13 ++++++++++++- source4/libcli/ldap/ldap.h | 2 ++ source4/libcli/ldap/ldap_client.c | 15 +++++++++++++++ source4/libcli/ldap/ldap_controls.c | 18 ++++++++++++++++-- 4 files changed, 45 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 11689fbd79..34d715e3e5 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -1325,10 +1325,12 @@ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) } msg->controls = NULL; + msg->controls_decoded = NULL; if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { int i = 0; struct ldb_control **ctrl = NULL; + bool *decoded = NULL; asn1_start_tag(data, ASN1_CONTEXT(0)); @@ -1341,6 +1343,11 @@ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); } + decoded = talloc_realloc(msg, decoded, bool, i+1); + if (!decoded) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + ctrl[i] = talloc(ctrl, struct ldb_control); if (!ctrl[i]) { return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); @@ -1352,12 +1359,15 @@ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) if (!ldap_decode_control_value(ctrl, value, ctrl[i])) { if (ctrl[i]->critical) { - return NT_STATUS_LDAP(LDAP_UNAVAILABLE_CRITICAL_EXTENSION); + ctrl[i]->data = NULL; + decoded[i] = false; + i++; } else { talloc_free(ctrl[i]); ctrl[i] = NULL; } } else { + decoded[i] = true; i++; } } @@ -1367,6 +1377,7 @@ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) } msg->controls = ctrl; + msg->controls_decoded = decoded; asn1_end_tag(data); } diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index e89322213a..6f5e86744e 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -240,11 +240,13 @@ union ldap_Request { struct ldap_ExtendedResponse ExtendedResponse; }; + struct ldap_message { int messageid; enum ldap_request_tag type; union ldap_Request r; struct ldb_control **controls; + bool *controls_decoded; }; struct event_context; diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index fcb2d92214..41e9c37196 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -116,6 +116,7 @@ static void ldap_error_handler(void *private_data, NTSTATUS status) static void ldap_match_message(struct ldap_connection *conn, struct ldap_message *msg) { struct ldap_request *req; + int i; for (req=conn->pending; req; req=req->next) { if (req->messageid == msg->messageid) break; @@ -132,6 +133,20 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message return; } + /* Check for undecoded critical extensions */ + for (i=0; msg->controls && msg->controls[i]; i++) { + if (!msg->controls_decoded[i] && + msg->controls[i]->critical) { + req->status = NT_STATUS_LDAP(LDAP_UNAVAILABLE_CRITICAL_EXTENSION); + req->state = LDAP_REQUEST_DONE; + DLIST_REMOVE(conn->pending, req); + if (req->async.fn) { + req->async.fn(req); + } + return; + } + } + /* add to the list of replies received */ talloc_steal(req, msg); req->replies = talloc_realloc(req, req->replies, diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index b7fd1ce178..34e5cccf75 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -156,9 +156,16 @@ static bool decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) static bool decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out) { - struct asn1_data *data = asn1_init(mem_ctx); + struct asn1_data *data; struct ldb_extended_dn_control *ledc; + /* The content of this control is optional */ + if (in.length == 0) { + *out = NULL; + return true; + } + + data = asn1_init(mem_ctx); if (!data) return false; if (!asn1_load(data, in)) { @@ -717,7 +724,14 @@ static bool encode_server_sort_request(void *mem_ctx, void *in, DATA_BLOB *out) 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 = asn1_init(mem_ctx); + struct asn1_data *data; + + if (!in) { + *out = data_blob(NULL, 0); + return true; + } + + data = asn1_init(mem_ctx); if (!data) return false; -- cgit From bbdfbf8d9d486aee51117976b8f825759a4c4a37 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Dec 2007 00:28:22 +0100 Subject: r26238: Add a loadparm context parameter to torture_context, remove more uses of global_loadparm. (This used to be commit a33a5530545086b81a3b205aa109dff11c546926) --- source4/libcli/ldap/ldap_client.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 41e9c37196..f1cfaad18b 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -34,6 +34,7 @@ #include "lib/tls/tls.h" #include "auth/gensec/gensec.h" #include "system/time.h" +#include "param/param.h" /* @@ -391,7 +392,17 @@ static void ldap_connect_got_sock(struct composite_context *ctx, struct ldap_con talloc_steal(conn, conn->sock); if (conn->ldaps) { - struct socket_context *tls_socket = tls_init_client(conn->sock, conn->event.fde); + struct socket_context *tls_socket; + char *cafile = private_path(conn->sock, global_loadparm, lp_tls_cafile(global_loadparm)); + + if (!cafile || !*cafile) { + talloc_free(conn->sock); + return; + } + + tls_socket = tls_init_client(conn->sock, conn->event.fde, cafile); + talloc_free(cafile); + if (tls_socket == NULL) { talloc_free(conn->sock); return; -- cgit From ecea5ce24553989103d4a06296b24f4d29f30a36 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Dec 2007 17:41:50 +0100 Subject: r26260: Store loadparm context in gensec context. (This used to be commit b9e3a4862e267be39d603fed8207a237c3d72081) --- source4/libcli/ldap/ldap_bind.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index d285735d4e..60bfb52e2d 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -29,6 +29,7 @@ #include "auth/gensec/socket.h" #include "auth/credentials/credentials.h" #include "lib/stream/packet.h" +#include "param/param.h" struct ldap_simple_creds { const char *dn; @@ -217,7 +218,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *cr NULL }; - status = gensec_client_start(conn, &conn->gensec, NULL); + status = gensec_client_start(conn, &conn->gensec, NULL, global_loadparm); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); goto failed; -- cgit From 2f8dc4f48f1802baa3405e7803563f6840e0d1b3 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Dec 2007 21:25:06 +0100 Subject: r26266: Remove more global_loadparm uses. (This used to be commit 99113075c4a96679bcec4f4d6bba4acb3dee4245) --- source4/libcli/ldap/ldap_client.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index f1cfaad18b..2fe0c78555 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -377,7 +377,8 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, return NULL; } -static void ldap_connect_got_sock(struct composite_context *ctx, struct ldap_connection *conn) +static void ldap_connect_got_sock(struct composite_context *ctx, + struct ldap_connection *conn) { /* setup a handler for events on this socket */ conn->event.fde = event_add_fd(conn->event.event_ctx, conn->sock, -- cgit From 9ebcd7a0df117158f1817b7d3a9a21ad4e1fa97a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 4 Dec 2007 01:51:36 +0100 Subject: r26277: Move loadparm context higher up the stack. (This used to be commit 38fa08310ce573e9b46e76c840ddda6f18863573) --- source4/libcli/ldap/ldap_bind.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 60bfb52e2d..99b471e9a6 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -199,7 +199,8 @@ static struct ldap_message *new_ldap_sasl_bind_msg(struct ldap_connection *conn, /* perform a sasl bind using the given credentials */ -NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds) +NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, + struct cli_credentials *creds) { NTSTATUS status; TALLOC_CTX *tmp_ctx = NULL; -- cgit From 41db2ab12cea20b271d690be554ab8e6095c2b4e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 6 Dec 2007 21:39:49 +0100 Subject: r26319: Split encoding functions out of libcli_ldap. (This used to be commit 95a6ef7fc8757ccfd90dbf0d6c9b5098f10b10b6) --- source4/libcli/ldap/config.mk | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index adccd23eb1..444306b328 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -5,9 +5,14 @@ OBJ_FILES = ldap.o \ ldap_client.o \ ldap_bind.o \ ldap_msg.o \ - ldap_ndr.o \ ldap_ildap.o \ ldap_controls.o -PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET -PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket LIBCLI_RESOLVE NDR_SAMR LIBTLS ASN1_UTIL GENSEC_SOCKET -#FIXME: PRIVATE_DEPENDENCIES = gensec +PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET +PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket NDR_SAMR LIBTLS ASN1_UTIL \ + LDAP_ENCODE LIBNDR + + +[SUBSYSTEM::LDAP_ENCODE] +PUBLIC_PROTO_HEADER = ldap_ndr.h +OBJ_FILES = ldap_ndr.o +# FIXME PRIVATE_DEPENDENCIES = LIBLDB -- cgit From 01d2acfdb4c4c0349a28a18c5c0da5b960b02791 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 Dec 2007 16:04:17 +0100 Subject: r26335: Specify name_resolve_order to socket code. (This used to be commit b03e5d00110be3f1fe5809dad4eb6ca5cea7463d) --- source4/libcli/ldap/ldap_client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 2fe0c78555..c859b4a4d1 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -352,7 +352,7 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, } ctx = socket_connect_send(conn->sock, NULL, unix_addr, - 0, conn->event.event_ctx); + 0, lp_name_resolve_order(global_loadparm), conn->event.event_ctx); ctx->async.fn = ldap_connect_recv_unix_conn; ctx->async.private_data = state; return result; @@ -365,7 +365,7 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, } ctx = socket_connect_multi_send(state, conn->host, 1, &conn->port, - conn->event.event_ctx); + lp_name_resolve_order(global_loadparm), conn->event.event_ctx); if (ctx == NULL) goto failed; ctx->async.fn = ldap_connect_recv_tcp_conn; -- cgit From a72c5053c587f0ed6113ef514fe3739cb81e7abf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Dec 2007 23:32:43 +0100 Subject: r26353: Remove use of global_loadparm. (This used to be commit 17637e4490e42db6cdef619286c4d5a0982e9d1a) --- source4/libcli/ldap/ldap_bind.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 99b471e9a6..ba1ae90ebd 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -43,7 +43,8 @@ NTSTATUS ldap_rebind(struct ldap_connection *conn) switch (conn->bind.type) { case LDAP_BIND_SASL: - status = ldap_bind_sasl(conn, (struct cli_credentials *)conn->bind.creds); + status = ldap_bind_sasl(conn, (struct cli_credentials *)conn->bind.creds, + global_loadparm); break; case LDAP_BIND_SIMPLE: @@ -200,7 +201,8 @@ static struct ldap_message *new_ldap_sasl_bind_msg(struct ldap_connection *conn, perform a sasl bind using the given credentials */ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, - struct cli_credentials *creds) + struct cli_credentials *creds, + struct loadparm_context *lp_ctx) { NTSTATUS status; TALLOC_CTX *tmp_ctx = NULL; @@ -219,7 +221,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, NULL }; - status = gensec_client_start(conn, &conn->gensec, NULL, global_loadparm); + status = gensec_client_start(conn, &conn->gensec, NULL, lp_ctx); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); goto failed; -- cgit From b65dba2245bf382c47d65c95ac9b1efa43918fc0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 10 Dec 2007 04:33:16 +0100 Subject: r26355: Eliminate global_loadparm in more places. (This used to be commit 5d589a0d94bd76a9b4c9fc748854e8098ea43c4d) --- source4/libcli/ldap/ldap_bind.c | 2 +- source4/libcli/ldap/ldap_client.c | 13 ++++++++----- source4/libcli/ldap/ldap_client.h | 2 ++ 3 files changed, 11 insertions(+), 6 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index ba1ae90ebd..bd548be38e 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -44,7 +44,7 @@ NTSTATUS ldap_rebind(struct ldap_connection *conn) switch (conn->bind.type) { case LDAP_BIND_SASL: status = ldap_bind_sasl(conn, (struct cli_credentials *)conn->bind.creds, - global_loadparm); + conn->lp_ctx); break; case LDAP_BIND_SIMPLE: diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index c859b4a4d1..906e9c2574 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -37,11 +37,12 @@ #include "param/param.h" -/* +/** create a new ldap_connection stucture. The event context is optional */ struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx, - struct event_context *ev) + struct loadparm_context *lp_ctx, + struct event_context *ev) { struct ldap_connection *conn; @@ -61,6 +62,8 @@ struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx, conn->next_messageid = 1; conn->event.event_ctx = ev; + conn->lp_ctx = lp_ctx; + /* set a reasonable request timeout */ conn->timeout = 60; @@ -352,7 +355,7 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, } ctx = socket_connect_send(conn->sock, NULL, unix_addr, - 0, lp_name_resolve_order(global_loadparm), conn->event.event_ctx); + 0, lp_name_resolve_order(conn->lp_ctx), conn->event.event_ctx); ctx->async.fn = ldap_connect_recv_unix_conn; ctx->async.private_data = state; return result; @@ -365,7 +368,7 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, } ctx = socket_connect_multi_send(state, conn->host, 1, &conn->port, - lp_name_resolve_order(global_loadparm), conn->event.event_ctx); + lp_name_resolve_order(conn->lp_ctx), conn->event.event_ctx); if (ctx == NULL) goto failed; ctx->async.fn = ldap_connect_recv_tcp_conn; @@ -394,7 +397,7 @@ static void ldap_connect_got_sock(struct composite_context *ctx, talloc_steal(conn, conn->sock); if (conn->ldaps) { struct socket_context *tls_socket; - char *cafile = private_path(conn->sock, global_loadparm, lp_tls_cafile(global_loadparm)); + char *cafile = private_path(conn->sock, conn->lp_ctx, lp_tls_cafile(conn->lp_ctx)); if (!cafile || !*cafile) { talloc_free(conn->sock); diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h index d2a12ee8b5..d5ff441aff 100644 --- a/source4/libcli/ldap/ldap_client.h +++ b/source4/libcli/ldap/ldap_client.h @@ -51,6 +51,8 @@ struct ldap_request { /* main context for a ldap client connection */ struct ldap_connection { struct socket_context *sock; + struct loadparm_context *lp_ctx; + char *host; uint16_t port; bool ldaps; -- cgit From 5f4842cf65ce64bfdf577cd549565da20ca818cf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 10 Dec 2007 18:41:19 +0100 Subject: r26376: Add context for libcli_resolve. (This used to be commit 459e1466a411d6f83b7372e248566e6e71c745fc) --- source4/libcli/ldap/ldap_client.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 906e9c2574..6b8a7a3f28 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -35,6 +35,7 @@ #include "auth/gensec/gensec.h" #include "system/time.h" #include "param/param.h" +#include "libcli/resolve/resolve.h" /** @@ -355,7 +356,7 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, } ctx = socket_connect_send(conn->sock, NULL, unix_addr, - 0, lp_name_resolve_order(conn->lp_ctx), conn->event.event_ctx); + 0, lp_resolve_context(conn->lp_ctx), conn->event.event_ctx); ctx->async.fn = ldap_connect_recv_unix_conn; ctx->async.private_data = state; return result; @@ -368,7 +369,7 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn, } ctx = socket_connect_multi_send(state, conn->host, 1, &conn->port, - lp_name_resolve_order(conn->lp_ctx), conn->event.event_ctx); + lp_resolve_context(conn->lp_ctx), conn->event.event_ctx); if (ctx == NULL) goto failed; ctx->async.fn = ldap_connect_recv_tcp_conn; -- cgit From 3da665e9ac324320fed68a21163fffdf4bd3df89 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 10 Dec 2007 18:42:07 +0100 Subject: r26385: Integrate gensec-socket into gensec. (This used to be commit 78bb444b4b73df9a84f8702814f9b30b32ffd885) --- source4/libcli/ldap/ldap_bind.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index bd548be38e..fd15ff2fc7 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -26,7 +26,6 @@ #include "libcli/ldap/ldap_client.h" #include "lib/tls/tls.h" #include "auth/gensec/gensec.h" -#include "auth/gensec/socket.h" #include "auth/credentials/credentials.h" #include "lib/stream/packet.h" #include "param/param.h" @@ -221,6 +220,8 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, NULL }; + gensec_init(lp_ctx); + status = gensec_client_start(conn, &conn->gensec, NULL, lp_ctx); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); -- cgit From 1ea47faa979ad2e4aa4cf1f4252aa33aef98dbd8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 11 Dec 2007 13:38:54 +0100 Subject: r26397: Fix circular dependency in samba-socket. (This used to be commit 801c8c766cb6a104751be8829593e0e123508134) --- source4/libcli/ldap/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 444306b328..4af0f9de6d 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -9,7 +9,7 @@ OBJ_FILES = ldap.o \ ldap_controls.o PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket NDR_SAMR LIBTLS ASN1_UTIL \ - LDAP_ENCODE LIBNDR + LDAP_ENCODE LIBNDR LP_RESOLVE [SUBSYSTEM::LDAP_ENCODE] -- cgit From 71e2cafe96f4755b67d01ced497bf5b63aad30f6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 04:22:44 +0100 Subject: r26483: Merge ldb module dependency fixes, fix auth python module. (This used to be commit 85eeecf997a071ca7e7ad0247e8d34d49b7ffcbb) --- source4/libcli/ldap/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 4af0f9de6d..239ee1f161 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -9,7 +9,7 @@ OBJ_FILES = ldap.o \ ldap_controls.o PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket NDR_SAMR LIBTLS ASN1_UTIL \ - LDAP_ENCODE LIBNDR LP_RESOLVE + LDAP_ENCODE LIBNDR LP_RESOLVE gensec [SUBSYSTEM::LDAP_ENCODE] -- cgit From 3e75f222bcdf114238cc4f2bcc61332dc059135f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 19 Dec 2007 23:27:42 +0100 Subject: r26539: Remove unnecessary statics. (This used to be commit e53e79eebef3ece6978f0a2b4a1ee0a0814bb5d2) --- source4/libcli/ldap/ldap_bind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index fd15ff2fc7..264a6b39ee 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -215,7 +215,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, const char **sasl_names; uint32_t old_gensec_features; - static const char *supported_sasl_mech_attrs[] = { + const char *supported_sasl_mech_attrs[] = { "supportedSASLMechanisms", NULL }; -- cgit From 0500b87092540d300b4e021a0fb95ce16a44fbd2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 20 Dec 2007 00:02:15 +0100 Subject: r26540: Revert my previous commit after concerns raised by Andrew. (This used to be commit 6ac86f8be7d9a8c5ab396a93e6d1e6819e11f173) --- source4/libcli/ldap/ldap_bind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 264a6b39ee..fd15ff2fc7 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -215,7 +215,7 @@ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, const char **sasl_names; uint32_t old_gensec_features; - const char *supported_sasl_mech_attrs[] = { + static const char *supported_sasl_mech_attrs[] = { "supportedSASLMechanisms", NULL }; -- cgit From 70cb5ac03c476110c0348881f49ad0697037ca38 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 27 Dec 2007 07:47:11 -0600 Subject: r26613: Add a function to write a DATA_BLOB into an LDAPString. This respects the length set in the DATA_BLOB, rather than hoping to see NULL termination of the data pointer. (found testing the Ambigious Name Resolution code against OpenLDAP). Andrew Bartlett (This used to be commit bc0022e8c7357b126dc91a945f0e53e4e4108e7d) --- source4/libcli/ldap/ldap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 34d715e3e5..586f2fa653 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -77,7 +77,7 @@ static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree i = 0; if ( ! tree->u.substring.start_with_wildcard) { asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write_LDAPString(data, (char *)tree->u.substring.chunks[i]->data); + asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); asn1_pop_tag(data); i++; } @@ -91,7 +91,7 @@ static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree ctx = 1; } asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(ctx)); - asn1_write_LDAPString(data, (char *)tree->u.substring.chunks[i]->data); + asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); asn1_pop_tag(data); i++; } @@ -157,7 +157,7 @@ static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree asn1_pop_tag(data); } asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3)); - asn1_write_LDAPString(data, (char *)tree->u.extended.value.data); + asn1_write_DATA_BLOB_LDAPString(data, &tree->u.extended.value); asn1_pop_tag(data); asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4)); asn1_write_uint8(data, tree->u.extended.dnAttributes); -- cgit From 86dc05e99f124db47f2743d1fc23117a7f5145ab Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 1 Jan 2008 22:05:05 -0600 Subject: r26638: libndr: Require explicitly specifying iconv_convenience for ndr_struct_push_blob(). (This used to be commit 61ad78ac98937ef7a9aa32075a91a1c95b7606b3) --- source4/libcli/ldap/ldap_ndr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index 468c366c85..fde623bece 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -46,7 +46,7 @@ char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) DATA_BLOB blob; enum ndr_err_code ndr_err; char *ret; - ndr_err = ndr_push_struct_blob(&blob, mem_ctx, sid, + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, sid, (ndr_push_flags_fn_t)ndr_push_dom_sid); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return NULL; @@ -65,7 +65,7 @@ char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) DATA_BLOB blob; enum ndr_err_code ndr_err; char *ret; - ndr_err = ndr_push_struct_blob(&blob, mem_ctx, guid, + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, guid, (ndr_push_flags_fn_t)ndr_push_GUID); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return NULL; -- cgit From 7d5f0e0893d42b56145a3ffa34e3b4b9906cbd91 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 1 Jan 2008 22:05:13 -0600 Subject: r26639: librpc: Pass iconv convenience on from RPC connection to NDR library, so it can be overridden by OpenChange. (This used to be commit 2f29f80e07adef1f020173f2cd6d947d0ef505ce) --- source4/libcli/ldap/ldap_ndr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index fde623bece..3f7cb8f538 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -85,7 +85,7 @@ NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GU blob.data = val.data; blob.length = val.length; - ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, guid, + ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, guid, (ndr_pull_flags_fn_t)ndr_pull_GUID); talloc_free(val.data); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { -- cgit From 939edd0eb7c3952859afb802c8e542449a2c4031 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 15 Jan 2008 01:04:38 +0100 Subject: util: Move asn1 to lib/util to trim down the number of subsystems. (This used to be commit 44e1cfd2d0ef62e4ee541cec00581a7151d951b3) --- source4/libcli/ldap/ldap.c | 2 +- source4/libcli/ldap/ldap_client.c | 2 +- source4/libcli/ldap/ldap_controls.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 586f2fa653..00a0631753 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -23,7 +23,7 @@ */ #include "includes.h" -#include "libcli/util/asn_1.h" +#include "lib/util/asn1.h" #include "libcli/ldap/ldap.h" diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 6b8a7a3f28..d99851ee15 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -23,7 +23,7 @@ */ #include "includes.h" -#include "libcli/util/asn_1.h" +#include "lib/util/asn1.h" #include "lib/util/dlinklist.h" #include "lib/events/events.h" #include "lib/socket/socket.h" diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 34e5cccf75..3b94580033 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -20,7 +20,7 @@ */ #include "includes.h" -#include "libcli/util/asn_1.h" +#include "lib/util/asn1.h" #include "libcli/ldap/ldap.h" #include "lib/ldb/include/ldb.h" -- cgit From 1ada7108408f567f61cfbf2b625730ba898452db Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 29 Feb 2008 14:23:38 +0100 Subject: Move public header accumulation out of the perl code. Never install generated prototype files. It's easier to break the API when using them and they're not easily readable for 3rd party users. Conflicts: source/auth/config.mk source/auth/credentials/config.mk source/auth/gensec/config.mk source/build/smb_build/config_mk.pm source/build/smb_build/main.pl source/build/smb_build/makefile.pm source/dsdb/config.mk source/lib/charset/config.mk source/lib/tdr/config.mk source/lib/util/config.mk source/libcli/config.mk source/libcli/ldap/config.mk source/librpc/config.mk source/param/config.mk source/rpc_server/config.mk source/torture/config.mk (This used to be commit 6c659689ed4081f1d7a6253c538c7f01784197ba) --- source4/libcli/ldap/config.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 239ee1f161..9b0dc1a0f4 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,6 +1,5 @@ [SUBSYSTEM::LIBCLI_LDAP] -PUBLIC_PROTO_HEADER = ldap_proto.h -PUBLIC_HEADERS = ldap.h +PRIVATE_PROTO_HEADER = ldap_proto.h OBJ_FILES = ldap.o \ ldap_client.o \ ldap_bind.o \ @@ -11,6 +10,7 @@ PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket NDR_SAMR LIBTLS ASN1_UTIL \ LDAP_ENCODE LIBNDR LP_RESOLVE gensec +PUBLIC_HEADERS += libcli/ldap/ldap.h [SUBSYSTEM::LDAP_ENCODE] PUBLIC_PROTO_HEADER = ldap_ndr.h -- cgit From 489f66cd422453c00afd14121fb61a41a6785249 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 29 Feb 2008 14:36:51 +0100 Subject: Change remaining prototype headers to be private. (This used to be commit 2f7ff409e89c9682e681ddcf54439db9e3b6ccb4) --- source4/libcli/ldap/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 9b0dc1a0f4..bcdedd3440 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -13,6 +13,6 @@ PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket NDR_SAMR LIBTLS ASN1_UTIL \ PUBLIC_HEADERS += libcli/ldap/ldap.h [SUBSYSTEM::LDAP_ENCODE] -PUBLIC_PROTO_HEADER = ldap_ndr.h +PRIVATE_PROTO_HEADER = ldap_ndr.h OBJ_FILES = ldap_ndr.o # FIXME PRIVATE_DEPENDENCIES = LIBLDB -- cgit From afe3e8172ddaa5e4aa811faceecda4f943d6e2ef Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 2 Apr 2008 04:53:27 +0200 Subject: Install public header files again and include required prototypes. (This used to be commit 47ffbbf67435904754469544390b67d34c958343) --- source4/libcli/ldap/config.mk | 3 +-- source4/libcli/ldap/ldap.c | 5 +++-- source4/libcli/ldap/ldap.h | 4 +++- source4/libcli/ldap/ldap_bind.c | 7 ++++--- source4/libcli/ldap/ldap_client.c | 23 ++++++++++---------- source4/libcli/ldap/ldap_client.h | 44 +++++++++++++++++++++++++++++++++++++++ source4/libcli/ldap/ldap_ildap.c | 6 +++--- source4/libcli/ldap/ldap_msg.c | 2 +- 8 files changed, 71 insertions(+), 23 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index bcdedd3440..0c5236c138 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -10,9 +10,8 @@ PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket NDR_SAMR LIBTLS ASN1_UTIL \ LDAP_ENCODE LIBNDR LP_RESOLVE gensec -PUBLIC_HEADERS += libcli/ldap/ldap.h +PUBLIC_HEADERS += libcli/ldap/ldap.h libcli/ldap/ldap_ndr.h [SUBSYSTEM::LDAP_ENCODE] -PRIVATE_PROTO_HEADER = ldap_ndr.h OBJ_FILES = ldap_ndr.o # FIXME PRIVATE_DEPENDENCIES = LIBLDB diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index 00a0631753..fc6de7993e 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -25,6 +25,7 @@ #include "includes.h" #include "lib/util/asn1.h" #include "libcli/ldap/ldap.h" +#include "libcli/ldap/ldap_proto.h" static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree) @@ -187,7 +188,7 @@ static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *res } } -bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) +_PUBLIC_ bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) { struct asn1_data *data = asn1_init(mem_ctx); int i, j; @@ -927,7 +928,7 @@ static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, /* This routine returns LDAP status codes */ -NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) +_PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) { uint8_t tag; diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 6f5e86744e..a336a7ad85 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -254,6 +254,8 @@ struct cli_credentials; struct dom_sid; struct asn1_data; -#include "libcli/ldap/ldap_proto.h" +struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx); +NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg); +bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx); #endif diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index fd15ff2fc7..2c04edf950 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_proto.h" #include "libcli/ldap/ldap_client.h" #include "lib/tls/tls.h" #include "auth/gensec/gensec.h" @@ -35,7 +36,7 @@ struct ldap_simple_creds { const char *pw; }; -NTSTATUS ldap_rebind(struct ldap_connection *conn) +_PUBLIC_ NTSTATUS ldap_rebind(struct ldap_connection *conn) { NTSTATUS status; struct ldap_simple_creds *creds; @@ -88,7 +89,7 @@ static struct ldap_message *new_ldap_simple_bind_msg(struct ldap_connection *con /* perform a simple username/password bind */ -NTSTATUS ldap_bind_simple(struct ldap_connection *conn, +_PUBLIC_ NTSTATUS ldap_bind_simple(struct ldap_connection *conn, const char *userdn, const char *password) { struct ldap_request *req; @@ -199,7 +200,7 @@ static struct ldap_message *new_ldap_sasl_bind_msg(struct ldap_connection *conn, /* perform a sasl bind using the given credentials */ -NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, +_PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds, struct loadparm_context *lp_ctx) { diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index d99851ee15..296a7b11f2 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -28,6 +28,7 @@ #include "lib/events/events.h" #include "lib/socket/socket.h" #include "libcli/ldap/ldap.h" +#include "libcli/ldap/ldap_proto.h" #include "libcli/ldap/ldap_client.h" #include "libcli/composite/composite.h" #include "lib/stream/packet.h" @@ -41,7 +42,7 @@ /** create a new ldap_connection stucture. The event context is optional */ -struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx, +_PUBLIC_ struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct event_context *ev) { @@ -293,7 +294,7 @@ struct ldap_connect_state { static void ldap_connect_recv_unix_conn(struct composite_context *ctx); static void ldap_connect_recv_tcp_conn(struct composite_context *ctx); -struct composite_context *ldap_connect_send(struct ldap_connection *conn, +_PUBLIC_ struct composite_context *ldap_connect_send(struct ldap_connection *conn, const char *url) { struct composite_context *result, *ctx; @@ -476,7 +477,7 @@ _PUBLIC_ NTSTATUS ldap_connect_recv(struct composite_context *ctx) return status; } -NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url) +_PUBLIC_ NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url) { struct composite_context *ctx = ldap_connect_send(conn, url); return ldap_connect_recv(ctx); @@ -484,7 +485,7 @@ NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url) /* set reconnect parameters */ -void ldap_set_reconn_params(struct ldap_connection *conn, int max_retries) +_PUBLIC_ void ldap_set_reconn_params(struct ldap_connection *conn, int max_retries) { if (conn) { conn->reconnect.max_retries = max_retries; @@ -569,7 +570,7 @@ static void ldap_request_complete(struct event_context *ev, struct timed_event * /* send a ldap message - async interface */ -struct ldap_request *ldap_request_send(struct ldap_connection *conn, +_PUBLIC_ struct ldap_request *ldap_request_send(struct ldap_connection *conn, struct ldap_message *msg) { struct ldap_request *req; @@ -645,7 +646,7 @@ failed: wait for a request to complete note that this does not destroy the request */ -NTSTATUS ldap_request_wait(struct ldap_request *req) +_PUBLIC_ NTSTATUS ldap_request_wait(struct ldap_request *req) { while (req->state < LDAP_REQUEST_DONE) { if (event_loop_once(req->conn->event.event_ctx) != 0) { @@ -709,7 +710,7 @@ static const struct { /* used to setup the status code from a ldap response */ -NTSTATUS ldap_check_response(struct ldap_connection *conn, struct ldap_Result *r) +_PUBLIC_ NTSTATUS ldap_check_response(struct ldap_connection *conn, struct ldap_Result *r) { int i; const char *codename = "unknown"; @@ -742,7 +743,7 @@ NTSTATUS ldap_check_response(struct ldap_connection *conn, struct ldap_Result *r /* return error string representing the last error */ -const char *ldap_errstr(struct ldap_connection *conn, +_PUBLIC_ const char *ldap_errstr(struct ldap_connection *conn, TALLOC_CTX *mem_ctx, NTSTATUS status) { @@ -756,7 +757,7 @@ const char *ldap_errstr(struct ldap_connection *conn, /* return the Nth result message, waiting if necessary */ -NTSTATUS ldap_result_n(struct ldap_request *req, int n, struct ldap_message **msg) +_PUBLIC_ NTSTATUS ldap_result_n(struct ldap_request *req, int n, struct ldap_message **msg) { *msg = NULL; @@ -784,7 +785,7 @@ NTSTATUS ldap_result_n(struct ldap_request *req, int n, struct ldap_message **ms /* return a single result message, checking if it is of the expected LDAP type */ -NTSTATUS ldap_result_one(struct ldap_request *req, struct ldap_message **msg, int type) +_PUBLIC_ NTSTATUS ldap_result_one(struct ldap_request *req, struct ldap_message **msg, int type) { NTSTATUS status; status = ldap_result_n(req, 0, msg); @@ -802,7 +803,7 @@ NTSTATUS ldap_result_one(struct ldap_request *req, struct ldap_message **msg, in a simple ldap transaction, for single result requests that only need a status code this relies on single valued requests having the response type == request type + 1 */ -NTSTATUS ldap_transaction(struct ldap_connection *conn, struct ldap_message *msg) +_PUBLIC_ NTSTATUS ldap_transaction(struct ldap_connection *conn, struct ldap_message *msg) { struct ldap_request *req = ldap_request_send(conn, msg); struct ldap_message *res; diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h index d5ff441aff..13b0bf725c 100644 --- a/source4/libcli/ldap/ldap_client.h +++ b/source4/libcli/ldap/ldap_client.h @@ -94,3 +94,47 @@ struct ldap_connection { struct packet_context *packet; }; + +struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, + struct event_context *ev); + +NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url); +struct composite_context *ldap_connect_send(struct ldap_connection *conn, + const char *url); + +NTSTATUS ldap_rebind(struct ldap_connection *conn); +NTSTATUS ldap_bind_simple(struct ldap_connection *conn, + const char *userdn, const char *password); +NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, + struct cli_credentials *creds, + struct loadparm_context *lp_ctx); +struct ldap_request *ldap_request_send(struct ldap_connection *conn, + struct ldap_message *msg); +NTSTATUS ldap_request_wait(struct ldap_request *req); +struct composite_context; +NTSTATUS ldap_connect_recv(struct composite_context *ctx); +NTSTATUS ldap_result_n(struct ldap_request *req, int n, struct ldap_message **msg); +NTSTATUS ldap_result_one(struct ldap_request *req, struct ldap_message **msg, int type); +NTSTATUS ldap_transaction(struct ldap_connection *conn, struct ldap_message *msg); +const char *ldap_errstr(struct ldap_connection *conn, + TALLOC_CTX *mem_ctx, + NTSTATUS status); +NTSTATUS ldap_check_response(struct ldap_connection *conn, struct ldap_Result *r); +void ldap_set_reconn_params(struct ldap_connection *conn, int max_retries); +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 ldb_control **control_req, + struct ldb_control ***control_res, + struct ldap_message ***results); +NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn, + int scope, const char *expression, + const char * const *attrs, bool attributesonly, + struct ldb_control **control_req, + struct ldb_control ***control_res, + struct ldap_message ***results); + + + diff --git a/source4/libcli/ldap/ldap_ildap.c b/source4/libcli/ldap/ldap_ildap.c index 7b592c65ae..8f21af0690 100644 --- a/source4/libcli/ldap/ldap_ildap.c +++ b/source4/libcli/ldap/ldap_ildap.c @@ -28,7 +28,7 @@ /* count the returned search entries */ -int ildap_count_entries(struct ldap_connection *conn, struct ldap_message **res) +_PUBLIC_ int ildap_count_entries(struct ldap_connection *conn, struct ldap_message **res) { int i; for (i=0;res && res[i];i++) /* noop */ ; @@ -39,7 +39,7 @@ int ildap_count_entries(struct ldap_connection *conn, struct ldap_message **res) /* perform a synchronous ldap search */ -NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn, +_PUBLIC_ 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 ldb_control **control_req, @@ -112,7 +112,7 @@ NTSTATUS ildap_search_bytree(struct ldap_connection *conn, const char *basedn, /* perform a ldap search */ -NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn, +_PUBLIC_ NTSTATUS ildap_search(struct ldap_connection *conn, const char *basedn, int scope, const char *expression, const char * const *attrs, bool attributesonly, struct ldb_control **control_req, diff --git a/source4/libcli/ldap/ldap_msg.c b/source4/libcli/ldap/ldap_msg.c index 12832b8ec4..c712e1e654 100644 --- a/source4/libcli/ldap/ldap_msg.c +++ b/source4/libcli/ldap/ldap_msg.c @@ -26,7 +26,7 @@ #include "libcli/ldap/ldap_client.h" -struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) +_PUBLIC_ struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) { return talloc_zero(mem_ctx, struct ldap_message); } -- cgit From 4e5e7a7c688d8a065994cb16fb1da7581bab081a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 2 Apr 2008 16:47:17 +0200 Subject: Reintroduce header previously autogenerated but ignored by git. Also fixed extra include in regpatch. (This used to be commit 0e371cf169e9a607fcbb3e65437ab9413935dd52) --- source4/libcli/ldap/ldap_ndr.h | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 source4/libcli/ldap/ldap_ndr.h (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_ndr.h b/source4/libcli/ldap/ldap_ndr.h new file mode 100644 index 0000000000..dfbb723c36 --- /dev/null +++ b/source4/libcli/ldap/ldap_ndr.h @@ -0,0 +1,10 @@ +#ifndef __LIBCLI_LDAP_LDAP_NDR_H__ +#define __LIBCLI_LDAP_LDAP_NDR_H__ + +char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value); +char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid); +char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid); +NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GUID *guid); + +#endif /* __LIBCLI_LDAP_LDAP_NDR_H__ */ + -- cgit From e9017ba418202b4b191c5a9ad4a96857558ce606 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Apr 2008 17:22:58 +0200 Subject: Use _OBJ_FILES variables in a couple more places. (This used to be commit 92856d5054106894b65cd1a1b5119c0facfc4cff) --- source4/libcli/ldap/config.mk | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 0c5236c138..33e32c7417 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,17 +1,17 @@ [SUBSYSTEM::LIBCLI_LDAP] PRIVATE_PROTO_HEADER = ldap_proto.h -OBJ_FILES = ldap.o \ - ldap_client.o \ - ldap_bind.o \ - ldap_msg.o \ - ldap_ildap.o \ - ldap_controls.o PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket NDR_SAMR LIBTLS ASN1_UTIL \ LDAP_ENCODE LIBNDR LP_RESOLVE gensec +LIBCLI_LDAP_OBJ_FILES = $(addprefix libcli/ldap/, \ + ldap.o ldap_client.o ldap_bind.o \ + ldap_msg.o ldap_ildap.o ldap_controls.o) + + PUBLIC_HEADERS += libcli/ldap/ldap.h libcli/ldap/ldap_ndr.h [SUBSYSTEM::LDAP_ENCODE] -OBJ_FILES = ldap_ndr.o # FIXME PRIVATE_DEPENDENCIES = LIBLDB + +LDAP_ENCODE_OBJ_FILES = libcli/ldap/ldap_ndr.o -- cgit From 1a8bfba5452f7b72d9f0b2a178f7e8a66557c463 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 15 Apr 2008 12:15:43 +0200 Subject: Fix warnings. (This used to be commit 88013ca9775a6ff5e5a393f9d8238dbcd197f26f) --- source4/libcli/ldap/ldap_ndr.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_ndr.h b/source4/libcli/ldap/ldap_ndr.h index dfbb723c36..ee1f702c78 100644 --- a/source4/libcli/ldap/ldap_ndr.h +++ b/source4/libcli/ldap/ldap_ndr.h @@ -1,6 +1,8 @@ #ifndef __LIBCLI_LDAP_LDAP_NDR_H__ #define __LIBCLI_LDAP_LDAP_NDR_H__ +#include "librpc/gen_ndr/ndr_misc.h" + char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value); char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid); char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid); -- cgit From 4e83011f72ba3df387512755a17760b42a7bf2f2 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 21 Apr 2008 17:58:23 -0400 Subject: Remove more event_context_init() uses from function calls within deep down the code. Make sure we pass around the event_context where we need it instead. All test but a few python ones fail. Jelmer promised to fix them. (This used to be commit 3045d391626fba169aa26be52174883e18d323e9) --- source4/libcli/ldap/ldap_bind.c | 5 +++-- source4/libcli/ldap/ldap_client.c | 12 ++++-------- 2 files changed, 7 insertions(+), 10 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 2c04edf950..e1569e7296 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -200,7 +200,7 @@ static struct ldap_message *new_ldap_sasl_bind_msg(struct ldap_connection *conn, /* perform a sasl bind using the given credentials */ -_PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, +_PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, struct cli_credentials *creds, struct loadparm_context *lp_ctx) { @@ -223,7 +223,8 @@ _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, gensec_init(lp_ctx); - status = gensec_client_start(conn, &conn->gensec, NULL, lp_ctx); + status = gensec_client_start(conn, &conn->gensec, + conn->event.event_ctx, lp_ctx); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); goto failed; diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 296a7b11f2..bca867b033 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -48,17 +48,13 @@ _PUBLIC_ struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx, { struct ldap_connection *conn; - conn = talloc_zero(mem_ctx, struct ldap_connection); - if (conn == NULL) { + if (ev == NULL) { return NULL; } - if (ev == NULL) { - ev = event_context_init(conn); - if (ev == NULL) { - talloc_free(conn); - return NULL; - } + conn = talloc_zero(mem_ctx, struct ldap_connection); + if (conn == NULL) { + return NULL; } conn->next_messageid = 1; -- cgit From 03643aec88244d976da394521adbd29a31339569 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 18 May 2008 19:54:27 +0200 Subject: Use variables for source directory in a couple more places. (This used to be commit c41bd3005f5f0b9cfd3709fc9217b4a401d265b4) --- source4/libcli/ldap/config.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 33e32c7417..d5b7c5d2b5 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -4,14 +4,14 @@ PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket NDR_SAMR LIBTLS ASN1_UTIL \ LDAP_ENCODE LIBNDR LP_RESOLVE gensec -LIBCLI_LDAP_OBJ_FILES = $(addprefix libcli/ldap/, \ +LIBCLI_LDAP_OBJ_FILES = $(addprefix $(libclisrcdir)/ldap/, \ ldap.o ldap_client.o ldap_bind.o \ ldap_msg.o ldap_ildap.o ldap_controls.o) -PUBLIC_HEADERS += libcli/ldap/ldap.h libcli/ldap/ldap_ndr.h +PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap.h $(libclisrcdir)/ldap/ldap_ndr.h [SUBSYSTEM::LDAP_ENCODE] # FIXME PRIVATE_DEPENDENCIES = LIBLDB -LDAP_ENCODE_OBJ_FILES = libcli/ldap/ldap_ndr.o +LDAP_ENCODE_OBJ_FILES = $(libclisrcdir)/ldap/ldap_ndr.o -- cgit From 4c8756f147f8b9a2806fd76e4cb06bb99d391516 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 18 May 2008 22:30:08 +0200 Subject: Create prototype headers from Makefile directory, without smb_build in the middle. (This used to be commit f4a77b96f9c17d853348b70794026e5b9e384942) --- source4/libcli/ldap/config.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index d5b7c5d2b5..e761b80024 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,5 +1,4 @@ [SUBSYSTEM::LIBCLI_LDAP] -PRIVATE_PROTO_HEADER = ldap_proto.h PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket NDR_SAMR LIBTLS ASN1_UTIL \ LDAP_ENCODE LIBNDR LP_RESOLVE gensec @@ -11,6 +10,8 @@ LIBCLI_LDAP_OBJ_FILES = $(addprefix $(libclisrcdir)/ldap/, \ PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap.h $(libclisrcdir)/ldap/ldap_ndr.h +$(call proto_header_template,$(libclisrcdir)/ldap/ldap_proto.h,$(LIBCLI_LDAP_OBJ_FILES:.o=.c)) + [SUBSYSTEM::LDAP_ENCODE] # FIXME PRIVATE_DEPENDENCIES = LIBLDB -- cgit From 4c70cda986c86fe536327321d04c29eca81b6409 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 18 May 2008 23:02:47 +0200 Subject: Fix a couple (well, little more than that..) of typos. (This used to be commit a6b52119940a900fb0de3864b8bca94e2965cc24) --- source4/libcli/ldap/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index e761b80024..02678eed7a 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -10,7 +10,7 @@ LIBCLI_LDAP_OBJ_FILES = $(addprefix $(libclisrcdir)/ldap/, \ PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap.h $(libclisrcdir)/ldap/ldap_ndr.h -$(call proto_header_template,$(libclisrcdir)/ldap/ldap_proto.h,$(LIBCLI_LDAP_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(libclisrcdir)/ldap/ldap_proto.h,$(LIBCLI_LDAP_OBJ_FILES:.o=.c))) [SUBSYSTEM::LDAP_ENCODE] # FIXME PRIVATE_DEPENDENCIES = LIBLDB -- cgit From 929adc9efa5cf985f0585214d30d18521aa1a821 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 14 Jun 2008 11:24:17 -0400 Subject: Make up the right dependencies now that ldb depends on libevents (This used to be commit 3b8eec7ca334528cad3cdcd5e3fc5ee555d8d0e0) --- source4/libcli/ldap/ldap_ndr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c index 3f7cb8f538..a10f80ae2c 100644 --- a/source4/libcli/ldap/ldap_ndr.c +++ b/source4/libcli/ldap/ldap_ndr.c @@ -21,6 +21,7 @@ */ #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" -- cgit From ab00b65dde3fad666425cd9b4b6e45dabc33b279 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 15 Jul 2008 15:08:57 +1000 Subject: Cleanup ldap_bind_sasl. With these changes, we don't leak the LDAP socket, and don't reset all credentials feature flags, just the ones we are actually incompatible with. Andrew Bartlett (This used to be commit 72e52a301102941c41ab423e0212fe9a1aed0405) --- source4/libcli/ldap/ldap_bind.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index e1569e7296..65673116be 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -234,7 +234,7 @@ _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, * Windows seem not to like double encryption */ old_gensec_features = cli_credentials_get_gensec_features(creds); if (tls_enabled(conn->sock)) { - cli_credentials_set_gensec_features(creds, 0); + cli_credentials_set_gensec_features(creds, old_gensec_features & ~(GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL)); } /* this call also sets the gensec_want_features */ @@ -245,7 +245,8 @@ _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, goto failed; } - /* reset the original gensec_features */ + /* reset the original gensec_features (on the credentials + * context, so we don't tatoo it ) */ cli_credentials_set_gensec_features(creds, old_gensec_features); if (conn->host) { @@ -393,8 +394,6 @@ _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, &sasl_socket); if (!NT_STATUS_IS_OK(status)) goto failed; - talloc_steal(conn->sock, sasl_socket); - talloc_unlink(conn, conn->sock); conn->sock = sasl_socket; packet_set_socket(conn->packet, conn->sock); -- cgit From 403f4f94ffec28d1c1dc910e1960531f4c14534b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 15 Jul 2008 15:10:29 +1000 Subject: Make up a full hostname for ldapi connections. The DIGEST-MD5 SASL method requires a hostname, so provide one. Andrew Bartlett (This used to be commit edfb2ed1f22bc735af5a0c3d3ae6ab6771d28f2c) --- source4/libcli/ldap/ldap_client.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source4/libcli/ldap') diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index bca867b033..844238afdb 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -38,7 +38,6 @@ #include "param/param.h" #include "libcli/resolve/resolve.h" - /** create a new ldap_connection stucture. The event context is optional */ @@ -298,7 +297,7 @@ _PUBLIC_ struct composite_context *ldap_connect_send(struct ldap_connection *con char protocol[11]; int ret; - result = talloc_zero(NULL, struct composite_context); + result = talloc_zero(conn, struct composite_context); if (result == NULL) goto failed; result->state = COMPOSITE_STATE_IN_PROGRESS; result->async.fn = NULL; @@ -336,6 +335,12 @@ _PUBLIC_ struct composite_context *ldap_connect_send(struct ldap_connection *con SMB_ASSERT(sizeof(protocol)>10); SMB_ASSERT(sizeof(path)>1024); + /* LDAPI connections are to localhost, so give the local host name as the target for gensec */ + conn->host = talloc_asprintf(conn, "%s.%s", lp_netbios_name(conn->lp_ctx), lp_realm(conn->lp_ctx)); + if (composite_nomem(conn->host, state->ctx)) { + return result; + } + /* The %c specifier doesn't null terminate :-( */ ZERO_STRUCT(path); ret = sscanf(url, "%10[^:]://%1025c", protocol, path); -- cgit