r6867: this code will change the way the @ATTRIBUTES object is handled
authorSimo Sorce <idra@samba.org>
Tue, 17 May 2005 21:43:47 +0000 (21:43 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:16:52 +0000 (13:16 -0500)
this object properties are now used as multivalue attributes
now all values inserted are checked against a "valid values table"

eg:

this form is now accepted:

dn: @ATTRIBUTES
uid: CASE_INSENSITIVE
uid: WILDCARD

this form is now rejected:

dn: @ATTRIBUTES
uid: CASE_INSENSITIVE WILDCARD

please update your .ldb files if you make use of @ATTRIBUTES
(sam.ldb heavily uses it)

the code passes all make test tests for both tdb and ldap, it also
passes the new test to check for wrong @ATTRIBUTES attribute values

Simo.

source/lib/ldb/ldb_tdb/ldb_cache.c
source/lib/ldb/ldb_tdb/ldb_tdb.c
source/lib/ldb/ldb_tdb/ldb_tdb.h
source/lib/ldb/tests/schema-tests/schema.ldif
source/lib/ldb/tests/test-attribs.ldif
source/lib/ldb/tests/test-generic.sh
source/lib/ldb/tests/test-index.ldif
source/lib/ldb/tests/test-wrong_attributes.ldif [new file with mode: 0644]

index ec22aca3eca7ea556e28f94b4f1eed90a770edfa..0fe573a829bbfb3ef58b2e2e7d22dec667cf2d7e 100644 (file)
 #include "ldb/include/ldb_private.h"
 #include "ldb/ldb_tdb/ldb_tdb.h"
 
+
+/* valid attribute flags */
+static const struct {
+       const char *name;
+       int value;
+} ltdb_valid_attr_flags[] = {
+       { "CASE_INSENSITIVE", LTDB_FLAG_CASE_INSENSITIVE },
+       { "INTEGER", LTDB_FLAG_INTEGER },
+       { "WILDCARD", LTDB_FLAG_WILDCARD },
+       { "HIDDEN", LTDB_FLAG_HIDDEN },
+       { "NONE", LTDB_FLAG_NONE },
+       { NULL, 0 }
+};
+
+
 /*
   initialise the baseinfo record
 */
@@ -245,18 +260,7 @@ int ltdb_increase_sequence_number(struct ldb_module *module)
 int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name)
 {
        struct ltdb_private *ltdb = module->private_data;
-       const char *attrs;
-       const struct {
-               const char *name;
-               int value;
-       } names[] = {
-               { "CASE_INSENSITIVE", LTDB_FLAG_CASE_INSENSITIVE },
-               { "INTEGER", LTDB_FLAG_INTEGER },
-               { "WILDCARD", LTDB_FLAG_WILDCARD },
-               { "HIDDEN", LTDB_FLAG_HIDDEN },
-               { NULL, 0}
-       };
-       size_t len;
+       const struct ldb_message_element *attr_el;
        int i, ret=0;
 
        if (ltdb->cache->last_attribute.name &&
@@ -269,30 +273,22 @@ int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name)
                ret = LTDB_FLAG_OBJECTCLASS | LTDB_FLAG_CASE_INSENSITIVE;
        }
 
-       attrs = ldb_msg_find_string(ltdb->cache->attributes, attr_name, NULL);
+       attr_el = ldb_msg_find_element(ltdb->cache->attributes, attr_name);
 
