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/ldap.c | 1989 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1989 insertions(+) create mode 100644 source4/libcli/ldap/ldap.c (limited to 'source4/libcli/ldap/ldap.c') 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; +} -- 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/ldap.c') 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/ldap.c') 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/ldap.c') 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/ldap.c') 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/ldap.c') 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 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 153 insertions(+), 16 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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) { -- 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 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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); -- 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/ldap.c') 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/ldap.c') 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/ldap.c') 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 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/ldap.c | 411 --------------------------------------------- 1 file changed, 411 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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) { -- 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 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap/ldap.c') 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) { -- 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/ldap.c') 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/ldap.c') 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/ldap.c') 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/ldap.c') 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/ldap.c') 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 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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; -- 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 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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; } -- 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 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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; } -- 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 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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; } -- 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/ldap.c') 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/ldap.c') 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/ldap.c') 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/ldap.c') 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/ldap.c') 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/ldap.c') 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 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/ldap.c') 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 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli/ldap/ldap.c') 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" /**************************************************************************** * -- 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/ldap.c') 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/ldap.c') 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/ldap.c') 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/ldap.c | 655 +-------------------------------------------- 1 file changed, 3 insertions(+), 652 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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; -} -- 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 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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; } -- 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/ldap.c') 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 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/ldap.c') 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 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 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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); -- 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 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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; } -- 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/ldap.c') 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 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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); -- 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/ldap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli/ldap/ldap.c') 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" /**************************************************************************** * -- 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/ldap.c') 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 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 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 59 insertions(+), 20 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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); } + + -- 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/ldap.c') 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 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 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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); +} -- 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/ldap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap/ldap.c') 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); } + + + -- 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 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap/ldap.c') 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; -- 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 ++------------------------------------------- 1 file changed, 17 insertions(+), 375 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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); -} - - - -- 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/ldap.c') 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 +++++++++-------------------------------- 1 file changed, 9 insertions(+), 32 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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)); -- 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/ldap.c') 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 +++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 36 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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); } } -- 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 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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, -- 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 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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); -- 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/ldap.c | 40 ---------------------------------------- 1 file changed, 40 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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); -} -- 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 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap/ldap.c') 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); -- 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/ldap.c') 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/ldap.c') 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 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/ldap.c') 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 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/ldap.c') 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 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/ldap.c') 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/ldap.c') 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 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/ldap.c') 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 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 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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; } -- 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/ldap.c') 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 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/ldap.c') 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 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 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source4/libcli/ldap/ldap.c') 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); +} -- 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 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap/ldap.c') 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" -- 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/ldap.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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); -- 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/ldap.c') 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 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/ldap.c') 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 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 ++++++++++++++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 33 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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; } -- 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 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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); } -- 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/ldap.c') 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 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 - 1 file changed, 1 deletion(-) (limited to 'source4/libcli/ldap/ldap.c') 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" -- 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/ldap.c') 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 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/ldap.c') 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 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/ldap.c') 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/ldap.c') 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 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 ++++++++++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 29 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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; } -- 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 ++++++++++++++++++++++----------------------- 1 file changed, 148 insertions(+), 149 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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); } -- 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 ++ 1 file changed, 2 insertions(+) (limited to 'source4/libcli/ldap/ldap.c') 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); -- 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 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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 . */ -- 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/ldap.c') 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 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 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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, -- 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 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'source4/libcli/ldap/ldap.c') 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); } -- 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/ldap.c') 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 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 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/ldap/ldap.c') 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" -- 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/ldap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/libcli/ldap/ldap.c') 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; -- cgit