r4759: use ldb_attr_cmp() to compare attribute names
authorSimo Sorce <idra@samba.org>
Sat, 15 Jan 2005 17:24:42 +0000 (17:24 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:08:51 +0000 (13:08 -0500)
check required attributes are not deleted on modify operation
if the objectclass is deleted then deny the operation if
orphan atributes are left behind
(This used to be commit 8c11038d67c495f8d5f06cf1fdfe976088864b45)

source4/lib/ldb/modules/schema.c
source4/lib/ldb/modules/timestamps.c

index 63d94eed81bc8247dae945369b036d62bc52e2e3..85f57fc2eb5d39bcb28b8b664a8c3abf081860fa 100644 (file)
@@ -63,9 +63,14 @@ static struct attribute_syntax attrsyn[] = {
 
 #define SCHEMA_TALLOC_CHECK(root, mem, ret) do { if (!mem) { talloc_free(root); return ret;} } while(0);
 
-#define SA_FLAG_RESET          0
-#define SA_FLAG_AUXCLASS       1
-#define SA_FLAG_CHECKED        2
+#define SCHEMA_FLAG_RESET      0
+#define SCHEMA_FLAG_MOD_MASK   0x03
+#define SCHEMA_FLAG_MOD_ADD    0x01
+#define SCHEMA_FLAG_MOD_REPLACE        0x02
+#define SCHEMA_FLAG_MOD_DELETE 0x03
+#define SCHEMA_FLAG_AUXCLASS   0x10
+#define SCHEMA_FLAG_CHECKED    0x20
+
 
 struct private_data {
        struct ldb_context *schema_db;
@@ -136,7 +141,7 @@ static int get_object_objectclasses(struct ldb_context *ldb, const char *dn, str
                                        ldb_search_free(ldb, srch);
                                        return -1;
                                }
-                               schema_struct->objectclass_list[j].flags = SA_FLAG_RESET;
+                               schema_struct->objectclass_list[j].flags = SCHEMA_FLAG_RESET;
                        }
                }
                ldb_search_free(ldb, srch);
@@ -162,7 +167,7 @@ static int get_check_list(struct ldb_module *module, struct schema_structures *s
                return -1;
        }
        for (i = 0, j = 0; i < msg->num_elements; i++) {
-               if (strcasecmp(msg->elements[i].name, "objectclass") == 0) {
+               if (ldb_attr_cmp(msg->elements[i].name, "objectclass") == 0) {
                        schema_struct->objectclass_list_num = msg->elements[i].num_values;
                        schema_struct->objectclass_list = talloc_array(schema_struct,
                                                                         struct attribute_list,
@@ -177,11 +182,11 @@ static int get_check_list(struct ldb_module *module, struct schema_structures *s
                                if (schema_struct->objectclass_list[k].name == 0) {
                                        return -1;
                                }
-                               schema_struct->objectclass_list[k].flags = SA_FLAG_RESET;
+                               schema_struct->objectclass_list[k].flags = msg->elements[i].flags;
                        }
                }
 
-               schema_struct->check_list[j].flags = SA_FLAG_RESET;
+               schema_struct->check_list[j].flags = msg->elements[i].flags;
                schema_struct->check_list[j].name = talloc_strdup(schema_struct->check_list,
                                                                  msg->elements[i].name);
                if (schema_struct->check_list[j].name == 0) {
@@ -243,6 +248,9 @@ static int get_attr_list_recursive(struct ldb_module *module, struct ldb_context
        for (i = 0; i < schema_struct->objectclass_list_num; i++) {
                char *filter;
 
+               if ((schema_struct->objectclass_list[i].flags & SCHEMA_FLAG_MOD_MASK) == SCHEMA_FLAG_MOD_DELETE) {
+                       continue;
+               }
                filter = talloc_asprintf(schema_struct, "lDAPDisplayName=%s", schema_struct->objectclass_list[i].name);
                SCHEMA_TALLOC_CHECK(schema_struct, filter, -1);
                ret = ldb_search(ldb, NULL, LDB_SCOPE_SUBTREE, filter, NULL, &srch);
@@ -251,7 +259,7 @@ static int get_attr_list_recursive(struct ldb_module *module, struct ldb_context
 
                        ok = 0;
                        /* suppose auxiliary classeschema_struct are not required */
-                       if (schema_struct->objectclass_list[i].flags & SA_FLAG_AUXCLASS) {
+                       if (schema_struct->objectclass_list[i].flags & SCHEMA_FLAG_AUXCLASS) {
                                int d;
                                ok = 1;
                                schema_struct->objectclass_list_num -= 1;
@@ -286,11 +294,11 @@ static int get_attr_list_recursive(struct ldb_module *module, struct ldb_context
 
                        is_aux = 0;
                        is_class = 0;
-                       if (strcasecmp((*srch)->elements[j].name, "systemAuxiliaryclass") == 0) {
-                               is_aux = SA_FLAG_AUXCLASS;
+                       if (ldb_attr_cmp((*srch)->elements[j].name, "systemAuxiliaryclass") == 0) {
+                               is_aux = SCHEMA_FLAG_AUXCLASS;
                                is_class = 1;
                        }
-                       if (strcasecmp((*srch)->elements[j].name, "subClassOf") == 0) {
+                       if (ldb_attr_cmp((*srch)->elements[j].name, "subClassOf") == 0) {
                                is_class = 1;
                        }
 
@@ -304,23 +312,23 @@ static int get_attr_list_recursive(struct ldb_module *module, struct ldb_context
                                }
                        } else {
 
-                               if (strcasecmp((*srch)->elements[j].name, "mustContain") == 0 ||
-                                       strcasecmp((*srch)->elements[j].name, "SystemMustContain") == 0) {
+                               if (ldb_attr_cmp((*srch)->elements[j].name, "mustContain") == 0 ||
+                                       ldb_attr_cmp((*srch)->elements[j].name, "SystemMustContain") == 0) {
                                        if (add_attribute_uniq(&schema_struct->must,
                                                                &schema_struct->must_num,
-                                                               SA_FLAG_RESET,
+                                                               SCHEMA_FLAG_RESET,
                                                                &(*srch)->elements[j],
                                                                schema_struct) != 0) {
                                                return -1;
                                        }
                                }
 
-                               if (strcasecmp((*srch)->elements[j].name, "mayContain") == 0 ||
-                                   strcasecmp((*srch)->elements[j].name, "SystemMayContain") == 0) {
+                               if (ldb_attr_cmp((*srch)->elements[j].name, "mayContain") == 0 ||
+                                   ldb_attr_cmp((*srch)->elements[j].name, "SystemMayContain") == 0) {
 
                                        if (add_attribute_uniq(&schema_struct->may,
                                                                &schema_struct->may_num,
-                                                               SA_FLAG_RESET,
+                                                               SCHEMA_FLAG_RESET,
                                                                &(*srch)->elements[j],
                                                                schema_struct) != 0) {
                                                return -1;
@@ -374,8 +382,8 @@ static int schema_add_record(struct ldb_module *module, const struct ldb_message
 
                found = 0;
                for (j = 0; j < entry_structs->check_list_num; j++) {
-                       if (strcasecmp(entry_structs->must[i].name, entry_structs->check_list[j].name) == 0) {
-                               entry_structs->check_list[j].flags = SA_FLAG_CHECKED;
+                       if (ldb_attr_cmp(entry_structs->must[i].name, entry_structs->check_list[j].name) == 0) {
+                               entry_structs->check_list[j].flags = SCHEMA_FLAG_CHECKED;
                                found = 1;
                                break;
                        }
@@ -392,13 +400,13 @@ static int schema_add_record(struct ldb_module *module, const struct ldb_message
        /* now check all others atribs are found in mays */
        for (i = 0; i < entry_structs->check_list_num; i++) {
 
-               if (entry_structs->check_list[i].flags != SA_FLAG_CHECKED) {
+               if (entry_structs->check_list[i].flags != SCHEMA_FLAG_CHECKED) {
                        int found;
 
                        found = 0;
                        for (j = 0; j < entry_structs->may_num; j++) {
-                               if (strcasecmp(entry_structs->may[j].name, entry_structs->check_list[i].name) == 0) {
-                                       entry_structs->check_list[i].flags = SA_FLAG_CHECKED;
+                               if (ldb_attr_cmp(entry_structs->may[j].name, entry_structs->check_list[i].name) == 0) {
+                                       entry_structs->check_list[i].flags = SCHEMA_FLAG_CHECKED;
                                        found = 1;
                                        break;
                                }
@@ -484,17 +492,22 @@ static int schema_modify_record(struct ldb_module *module, const struct ldb_mess
                int found;
 
                found = 0;
-               for (j = 0; j < entry_structs->may_num; j++) {
-                       if (strcasecmp(entry_structs->may[j].name, modify_structs->check_list[i].name) == 0) {
-                               modify_structs->check_list[i].flags = SA_FLAG_CHECKED;
+               for (j = 0; j < entry_structs->must_num; j++) {
+                       if (ldb_attr_cmp(entry_structs->must[j].name, modify_structs->check_list[i].name) == 0) {
+                               if ((modify_structs->check_list[i].flags & SCHEMA_FLAG_MOD_MASK) == SCHEMA_FLAG_MOD_DELETE) {
+                                       data->error_string = "Objectclass violation: trying to delete a required attribute";
+                                       talloc_free(entry_structs);
+                                       return -1;
+                               }
+                               modify_structs->check_list[i].flags |= SCHEMA_FLAG_CHECKED;
                                found = 1;
                                break;
                        }
                }
                if ( ! found) {
-                       for (j = 0; j < entry_structs->must_num; j++) {
-                               if (strcasecmp(entry_structs->must[j].name, modify_structs->check_list[i].name) == 0) {
-                                       modify_structs->check_list[i].flags = SA_FLAG_CHECKED;
+                       for (j = 0; j < entry_structs->may_num; j++) {
+                               if (ldb_attr_cmp(entry_structs->may[j].name, modify_structs->check_list[i].name) == 0) {
+                                       modify_structs->check_list[i].flags |= SCHEMA_FLAG_CHECKED;
                                        break;
                                }
                        }
@@ -507,8 +520,13 @@ static int schema_modify_record(struct ldb_module *module, const struct ldb_mess
 
                found = 0;
                for (j = 0; j < modify_structs->check_list_num; j++) {
-                       if (strcasecmp(modify_structs->must[i].name, modify_structs->check_list[j].name) == 0) {
-                               modify_structs->check_list[j].flags = SA_FLAG_CHECKED;
+                       if (ldb_attr_cmp(modify_structs->must[i].name, modify_structs->check_list[j].name) == 0) {
+                               if ((modify_structs->check_list[i].flags & SCHEMA_FLAG_MOD_MASK) == SCHEMA_FLAG_MOD_DELETE) {
+                                       data->error_string = "Objectclass violation: trying to delete a required attribute";
+                                       talloc_free(entry_structs);
+                                       return -1;
+                               }
+                               modify_structs->check_list[j].flags |= SCHEMA_FLAG_CHECKED;
                                found = 1;
                                break;
                        }
@@ -525,13 +543,14 @@ static int schema_modify_record(struct ldb_module *module, const struct ldb_mess
        /* now check all others atribs are found in mays */
        for (i = 0; i < modify_structs->check_list_num; i++) {
 
-               if (modify_structs->check_list[i].flags != SA_FLAG_CHECKED) {
+               if ((modify_structs->check_list[i].flags & SCHEMA_FLAG_CHECKED) == 0 &&
+                   (modify_structs->check_list[i].flags & SCHEMA_FLAG_MOD_MASK) != SCHEMA_FLAG_MOD_DELETE) {
                        int found;
 
                        found = 0;
                        for (j = 0; j < modify_structs->may_num; j++) {
-                               if (strcasecmp(modify_structs->may[j].name, modify_structs->check_list[i].name) == 0) {
-                                       modify_structs->check_list[i].flags = SA_FLAG_CHECKED;
+                               if (ldb_attr_cmp(modify_structs->may[j].name, modify_structs->check_list[i].name) == 0) {
+                                       modify_structs->check_list[i].flags |= SCHEMA_FLAG_CHECKED;
                                        found = 1;
                                        break;
                                }
index 4066d231cde76f8efef31994551f64721e75221a..1deeeb218b095108ad9690ee62478c9f77ade2e0 100644 (file)
@@ -69,7 +69,7 @@ static int add_time_element(struct ldb_module *module, struct ldb_message *msg,
        int i;
 
        for (i = 0; i < msg->num_elements; i++) {
-               if (strcasecmp(msg->elements[i].name, attr_name) == 0) {
+               if (ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) {
                        return 0;
                }
        }