-       if (!attrs) {
+       if (!attr_el) {
 
                /* check if theres a wildcard attribute */
-               attrs = ldb_msg_find_string(ltdb->cache->attributes, "*", NULL);
+               attr_el = ldb_msg_find_element(ltdb->cache->attributes, "*");
 
-               if (!attrs) {
+               if (!attr_el) {
                        return ret;
                }
        }
 
-       /* we avoid using strtok and friends due to their nasty
-          interface. This is a little trickier, but much nicer
-          from a C interface point of view */
-       while ((len = strcspn(attrs, " ,")) > 0) {
-               for (i=0;names[i].name;i++) {
-                       if (strncmp(names[i].name, attrs, len) == 0 &&
-                           names[i].name[len] == 0) {
-                               ret |= names[i].value;
-                       }
+       for (i = 0; i < attr_el->num_values; i++) {
+               if (strcmp(ltdb_valid_attr_flags[i].name, attr_el->values[i].data) == 0) {
+                       ret |= ltdb_valid_attr_flags[i].value;
                }
-               attrs += len;
-               attrs += strspn(attrs, " ,");
        }
 
        talloc_free(ltdb->cache->last_attribute.name);
@@ -302,3 +298,17 @@ int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name)
 
        return ret;
 }
+
+int ltdb_check_at_attributes_values(const struct ldb_val *value)
+{
+       int i;
+
+       for (i = 0; ltdb_valid_attr_flags[i].name != NULL; i++) {
+               if ((strcmp(ltdb_valid_attr_flags[i].name, value->data) == 0)) {
+                       return 0;
+               }
+       }
+
+       return -1;
+}
+
index b47d79de528879fe3304b39da691445e695a78ec..f6a23d743341235e3dfc3e0b7def3b64e1defea3 100644 (file)
@@ -281,6 +281,33 @@ int ltdb_unlock_read(struct ldb_module *module)
        return 0;
 }
 
+/*
+  check special dn's have valid attributes
+  currently only @ATTRIBUTES is checked
+*/
+int ltdb_check_special_dn(struct ldb_module *module, const struct ldb_message *msg)
+{
+       struct ltdb_private *ltdb = module->private_data;
+       int i, j;
+
+       if (strcmp(msg->dn, LTDB_ATTRIBUTES) != 0) {
+               return 0;
+       }
+
+       /* we have @ATTRIBUTES, let's check attributes are fine */
+       /* should we check that we deny multivalued attributes ? */
+       for (i = 0; i < msg->num_elements; i++) {
+               for (j = 0; j < msg->elements[i].num_values; j++) {
+                       if (ltdb_check_at_attributes_values(&msg->elements[i].values[j]) != 0) {
+                               ltdb->last_err_string = "Invalid attribute value in an @ATTRIBUTES entry";
+                               return -1;
+                       }
+               }
+       }
+
+       return 0;
+}
+
 
 /*
   we've made a modification to a dn - possibly reindex and 
@@ -351,6 +378,11 @@ static int ltdb_add(struct ldb_module *module, const struct ldb_message *msg)
 
        ltdb->last_err_string = NULL;
 
+       ret = ltdb_check_special_dn(module, msg);
+       if (ret != 0) {
+               return ret;
+       }
+       
        if (ltdb_lock(module, LDBLOCK) != 0) {
                return -1;
        }
@@ -359,7 +391,7 @@ static int ltdb_add(struct ldb_module *module, const struct ldb_message *msg)
                ltdb_unlock(module, LDBLOCK);
                return -1;
        }
-       
+
        ret = ltdb_store(module, msg, TDB_INSERT);
 
        if (ret == 0) {
@@ -736,6 +768,11 @@ static int ltdb_modify(struct ldb_module *module, const struct ldb_message *msg)
 
        ltdb->last_err_string = NULL;
 
+       ret = ltdb_check_special_dn(module, msg);
+       if (ret != 0) {
+               return ret;
+       }
+       
        if (ltdb_lock(module, LDBLOCK) != 0) {
                return -1;
        }
index dfb985319ec84580fd07d381d9df88d7d35c61e2..eb6c7825d2f46a44bfcc68bb6dd819b397dfdc50 100644 (file)
@@ -51,6 +51,7 @@ struct ltdb_private {
 #define LTDB_FLAG_WILDCARD         (1<<2)
 #define LTDB_FLAG_OBJECTCLASS      (1<<3)
 #define LTDB_FLAG_HIDDEN           (1<<4)
+#define LTDB_FLAG_NONE             0 
 
 /* The following definitions come from lib/ldb/ldb_tdb/ldb_cache.c  */
 
@@ -58,6 +59,7 @@ int ltdb_cache_reload(struct ldb_module *module);
 int ltdb_cache_load(struct ldb_module *module);
 int ltdb_increase_sequence_number(struct ldb_module *module);
 int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name);
+int ltdb_check_at_attributes_values(const struct ldb_val *value);
 
 /* The following definitions come from lib/ldb/ldb_tdb/ldb_index.c  */
 
index 651fdac41f582aa28442cff292c01189ab5978d5..59757d22a92494f4ff544b05e49bd4d51bb92989 100644 (file)
@@ -12,9 +12,12 @@ dn: @ATTRIBUTES
 realm: CASE_INSENSITIVE
 userPrincipalName: CASE_INSENSITIVE
 servicePrincipalName: CASE_INSENSITIVE
-name: CASE_INSENSITIVE WILDCARD
-dn: CASE_INSENSITIVE WILDCARD
-sAMAccountName: CASE_INSENSITIVE WILDCARD
+name: CASE_INSENSITIVE
+name: WILDCARD
+dn: CASE_INSENSITIVE
+dn: WILDCARD
+sAMAccountName: CASE_INSENSITIVE
+sAMAccountName: WILDCARD
 objectClass: CASE_INSENSITIVE
 unicodePwd: HIDDEN
 ntPwdHash: HIDDEN
index 4bfb1ebd6542f0aecb128068441b1d9f60777683..e6fe1dcf5a0dd3ab8ba92625e05548cfb06b28dc 100644 (file)
@@ -1,5 +1,6 @@
 dn: @ATTRIBUTES
-uid: CASE_INSENSITIVE WILDCARD
+uid: CASE_INSENSITIVE
+uid: WILDCARD
 cn: CASE_INSENSITIVE
 ou: CASE_INSENSITIVE
 dn: CASE_INSENSITIVE
index 2b2ab2e78a860e5b2746bea4b177157b17f9e515..78fed1c12be38c287fa50cd62da36411687776a4 100755 (executable)
@@ -25,6 +25,9 @@ time $VALGRIND bin/ldbtest -r 1000 -s 10  || exit 1
 echo "Adding index"
 $VALGRIND bin/ldbadd tests/test-index.ldif  || exit 1
 
+echo "Adding attributes"
+$VALGRIND bin/ldbadd tests/test-wrong_attributes.ldif  || exit 1
+
 echo "testing indexed search"
 $VALGRIND bin/ldbsearch '(uid=uham)'  || exit 1
 $VALGRIND bin/ldbsearch '(&(objectclass=person)(objectclass=person)(objectclass=top))' || exit 1
index 24ac4087641fea68ca293841b399d9fb90fbddd3..7ba0106394a1fedc14772a2e703984d2fe610cb8 100644 (file)
@@ -3,7 +3,8 @@ dn: @INDEXLIST
 @IDXATTR: objectclass
 
 dn: @ATTRIBUTES
-uid: CASE_INSENSITIVE WILDCARD
+uid: CASE_INSENSITIVE
+uid: WILDCARD
 
 dn: @SUBCLASSES
 top: person
diff --git a/source/lib/ldb/tests/test-wrong_attributes.ldif b/source/lib/ldb/tests/test-wrong_attributes.ldif
new file mode 100644 (file)
index 0000000..27f45f0
--- /dev/null
@@ -0,0 +1,3 @@
+dn: @ATTRIBUTES
+uid: CASE_INTENSIVE
+