summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Dieter Wallnöfer <mdw@samba.org>2010-05-31 14:52:46 +0200
committerMatthias Dieter Wallnöfer <mdw@samba.org>2010-06-06 20:47:10 +0200
commitcadf774f8b8af2aedcdd359acf51695e9f4b04db (patch)
tree673c776cbd46c8c7a4e2ab932ae81ddd7a874e7b
parentfa2a86ec61a80f7fe85a2bb9668885a0b287afd6 (diff)
downloadsamba-cadf774f8b8af2aedcdd359acf51695e9f4b04db.tar.gz
samba-cadf774f8b8af2aedcdd359acf51695e9f4b04db.tar.bz2
samba-cadf774f8b8af2aedcdd359acf51695e9f4b04db.zip
s4:dsdb/common/util.c - provide a better implementation of the "samdb_msg_add_(add/del)val" calls
This supports now also coexisting add and delete message elements with the same attribute name.
-rw-r--r--source4/dsdb/common/util.c118
1 files changed, 90 insertions, 28 deletions
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 408a959276..811d4745a7 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -837,52 +837,114 @@ int samdb_msg_add_delete(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struc
}
/*
- add a add attribute value to a message
+ add an add attribute value to a message or enhance an existing attribute
+ which has the same name and the add flag set.
*/
-int samdb_msg_add_addval(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
- const char *attr_name, const char *value)
+int samdb_msg_add_addval(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx,
+ struct ldb_message *msg, const char *attr_name,
+ const char *value)
{
struct ldb_message_element *el;
- char *a, *v;
+ struct ldb_val val, *vals;
+ char *v;
+ unsigned int i;
+ bool found = false;
int ret;
- a = talloc_strdup(mem_ctx, attr_name);
- if (a == NULL)
- return LDB_ERR_OPERATIONS_ERROR;
+
v = talloc_strdup(mem_ctx, value);
- if (v == NULL)
+ if (v == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
- ret = ldb_msg_add_string(msg, a, v);
- if (ret != 0)
- return ret;
- el = ldb_msg_find_element(msg, a);
- if (el == NULL)
+ }
+
+ val.data = (uint8_t *) v;
+ val.length = strlen(v);
+
+ if (val.length == 0) {
+ /* allow empty strings as non-existent attributes */
+ return LDB_SUCCESS;
+ }
+
+ for (i = 0; i < msg->num_elements; i++) {
+ el = &msg->elements[i];
+ if ((ldb_attr_cmp(el->name, attr_name) == 0) &&
+ (el->flags == LDB_FLAG_MOD_ADD)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ ret = ldb_msg_add_empty(msg, attr_name, LDB_FLAG_MOD_ADD,
+ &el);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+
+ vals = talloc_realloc(msg, el->values, struct ldb_val,
+ el->num_values + 1);
+ if (vals == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
- el->flags = LDB_FLAG_MOD_ADD;
+ }
+ el->values = vals;
+ el->values[el->num_values] = val;
+ ++(el->num_values);
+
return LDB_SUCCESS;
}
/*
- add a delete attribute value to a message
+ add a delete attribute value to a message or enhance an existing attribute
+ which has the same name and the delete flag set.
*/
-int samdb_msg_add_delval(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
- const char *attr_name, const char *value)
+int samdb_msg_add_delval(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx,
+ struct ldb_message *msg, const char *attr_name,
+ const char *value)
{
struct ldb_message_element *el;
- char *a, *v;
+ struct ldb_val val, *vals;
+ char *v;
+ unsigned int i;
+ bool found = false;
int ret;
- a = talloc_strdup(mem_ctx, attr_name);
- if (a == NULL)
- return LDB_ERR_OPERATIONS_ERROR;
+
v = talloc_strdup(mem_ctx, value);
- if (v == NULL)
+ if (v == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
- ret = ldb_msg_add_string(msg, a, v);
- if (ret != 0)
- return ret;
- el = ldb_msg_find_element(msg, a);
- if (el == NULL)
+ }
+
+ val.data = (uint8_t *) v;
+ val.length = strlen(v);
+
+ if (val.length == 0) {
+ /* allow empty strings as non-existent attributes */
+ return LDB_SUCCESS;
+ }
+
+ for (i = 0; i < msg->num_elements; i++) {
+ el = &msg->elements[i];
+ if ((ldb_attr_cmp(el->name, attr_name) == 0) &&
+ (el->flags == LDB_FLAG_MOD_DELETE)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ ret = ldb_msg_add_empty(msg, attr_name, LDB_FLAG_MOD_DELETE,
+ &el);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+
+ vals = talloc_realloc(msg, el->values, struct ldb_val,
+ el->num_values + 1);
+ if (vals == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
- el->flags = LDB_FLAG_MOD_DELETE;
+ }
+ el->values = vals;
+ el->values[el->num_values] = val;
+ ++(el->num_values);
+
return LDB_SUCCESS;
}