diff options
author | Simo Sorce <idra@samba.org> | 2005-01-12 16:00:01 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:08:47 -0500 |
commit | a2f77f979d7271a9708ed06f43b00ffb10ec7f4c (patch) | |
tree | f9de8a02597f95ba9c7af1c2086a69cafacb3a87 /source4/lib/ldb/modules/schema.c | |
parent | 7588b41e153ebd84c974f7289847bcd05f32ba4b (diff) | |
download | samba-a2f77f979d7271a9708ed06f43b00ffb10ec7f4c.tar.gz samba-a2f77f979d7271a9708ed06f43b00ffb10ec7f4c.tar.bz2 samba-a2f77f979d7271a9708ed06f43b00ffb10ec7f4c.zip |
r4714: move the ldb code to the new talloc interface (eg remove _p suffix)
this helps standalone building of ldb
renew the schema module
split code into functions to improve readability and code reuse
add and modify works correctly but we need a proper testsuite
Simo
(This used to be commit a681ae365ff1b5a2771b42ebd90336651ce1e513)
Diffstat (limited to 'source4/lib/ldb/modules/schema.c')
-rw-r--r-- | source4/lib/ldb/modules/schema.c | 799 |
1 files changed, 267 insertions, 532 deletions
diff --git a/source4/lib/ldb/modules/schema.c b/source4/lib/ldb/modules/schema.c index 1f9017976e..63d94eed81 100644 --- a/source4/lib/ldb/modules/schema.c +++ b/source4/lib/ldb/modules/schema.c @@ -63,6 +63,10 @@ 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 + struct private_data { struct ldb_context *schema_db; const char *error_string; @@ -88,105 +92,177 @@ static int schema_search_free(struct ldb_module *module, struct ldb_message **re return ldb_next_search_free(module, res); } -struct check_list { - int check; - char *name; -}; - -struct attr_list { - int syntax; - char *name; -}; - -struct objc_list { - int aux; +struct attribute_list { + int flags; char *name; }; struct schema_structures { - struct check_list *cl; - struct objc_list *ol; - struct attr_list *must; - struct attr_list *may; - int num_cl; - int num_objc; - int num_must; - int num_may; + struct attribute_list *check_list; + struct attribute_list *objectclass_list; + struct attribute_list *must; + struct attribute_list *may; + int check_list_num; + int objectclass_list_num; + int must_num; + int may_num; }; -/* add_record */ -static int schema_add_record(struct ldb_module *module, const struct ldb_message *msg) +static int get_object_objectclasses(struct ldb_context *ldb, const char *dn, struct schema_structures *schema_struct) { - struct private_data *data = (struct private_data *)module->private_data; + char *filter = talloc_asprintf(schema_struct, "dn=%s", dn); + const char *attrs[] = {"objectClass", NULL}; struct ldb_message **srch; - struct schema_structures *ss; - int i, j, k, l; - int ret; + int i, j, ret; + + schema_struct->objectclass_list = NULL; + schema_struct->objectclass_list_num = 0; + ret = ldb_search(ldb, NULL, LDB_SCOPE_SUBTREE, filter, attrs, &srch); + if (ret == 1) { + for (i = 0; i < (*srch)->num_elements; i++) { + schema_struct->objectclass_list_num = (*srch)->elements[i].num_values; + schema_struct->objectclass_list = talloc_array(schema_struct, + struct attribute_list, + schema_struct->objectclass_list_num); + if (schema_struct->objectclass_list == 0) { + ldb_search_free(ldb, srch); + return -1; + } + for (j = 0; j < schema_struct->objectclass_list_num; j++) { + schema_struct->objectclass_list[j].name = talloc_strndup(schema_struct->objectclass_list, + (*srch)->elements[i].values[j].data, + (*srch)->elements[i].values[j].length); + if (schema_struct->objectclass_list[j].name == 0) { + ldb_search_free(ldb, srch); + return -1; + } + schema_struct->objectclass_list[j].flags = SA_FLAG_RESET; + } + } + ldb_search_free(ldb, srch); + } else { + ldb_search_free(ldb, srch); + return -1; + } - /* First implementation: - Build up a list of must and mays from each objectclass - Check all the musts are there and all the other attributes are mays - Throw an error in case a check fail - Free all structures and commit the change - */ + return 0; +} - ss = talloc_p(module, struct schema_structures); - if (!ss) { +static int get_check_list(struct ldb_module *module, struct schema_structures *schema_struct, const struct ldb_message *msg) +{ + int i, j, k; + + schema_struct->objectclass_list = NULL; + schema_struct->objectclass_list_num = 0; + schema_struct->check_list_num = msg->num_elements; + schema_struct->check_list = talloc_array(schema_struct, + struct attribute_list, + schema_struct->check_list_num); + if (schema_struct->check_list == 0) { return -1; } - - ss->ol = NULL; - ss->num_objc = 0; - ss->num_cl = msg->num_elements; - ss->cl = talloc_array_p(ss, struct check_list, ss->num_cl); - SCHEMA_TALLOC_CHECK(ss, ss->cl, -1); for (i = 0, j = 0; i < msg->num_elements; i++) { if (strcasecmp(msg->elements[i].name, "objectclass") == 0) { - ss->num_objc = msg->elements[i].num_values; - ss->ol = talloc_array_p(ss, struct objc_list, ss->num_objc); - SCHEMA_TALLOC_CHECK(ss, ss->ol, -1); - for (k = 0; k < ss->num_objc; k++) { - ss->ol[k].name = talloc_strndup(ss->ol, msg->elements[i].values[k].data, msg->elements[i].values[k].length); - SCHEMA_TALLOC_CHECK(ss, ss->ol[k].name, -1); - ss->ol[k].aux = 0; + schema_struct->objectclass_list_num = msg->elements[i].num_values; + schema_struct->objectclass_list = talloc_array(schema_struct, + struct attribute_list, + schema_struct->objectclass_list_num); + if (schema_struct->objectclass_list == 0) { + return -1; + } + for (k = 0; k < schema_struct->objectclass_list_num; k++) { + schema_struct->objectclass_list[k].name = talloc_strndup(schema_struct->objectclass_list, + msg->elements[i].values[k].data, + msg->elements[i].values[k].length); + if (schema_struct->objectclass_list[k].name == 0) { + return -1; + } + schema_struct->objectclass_list[k].flags = SA_FLAG_RESET; } } - ss->cl[j].check = 0; - ss->cl[j].name = talloc_strdup(ss->cl, msg->elements[i].name); - SCHEMA_TALLOC_CHECK(ss, ss->cl[j].name, -1); + schema_struct->check_list[j].flags = SA_FLAG_RESET; + schema_struct->check_list[j].name = talloc_strdup(schema_struct->check_list, + msg->elements[i].name); + if (schema_struct->check_list[j].name == 0) { + return -1; + } j++; } - /* find all other objectclasses recursively */ - ss->must = NULL; - ss->may = NULL; - ss->num_must = 0; - ss->num_may = 0; - for (i = 0; i < ss->num_objc; i++) { + return 0; +} + +static int add_attribute_uniq(struct attribute_list **list, int *list_num, int flags, struct ldb_message_element *el, void *mem_ctx) +{ + int i, j, vals; + + vals = el->num_values; + *list = talloc_realloc(mem_ctx, *list, struct attribute_list, *list_num + vals); + if (list == 0) { + return -1; + } + for (i = 0, j = 0; i < vals; i++) { + int c, found, len; + + found = 0; + for (c = 0; c < *list_num; c++) { + len = strlen((*list)[c].name); + if (len == el->values[i].length) { + if (strncasecmp((*list)[c].name, el->values[i].data, len) == 0) { + found = 1; + break; + } + } + } + if (!found) { + (*list)[j + *list_num].name = talloc_strndup(*list, el->values[i].data, el->values[i].length); + if ((*list)[j + *list_num].name == 0) { + return -1; + } + (*list)[j + *list_num].flags = flags; + j++; + } + } + *list_num += j; + + return 0; +} + +static int get_attr_list_recursive(struct ldb_module *module, struct ldb_context *ldb, struct schema_structures *schema_struct) +{ + struct private_data *data = (struct private_data *)module->private_data; + struct ldb_message **srch; + int i, j; + int ret; + + schema_struct->must = NULL; + schema_struct->may = NULL; + schema_struct->must_num = 0; + schema_struct->may_num = 0; + for (i = 0; i < schema_struct->objectclass_list_num; i++) { char *filter; - filter = talloc_asprintf(ss, "lDAPDisplayName=%s", ss->ol[i].name); - SCHEMA_TALLOC_CHECK(ss, filter, -1); - ret = ldb_search(data->schema_db, NULL, LDB_SCOPE_SUBTREE, filter, NULL, &srch); + 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); if (ret == 0) { int ok; ok = 0; - /* suppose auxiliary classess are not required */ - if (ss->ol[i].aux) { + /* suppose auxiliary classeschema_struct are not required */ + if (schema_struct->objectclass_list[i].flags & SA_FLAG_AUXCLASS) { int d; ok = 1; - ss->num_objc -= 1; - for (d = i; d < ss->num_objc; d++) { - ss->ol[d] = ss->ol[d + 1]; + schema_struct->objectclass_list_num -= 1; + for (d = i; d < schema_struct->objectclass_list_num; d++) { + schema_struct->objectclass_list[d] = schema_struct->objectclass_list[d + 1]; } i -= 1; } if (!ok) { /* Schema Violation: Object Class Description Not Found */ data->error_string = "ObjectClass not found"; - talloc_free(ss); return -1; } continue; @@ -194,13 +270,11 @@ static int schema_add_record(struct ldb_module *module, const struct ldb_message if (ret < 0) { /* Schema DB Error: Error occurred retrieving Object Class Description */ data->error_string = "Internal error. Error retrieving schema objectclass"; - talloc_free(ss); return -1; } if (ret > 1) { /* Schema DB Error: Too Many Records */ data->error_string = "Internal error. Too many records searching for schema objectclass"; - talloc_free(ss); return -1; } } @@ -208,12 +282,12 @@ static int schema_add_record(struct ldb_module *module, const struct ldb_message /* Add inherited classes eliminating duplicates */ /* fill in kust and may attribute lists */ for (j = 0; j < (*srch)->num_elements; j++) { - int o, is_aux, is_class; + int is_aux, is_class; is_aux = 0; is_class = 0; if (strcasecmp((*srch)->elements[j].name, "systemAuxiliaryclass") == 0) { - is_aux = 1; + is_aux = SA_FLAG_AUXCLASS; is_class = 1; } if (strcasecmp((*srch)->elements[j].name, "subClassOf") == 0) { @@ -221,103 +295,87 @@ static int schema_add_record(struct ldb_module *module, const struct ldb_message } if (is_class) { - o = (*srch)->elements[j].num_values; - ss->ol = talloc_realloc_p(ss, ss->ol, struct objc_list, ss->num_objc + o); - SCHEMA_TALLOC_CHECK(ss, ss->ol, -1); - for (k = 0, l = 0; k < o; k++) { - int c, found, len; - - found = 0; - for (c = 0; c < ss->num_objc; c++) { - len = strlen(ss->ol[c].name); - if (len == (*srch)->elements[j].values[k].length) { - if (strncasecmp(ss->ol[c].name, (*srch)->elements[j].values[k].data, len) == 0) { - found = 1; - break; - } - } - } - if (!found) { - ss->ol[l + ss->num_objc].name = talloc_strndup(ss->ol, (*srch)->elements[j].values[k].data, (*srch)->elements[j].values[k].length); - SCHEMA_TALLOC_CHECK(ss, ss->ol[l + ss->num_objc].name, -1); - ss->ol[l + ss->num_objc].aux = is_aux; - l++; - } + if (add_attribute_uniq(&schema_struct->objectclass_list, + &schema_struct->objectclass_list_num, + is_aux, + &(*srch)->elements[j], + schema_struct) != 0) { + return -1; } - ss->num_objc += l; } else { - if (strcasecmp((*srch)->elements[j].name, "mustContain") == 0 || strcasecmp((*srch)->elements[j].name, "SystemMustContain") == 0) { - int m; - - m = (*srch)->elements[j].num_values; - - ss->must = talloc_realloc_p(ss, ss->must, struct attr_list, ss->num_must + m); - SCHEMA_TALLOC_CHECK(ss, ss->must, -1); - for (k = 0, l = 0; k < m; k++) { - int c, found, len; - - found = 0; - for (c = 0; c < ss->num_must; c++) { - len = strlen(ss->must[c].name); - if (len == (*srch)->elements[j].values[k].length) { - if (strncasecmp(ss->must[c].name, (*srch)->elements[j].values[k].data, len) == 0) { - found = 1; - break; - } - } - } - if (!found) { - ss->must[l + ss->num_must].name = talloc_strndup(ss->must, (*srch)->elements[j].values[k].data, (*srch)->elements[j].values[k].length); - SCHEMA_TALLOC_CHECK(ss, ss->must[l + ss->num_must].name, -1); - l++; - } + if (strcasecmp((*srch)->elements[j].name, "mustContain") == 0 || + strcasecmp((*srch)->elements[j].name, "SystemMustContain") == 0) { + if (add_attribute_uniq(&schema_struct->must, + &schema_struct->must_num, + SA_FLAG_RESET, + &(*srch)->elements[j], + schema_struct) != 0) { + return -1; } - ss->num_must += l; } - if (strcasecmp((*srch)->elements[j].name, "mayContain") == 0 || strcasecmp((*srch)->elements[j].name, "SystemMayContain") == 0) { - int m; - - m = (*srch)->elements[j].num_values; - - ss->may = talloc_realloc_p(ss, ss->may, struct attr_list, ss->num_may + m); - SCHEMA_TALLOC_CHECK(ss, ss->may, -1); - for (k = 0, l = 0; k < m; k++) { - int c, found, len; - - found = 0; - for (c = 0; c < ss->num_may; c++) { - len = strlen(ss->may[c].name); - if (len == (*srch)->elements[j].values[k].length) { - if (strncasecmp(ss->may[c].name, (*srch)->elements[j].values[k].data, (*srch)->elements[j].values[k].length) == 0) { - found = 1; - break; - } - } - } - if (!found) { - ss->may[l + ss->num_may].name = talloc_strndup(ss->may, (*srch)->elements[j].values[k].data, (*srch)->elements[j].values[k].length); - SCHEMA_TALLOC_CHECK(ss, ss->may[l + ss->num_may].name, -1); - l++; - } + if (strcasecmp((*srch)->elements[j].name, "mayContain") == 0 || + strcasecmp((*srch)->elements[j].name, "SystemMayContain") == 0) { + + if (add_attribute_uniq(&schema_struct->may, + &schema_struct->may_num, + SA_FLAG_RESET, + &(*srch)->elements[j], + schema_struct) != 0) { + return -1; } - ss->num_may += l; } } } - ldb_search_free(data->schema_db, srch); + ldb_search_free(ldb, srch); + } + + return 0; +} + +/* add_record */ +static int schema_add_record(struct ldb_module *module, const struct ldb_message *msg) +{ + struct private_data *data = (struct private_data *)module->private_data; + struct schema_structures *entry_structs; + int i, j; + int ret; + + /* First implementation: + Build up a list of must and mays from each objectclass + Check all the musts are there and all the other attributes are mays + Throw an error in case a check fail + Free all structures and commit the change + */ + + entry_structs = talloc(module, struct schema_structures); + if (!entry_structs) { + return -1; + } + + ret = get_check_list(module, entry_structs, msg); + if (ret != 0) { + talloc_free(entry_structs); + return ret; + } + + /* find all other objectclasses recursively */ + ret = get_attr_list_recursive(module, data->schema_db, entry_structs); + if (ret != 0) { + talloc_free(entry_structs); + return ret; } /* now check all musts are present */ - for (i = 0; i < ss->num_must; i++) { + for (i = 0; i < entry_structs->must_num; i++) { int found; found = 0; - for (j = 0; j < ss->num_cl; j++) { - if (strcasecmp(ss->must[i].name, ss->cl[j].name) == 0) { - ss->cl[j].check = 1; + 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; found = 1; break; } @@ -325,22 +383,22 @@ static int schema_add_record(struct ldb_module *module, const struct ldb_message if ( ! found ) { /* TODO: set the error string */ - data->error_string = "Objectclass violation, a required attribute is missing"; - talloc_free(ss); + data->error_string = "Objectclass violation, a required attribute is mischema_structing"; + talloc_free(entry_structs); return -1; } } /* now check all others atribs are found in mays */ - for (i = 0; i < ss->num_cl; i++) { + for (i = 0; i < entry_structs->check_list_num; i++) { - if ( ! ss->cl[i].check ) { + if (entry_structs->check_list[i].flags != SA_FLAG_CHECKED) { int found; found = 0; - for (j = 0; j < ss->num_may; j++) { - if (strcasecmp(ss->may[j].name, ss->cl[i].name) == 0) { - ss->cl[i].check = 1; + 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; found = 1; break; } @@ -348,13 +406,13 @@ static int schema_add_record(struct ldb_module *module, const struct ldb_message if ( ! found ) { data->error_string = "Objectclass violation, an invalid attribute name was found"; - talloc_free(ss); + talloc_free(entry_structs); return -1; } } } - talloc_free(ss); + talloc_free(entry_structs); return ldb_next_add_record(module, msg); } @@ -363,9 +421,8 @@ static int schema_add_record(struct ldb_module *module, const struct ldb_message static int schema_modify_record(struct ldb_module *module, const struct ldb_message *msg) { struct private_data *data = (struct private_data *)module->private_data; - struct ldb_message **srch; - struct schema_structures *ss, *ms; - int i, j, k, l; + struct schema_structures *entry_structs, *modify_structs; + int i, j; int ret; /* First implementation: @@ -379,387 +436,65 @@ static int schema_modify_record(struct ldb_module *module, const struct ldb_mess Free all structures and commit the change. */ - ss = talloc_p(module, struct schema_structures); - if (!ss) { + /* allocate object structs */ + entry_structs = talloc(module, struct schema_structures); + if (!entry_structs) { return -1; } - ms = talloc_p(module, struct schema_structures); - SCHEMA_TALLOC_CHECK(ss, ms, -1); - - ms->ol = NULL; - ms->num_objc = 0; - ms->num_cl = msg->num_elements; - ms->cl = talloc_array_p(ms, struct check_list, ms->num_cl); - SCHEMA_TALLOC_CHECK(ss, ms->cl, -1); - for (i = 0, j = 0; i < msg->num_elements; i++) { - if (strcasecmp(msg->elements[i].name, "objectclass") == 0) { - ms->num_objc = msg->elements[i].num_values; - ms->ol = talloc_array_p(ms, struct objc_list, ms->num_objc); - SCHEMA_TALLOC_CHECK(ss, ms->ol, -1); - for (k = 0; k < ms->num_objc; k++) { - ms->ol[k].name = talloc_strndup(ms->ol, msg->elements[i].values[k].data, msg->elements[i].values[k].length); - SCHEMA_TALLOC_CHECK(ss, ms->ol[k].name, -1); - ms->ol[k].aux = 0; - } - } + /* allocate modification entry structs */ + modify_structs = talloc(entry_structs, struct schema_structures); + if (!modify_structs) { + talloc_free(entry_structs); + return -1; + } - ms->cl[j].check = 0; - ms->cl[j].name = talloc_strdup(ms->cl, msg->elements[i].name); - SCHEMA_TALLOC_CHECK(ss, ms->cl[j].name, -1); - j++; + /* get list of values to modify */ + ret = get_check_list(module, modify_structs, msg); + if (ret != 0) { + talloc_free(entry_structs); + return ret; } /* find all modify objectclasses recursively if any objectclass is being added */ - ms->must = NULL; - ms->may = NULL; - ms->num_must = 0; - ms->num_may = 0; - for (i = 0; i < ms->num_objc; i++) { - char *filter; - - filter = talloc_asprintf(ss, "lDAPDisplayName=%s", ms->ol[i].name); - SCHEMA_TALLOC_CHECK(ss, filter, -1); - ret = ldb_search(data->schema_db, NULL, LDB_SCOPE_SUBTREE, filter, NULL, &srch); - if (ret == 0) { - int ok; - - ok = 0; - /* suppose auxiliary classess are not required */ - if (ms->ol[i].aux) { - int d; - ok = 1; - ms->num_objc -= 1; - for (d = i; d < ms->num_objc; d++) { - ms->ol[d] = ms->ol[d + 1]; - } - i -= 1; - } - if (!ok) { - /* Schema Violation: Object Class Description Not Found */ - data->error_string = "ObjectClass not found"; - talloc_free(ss); - return -1; - } - continue; - } else { - if (ret < 0) { - /* Schema DB Error: Error occurred retrieving Object Class Description */ - data->error_string = "Internal error. Error retrieving schema objectclass"; - talloc_free(ss); - return -1; - } - if (ret > 1) { - /* Schema DB Error: Too Many Records */ - data->error_string = "Internal error. Too many records searching for schema objectclass"; - talloc_free(ss); - return -1; - } - } - - /* Add inherited classes eliminating duplicates */ - /* fill in kust and may attribute lists */ - for (j = 0; j < (*srch)->num_elements; j++) { - int o, is_aux, is_class; - - is_aux = 0; - is_class = 0; - if (strcasecmp((*srch)->elements[j].name, "systemAuxiliaryclass") == 0) { - is_aux = 1; - is_class = 1; - } - if (strcasecmp((*srch)->elements[j].name, "subClassOf") == 0) { - is_class = 1; - } - - if (is_class) { - o = (*srch)->elements[j].num_values; - ms->ol = talloc_realloc_p(ms, ms->ol, struct objc_list, ms->num_objc + o); - SCHEMA_TALLOC_CHECK(ss, ms->ol, -1); - for (k = 0, l = 0; k < o; k++) { - int c, found, len; - - found = 0; - for (c = 0; c < ms->num_objc; c++) { - len = strlen(ms->ol[c].name); - if (len == (*srch)->elements[j].values[k].length) { - if (strncasecmp(ss->ol[c].name, (*srch)->elements[j].values[k].data, len) == 0) { - found = 1; - break; - } - } - } - if (!found) { - ms->ol[l + ms->num_objc].name = talloc_strndup(ms->ol, (*srch)->elements[j].values[k].data, (*srch)->elements[j].values[k].length); - SCHEMA_TALLOC_CHECK(ss, ms->ol[l + ms->num_objc].name, -1); - ms->ol[l + ms->num_objc].aux = is_aux; - l++; - } - } - ms->num_objc += l; - } else { - - if (strcasecmp((*srch)->elements[j].name, "mustContain") == 0 || strcasecmp((*srch)->elements[j].name, "SystemMustContain") == 0) { - int m; - - m = (*srch)->elements[j].num_values; - - ms->must = talloc_realloc_p(ms, ms->must, struct attr_list, ms->num_must + m); - SCHEMA_TALLOC_CHECK(ss, ms->must, -1); - for (k = 0, l = 0; k < m; k++) { - int c, found, len; - - found = 0; - for (c = 0; c < ms->num_must; c++) { - len = strlen(ms->must[c].name); - if (len == (*srch)->elements[j].values[k].length) { - if (strncasecmp(ms->must[c].name, (*srch)->elements[j].values[k].data, len) == 0) { - found = 1; - break; - } - } - } - if (!found) { - ms->must[l + ms->num_must].name = talloc_strndup(ms->must, (*srch)->elements[j].values[k].data, (*srch)->elements[j].values[k].length); - SCHEMA_TALLOC_CHECK(ss, ms->must[l + ms->num_must].name, -1); - l++; - } - } - ms->num_must += l; - } - - if (strcasecmp((*srch)->elements[j].name, "mayContain") == 0 || strcasecmp((*srch)->elements[j].name, "SystemMayContain") == 0) { - int m; - - m = (*srch)->elements[j].num_values; - - ms->may = talloc_realloc_p(ms, ms->may, struct attr_list, ms->num_may + m); - SCHEMA_TALLOC_CHECK(ss, ms->may, -1); - for (k = 0, l = 0; k < m; k++) { - int c, found, len; - - found = 0; - for (c = 0; c < ms->num_may; c++) { - len = strlen(ms->may[c].name); - if (len == (*srch)->elements[j].values[k].length) { - if (strncasecmp(ms->may[c].name, (*srch)->elements[j].values[k].data, (*srch)->elements[j].values[k].length) == 0) { - found = 1; - break; - } - } - } - if (!found) { - ms->may[l + ms->num_may].name = talloc_strndup(ms->may, (*srch)->elements[j].values[k].data, (*srch)->elements[j].values[k].length); - SCHEMA_TALLOC_CHECK(ss, ms->may[l + ms->num_may].name, -1); - l++; - } - } - ms->num_may += l; - } - } - } - - ldb_search_free(data->schema_db, srch); + ret = get_attr_list_recursive(module, data->schema_db, modify_structs); + if (ret != 0) { + talloc_free(entry_structs); + return ret; } /* now search for the original object objectclasses */ - - ss->ol = NULL; - ss->num_objc = 0; - - /* find all other objectclasses recursively */ - { - char *filter = talloc_asprintf(ss, "dn=%s", msg->dn); - const char *attrs[] = {"objectClass", NULL}; - - ret = ldb_search(module->ldb, NULL, LDB_SCOPE_SUBTREE, filter, attrs, &srch); - if (ret == 1) { - for (i = 0; i < msg->num_elements; i++) { - ss->num_objc = (*srch)->elements[i].num_values; - ss->ol = talloc_array_p(ss, struct objc_list, ss->num_objc); - SCHEMA_TALLOC_CHECK(ss, ss->ol, -1); - for (k = 0; k < ss->num_objc; k++) { - ss->ol[k].name = talloc_strndup(ss->ol, (*srch)->elements[i].values[k].data, (*srch)->elements[i].values[k].length); - SCHEMA_TALLOC_CHECK(ss, ss->ol[k].name, -1); - ss->ol[k].aux = 0; - } - } - ldb_search_free(module->ldb, srch); - } else { - ldb_search_free(module->ldb, srch); - return -1; - } + ret = get_object_objectclasses(module->ldb, msg->dn, entry_structs); + if (ret != 0) { + talloc_free(entry_structs); + return ret; } - ss->must = NULL; - ss->may = NULL; - ss->num_must = 0; - ss->num_may = 0; - for (i = 0; i < ss->num_objc; i++) { - char *filter; - - filter = talloc_asprintf(ss, "lDAPDisplayName=%s", ss->ol[i].name); - SCHEMA_TALLOC_CHECK(ss, filter, -1); - ret = ldb_search(data->schema_db, NULL, LDB_SCOPE_SUBTREE, filter, NULL, &srch); - if (ret == 0) { - int ok; - - ok = 0; - /* suppose auxiliary classess are not required */ - if (ss->ol[i].aux) { - int d; - ok = 1; - ss->num_objc -= 1; - for (d = i; d < ss->num_objc; d++) { - ss->ol[d] = ss->ol[d + 1]; - } - i -= 1; - } - if (!ok) { - /* Schema Violation: Object Class Description Not Found */ - data->error_string = "ObjectClass not found"; - talloc_free(ss); - return -1; - } - continue; - } else { - if (ret < 0) { - /* Schema DB Error: Error occurred retrieving Object Class Description */ - data->error_string = "Internal error. Error retrieving schema objectclass"; - talloc_free(ss); - return -1; - } - if (ret > 1) { - /* Schema DB Error: Too Many Records */ - data->error_string = "Internal error. Too many records searching for schema objectclass"; - talloc_free(ss); - return -1; - } - } - - /* Add inherited classes eliminating duplicates */ - /* fill in kust and may attribute lists */ - for (j = 0; j < (*srch)->num_elements; j++) { - int o, is_aux, is_class; - - is_aux = 0; - is_class = 0; - if (strcasecmp((*srch)->elements[j].name, "systemAuxiliaryclass") == 0) { - is_aux = 1; - is_class = 1; - } - if (strcasecmp((*srch)->elements[j].name, "subClassOf") == 0) { - is_class = 1; - } - - if (is_class) { - o = (*srch)->elements[j].num_values; - ss->ol = talloc_realloc_p(ss, ss->ol, struct objc_list, ss->num_objc + o); - SCHEMA_TALLOC_CHECK(ss, ss->ol, -1); - for (k = 0, l = 0; k < o; k++) { - int c, found, len; - - found = 0; - for (c = 0; c < ss->num_objc; c++) { - len = strlen(ss->ol[c].name); - if (len == (*srch)->elements[j].values[k].length) { - if (strncasecmp(ss->ol[c].name, (*srch)->elements[j].values[k].data, len) == 0) { - found = 1; - break; - } - } - } - if (!found) { - ss->ol[l + ss->num_objc].name = talloc_strndup(ss->ol, (*srch)->elements[j].values[k].data, (*srch)->elements[j].values[k].length); - SCHEMA_TALLOC_CHECK(ss, ss->ol[l + ss->num_objc].name, -1); - ss->ol[l + ss->num_objc].aux = is_aux; - l++; - } - } - ss->num_objc += l; - } else { - - if (strcasecmp((*srch)->elements[j].name, "mustContain") == 0 || strcasecmp((*srch)->elements[j].name, "SystemMustContain") == 0) { - int m; - - m = (*srch)->elements[j].num_values; - - ss->must = talloc_realloc_p(ss, ss->must, struct attr_list, ss->num_must + m); - SCHEMA_TALLOC_CHECK(ss, ss->must, -1); - for (k = 0, l = 0; k < m; k++) { - int c, found, len; - - found = 0; - for (c = 0; c < ss->num_must; c++) { - len = strlen(ss->must[c].name); - if (len == (*srch)->elements[j].values[k].length) { - if (strncasecmp(ss->must[c].name, (*srch)->elements[j].values[k].data, len) == 0) { - found = 1; - break; - } - } - } - if (!found) { - ss->must[l + ss->num_must].name = talloc_strndup(ss->must, (*srch)->elements[j].values[k].data, (*srch)->elements[j].values[k].length); - SCHEMA_TALLOC_CHECK(ss, ss->must[l + ss->num_must].name, -1); - l++; - } - } - ss->num_must += l; - } - - if (strcasecmp((*srch)->elements[j].name, "mayContain") == 0 || strcasecmp((*srch)->elements[j].name, "SystemMayContain") == 0) { - int m; - - m = (*srch)->elements[j].num_values; - - ss->may = talloc_realloc_p(ss, ss->may, struct attr_list, ss->num_may + m); - SCHEMA_TALLOC_CHECK(ss, ss->may, -1); - for (k = 0, l = 0; k < m; k++) { - int c, found, len; - - found = 0; - for (c = 0; c < ss->num_may; c++) { - len = strlen(ss->may[c].name); - if (len == (*srch)->elements[j].values[k].length) { - if (strncasecmp(ss->may[c].name, (*srch)->elements[j].values[k].data, (*srch)->elements[j].values[k].length) == 0) { - found = 1; - break; - } - } - } - if (!found) { - ss->may[l + ss->num_may].name = talloc_strndup(ss->may, (*srch)->elements[j].values[k].data, (*srch)->elements[j].values[k].length); - SCHEMA_TALLOC_CHECK(ss, ss->may[l + ss->num_may].name, -1); - l++; - } - } - ss->num_may += l; - } - } - } - - ldb_search_free(data->schema_db, srch); + /* find all other objectclasses recursively */ + ret = get_attr_list_recursive(module, data->schema_db, entry_structs); + if (ret != 0) { + talloc_free(entry_structs); + return ret; } /* now check all entries are present either as musts or mays of curent objectclasses */ /* do not return errors there may be attirbutes defined in new objectclasses */ /* just mark them as being proved valid attribs */ - for (i = 0; i < ms->num_cl; i++) { + for (i = 0; i < modify_structs->check_list_num; i++) { int found; found = 0; - for (j = 0; j < ss->num_may; j++) { - if (strcasecmp(ss->may[j].name, ms->cl[i].name) == 0) { - ms->cl[i].check = 1; + 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; found = 1; break; } } if ( ! found) { - for (j = 0; j < ss->num_must; j++) { - if (strcasecmp(ss->must[j].name, ms->cl[i].name) == 0) { - ms->cl[i].check = 1; + 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; break; } } @@ -767,13 +502,13 @@ static int schema_modify_record(struct ldb_module *module, const struct ldb_mess } /* now check all new objectclasses musts are present */ - for (i = 0; i < ms->num_must; i++) { + for (i = 0; i < modify_structs->must_num; i++) { int found; found = 0; - for (j = 0; j < ms->num_cl; j++) { - if (strcasecmp(ms->must[i].name, ms->cl[j].name) == 0) { - ms->cl[j].check = 1; + 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; found = 1; break; } @@ -782,21 +517,21 @@ static int schema_modify_record(struct ldb_module *module, const struct ldb_mess if ( ! found ) { /* TODO: set the error string */ data->error_string = "Objectclass violation, a required attribute is missing"; - talloc_free(ss); + talloc_free(entry_structs); return -1; } } /* now check all others atribs are found in mays */ - for (i = 0; i < ms->num_cl; i++) { + for (i = 0; i < modify_structs->check_list_num; i++) { - if ( ! ms->cl[i].check ) { + if (modify_structs->check_list[i].flags != SA_FLAG_CHECKED) { int found; found = 0; - for (j = 0; j < ms->num_may; j++) { - if (strcasecmp(ms->may[j].name, ms->cl[i].name) == 0) { - ms->cl[i].check = 1; + 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; found = 1; break; } @@ -804,13 +539,13 @@ static int schema_modify_record(struct ldb_module *module, const struct ldb_mess if ( ! found ) { data->error_string = "Objectclass violation, an invalid attribute name was found"; - talloc_free(ss); + talloc_free(entry_structs); return -1; } } } - talloc_free(ss); + talloc_free(entry_structs); return ldb_next_modify_record(module, msg); } @@ -818,7 +553,7 @@ static int schema_modify_record(struct ldb_module *module, const struct ldb_mess /* delete_record */ static int schema_delete_record(struct ldb_module *module, const char *dn) { - struct private_data *data = (struct private_data *)module->private_data; +/* struct private_data *data = (struct private_data *)module->private_data; */ return ldb_next_delete_record(module, dn); } @@ -880,7 +615,7 @@ struct ldb_module *schema_module_init(struct ldb_context *ldb, const char *optio char *db_url = NULL; int i; - ctx = talloc_p(ldb, struct ldb_module); + ctx = talloc(ldb, struct ldb_module); if (!ctx) { return NULL; } @@ -923,7 +658,7 @@ struct ldb_module *schema_module_init(struct ldb_context *ldb, const char *optio ldb_search_free(ldb, msgs); } - data = talloc_p(ctx, struct private_data); + data = talloc(ctx, struct private_data); SCHEMA_TALLOC_CHECK(ctx, data, NULL); data->schema_db = ldb_connect(db_url, 0, NULL); |