r574: - another attempt at const cleanliness in ldb
authorAndrew Tridgell <tridge@samba.org>
Fri, 7 May 2004 23:54:41 +0000 (23:54 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:51:47 +0000 (12:51 -0500)
 - 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)

13 files changed:
source4/lib/ldb/common/ldb.c
source4/lib/ldb/common/ldb_msg.c
source4/lib/ldb/common/ldb_parse.c
source4/lib/ldb/include/ldb.h
source4/lib/ldb/ldb_ldap/ldb_ldap.c
source4/lib/ldb/ldb_tdb/ldb_index.c
source4/lib/ldb/ldb_tdb/ldb_search.c
source4/lib/ldb/ldb_tdb/ldb_tdb.c
source4/lib/ldb/tests/test-modify.ldif
source4/lib/ldb/tools/ldbedit.c
source4/lib/ldb/tools/ldbmodify.c
source4/lib/ldb/tools/ldbsearch.c
source4/lib/ldb/tools/ldbtest.c

index b8f61e017ac5193809618ebbb87f78f50bf5c3a0..c6e8d3767110a03fe1edff2256832cffdafea3df 100644 (file)
@@ -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);
index 5976db81b6a5a66a3ad1f64139206e32be2a8040..01f32751e130e37f384e32441c541bb89383abf2 100644 (file)
@@ -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
index 75eb44fcc0e867fe1397169fd9bce78b7cf8a377..5d2a42fd20dde8425b683643b493524dddfb6974 100644 (file)
@@ -56,10 +56,12 @@ a filter is defined by:
                <filtertype> ::= '=' | '~=' | '<=' | '>='
 */
 
+#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;
        }
index adb6c31952699834aa2e1ad07d7ffb4f3e4303a6..7215bf5705be4c8175f0d34e368eccdbee66a59f 100644 (file)
@@ -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
index 7e959e7854f3fbbe5935dd8a3b5522b10134519e..d96bfd62d328d634d633d1ef3486c642deea3fe9 100644 (file)
@@ -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;
index 877955a9b79f6779a8a207213d441a7d113614f9..0e9f3e3c55f4702a60af34a565306f3e69ef150b 100644 (file)
@@ -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;
index 5ee4449deeb69029b66d2104bec50b293b71c724..60eaf3117cdfe51ca209b00b54555be2d799ff71 100644 (file)
@@ -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;
index eb28bc4938b1678354b8167b2ca1bf7aa7dc7f8c..09d1618ffcd977796e8841fb7935c9565cc4a343 100644 (file)
@@ -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;
                                }
                        }
index 521c6d8b5680008cd62318c1057fc6f18cf0a744..78d8353d3c44522d39c2d2eddf3b69f77632d929 100644 (file)
@@ -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
index 739c3b6301571300ba21e97ab6d379caa4506e5c..debe06c23192aff49c814dc3078be1c548e0b5b3 100644 (file)
@@ -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);
index 9f7cbe4527bcfa8651fcd7245d396cef26356050..828b7d4865f1f15a852e3547eaed7a9f92e34a61 100644 (file)
@@ -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;
 }
index f80f81b50e8fc82b481cf3f45212d853de729e85..478601ec7eb1196c1079c4318557792c574dd88d 100644 (file)
@@ -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);
index fc224115f57fe64a9db3b4c4d7cec2ea3a0bde8b..d7b4023895521a98c2bdc1121d0fcf81dcba3896 100644 (file)
@@ -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<msg.num_elements;j++) {
+                       free(el[j].name);
+               }
                free(name);
                free(msg.dn);
                free(vals[1][0].data);
                ldb_free(ldb, vals[2][0].data);
                free(vals[3][0].data);
+               free(vals[4][0].data);
        }
 
        printf("\n");
@@ -139,6 +144,7 @@ static void modify_records(struct ldb_context *ldb,
                struct ldb_message_element el[3];
                struct ldb_val vals[3];
                char *name;
+               int j;
                
                asprintf(&name, "Test%d", i);
                asprintf(&msg.dn, "cn=%s,%s", name, basedn);
@@ -147,18 +153,18 @@ static void modify_records(struct ldb_context *ldb,
                msg.elements = el;
 
                el[0].flags = LDB_FLAG_MOD_DELETE;
-               el[0].name = "mail";
+               el[0].name = strdup("mail");
                el[0].num_values = 0;
 
                el[1].flags = LDB_FLAG_MOD_ADD;
-               el[1].name = "mail";
+               el[1].name = strdup("mail");
                el[1].num_values = 1;
                el[1].values = &vals[1];
                asprintf((char **)&vals[1].data, "%s@other.example.com", name);
                vals[1].length = strlen(vals[1].data);
 
                el[2].flags = LDB_FLAG_MOD_REPLACE;
-               el[2].name = "mail";
+               el[2].name = strdup("mail");
                el[2].num_values = 1;
                el[2].values = &vals[2];
                asprintf((char **)&vals[2].data, "%s@other2.example.com", name);
@@ -172,6 +178,9 @@ static void modify_records(struct ldb_context *ldb,
                printf("Modifying uid %s\r", name);
                fflush(stdout);
 
+               for (j=0;j<msg.num_elements;j++) {
+                       free(el[j].name);
+               }
                free(name);
                free(msg.dn);
                free(vals[1].data);