From 3e2c696e45b24b0192ab7b1ddaf1dd4d79571609 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 24 Sep 2006 02:49:04 +0000 Subject: r18866: Jeremy and Volker have given the go-ahead on the group mapping ldb code. Yay! This first commit copies lib/ldb/ from Samba4. A huge congratulations should go to Simo on this - he has put an enormous amount of work into ldb, and it's great to see it go into the Samba3 tree. (This used to be commit bbedf2e34315f5c420a3a05dfe22b1d5cf79f042) --- source3/lib/ldb/common/ldb_msg.c | 802 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 802 insertions(+) create mode 100644 source3/lib/ldb/common/ldb_msg.c (limited to 'source3/lib/ldb/common/ldb_msg.c') diff --git a/source3/lib/ldb/common/ldb_msg.c b/source3/lib/ldb/common/ldb_msg.c new file mode 100644 index 0000000000..52c6b82484 --- /dev/null +++ b/source3/lib/ldb/common/ldb_msg.c @@ -0,0 +1,802 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + * Name: ldb + * + * Component: ldb message component utility functions + * + * Description: functions for manipulating ldb_message structures + * + * Author: Andrew Tridgell + */ + +#include "includes.h" +#include "ldb/include/includes.h" + +/* + create a new ldb_message in a given memory context (NULL for top level) +*/ +struct ldb_message *ldb_msg_new(void *mem_ctx) +{ + return talloc_zero(mem_ctx, struct ldb_message); +} + +/* + find an element in a message by attribute name +*/ +struct ldb_message_element *ldb_msg_find_element(const struct ldb_message *msg, + const char *attr_name) +{ + unsigned int i; + for (i=0;inum_elements;i++) { + if (ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) { + return &msg->elements[i]; + } + } + return NULL; +} + +/* + see if two ldb_val structures contain exactly the same data + return 1 for a match, 0 for a mis-match +*/ +int ldb_val_equal_exact(const struct ldb_val *v1, const struct ldb_val *v2) +{ + if (v1->length != v2->length) return 0; + + if (v1->length == 0) return 1; + + if (memcmp(v1->data, v2->data, v1->length) == 0) { + return 1; + } + + return 0; +} + +/* + find a value in an element + assumes case sensitive comparison +*/ +struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el, + struct ldb_val *val) +{ + unsigned int i; + for (i=0;inum_values;i++) { + if (ldb_val_equal_exact(val, &el->values[i])) { + return &el->values[i]; + } + } + return NULL; +} + +/* + duplicate a ldb_val structure +*/ +struct ldb_val ldb_val_dup(void *mem_ctx, const struct ldb_val *v) +{ + struct ldb_val v2; + v2.length = v->length; + if (v->data == NULL) { + v2.data = NULL; + return v2; + } + + /* the +1 is to cope with buggy C library routines like strndup + that look one byte beyond */ + v2.data = talloc_array(mem_ctx, uint8_t, v->length+1); + if (!v2.data) { + v2.length = 0; + return v2; + } + + memcpy(v2.data, v->data, v->length); + ((char *)v2.data)[v->length] = 0; + return v2; +} + +/* + add an empty element to a message +*/ +int ldb_msg_add_empty(struct ldb_message *msg, const char *attr_name, int flags) +{ + struct ldb_message_element *els; + + if (! ldb_valid_attr_name(attr_name)) { + return LDB_ERR_OPERATIONS_ERROR; + } + + els = talloc_realloc(msg, msg->elements, + struct ldb_message_element, msg->num_elements+1); + if (!els) { + errno = ENOMEM; + return LDB_ERR_OPERATIONS_ERROR; + } + + els[msg->num_elements].values = NULL; + els[msg->num_elements].num_values = 0; + els[msg->num_elements].flags = flags; + els[msg->num_elements].name = talloc_strdup(els, attr_name); + if (!els[msg->num_elements].name) { + errno = ENOMEM; + return LDB_ERR_OPERATIONS_ERROR; + } + + msg->elements = els; + msg->num_elements++; + + return LDB_SUCCESS; +} + +/* + add an empty element to a message +*/ +int ldb_msg_add(struct ldb_message *msg, + const struct ldb_message_element *el, + int flags) +{ + if (ldb_msg_add_empty(msg, el->name, flags) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + msg->elements[msg->num_elements-1] = *el; + msg->elements[msg->num_elements-1].flags = flags; + + return LDB_SUCCESS; +} + +/* + add a value to a message +*/ +int ldb_msg_add_value(struct ldb_message *msg, + const char *attr_name, + const struct ldb_val *val) +{ + struct ldb_message_element *el; + struct ldb_val *vals; + + el = ldb_msg_find_element(msg, attr_name); + if (!el) { + ldb_msg_add_empty(msg, attr_name, 0); + el = ldb_msg_find_element(msg, attr_name); + } + if (!el) { + return LDB_ERR_OPERATIONS_ERROR; + } + + vals = talloc_realloc(msg, el->values, struct ldb_val, el->num_values+1); + if (!vals) { + errno = ENOMEM; + return LDB_ERR_OPERATIONS_ERROR; + } + el->values = vals; + el->values[el->num_values] = *val; + el->num_values++; + + return LDB_SUCCESS; +} + + +/* + add a value to a message, stealing it into the 'right' place +*/ +int ldb_msg_add_steal_value(struct ldb_message *msg, + const char *attr_name, + struct ldb_val *val) +{ + int ret; + ret = ldb_msg_add_value(msg, attr_name, val); + if (ret == LDB_SUCCESS) { + struct ldb_message_element *el; + el = ldb_msg_find_element(msg, attr_name); + talloc_steal(el->values, val->data); + } + return ret; +} + + +/* + add a string element to a message +*/ +int ldb_msg_add_string(struct ldb_message *msg, + const char *attr_name, const char *str) +{ + struct ldb_val val; + + val.data = discard_const_p(uint8_t, str); + val.length = strlen(str); + + return ldb_msg_add_value(msg, attr_name, &val); +} + +/* + add a string element to a message, stealing it into the 'right' place +*/ +int ldb_msg_add_steal_string(struct ldb_message *msg, + const char *attr_name, char *str) +{ + struct ldb_val val; + + val.data = (uint8_t *)str; + val.length = strlen(str); + + return ldb_msg_add_steal_value(msg, attr_name, &val); +} + +/* + add a printf formatted element to a message +*/ +int ldb_msg_add_fmt(struct ldb_message *msg, + const char *attr_name, const char *fmt, ...) +{ + struct ldb_val val; + va_list ap; + char *str; + + va_start(ap, fmt); + str = talloc_vasprintf(msg, fmt, ap); + va_end(ap); + + if (str == NULL) return LDB_ERR_OPERATIONS_ERROR; + + val.data = (uint8_t *)str; + val.length = strlen(str); + + return ldb_msg_add_steal_value(msg, attr_name, &val); +} + +/* + compare two ldb_message_element structures + assumes case senistive comparison +*/ +int ldb_msg_element_compare(struct ldb_message_element *el1, + struct ldb_message_element *el2) +{ + unsigned int i; + + if (el1->num_values != el2->num_values) { + return el1->num_values - el2->num_values; + } + + for (i=0;inum_values;i++) { + if (!ldb_msg_find_val(el2, &el1->values[i])) { + return -1; + } + } + + return 0; +} + +/* + compare two ldb_message_element structures + comparing by element name +*/ +int ldb_msg_element_compare_name(struct ldb_message_element *el1, + struct ldb_message_element *el2) +{ + return ldb_attr_cmp(el1->name, el2->name); +} + +/* + convenience functions to return common types from a message + these return the first value if the attribute is multi-valued +*/ +const struct ldb_val *ldb_msg_find_ldb_val(const struct ldb_message *msg, const char *attr_name) +{ + struct ldb_message_element *el = ldb_msg_find_element(msg, attr_name); + if (!el || el->num_values == 0) { + return NULL; + } + return &el->values[0]; +} + +int ldb_msg_find_attr_as_int(const struct ldb_message *msg, + const char *attr_name, + int default_value) +{ + const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + if (!v || !v->data) { + return default_value; + } + return strtol((const char *)v->data, NULL, 0); +} + +unsigned int ldb_msg_find_attr_as_uint(const struct ldb_message *msg, + const char *attr_name, + unsigned int default_value) +{ + const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + if (!v || !v->data) { + return default_value; + } + return strtoul((const char *)v->data, NULL, 0); +} + +int64_t ldb_msg_find_attr_as_int64(const struct ldb_message *msg, + const char *attr_name, + int64_t default_value) +{ + const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + if (!v || !v->data) { + return default_value; + } + return strtoll((const char *)v->data, NULL, 0); +} + +uint64_t ldb_msg_find_attr_as_uint64(const struct ldb_message *msg, + const char *attr_name, + uint64_t default_value) +{ + const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + if (!v || !v->data) { + return default_value; + } + return strtoull((const char *)v->data, NULL, 0); +} + +double ldb_msg_find_attr_as_double(const struct ldb_message *msg, + const char *attr_name, + double default_value) +{ + const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + if (!v || !v->data) { + return default_value; + } + return strtod((const char *)v->data, NULL); +} + +int ldb_msg_find_attr_as_bool(const struct ldb_message *msg, + const char *attr_name, + int default_value) +{ + const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + if (!v || !v->data) { + return default_value; + } + if (strcasecmp((const char *)v->data, "FALSE") == 0) { + return 0; + } + if (strcasecmp((const char *)v->data, "TRUE") == 0) { + return 1; + } + return default_value; +} + +const char *ldb_msg_find_attr_as_string(const struct ldb_message *msg, + const char *attr_name, + const char *default_value) +{ + const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + if (!v || !v->data) { + return default_value; + } + return (const char *)v->data; +} + +struct ldb_dn *ldb_msg_find_attr_as_dn(void *mem_ctx, + const struct ldb_message *msg, + const char *attr_name) +{ + const struct ldb_val *v; + + v = ldb_msg_find_ldb_val(msg, attr_name); + if (!v || !v->data) { + return NULL; + } + return ldb_dn_explode(mem_ctx, (const char *)v->data); +} + +/* + sort the elements of a message by name +*/ +void ldb_msg_sort_elements(struct ldb_message *msg) +{ + qsort(msg->elements, msg->num_elements, sizeof(struct ldb_message_element), + (comparison_fn_t)ldb_msg_element_compare_name); +} + +/* + shallow copy a message - copying only the elements array so that the caller + can safely add new elements without changing the message +*/ +struct ldb_message *ldb_msg_copy_shallow(TALLOC_CTX *mem_ctx, + const struct ldb_message *msg) +{ + struct ldb_message *msg2; + int i; + + msg2 = talloc(mem_ctx, struct ldb_message); + if (msg2 == NULL) return NULL; + + *msg2 = *msg; + msg2->private_data = NULL; + + msg2->elements = talloc_array(msg2, struct ldb_message_element, + msg2->num_elements); + if (msg2->elements == NULL) goto failed; + + for (i=0;inum_elements;i++) { + msg2->elements[i] = msg->elements[i]; + } + + return msg2; + +failed: + talloc_free(msg2); + return NULL; +} + + +/* + copy a message, allocating new memory for all parts +*/ +struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx, + const struct ldb_message *msg) +{ + struct ldb_message *msg2; + int i, j; + + msg2 = ldb_msg_copy_shallow(mem_ctx, msg); + if (msg2 == NULL) return NULL; + + msg2->dn = ldb_dn_copy(msg2, msg2->dn); + if (msg2->dn == NULL) goto failed; + + for (i=0;inum_elements;i++) { + struct ldb_message_element *el = &msg2->elements[i]; + struct ldb_val *values = el->values; + el->name = talloc_strdup(msg2->elements, el->name); + if (el->name == NULL) goto failed; + el->values = talloc_array(msg2->elements, struct ldb_val, el->num_values); + for (j=0;jnum_values;j++) { + el->values[j] = ldb_val_dup(el->values, &values[j]); + if (el->values[j].data == NULL && values[j].length != 0) { + goto failed; + } + } + } + + return msg2; + +failed: + talloc_free(msg2); + return NULL; +} + + +/* + canonicalise a message, merging elements of the same name +*/ +struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, + const struct ldb_message *msg) +{ + int i; + struct ldb_message *msg2; + + msg2 = ldb_msg_copy(ldb, msg); + if (msg2 == NULL) return NULL; + + ldb_msg_sort_elements(msg2); + + for (i=1;inum_elements;i++) { + struct ldb_message_element *el1 = &msg2->elements[i-1]; + struct ldb_message_element *el2 = &msg2->elements[i]; + if (ldb_msg_element_compare_name(el1, el2) == 0) { + el1->values = talloc_realloc(msg2->elements, el1->values, struct ldb_val, + el1->num_values + el2->num_values); + if (el1->values == NULL) { + return NULL; + } + memcpy(el1->values + el1->num_values, + el2->values, + sizeof(struct ldb_val) * el2->num_values); + el1->num_values += el2->num_values; + talloc_free(discard_const_p(char, el2->name)); + if (i+1num_elements) { + memmove(el2, el2+1, sizeof(struct ldb_message_element) * + (msg2->num_elements - (i+1))); + } + msg2->num_elements--; + i--; + } + } + + return msg2; +} + + +/* + return a ldb_message representing the differences between msg1 and msg2. If you + then use this in a ldb_modify() call it can be used to save edits to a message +*/ +struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, + struct ldb_message *msg1, + struct ldb_message *msg2) +{ + struct ldb_message *mod; + struct ldb_message_element *el; + unsigned int i; + + mod = ldb_msg_new(ldb); + + mod->dn = msg1->dn; + mod->num_elements = 0; + mod->elements = NULL; + + msg2 = ldb_msg_canonicalize(ldb, msg2); + if (msg2 == NULL) { + return NULL; + } + + /* look in msg2 to find elements that need to be added + or modified */ + for (i=0;inum_elements;i++) { + el = ldb_msg_find_element(msg1, msg2->elements[i].name); + + if (el && ldb_msg_element_compare(el, &msg2->elements[i]) == 0) { + continue; + } + + if (ldb_msg_add(mod, + &msg2->elements[i], + el?LDB_FLAG_MOD_REPLACE:LDB_FLAG_MOD_ADD) != 0) { + return NULL; + } + } + + /* look in msg1 to find elements that need to be deleted */ + for (i=0;inum_elements;i++) { + el = ldb_msg_find_element(msg2, msg1->elements[i].name); + if (!el) { + if (ldb_msg_add_empty(mod, + msg1->elements[i].name, + LDB_FLAG_MOD_DELETE) != 0) { + return NULL; + } + } + } + + return mod; +} + +int ldb_msg_sanity_check(struct ldb_context *ldb, + const struct ldb_message *msg) +{ + int i, j; + + /* basic check on DN */ + if (msg->dn == NULL) { + /* TODO: return also an error string */ + ldb_set_errstring(ldb, "ldb message lacks a DN!"); + return LDB_ERR_INVALID_DN_SYNTAX; + } + if (msg->dn->comp_num == 0) { + /* root dse has empty dn */ + ldb_set_errstring(ldb, "DN on new ldb message is '' (not permitted)!"); + return LDB_ERR_ENTRY_ALREADY_EXISTS; + } + + /* basic syntax checks */ + for (i = 0; i < msg->num_elements; i++) { + for (j = 0; j < msg->elements[i].num_values; j++) { + if (msg->elements[i].values[j].length == 0) { + TALLOC_CTX *mem_ctx = talloc_new(ldb); + /* an attribute cannot be empty */ + /* TODO: return also an error string */ + ldb_asprintf_errstring(ldb, "Element %s has empty attribute in ldb message (%s)!", + msg->elements[i].name, + ldb_dn_linearize(mem_ctx, msg->dn)); + talloc_free(mem_ctx); + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + } + } + + return LDB_SUCCESS; +} + + + + +/* + copy an attribute list. This only copies the array, not the elements + (ie. the elements are left as the same pointers) +*/ +const char **ldb_attr_list_copy(TALLOC_CTX *mem_ctx, const char * const *attrs) +{ + const char **ret; + int i; + for (i=0;attrs[i];i++) /* noop */ ; + ret = talloc_array(mem_ctx, const char *, i+1); + if (ret == NULL) { + return NULL; + } + for (i=0;attrs[i];i++) { + ret[i] = attrs[i]; + } + ret[i] = attrs[i]; + return ret; +} + + +/* + copy an attribute list. This only copies the array, not the elements + (ie. the elements are left as the same pointers) +*/ +const char **ldb_attr_list_copy_add(TALLOC_CTX *mem_ctx, const char * const *attrs, const char *new_attr) +{ + const char **ret; + int i; + for (i=0;attrs[i];i++) /* noop */ ; + ret = talloc_array(mem_ctx, const char *, i+2); + if (ret == NULL) { + return NULL; + } + for (i=0;attrs[i];i++) { + ret[i] = attrs[i]; + } + ret[i] = new_attr; + ret[i+1] = NULL; + return ret; +} + + +/* + return 1 if an attribute is in a list of attributes, or 0 otherwise +*/ +int ldb_attr_in_list(const char * const *attrs, const char *attr) +{ + int i; + for (i=0;attrs[i];i++) { + if (ldb_attr_cmp(attrs[i], attr) == 0) { + return 1; + } + } + return 0; +} + + +/* + rename the specified attribute in a search result +*/ +int ldb_msg_rename_attr(struct ldb_message *msg, const char *attr, const char *replace) +{ + struct ldb_message_element *el = ldb_msg_find_element(msg, attr); + if (el == NULL) { + return LDB_SUCCESS; + } + el->name = talloc_strdup(msg->elements, replace); + if (el->name == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + return LDB_SUCCESS; +} + + +/* + copy the specified attribute in a search result to a new attribute +*/ +int ldb_msg_copy_attr(struct ldb_message *msg, const char *attr, const char *replace) +{ + struct ldb_message_element *el = ldb_msg_find_element(msg, attr); + if (el == NULL) { + return LDB_SUCCESS; + } + if (ldb_msg_add(msg, el, 0) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + return ldb_msg_rename_attr(msg, attr, replace); +} + + +/* + remove the specified attribute in a search result +*/ +void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr) +{ + struct ldb_message_element *el = ldb_msg_find_element(msg, attr); + if (el) { + int n = (el - msg->elements); + if (n != msg->num_elements-1) { + memmove(el, el+1, ((msg->num_elements-1) - n)*sizeof(*el)); + } + msg->num_elements--; + } +} + +/* + return a LDAP formatted time string +*/ +char *ldb_timestring(TALLOC_CTX *mem_ctx, time_t t) +{ + struct tm *tm = gmtime(&t); + + if (!tm) { + return NULL; + } + + /* formatted like: 20040408072012.0Z */ + return talloc_asprintf(mem_ctx, + "%04u%02u%02u%02u%02u%02u.0Z", + tm->tm_year+1900, tm->tm_mon+1, + tm->tm_mday, tm->tm_hour, tm->tm_min, + tm->tm_sec); +} + + +/* + convert a LDAP time string to a time_t. Return 0 if unable to convert +*/ +time_t ldb_string_to_time(const char *s) +{ + struct tm tm; + + if (s == NULL) return 0; + + memset(&tm, 0, sizeof(tm)); + if (sscanf(s, "%04u%02u%02u%02u%02u%02u", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, + &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { + return 0; + } + tm.tm_year -= 1900; + tm.tm_mon -= 1; + + return timegm(&tm); +} + + +/* + dump a set of results to a file. Useful from within gdb +*/ +void ldb_dump_results(struct ldb_context *ldb, struct ldb_result *result, FILE *f) +{ + int i; + + for (i = 0; i < result->count; i++) { + struct ldb_ldif ldif; + fprintf(f, "# record %d\n", i+1); + ldif.changetype = LDB_CHANGETYPE_NONE; + ldif.msg = result->msgs[i]; + ldb_ldif_write_file(ldb, f, &ldif); + } +} + +int ldb_msg_check_string_attribute(const struct ldb_message *msg, const char *name, const char *value) +{ + struct ldb_message_element *el; + struct ldb_val val; + + el = ldb_msg_find_element(msg, name); + if (el == NULL) + return 0; + + val.data = discard_const(value); + val.length = strlen(value); + + if (ldb_msg_find_val(el, &val)) + return 1; + + return 0; +} -- cgit From 45c0a4874bcfc25f6ab28531d771ba0198191bbe Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 26 Sep 2006 01:21:34 +0000 Subject: r18910: Change ldb_msg_add_string() to not actually add an attribute if the string is zero length. This allows callers to not have to worry about creating an invalid ldap attribute. See extensive discussion on samba-technical list :-) (This used to be commit 9e66df05a4df3d3c7b02048d80e2661103d1d40a) --- source3/lib/ldb/common/ldb_msg.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/lib/ldb/common/ldb_msg.c') diff --git a/source3/lib/ldb/common/ldb_msg.c b/source3/lib/ldb/common/ldb_msg.c index 52c6b82484..a4ba045669 100644 --- a/source3/lib/ldb/common/ldb_msg.c +++ b/source3/lib/ldb/common/ldb_msg.c @@ -227,6 +227,11 @@ int ldb_msg_add_string(struct ldb_message *msg, val.data = discard_const_p(uint8_t, str); val.length = strlen(str); + if (val.length == 0) { + /* allow empty strings as non-existant attributes */ + return 0; + } + return ldb_msg_add_value(msg, attr_name, &val); } -- cgit From fd1cf23567566b65cdeecdbc04f58f29e29edd79 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 6 Oct 2006 14:39:47 +0000 Subject: r19132: Fix some C++ warnings. Is there interest to have them in Samba4 as well? I have some problems resolving the last 3 ones in attrib_handlers.c. In line 251 the function ldb_dn_explode_casefold is called with mem_ctx as the first argument. Looking at ldb_dn_explode_casefold I see that the first argument it expects is a struct ldb_context. I could certainly add a cast to (struct ldb_context *) to that call, but I would assume that this is the wrong fix. Is it possible that attrib_handlers.c:251 and :254 should have ldb and not mem_ctx as the first argument? Can anybody from Samba4 clarify this for me and apply the correct fix? Thanks a lot. Volker (This used to be commit 26f2cb71ebf00b2c6f356da5f32384f7fa083521) --- source3/lib/ldb/common/ldb_msg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/ldb/common/ldb_msg.c') diff --git a/source3/lib/ldb/common/ldb_msg.c b/source3/lib/ldb/common/ldb_msg.c index a4ba045669..f6fbb04afb 100644 --- a/source3/lib/ldb/common/ldb_msg.c +++ b/source3/lib/ldb/common/ldb_msg.c @@ -797,7 +797,7 @@ int ldb_msg_check_string_attribute(const struct ldb_message *msg, const char *na if (el == NULL) return 0; - val.data = discard_const(value); + val.data = (uint8_t *)discard_const(value); val.length = strlen(value); if (ldb_msg_find_val(el, &val)) -- cgit From a6e45f0da5b7a187f652fb80d172007d36a5e855 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 6 Oct 2006 15:17:02 +0000 Subject: r19137: that looks nicer:-) metze (This used to be commit db40552d9471f4a8ce2c5c724319a4eb242ed24a) --- source3/lib/ldb/common/ldb_msg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/ldb/common/ldb_msg.c') diff --git a/source3/lib/ldb/common/ldb_msg.c b/source3/lib/ldb/common/ldb_msg.c index f6fbb04afb..809d965745 100644 --- a/source3/lib/ldb/common/ldb_msg.c +++ b/source3/lib/ldb/common/ldb_msg.c @@ -797,7 +797,7 @@ int ldb_msg_check_string_attribute(const struct ldb_message *msg, const char *na if (el == NULL) return 0; - val.data = (uint8_t *)discard_const(value); + val.data = discard_const_p(uint8_t, value); val.length = strlen(value); if (ldb_msg_find_val(el, &val)) -- cgit From 25e233db5768f3dd90a87c5986dedbd75c2e439d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 9 Oct 2006 08:22:59 +0000 Subject: r19190: merge from samba4: remove wrong check and statement. to manipulate rootDSE we use ldb_dn_new() as base and that has 0 elements. metze (This used to be commit b81cae4180452d2a14c445392fd828032e6eddec) --- source3/lib/ldb/common/ldb_msg.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'source3/lib/ldb/common/ldb_msg.c') diff --git a/source3/lib/ldb/common/ldb_msg.c b/source3/lib/ldb/common/ldb_msg.c index 809d965745..7e001f9180 100644 --- a/source3/lib/ldb/common/ldb_msg.c +++ b/source3/lib/ldb/common/ldb_msg.c @@ -229,7 +229,7 @@ int ldb_msg_add_string(struct ldb_message *msg, if (val.length == 0) { /* allow empty strings as non-existant attributes */ - return 0; + return LDB_SUCCESS; } return ldb_msg_add_value(msg, attr_name, &val); @@ -596,11 +596,6 @@ int ldb_msg_sanity_check(struct ldb_context *ldb, ldb_set_errstring(ldb, "ldb message lacks a DN!"); return LDB_ERR_INVALID_DN_SYNTAX; } - if (msg->dn->comp_num == 0) { - /* root dse has empty dn */ - ldb_set_errstring(ldb, "DN on new ldb message is '' (not permitted)!"); - return LDB_ERR_ENTRY_ALREADY_EXISTS; - } /* basic syntax checks */ for (i = 0; i < msg->num_elements; i++) { -- cgit From 3a22bdf89ee71a72dc3e84aee6e1d10474b8852b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 24 Oct 2006 20:20:39 +0000 Subject: r19486: Probably Coverity is wrong here, but this fixes their ID 317. Not sure whether to merge it to 4_0. I want it in 3_0 because it took a bit to persuade myself that el can not be NULL here. Volker (This used to be commit c0c035b1c8b9d80cd205cde16ad3e838e2d44459) --- source3/lib/ldb/common/ldb_msg.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/lib/ldb/common/ldb_msg.c') diff --git a/source3/lib/ldb/common/ldb_msg.c b/source3/lib/ldb/common/ldb_msg.c index 7e001f9180..0d9cb47882 100644 --- a/source3/lib/ldb/common/ldb_msg.c +++ b/source3/lib/ldb/common/ldb_msg.c @@ -209,7 +209,9 @@ int ldb_msg_add_steal_value(struct ldb_message *msg, ret = ldb_msg_add_value(msg, attr_name, val); if (ret == LDB_SUCCESS) { struct ldb_message_element *el; - el = ldb_msg_find_element(msg, attr_name); + if (!(el = ldb_msg_find_element(msg, attr_name))) { + return LDB_ERR_OPERATIONS_ERROR; + } talloc_steal(el->values, val->data); } return ret; -- cgit From 151237477bef0d8fdcf926fa0fbe048580a58be5 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 25 Oct 2006 02:06:05 +0000 Subject: r19491: backport changes from samba4 (This used to be commit aa464c9fda978f615230241921f83884a60f4c6f) --- source3/lib/ldb/common/ldb_msg.c | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) (limited to 'source3/lib/ldb/common/ldb_msg.c') diff --git a/source3/lib/ldb/common/ldb_msg.c b/source3/lib/ldb/common/ldb_msg.c index 0d9cb47882..46ab721e2e 100644 --- a/source3/lib/ldb/common/ldb_msg.c +++ b/source3/lib/ldb/common/ldb_msg.c @@ -119,7 +119,10 @@ struct ldb_val ldb_val_dup(void *mem_ctx, const struct ldb_val *v) /* add an empty element to a message */ -int ldb_msg_add_empty(struct ldb_message *msg, const char *attr_name, int flags) +int ldb_msg_add_empty(struct ldb_message *msg, + const char *attr_name, + int flags, + struct ldb_message_element **return_el) { struct ldb_message_element *els; @@ -146,6 +149,10 @@ int ldb_msg_add_empty(struct ldb_message *msg, const char *attr_name, int flags) msg->elements = els; msg->num_elements++; + if (return_el) { + *return_el = &els[msg->num_elements-1]; + } + return LDB_SUCCESS; } @@ -156,7 +163,7 @@ int ldb_msg_add(struct ldb_message *msg, const struct ldb_message_element *el, int flags) { - if (ldb_msg_add_empty(msg, el->name, flags) != 0) { + if (ldb_msg_add_empty(msg, el->name, flags, NULL) != 0) { return LDB_ERR_OPERATIONS_ERROR; } @@ -171,18 +178,19 @@ int ldb_msg_add(struct ldb_message *msg, */ int ldb_msg_add_value(struct ldb_message *msg, const char *attr_name, - const struct ldb_val *val) + const struct ldb_val *val, + struct ldb_message_element **return_el) { struct ldb_message_element *el; struct ldb_val *vals; + int ret; el = ldb_msg_find_element(msg, attr_name); if (!el) { - ldb_msg_add_empty(msg, attr_name, 0); - el = ldb_msg_find_element(msg, attr_name); - } - if (!el) { - return LDB_ERR_OPERATIONS_ERROR; + ret = ldb_msg_add_empty(msg, attr_name, 0, &el); + if (ret != LDB_SUCCESS) { + return ret; + } } vals = talloc_realloc(msg, el->values, struct ldb_val, el->num_values+1); @@ -194,6 +202,10 @@ int ldb_msg_add_value(struct ldb_message *msg, el->values[el->num_values] = *val; el->num_values++; + if (return_el) { + *return_el = el; + } + return LDB_SUCCESS; } @@ -206,12 +218,10 @@ int ldb_msg_add_steal_value(struct ldb_message *msg, struct ldb_val *val) { int ret; - ret = ldb_msg_add_value(msg, attr_name, val); + struct ldb_message_element *el; + + ret = ldb_msg_add_value(msg, attr_name, val, &el); if (ret == LDB_SUCCESS) { - struct ldb_message_element *el; - if (!(el = ldb_msg_find_element(msg, attr_name))) { - return LDB_ERR_OPERATIONS_ERROR; - } talloc_steal(el->values, val->data); } return ret; @@ -234,7 +244,7 @@ int ldb_msg_add_string(struct ldb_message *msg, return LDB_SUCCESS; } - return ldb_msg_add_value(msg, attr_name, &val); + return ldb_msg_add_value(msg, attr_name, &val, NULL); } /* @@ -578,7 +588,7 @@ struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, if (!el) { if (ldb_msg_add_empty(mod, msg1->elements[i].name, - LDB_FLAG_MOD_DELETE) != 0) { + LDB_FLAG_MOD_DELETE, NULL) != 0) { return NULL; } } -- cgit From 866a3b6e40952193d5bcd812ec7079cf7434e600 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Nov 2006 17:34:20 +0000 Subject: r19725: sync samba3's ldb with samba4 metze (This used to be commit 207643e9c9c75546f38a09f12ea0b574b08086c5) --- source3/lib/ldb/common/ldb_msg.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/lib/ldb/common/ldb_msg.c') diff --git a/source3/lib/ldb/common/ldb_msg.c b/source3/lib/ldb/common/ldb_msg.c index 46ab721e2e..9cb4cf5ed0 100644 --- a/source3/lib/ldb/common/ldb_msg.c +++ b/source3/lib/ldb/common/ldb_msg.c @@ -119,10 +119,10 @@ struct ldb_val ldb_val_dup(void *mem_ctx, const struct ldb_val *v) /* add an empty element to a message */ -int ldb_msg_add_empty(struct ldb_message *msg, - const char *attr_name, - int flags, - struct ldb_message_element **return_el) +int ldb_msg_add_empty( struct ldb_message *msg, + const char *attr_name, + int flags, + struct ldb_message_element **return_el) { struct ldb_message_element *els; -- cgit From 9e7e5938abd9d542966a54374ca652679f42e8ee Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Nov 2006 11:18:05 +0000 Subject: r19744: merge from samba4 metze (This used to be commit fe61e6ebf7d771ce6441198bf2e330d53bf7b10e) --- source3/lib/ldb/common/ldb_msg.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'source3/lib/ldb/common/ldb_msg.c') diff --git a/source3/lib/ldb/common/ldb_msg.c b/source3/lib/ldb/common/ldb_msg.c index 9cb4cf5ed0..65d1ecacb7 100644 --- a/source3/lib/ldb/common/ldb_msg.c +++ b/source3/lib/ldb/common/ldb_msg.c @@ -654,7 +654,7 @@ const char **ldb_attr_list_copy(TALLOC_CTX *mem_ctx, const char * const *attrs) /* copy an attribute list. This only copies the array, not the elements - (ie. the elements are left as the same pointers) + (ie. the elements are left as the same pointers). The new attribute is added to the list. */ const char **ldb_attr_list_copy_add(TALLOC_CTX *mem_ctx, const char * const *attrs, const char *new_attr) { @@ -737,6 +737,18 @@ void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr) } } +/* + remove the specified element in a search result +*/ +void ldb_msg_remove_element(struct ldb_message *msg, struct ldb_message_element *el) +{ + int n = (el - msg->elements); + if (n != msg->num_elements-1) { + memmove(el, el+1, ((msg->num_elements-1) - n)*sizeof(*el)); + } + msg->num_elements--; +} + /* return a LDAP formatted time string */ -- cgit From e59e787b4868acffad49b6264e319d585643d5ab Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Wed, 20 Dec 2006 01:10:04 +0000 Subject: r20269: merge -r20264:20267 from SAMBA_3_0_24 more no previous prototype warnings (This used to be commit 41be182f78762372ae13759ede5d2bd40a71d7f5) --- source3/lib/ldb/common/ldb_msg.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/lib/ldb/common/ldb_msg.c') diff --git a/source3/lib/ldb/common/ldb_msg.c b/source3/lib/ldb/common/ldb_msg.c index 65d1ecacb7..bf217d2787 100644 --- a/source3/lib/ldb/common/ldb_msg.c +++ b/source3/lib/ldb/common/ldb_msg.c @@ -35,6 +35,10 @@ #include "includes.h" #include "ldb/include/includes.h" +void ldb_dump_results(struct ldb_context *ldb, struct ldb_result *result, FILE *f); +int ldb_msg_element_compare_name(struct ldb_message_element *el1, + struct ldb_message_element *el2); + /* create a new ldb_message in a given memory context (NULL for top level) */ -- cgit From 2c09988e46d4e917b1c53c9bda3f81a48bba4952 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 01:44:42 +0000 Subject: r23790: LGPLv3+ conversion for our LGPLv2+ library code (This used to be commit 1b78cace504f60c0f525765fbf59d9cc6506cd4d) --- source3/lib/ldb/common/ldb_msg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/ldb/common/ldb_msg.c') diff --git a/source3/lib/ldb/common/ldb_msg.c b/source3/lib/ldb/common/ldb_msg.c index bf217d2787..cd79779ddc 100644 --- a/source3/lib/ldb/common/ldb_msg.c +++ b/source3/lib/ldb/common/ldb_msg.c @@ -10,7 +10,7 @@ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. + version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -- cgit From 9fa1c63578733077c0aaaeeb2fc97c3b191089cc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 03:42:26 +0000 Subject: r23798: updated old Temple Place FSF addresses to new URL (This used to be commit c676a971142d7176fd5dbf21405fca14515a0a76) --- source3/lib/ldb/common/ldb_msg.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/lib/ldb/common/ldb_msg.c') diff --git a/source3/lib/ldb/common/ldb_msg.c b/source3/lib/ldb/common/ldb_msg.c index cd79779ddc..a8a6e93f12 100644 --- a/source3/lib/ldb/common/ldb_msg.c +++ b/source3/lib/ldb/common/ldb_msg.c @@ -18,8 +18,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + License along with this library; if not, see . */ /* -- cgit