From 265023fafa463c742f89510879acb2a830de8ab9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 7 May 2004 23:54:41 +0000 Subject: r574: - another attempt at const cleanliness in ldb - fixed a problem with searching for values containing an '=' sign - fixed the semantics of attempting an attribute deletion on an attribute that doesn't exist. - added some more ldb_msg_*() utilities (This used to be commit 62b4ec367d170330d837b0f1fe5cd13205a53b59) --- source4/lib/ldb/common/ldb.c | 2 +- source4/lib/ldb/common/ldb_msg.c | 47 ++++++++++++++++++++++++++++++++++ source4/lib/ldb/common/ldb_parse.c | 18 +++++++------ source4/lib/ldb/include/ldb.h | 4 +-- source4/lib/ldb/ldb_ldap/ldb_ldap.c | 2 +- source4/lib/ldb/ldb_tdb/ldb_index.c | 4 +-- source4/lib/ldb/ldb_tdb/ldb_search.c | 12 ++++----- source4/lib/ldb/ldb_tdb/ldb_tdb.c | 10 ++++++-- source4/lib/ldb/tests/test-modify.ldif | 6 +++++ source4/lib/ldb/tools/ldbedit.c | 2 +- source4/lib/ldb/tools/ldbmodify.c | 4 +++ source4/lib/ldb/tools/ldbsearch.c | 6 ++--- source4/lib/ldb/tools/ldbtest.c | 31 ++++++++++++++-------- 13 files changed, 111 insertions(+), 37 deletions(-) (limited to 'source4/lib') diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c index b8f61e017a..c6e8d37671 100644 --- a/source4/lib/ldb/common/ldb.c +++ b/source4/lib/ldb/common/ldb.c @@ -82,7 +82,7 @@ int ldb_search(struct ldb_context *ldb, const char *base, enum ldb_scope scope, const char *expression, - char * const *attrs, struct ldb_message ***res) + const char * const *attrs, struct ldb_message ***res) { int ret; ret = ldb->ops->search(ldb, base, scope, expression, attrs, res); diff --git a/source4/lib/ldb/common/ldb_msg.c b/source4/lib/ldb/common/ldb_msg.c index 5976db81b6..01f32751e1 100644 --- a/source4/lib/ldb/common/ldb_msg.c +++ b/source4/lib/ldb/common/ldb_msg.c @@ -131,6 +131,53 @@ int ldb_msg_add(struct ldb_context *ldb, return 0; } +/* + add a value to a message +*/ +int ldb_msg_add_value(struct ldb_context *ldb, + struct ldb_message *msg, + char *attr_name, + 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(ldb, msg, attr_name, 0); + el = ldb_msg_find_element(msg, attr_name); + } + if (!el) { + return -1; + } + + vals = ldb_realloc_p(ldb, el->values, struct ldb_val, el->num_values+1); + if (!vals) { + errno = ENOMEM; + return -1; + } + el->values = vals; + el->values[el->num_values] = *val; + el->num_values++; + + return 0; +} + + +/* + add a string element to a message +*/ +int ldb_msg_add_string(struct ldb_context *ldb, struct ldb_message *msg, + char *attr_name, char *str) +{ + struct ldb_val val; + + val.data = str; + val.length = strlen(str); + + return ldb_msg_add_value(ldb, msg, attr_name, &val); +} + /* compare two ldb_message_element structures assumes case senistive comparison diff --git a/source4/lib/ldb/common/ldb_parse.c b/source4/lib/ldb/common/ldb_parse.c index 75eb44fcc0..5d2a42fd20 100644 --- a/source4/lib/ldb/common/ldb_parse.c +++ b/source4/lib/ldb/common/ldb_parse.c @@ -56,10 +56,12 @@ a filter is defined by: ::= '=' | '~=' | '<=' | '>=' */ +#define LDB_ALL_SEP "()&|=!" + /* return next token element. Caller frees */ -static char *ldb_parse_lex(struct ldb_context *ldb, const char **s) +static char *ldb_parse_lex(struct ldb_context *ldb, const char **s, const char *sep) { const char *p = *s; char *ret; @@ -73,7 +75,7 @@ static char *ldb_parse_lex(struct ldb_context *ldb, const char **s) return NULL; } - if (strchr("()&|=!", *p)) { + if (strchr(sep, *p)) { (*s) = p+1; ret = ldb_strndup(ldb, p, 1); if (!ret) { @@ -82,7 +84,7 @@ static char *ldb_parse_lex(struct ldb_context *ldb, const char **s) return ret; } - while (*p && (isalnum(*p) || !strchr("()&|=!", *p))) { + while (*p && (isalnum(*p) || !strchr(sep, *p))) { p++; } @@ -132,7 +134,7 @@ static struct ldb_parse_tree *ldb_parse_simple(struct ldb_context *ldb, const ch char *eq, *val, *l; struct ldb_parse_tree *ret; - l = ldb_parse_lex(ldb, &s); + l = ldb_parse_lex(ldb, &s, LDB_ALL_SEP); if (!l) { return NULL; } @@ -142,7 +144,7 @@ static struct ldb_parse_tree *ldb_parse_simple(struct ldb_context *ldb, const ch return NULL; } - eq = ldb_parse_lex(ldb, &s); + eq = ldb_parse_lex(ldb, &s, LDB_ALL_SEP); if (!eq || strcmp(eq, "=") != 0) { ldb_free(ldb, l); if (eq) ldb_free(ldb, eq); @@ -150,8 +152,8 @@ static struct ldb_parse_tree *ldb_parse_simple(struct ldb_context *ldb, const ch } ldb_free(ldb, eq); - val = ldb_parse_lex(ldb, &s); - if (val && strchr("()&|=", *val)) { + val = ldb_parse_lex(ldb, &s, ")"); + if (val && strchr("()&|", *val)) { ldb_free(ldb, l); if (val) ldb_free(ldb, val); return NULL; @@ -288,7 +290,7 @@ static struct ldb_parse_tree *ldb_parse_filter(struct ldb_context *ldb, const ch const char *p, *p2; struct ldb_parse_tree *ret; - l = ldb_parse_lex(ldb, s); + l = ldb_parse_lex(ldb, s, LDB_ALL_SEP); if (!l) { return NULL; } diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h index adb6c31952..7215bf5705 100644 --- a/source4/lib/ldb/include/ldb.h +++ b/source4/lib/ldb/include/ldb.h @@ -129,7 +129,7 @@ typedef int (*ldb_traverse_fn)(struct ldb_context *, const struct ldb_message *) struct ldb_backend_ops { int (*close)(struct ldb_context *); int (*search)(struct ldb_context *, const char *, enum ldb_scope, - const char *, char * const [], struct ldb_message ***); + const char *, const char * const [], struct ldb_message ***); int (*search_free)(struct ldb_context *, struct ldb_message **); int (*add_record)(struct ldb_context *, const struct ldb_message *); int (*modify_record)(struct ldb_context *, const struct ldb_message *); @@ -216,7 +216,7 @@ int ldb_search(struct ldb_context *ldb, const char *base, enum ldb_scope scope, const char *expression, - char * const *attrs, struct ldb_message ***res); + const char * const *attrs, struct ldb_message ***res); /* free a set of messages returned by ldb_search diff --git a/source4/lib/ldb/ldb_ldap/ldb_ldap.c b/source4/lib/ldb/ldb_ldap/ldb_ldap.c index 7e959e7854..d96bfd62d3 100644 --- a/source4/lib/ldb/ldb_ldap/ldb_ldap.c +++ b/source4/lib/ldb/ldb_ldap/ldb_ldap.c @@ -210,7 +210,7 @@ static int lldb_add_msg_attr(struct ldb_context *ldb, */ static int lldb_search(struct ldb_context *ldb, const char *base, enum ldb_scope scope, const char *expression, - char * const *attrs, struct ldb_message ***res) + const char * const *attrs, struct ldb_message ***res) { struct lldb_private *lldb = ldb->private_data; int count, msg_count; diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c index 877955a9b7..0e9f3e3c55 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_index.c +++ b/source4/lib/ldb/ldb_tdb/ldb_index.c @@ -496,7 +496,7 @@ static int ldb_index_filter(struct ldb_context *ldb, struct ldb_parse_tree *tree const char *base, enum ldb_scope scope, const struct dn_list *dn_list, - char * const attrs[], struct ldb_message ***res) + const char * const attrs[], struct ldb_message ***res) { int i; unsigned int count = 0; @@ -536,7 +536,7 @@ int ltdb_search_indexed(struct ldb_context *ldb, const char *base, enum ldb_scope scope, struct ldb_parse_tree *tree, - char * const attrs[], struct ldb_message ***res) + const char * const attrs[], struct ldb_message ***res) { struct ltdb_private *ltdb = ldb->private_data; struct dn_list dn_list; diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c index 5ee4449dee..60eaf3117c 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_search.c +++ b/source4/lib/ldb/ldb_tdb/ldb_search.c @@ -149,7 +149,7 @@ static int msg_add_all_elements(struct ldb_context *ldb, struct ldb_message *ret */ static struct ldb_message *ltdb_pull_attrs(struct ldb_context *ldb, const struct ldb_message *msg, - char * const *attrs) + const char * const *attrs) { struct ldb_message *ret; int i; @@ -304,7 +304,7 @@ int ltdb_search_dn1(struct ldb_context *ldb, const char *dn, struct ldb_message search the database for a single simple dn */ int ltdb_search_dn(struct ldb_context *ldb, char *dn, - char * const attrs[], struct ldb_message ***res) + const char * const attrs[], struct ldb_message ***res) { int ret; struct ldb_message msg, *msg2; @@ -340,7 +340,7 @@ int ltdb_search_dn(struct ldb_context *ldb, char *dn, return 0 on success, -1 on failure */ int ltdb_add_attr_results(struct ldb_context *ldb, struct ldb_message *msg, - char * const attrs[], + const char * const attrs[], unsigned int *count, struct ldb_message ***res) { @@ -378,7 +378,7 @@ struct ltdb_search_info { struct ldb_parse_tree *tree; const char *base; enum ldb_scope scope; - char * const *attrs; + const char * const *attrs; struct ldb_message **msgs; int failures; int count; @@ -458,7 +458,7 @@ static int ltdb_search_full(struct ldb_context *ldb, const char *base, enum ldb_scope scope, struct ldb_parse_tree *tree, - char * const attrs[], struct ldb_message ***res) + const char * const attrs[], struct ldb_message ***res) { struct ltdb_private *ltdb = ldb->private_data; int ret; @@ -491,7 +491,7 @@ static int ltdb_search_full(struct ldb_context *ldb, */ int ltdb_search(struct ldb_context *ldb, const char *base, enum ldb_scope scope, const char *expression, - char * const attrs[], struct ldb_message ***res) + const char * const attrs[], struct ldb_message ***res) { struct ltdb_private *ltdb = ldb->private_data; struct ldb_parse_tree *tree; diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c index eb28bc4938..09d1618ffc 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c @@ -436,10 +436,13 @@ static int msg_delete_element(struct ldb_context *ldb, sizeof(el->values[i])*(el->num_values-(i+1))); } el->num_values--; + if (el->num_values == 0) { + return msg_delete_attribute(ldb, msg, name); + } return 0; } } - + return -1; } @@ -488,7 +491,7 @@ int ltdb_modify_internal(struct ldb_context *ldb, const struct ldb_message *msg) already exists */ ret = find_element(&msg2, msg->elements[i].name); if (ret != -1) { - errno = EEXIST; + ltdb->last_err_string = "Attribute exists"; goto failed; } if (msg_add_element(ldb, &msg2, &msg->elements[i]) != 0) { @@ -500,6 +503,7 @@ int ltdb_modify_internal(struct ldb_context *ldb, const struct ldb_message *msg) /* replace all elements of this attribute name with the elements listed */ if (msg_delete_attribute(ldb, &msg2, msg->elements[i].name) != 0) { + ltdb->last_err_string = "No such attribute"; goto failed; } /* add the replacement element */ @@ -514,6 +518,7 @@ int ltdb_modify_internal(struct ldb_context *ldb, const struct ldb_message *msg) if (msg->elements[i].num_values == 0) { if (msg_delete_attribute(ldb, &msg2, msg->elements[i].name) != 0) { + ltdb->last_err_string = "No such attribute"; goto failed; } break; @@ -523,6 +528,7 @@ int ltdb_modify_internal(struct ldb_context *ldb, const struct ldb_message *msg) &msg2, msg->elements[i].name, &msg->elements[i].values[j]) != 0) { + ltdb->last_err_string = "No such attribute"; goto failed; } } diff --git a/source4/lib/ldb/tests/test-modify.ldif b/source4/lib/ldb/tests/test-modify.ldif index 521c6d8b56..78d8353d3c 100644 --- a/source4/lib/ldb/tests/test-modify.ldif +++ b/source4/lib/ldb/tests/test-modify.ldif @@ -12,3 +12,9 @@ telephonenumber: +61 412 666 929 - delete: telephonenumber telephonenumber: +61 2 6260 6012 +- +delete: telephonenumber +telephonenumber: +61 412 666 929 +- +add: telephonenumber +telephonenumber: +61 412 666 929 diff --git a/source4/lib/ldb/tools/ldbedit.c b/source4/lib/ldb/tools/ldbedit.c index 739c3b6301..debe06c231 100644 --- a/source4/lib/ldb/tools/ldbedit.c +++ b/source4/lib/ldb/tools/ldbedit.c @@ -218,7 +218,7 @@ static int do_edit(struct ldb_context *ldb, struct ldb_message **msgs1, int coun fclose(f); - ldb_asprintf(ldb, &cmd, "%s %s", editor, template); + asprintf(&cmd, "%s %s", editor, template); if (!cmd) { unlink(template); diff --git a/source4/lib/ldb/tools/ldbmodify.c b/source4/lib/ldb/tools/ldbmodify.c index 9f7cbe4527..828b7d4865 100644 --- a/source4/lib/ldb/tools/ldbmodify.c +++ b/source4/lib/ldb/tools/ldbmodify.c @@ -144,6 +144,10 @@ static int process_file(struct ldb_context *ldb, FILE *f) ldb_close(ldb); printf("Modified %d records with %d failures\n", count, failures); + + if (failures != 0) { + return -1; + } return 0; } diff --git a/source4/lib/ldb/tools/ldbsearch.c b/source4/lib/ldb/tools/ldbsearch.c index f80f81b50e..478601ec7e 100644 --- a/source4/lib/ldb/tools/ldbsearch.c +++ b/source4/lib/ldb/tools/ldbsearch.c @@ -49,7 +49,7 @@ static int do_search(struct ldb_context *ldb, const char *basedn, int scope, const char *expression, - char * const *attrs) + const char * const *attrs) { int ret, i; struct ldb_message **msgs; @@ -86,7 +86,7 @@ static int do_search(struct ldb_context *ldb, int main(int argc, char * const argv[]) { struct ldb_context *ldb; - char * const * attrs = NULL; + const char * const * attrs = NULL; const char *ldb_url; const char *basedn = NULL; int opt; @@ -140,7 +140,7 @@ static int do_search(struct ldb_context *ldb, } if (argc > 1) { - attrs = argv+1; + attrs = (const char * const *)(argv+1); } ldb = ldb_connect(ldb_url, 0, NULL); diff --git a/source4/lib/ldb/tools/ldbtest.c b/source4/lib/ldb/tools/ldbtest.c index fc224115f5..d7b4023895 100644 --- a/source4/lib/ldb/tools/ldbtest.c +++ b/source4/lib/ldb/tools/ldbtest.c @@ -59,7 +59,8 @@ static void add_records(struct ldb_context *ldb, struct ldb_message_element el[6]; struct ldb_val vals[6][1]; char *name; - + int j; + asprintf(&name, "Test%d", i); asprintf(&msg.dn, "cn=%s,%s", name, basedn); @@ -67,42 +68,42 @@ static void add_records(struct ldb_context *ldb, msg.elements = el; el[0].flags = 0; - el[0].name = "cn"; + el[0].name = strdup("cn"); el[0].num_values = 1; el[0].values = vals[0]; vals[0][0].data = name; vals[0][0].length = strlen(name); el[1].flags = 0; - el[1].name = "title"; + el[1].name = strdup("title"); el[1].num_values = 1; el[1].values = vals[1]; asprintf((char **)&vals[1][0].data, "The title of %s", name); vals[1][0].length = strlen(vals[1][0].data); el[2].flags = 0; - el[2].name = "uid"; + el[2].name = strdup("uid"); el[2].num_values = 1; el[2].values = vals[2]; vals[2][0].data = ldb_casefold(ldb, name); vals[2][0].length = strlen(vals[2][0].data); el[3].flags = 0; - el[3].name = "mail"; + el[3].name = strdup("mail"); el[3].num_values = 1; el[3].values = vals[3]; asprintf((char **)&vals[3][0].data, "%s@example.com", name); vals[3][0].length = strlen(vals[3][0].data); el[4].flags = 0; - el[4].name = "objectClass"; + el[4].name = strdup("objectClass"); el[4].num_values = 1; el[4].values = vals[4]; - vals[4][0].data = "OpenLDAPperson"; + vals[4][0].data = strdup("OpenLDAPperson"); vals[4][0].length = strlen(vals[4][0].data); el[5].flags = 0; - el[5].name = "sn"; + el[5].name = strdup("sn"); el[5].num_values = 1; el[5].values = vals[5]; vals[5][0].data = name; @@ -118,11 +119,15 @@ static void add_records(struct ldb_context *ldb, printf("adding uid %s\r", name); fflush(stdout); + for (j=0;j