The branch, master has been updated via ab9d9cf s4:ldb: change version to 1.1.0 after adding new functions: via 93d5e7a ldb: add custom flags and functions for the application that wants to manipulate them via f04689a s4:ldb/tests: add tests for ldbmodify and 'modrdn' via e57a23d s4:ldb/tools: add support for "modrdn" to ldbmodify via a3b9522 s4:ldb/ldif: add support for "modrdn" from c7073f8 s3-vfs: rename open function to open_fn.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit ab9d9cfd33f12929dc05f8e02c3d671844e078fa Author: Stefan Metzmacher <me...@samba.org> Date: Sat Apr 9 11:33:03 2011 +0200 s4:ldb: change version to 1.1.0 after adding new functions: ldb_ldif_parse_modrdn() ldb_req_set_custom_flags() ldb_req_get_custom_flags() Signed-off-by: Simo Sorce <i...@samba.org> metze Autobuild-User: Stefan Metzmacher <me...@samba.org> Autobuild-Date: Thu Apr 21 17:15:16 CEST 2011 on sn-devel-104 commit 93d5e7a018cc4d999c2f322902fa337c6af724d1 Author: Matthieu Patou <m...@matws.net> Date: Wed Apr 20 20:26:47 2011 +0400 ldb: add custom flags and functions for the application that wants to manipulate them Signed-off-by: Simo Sorce <i...@samba.org> Signed-off-by: Stefan Metzmacher <me...@samba.org> commit f04689ae63a9dfdca6d5eb8679186561d3e450b4 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Apr 6 20:14:54 2011 +0200 s4:ldb/tests: add tests for ldbmodify and 'modrdn' Signed-off-by: Simo Sorce <i...@samba.org> metze commit e57a23d23f8af229168935681bf3394108df29cd Author: Stefan Metzmacher <me...@samba.org> Date: Tue Apr 5 14:42:06 2011 +0200 s4:ldb/tools: add support for "modrdn" to ldbmodify Signed-off-by: Simo Sorce <i...@samba.org> metze commit a3b952288987e2b62693bdece8c6bd0246f57262 Author: Stefan Metzmacher <me...@samba.org> Date: Tue Apr 5 14:41:27 2011 +0200 s4:ldb/ldif: add support for "modrdn" This add a ldb_ldif_parse_modrdn() helper function to parse the information out of a ldb_message structure. Signed-off-by: Simo Sorce <i...@samba.org> metze ----------------------------------------------------------------------- Summary of changes: .../lib/ldb/ABI/{ldb-1.0.2.sigs => ldb-1.1.0.sigs} | 3 + source4/lib/ldb/common/ldb.c | 38 ++++ source4/lib/ldb/common/ldb_ldif.c | 199 ++++++++++++++++++++ source4/lib/ldb/include/ldb.h | 28 +++- source4/lib/ldb/include/ldb_module.h | 14 ++ source4/lib/ldb/include/ldb_private.h | 2 + source4/lib/ldb/tests/test-generic.sh | 5 +- source4/lib/ldb/tests/test-modify-modrdn.ldif | 12 ++ source4/lib/ldb/tools/ldbmodify.c | 24 +++- source4/lib/ldb/wscript | 2 +- 10 files changed, 323 insertions(+), 4 deletions(-) copy source4/lib/ldb/ABI/{ldb-1.0.2.sigs => ldb-1.1.0.sigs} (98%) create mode 100644 source4/lib/ldb/tests/test-modify-modrdn.ldif Changeset truncated at 500 lines: diff --git a/source4/lib/ldb/ABI/ldb-1.0.2.sigs b/source4/lib/ldb/ABI/ldb-1.1.0.sigs similarity index 98% copy from source4/lib/ldb/ABI/ldb-1.0.2.sigs copy to source4/lib/ldb/ABI/ldb-1.1.0.sigs index c13ac87..149d4bc 100644 --- a/source4/lib/ldb/ABI/ldb-1.0.2.sigs +++ b/source4/lib/ldb/ABI/ldb-1.1.0.sigs @@ -97,6 +97,7 @@ ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, str ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) @@ -193,10 +194,12 @@ ldb_register_module: int (const struct ldb_module_ops *) ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) ldb_req_is_untrusted: bool (struct ldb_request *) ldb_req_location: const char *(struct ldb_request *) ldb_req_mark_trusted: void (struct ldb_request *) ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) ldb_req_set_location: void (struct ldb_request *, const char *) ldb_request: int (struct ldb_context *, struct ldb_request *) ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c index 0aadeb0..433f30b 100644 --- a/source4/lib/ldb/common/ldb.c +++ b/source4/lib/ldb/common/ldb.c @@ -1112,6 +1112,7 @@ int ldb_build_search_req_ex(struct ldb_request **ret_req, req->handle->nesting++; req->handle->parent = parent; req->handle->flags = parent->handle->flags; + req->handle->custom_flags = parent->handle->custom_flags; } *ret_req = req; @@ -1185,6 +1186,7 @@ int ldb_build_add_req(struct ldb_request **ret_req, req->handle->nesting++; req->handle->parent = parent; req->handle->flags = parent->handle->flags; + req->handle->custom_flags = parent->handle->custom_flags; } *ret_req = req; @@ -1229,6 +1231,7 @@ int ldb_build_mod_req(struct ldb_request **ret_req, req->handle->nesting++; req->handle->parent = parent; req->handle->flags = parent->handle->flags; + req->handle->custom_flags = parent->handle->custom_flags; } *ret_req = req; @@ -1273,6 +1276,7 @@ int ldb_build_del_req(struct ldb_request **ret_req, req->handle->nesting++; req->handle->parent = parent; req->handle->flags = parent->handle->flags; + req->handle->custom_flags = parent->handle->custom_flags; } *ret_req = req; @@ -1319,6 +1323,7 @@ int ldb_build_rename_req(struct ldb_request **ret_req, req->handle->nesting++; req->handle->parent = parent; req->handle->flags = parent->handle->flags; + req->handle->custom_flags = parent->handle->custom_flags; } *ret_req = req; @@ -1394,6 +1399,7 @@ int ldb_build_extended_req(struct ldb_request **ret_req, req->handle->nesting++; req->handle->parent = parent; req->handle->flags = parent->handle->flags; + req->handle->custom_flags = parent->handle->custom_flags; } *ret_req = req; @@ -1877,6 +1883,38 @@ void ldb_req_mark_trusted(struct ldb_request *req) } /** + set custom flags. Those flags are set by applications using ldb, + they are application dependent and the same bit can have different + meaning in different application. + */ +void ldb_req_set_custom_flags(struct ldb_request *req, uint32_t flags) +{ + if (req != NULL && req->handle != NULL) { + req->handle->custom_flags = flags; + } +} + + +/** + get custom flags. Those flags are set by applications using ldb, + they are application dependent and the same bit can have different + meaning in different application. + */ +uint32_t ldb_req_get_custom_flags(struct ldb_request *req) +{ + if (req != NULL && req->handle != NULL) { + return req->handle->custom_flags; + } + + /* + * 0 is not something any better or worse than + * anything else as req or the handle is NULL + */ + return 0; +} + + +/** return true is a request is untrusted */ bool ldb_req_is_untrusted(struct ldb_request *req) diff --git a/source4/lib/ldb/common/ldb_ldif.c b/source4/lib/ldb/common/ldb_ldif.c index f837012..63b797c 100644 --- a/source4/lib/ldb/common/ldb_ldif.c +++ b/source4/lib/ldb/common/ldb_ldif.c @@ -261,6 +261,8 @@ static const struct { {"add", LDB_CHANGETYPE_ADD}, {"delete", LDB_CHANGETYPE_DELETE}, {"modify", LDB_CHANGETYPE_MODIFY}, + {"modrdn", LDB_CHANGETYPE_MODRDN}, + {"moddn", LDB_CHANGETYPE_MODRDN}, {NULL, 0} }; @@ -526,6 +528,193 @@ void ldb_ldif_read_free(struct ldb_context *ldb, struct ldb_ldif *ldif) talloc_free(ldif); } +int ldb_ldif_parse_modrdn(struct ldb_context *ldb, + const struct ldb_ldif *ldif, + TALLOC_CTX *mem_ctx, + struct ldb_dn **_olddn, + struct ldb_dn **_newrdn, + bool *_deleteoldrdn, + struct ldb_dn **_newsuperior, + struct ldb_dn **_newdn) +{ + struct ldb_message *msg = ldif->msg; + struct ldb_val *newrdn_val = NULL; + struct ldb_val *deleteoldrdn_val = NULL; + struct ldb_val *newsuperior_val = NULL; + struct ldb_dn *olddn = NULL; + struct ldb_dn *newrdn = NULL; + bool deleteoldrdn = true; + struct ldb_dn *newsuperior = NULL; + struct ldb_dn *newdn = NULL; + struct ldb_val tmp_false; + struct ldb_val tmp_true; + bool ok; + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + + if (tmp_ctx == NULL) { + ldb_debug(ldb, LDB_DEBUG_FATAL, + "Error: talloc_new() failed"); + goto err_op; + } + + if (ldif->changetype != LDB_CHANGETYPE_MODRDN) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: invalid changetype '%d'", + ldif->changetype); + goto err_other; + } + + if (msg->num_elements < 2) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: num_elements[%u] < 2", + msg->num_elements); + goto err_other; + } + + if (msg->num_elements > 3) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: num_elements[%u] > 3", + msg->num_elements); + goto err_other; + } + +#define CHECK_ELEMENT(i, _name, v, needed) do { \ + v = NULL; \ + if (msg->num_elements < (i + 1)) { \ + if (needed) { \ + ldb_debug(ldb, LDB_DEBUG_ERROR, \ + "Error: num_elements[%u] < (%u + 1)", \ + msg->num_elements, i); \ + goto err_other; \ + } \ + } else if (ldb_attr_cmp(msg->elements[i].name, _name) != 0) { \ + ldb_debug(ldb, LDB_DEBUG_ERROR, \ + "Error: elements[%u].name[%s] != [%s]", \ + i, msg->elements[i].name, _name); \ + goto err_other; \ + } else if (msg->elements[i].flags != 0) { \ + ldb_debug(ldb, LDB_DEBUG_ERROR, \ + "Error: elements[%u].flags[0x%X} != [0x0]", \ + i, msg->elements[i].flags); \ + goto err_other; \ + } else if (msg->elements[i].num_values != 1) { \ + ldb_debug(ldb, LDB_DEBUG_ERROR, \ + "Error: elements[%u].num_values[%u] != 1", \ + i, msg->elements[i].num_values); \ + goto err_other; \ + } else { \ + v = &msg->elements[i].values[0]; \ + } \ +} while (0) + + CHECK_ELEMENT(0, "newrdn", newrdn_val, true); + CHECK_ELEMENT(1, "deleteoldrdn", deleteoldrdn_val, true); + CHECK_ELEMENT(2, "newsuperior", newsuperior_val, false); + +#undef CHECK_ELEMENT + + olddn = ldb_dn_copy(tmp_ctx, msg->dn); + if (olddn == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: failed to copy olddn '%s'", + ldb_dn_get_linearized(msg->dn)); + goto err_op; + } + + newrdn = ldb_dn_from_ldb_val(tmp_ctx, ldb, newrdn_val); + if (!ldb_dn_validate(newrdn)) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: Unable to parse dn '%s'", + (char *)newrdn_val->data); + goto err_dn; + } + + tmp_false.length = 1; + tmp_false.data = discard_const_p(uint8_t, "0"); + tmp_true.length = 1; + tmp_true.data = discard_const_p(uint8_t, "1"); + if (ldb_val_equal_exact(deleteoldrdn_val, &tmp_false) == 1) { + deleteoldrdn = false; + } else if (ldb_val_equal_exact(deleteoldrdn_val, &tmp_true) == 1) { + deleteoldrdn = true; + } else { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: deleteoldrdn value invalid '%s' not '0'/'1'", + (char *)deleteoldrdn_val->data); + goto err_attr; + } + + if (newsuperior_val) { + newsuperior = ldb_dn_from_ldb_val(tmp_ctx, ldb, newsuperior_val); + if (!ldb_dn_validate(newsuperior)) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: Unable to parse dn '%s'", + (char *)newsuperior_val->data); + goto err_dn; + } + } else { + newsuperior = ldb_dn_get_parent(tmp_ctx, msg->dn); + if (newsuperior == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: Unable to get parent dn '%s'", + ldb_dn_get_linearized(msg->dn)); + goto err_dn; + } + } + + newdn = ldb_dn_copy(tmp_ctx, newrdn); + if (newdn == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: failed to copy newrdn '%s'", + ldb_dn_get_linearized(newrdn)); + goto err_op; + } + + ok = ldb_dn_add_base(newdn, newsuperior); + if (!ok) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: failed to base '%s' to newdn '%s'", + ldb_dn_get_linearized(newsuperior), + ldb_dn_get_linearized(newdn)); + goto err_op; + } + + if (_olddn) { + *_olddn = talloc_move(mem_ctx, &olddn); + } + if (_newrdn) { + *_newrdn = talloc_move(mem_ctx, &newrdn); + } + if (_deleteoldrdn) { + *_deleteoldrdn = deleteoldrdn; + } + if (_newsuperior) { + if (newsuperior_val) { + *_newrdn = talloc_move(mem_ctx, &newrdn); + } else { + *_newrdn = NULL; + } + } + if (_newdn) { + *_newdn = talloc_move(mem_ctx, &newdn); + } + + talloc_free(tmp_ctx); + return LDB_SUCCESS; +err_other: + talloc_free(tmp_ctx); + return LDB_ERR_OTHER; +err_op: + talloc_free(tmp_ctx); + return LDB_ERR_OPERATIONS_ERROR; +err_attr: + talloc_free(tmp_ctx); + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; +err_dn: + talloc_free(tmp_ctx); + return LDB_ERR_INVALID_DN_SYNTAX; +} + /* read from a LDIF source, creating a ldb_message */ @@ -682,6 +871,16 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, } } + if (ldif->changetype == LDB_CHANGETYPE_MODRDN) { + int ret; + + ret = ldb_ldif_parse_modrdn(ldb, ldif, ldif, + NULL, NULL, NULL, NULL, NULL); + if (ret != LDB_SUCCESS) { + goto failed; + } + } + return ldif; failed: diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h index f5d5940..d745f37 100644 --- a/source4/lib/ldb/include/ldb.h +++ b/source4/lib/ldb/include/ldb.h @@ -183,7 +183,8 @@ enum ldb_changetype { LDB_CHANGETYPE_NONE=0, LDB_CHANGETYPE_ADD, LDB_CHANGETYPE_DELETE, - LDB_CHANGETYPE_MODIFY + LDB_CHANGETYPE_MODIFY, + LDB_CHANGETYPE_MODRDN }; /** @@ -1621,6 +1622,31 @@ struct ldb_ldif *ldb_ldif_read_file(struct ldb_context *ldb, FILE *f); struct ldb_ldif *ldb_ldif_read_string(struct ldb_context *ldb, const char **s); /** + Parse a modrdn LDIF message from a struct ldb_message + + \param ldb the ldb context (from ldb_init()) + \param ldif the preparsed LDIF chunk (from ldb_ldif_read()) + + \param mem_ctx the memory context that's used for return values + + \param olddn the old dn as struct ldb_dn, if not needed pass NULL + \param newrdn the new rdn as struct ldb_dn, if not needed pass NULL + \param deleteoldrdn the deleteoldrdn value as bool, if not needed pass NULL + \param newsuperior the newsuperior dn as struct ldb_dn, if not needed pass NULL + *newsuperior can be NULL as it is optional in the LDIF + \param newdn the full constructed new dn as struct ldb_dn, if not needed pass NULL + +*/ +int ldb_ldif_parse_modrdn(struct ldb_context *ldb, + const struct ldb_ldif *ldif, + TALLOC_CTX *mem_ctx, + struct ldb_dn **olddn, + struct ldb_dn **newrdn, + bool *deleteoldrdn, + struct ldb_dn **newsuperior, + struct ldb_dn **newdn); + +/** Write an LDIF message to a file \param ldb the ldb context (from ldb_init()) diff --git a/source4/lib/ldb/include/ldb_module.h b/source4/lib/ldb/include/ldb_module.h index db8726b..6d6fff2 100644 --- a/source4/lib/ldb/include/ldb_module.h +++ b/source4/lib/ldb/include/ldb_module.h @@ -240,6 +240,20 @@ void ldb_req_mark_trusted(struct ldb_request *req); */ bool ldb_req_is_untrusted(struct ldb_request *req); +/** + set custom flags. Those flags are set by applications using ldb, + they are application dependent and the same bit can have different + meaning in different application. + */ +void ldb_req_set_custom_flags(struct ldb_request *req, uint32_t flags); + +/** + get custom flags. Those flags are set by applications using ldb, + they are application dependent and the same bit can have different + meaning in different application. + */ +uint32_t ldb_req_get_custom_flags(struct ldb_request *req); + /* load all modules from the given directory */ int ldb_modules_load(const char *modules_path, const char *version); diff --git a/source4/lib/ldb/include/ldb_private.h b/source4/lib/ldb/include/ldb_private.h index 5397b79..cafc020 100644 --- a/source4/lib/ldb/include/ldb_private.h +++ b/source4/lib/ldb/include/ldb_private.h @@ -58,6 +58,8 @@ struct ldb_handle { enum ldb_state state; struct ldb_context *ldb; unsigned flags; + /* flags dedicated to be set by application using ldb */ + uint32_t custom_flags; unsigned nesting; /* used for debugging */ diff --git a/source4/lib/ldb/tests/test-generic.sh b/source4/lib/ldb/tests/test-generic.sh index 8bbb769..ae9ff73 100755 --- a/source4/lib/ldb/tests/test-generic.sh +++ b/source4/lib/ldb/tests/test-generic.sh @@ -22,7 +22,10 @@ $VALGRIND ldbmodify$EXEEXT $LDBDIR/tests/test-modify.ldif || exit 1 echo "Showing modified record" $VALGRIND ldbsearch$EXEEXT '(uid=uham)' || exit 1 -echo "Rename entry" +echo "Rename entry with ldbmodify - modrdn" +$VALGRIND ldbmodify$EXEEXT $LDBDIR/tests/test-modify-modrdn.ldif || exit 1 + +echo "Rename entry with ldbrename" OLDDN="cn=Ursula Hampster,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST" NEWDN="cn=Hampster Ursula,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST" $VALGRIND ldbrename$EXEEXT "$OLDDN" "$NEWDN" || exit 1 diff --git a/source4/lib/ldb/tests/test-modify-modrdn.ldif b/source4/lib/ldb/tests/test-modify-modrdn.ldif new file mode 100644 index 0000000..efa3149 --- /dev/null +++ b/source4/lib/ldb/tests/test-modify-modrdn.ldif @@ -0,0 +1,12 @@ +dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,o=University of Michiga + n,c=TEST +changetype: moddn +newrdn: cn=Hampster Ursula +deleteoldrdn: 1 +newsuperior: ou=Alumni Association,ou=People,o=University of Michigan,c=TEST + +dn: cn=Hampster Ursula,ou=Alumni Association,ou=People,o=University of Michiga + n,c=TEST +changetype: modrdn +newrdn: cn=Ursula Hampster +deleteoldrdn: 1 diff --git a/source4/lib/ldb/tools/ldbmodify.c b/source4/lib/ldb/tools/ldbmodify.c index 1e7aa80..2ca7b62 100644 --- a/source4/lib/ldb/tools/ldbmodify.c +++ b/source4/lib/ldb/tools/ldbmodify.c @@ -61,6 +61,11 @@ static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count) } while ((ldif = ldb_ldif_read_file(ldb, f))) { + struct ldb_dn *olddn; + bool deleteoldrdn = false; + struct ldb_dn *newdn; + const char *errstr = NULL; + switch (ldif->changetype) { case LDB_CHANGETYPE_NONE: case LDB_CHANGETYPE_ADD: @@ -72,11 +77,28 @@ static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count) case LDB_CHANGETYPE_MODIFY: ret = ldb_modify_ctrl(ldb, ldif->msg,req_ctrls); break; + case LDB_CHANGETYPE_MODRDN: + ret = ldb_ldif_parse_modrdn(ldb, ldif, ldif, &olddn, + NULL, &deleteoldrdn, + NULL, &newdn); + if (ret == LDB_SUCCESS) { + if (deleteoldrdn) { + ret = ldb_rename(ldb, olddn, newdn); + } else { + errstr = "modrdn: deleteoldrdn=0 " + "not supported."; + ret = LDB_ERR_CONSTRAINT_VIOLATION; + } + } + break; } if (ret != LDB_SUCCESS) { + if (errstr == NULL) { + errstr = ldb_errstring(ldb); + } -- Samba Shared Repository