diff options
Diffstat (limited to 'source4/lib/ldb')
-rw-r--r-- | source4/lib/ldb/common/ldb_modules.c | 2 | ||||
-rw-r--r-- | source4/lib/ldb/common/ldb_msg.c | 71 | ||||
-rw-r--r-- | source4/lib/ldb/include/ldb_private.h | 2 | ||||
-rw-r--r-- | source4/lib/ldb/modules/operational.c | 101 | ||||
-rw-r--r-- | source4/lib/ldb/modules/rdn_name.c | 8 |
5 files changed, 145 insertions, 39 deletions
diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c index 5ca666c194..f3ca4df9b4 100644 --- a/source4/lib/ldb/common/ldb_modules.c +++ b/source4/lib/ldb/common/ldb_modules.c @@ -127,7 +127,7 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[]) ldb_module_init_t init; } well_known_modules[] = { { "schema", schema_module_init }, - { "timestamps", timestamps_module_init }, + { "operational", operational_module_init }, { "rdn_name", rdn_name_module_init }, #ifdef _SAMBA_BUILD_ { "objectguid", objectguid_module_init }, diff --git a/source4/lib/ldb/common/ldb_msg.c b/source4/lib/ldb/common/ldb_msg.c index 2aef7acc42..1c7ae3920a 100644 --- a/source4/lib/ldb/common/ldb_msg.c +++ b/source4/lib/ldb/common/ldb_msg.c @@ -353,47 +353,64 @@ void ldb_msg_sort_elements(struct ldb_message *msg) } /* - copy a message, allocating new memory for all parts + shallow copy a message - copying only the elements array so that the caller + can safely add new elements without changing the message */ -struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx, - const struct ldb_message *msg) +struct ldb_message *ldb_msg_copy_shallow(TALLOC_CTX *mem_ctx, + const struct ldb_message *msg) { struct ldb_message *msg2; - int i, j; + int i; msg2 = talloc(mem_ctx, struct ldb_message); if (msg2 == NULL) return NULL; - msg2->elements = NULL; - msg2->num_elements = 0; + *msg2 = *msg; msg2->private_data = NULL; - msg2->dn = ldb_dn_copy(msg2, msg->dn); - if (msg2->dn == NULL) goto failed; - - msg2->elements = talloc_array(msg2, struct ldb_message_element, msg->num_elements); + msg2->elements = talloc_array(msg2, struct ldb_message_element, + msg2->num_elements); if (msg2->elements == NULL) goto failed; - for (i=0;i<msg->num_elements;i++) { - struct ldb_message_element *el1 = &msg->elements[i]; - struct ldb_message_element *el2 = &msg2->elements[i]; + for (i=0;i<msg2->num_elements;i++) { + msg2->elements[i] = msg->elements[i]; + } + + return msg2; - el2->flags = el1->flags; - el2->num_values = 0; - el2->values = NULL; - el2->name = talloc_strdup(msg2->elements, el1->name); - if (el2->name == NULL) goto failed; - el2->values = talloc_array(msg2->elements, struct ldb_val, el1->num_values); - for (j=0;j<el1->num_values;j++) { - el2->values[j] = ldb_val_dup(el2->values, &el1->values[j]); - if (el2->values[j].data == NULL && - el1->values[j].length != 0) { +failed: + talloc_free(msg2); + return NULL; +} + + +/* + copy a message, allocating new memory for all parts +*/ +struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx, + const struct ldb_message *msg) +{ + struct ldb_message *msg2; + int i, j; + + msg2 = ldb_msg_copy_shallow(mem_ctx, msg); + if (msg2 == NULL) return NULL; + + msg2->dn = ldb_dn_copy(msg2, msg2->dn); + if (msg2->dn == NULL) goto failed; + + for (i=0;i<msg2->num_elements;i++) { + struct ldb_message_element *el = &msg2->elements[i]; + struct ldb_val *values = el->values; + el->name = talloc_strdup(msg2->elements, el->name); + if (el->name == NULL) goto failed; + el->values = talloc_array(msg2->elements, struct ldb_val, el->num_values); + for (j=0;j<el->num_values;j++) { + el->values[j] = ldb_val_dup(el->values, &values[j]); + if (el->values[j].data == NULL && values[j].length != 0) { goto failed; } - el2->num_values++; } - - msg2->num_elements++; } return msg2; @@ -626,7 +643,7 @@ time_t ldb_string_to_time(const char *s) if (s == NULL) return 0; ZERO_STRUCT(tm); - if (sscanf(s, "%04u%02u%02u%02u%02u%02u.0Z", + if (sscanf(s, "%04u%02u%02u%02u%02u%02u", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { return 0; diff --git a/source4/lib/ldb/include/ldb_private.h b/source4/lib/ldb/include/ldb_private.h index 2367d6c3f8..e444b7235a 100644 --- a/source4/lib/ldb/include/ldb_private.h +++ b/source4/lib/ldb/include/ldb_private.h @@ -183,6 +183,8 @@ int ldb_set_attrib_handlers(struct ldb_context *ldb, const struct ldb_attrib_handler *handlers, unsigned num_handlers); int ldb_setup_wellknown_attributes(struct ldb_context *ldb); +int ldb_set_attrib_handler_syntax(struct ldb_context *ldb, + const char *attr, const char *syntax); /* The following definitions come from lib/ldb/common/ldb_attributes.c */ const char **ldb_subclass_list(struct ldb_context *ldb, const char *class); diff --git a/source4/lib/ldb/modules/operational.c b/source4/lib/ldb/modules/operational.c index 911bc087ca..d1e83c02e0 100644 --- a/source4/lib/ldb/modules/operational.c +++ b/source4/lib/ldb/modules/operational.c @@ -126,7 +126,7 @@ static int operational_search_bytree(struct ldb_module *module, attributes to the alias for any hidden attributes that can be fetched directly using non-hidden names */ for (i=0;i<ARRAY_SIZE(search_sub);i++) { - for (a=0;attrs[a];a++) { + for (a=0;attrs && attrs[a];a++) { if (ldb_attr_cmp(attrs[a], search_sub[i].attr) == 0) { if (!search_attrs) { search_attrs = ldb_attr_list_copy(module, attrs); @@ -153,7 +153,7 @@ static int operational_search_bytree(struct ldb_module *module, them (if the aliased entry was not asked for) */ for (r=0;r<ret;r++) { for (i=0;i<ARRAY_SIZE(search_sub);i++) { - for (a=0;attrs[a];a++) { + for (a=0;attrs && attrs[a];a++) { if (ldb_attr_cmp(attrs[a], search_sub[i].attr) != 0) { continue; } @@ -183,15 +183,98 @@ oom: return -1; } +/* + add a time element to a record +*/ +static int add_time_element(struct ldb_message *msg, const char *attr, time_t t) +{ + struct ldb_message_element *el; + char *s; + + if (ldb_msg_find_element(msg, attr) != NULL) { + return 0; + } + + s = ldb_timestring(msg, t); + if (s == NULL) { + return -1; + } + + if (ldb_msg_add_string(msg, attr, s) != 0) { + return -1; + } + + el = ldb_msg_find_element(msg, attr); + /* always set as replace. This works because on add ops, the flag + is ignored */ + el->flags = LDB_FLAG_MOD_REPLACE; + + return 0; +} + + +/* + hook add record ops +*/ +static int operational_add_record(struct ldb_module *module, + const struct ldb_message *msg) +{ + time_t t = time(NULL); + struct ldb_message *msg2; + int ret; + + if (ldb_dn_is_special(msg->dn)) { + return ldb_next_add_record(module, msg); + } + + /* we have to copy the message as the caller might have it as a const */ + msg2 = ldb_msg_copy_shallow(module, msg); + if (msg2 == NULL) { + return -1; + } + if (add_time_element(msg2, "whenCreated", t) != 0 || + add_time_element(msg2, "whenChanged", t) != 0) { + talloc_free(msg2); + return -1; + } + ret = ldb_next_add_record(module, msg2); + talloc_free(msg2); + return ret; +} + +/* + hook modify record ops +*/ +static int operational_modify_record(struct ldb_module *module, + const struct ldb_message *msg) +{ + time_t t = time(NULL); + struct ldb_message *msg2; + int ret; + + if (ldb_dn_is_special(msg->dn)) { + return ldb_next_modify_record(module, msg); + } + + /* we have to copy the message as the caller might have it as a const */ + msg2 = ldb_msg_copy_shallow(module, msg); + if (msg2 == NULL) { + return -1; + } + if (add_time_element(msg2, "whenChanged", t) != 0) { + talloc_free(msg2); + return -1; + } + ret = ldb_next_modify_record(module, msg2); + talloc_free(msg2); + return ret; +} static const struct ldb_module_ops operational_ops = { .name = "operational", .search_bytree = operational_search_bytree, -#if 0 .add_record = operational_add_record, - .modify_record = operational_modify_record, - .rename_record = operational_rename_record -#endif + .modify_record = operational_modify_record }; @@ -213,5 +296,11 @@ struct ldb_module *operational_module_init(struct ldb_context *ldb, const char * ctx->prev = ctx->next = NULL; ctx->ops = &operational_ops; + /* setup some standard attribute handlers */ + ldb_set_attrib_handler_syntax(ldb, "whenCreated", LDB_SYNTAX_UTC_TIME); + ldb_set_attrib_handler_syntax(ldb, "whenChanged", LDB_SYNTAX_UTC_TIME); + ldb_set_attrib_handler_syntax(ldb, "subschemaSubentry", LDB_SYNTAX_DN); + ldb_set_attrib_handler_syntax(ldb, "structuralObjectClass", LDB_SYNTAX_OBJECTCLASS); + return ctx; } diff --git a/source4/lib/ldb/modules/rdn_name.c b/source4/lib/ldb/modules/rdn_name.c index c8f2ebaabd..c51aa74244 100644 --- a/source4/lib/ldb/modules/rdn_name.c +++ b/source4/lib/ldb/modules/rdn_name.c @@ -120,11 +120,9 @@ static int rdn_name_add_record(struct ldb_module *module, const struct ldb_messa } } if (i == attribute->num_values) { - char *error_string = talloc_asprintf(module, "RDN mismatch on %s: %s", ldb_dn_linearize(msg2, msg2->dn), rdn->name); - if (error_string) { - ldb_set_errstring(module, error_string); - ldb_debug(module->ldb, LDB_DEBUG_FATAL, "%s\n", error_string); - } + ldb_debug_set(module->ldb, LDB_DEBUG_FATAL, + "RDN mismatch on %s: %s", + ldb_dn_linearize(msg2, msg2->dn), rdn->name); talloc_free(msg2); return -1; } |