ldb_rename()

Stefan (metze) Metzmacher metze at samba.org
Mon Oct 18 19:55:15 GMT 2004


Hi tridge,

here's a preview patch for implmenting ldb_rename()

it's not complete currently, I need to test the semantics of
LDB_RENAME_FLG_DELETE_OLDRDN in ldap.

Can you look at the ltdb code and tell me if this looks ok or not?

-- 
metze

Stefan Metzmacher <metze at samba.org> www.samba.org
-------------- next part --------------
Index: lib/ldb/tools/ldbrename.c
===================================================================
--- lib/ldb/tools/ldbrename.c	(revision 0)
+++ lib/ldb/tools/ldbrename.c	(revision 0)
@@ -0,0 +1,109 @@
+/* 
+   ldb database library
+
+   Copyright (C) Andrew Tridgell  2004
+   Copyright (C) Stefan Metzmacher  2004
+
+     ** NOTE! The following LGPL license applies to the ldb
+     ** library. This does NOT imply that all of Samba is released
+     ** under the LGPL
+   
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+/*
+ *  Name: ldb
+ *
+ *  Component: ldbrename
+ *
+ *  Description: utility to rename records - modelled on ldapmodrdn
+ *
+ *  Author: Andrew Tridgell
+ *  Author: Stefan Metzmacher
+ */
+
+#include "includes.h"
+
+static void usage(void)
+{
+	printf("Usage: ldbrename [<options>] <olddn> <newdn>\n");
+	printf("Options:\n");
+	printf("  -r               remove old RDN\n");
+	printf("  -H ldb_url       choose the database (or $LDB_URL)\n");
+	printf("\n");
+	printf("Renames records in a ldb\n\n");
+	exit(1);
+}
+
+
+ int main(int argc, char * const argv[])
+{
+	struct ldb_context *ldb;
+	const char *ldb_url;
+	int opt, ret;
+	int flags = 0;
+
+	ldb_url = getenv("LDB_URL");
+
+	while ((opt = getopt(argc, argv, "hH:r")) != EOF) {
+		switch (opt) {
+		case 'H':
+			ldb_url = optarg;
+			break;
+
+		case 'r':
+			flags |=LDB_RENAME_FLG_DELETE_OLDRDN;
+			break;
+
+		case 'h':
+		default:
+			usage();
+			break;
+		}
+	}
+
+	if (!ldb_url) {
+		fprintf(stderr, "You must specify a ldb URL\n\n");
+		usage();
+	}
+
+	argc -= optind;
+	argv += optind;
+
+	ldb = ldb_connect(ldb_url, 0, NULL);
+
+	if (!ldb) {
+		perror("ldb_connect");
+		exit(1);
+	}
+
+	ldb_set_debug_stderr(ldb);
+
+	if (argc < 2) {
+		usage();
+	}
+
+	ret = ldb_rename(ldb, argv[0], argv[1], flags);
+	if (ret == 0) {
+		printf("Renamed 1 record\n");
+	} else  {
+		printf("rename of '%s' to '%s' rmolddn:%d failed - %s\n", 
+			argv[0], argv[1], flags, ldb_errstring(ldb));
+	}
+
+	ldb_close(ldb);
+	
+	return 0;
+}
Index: lib/ldb/ldb_ldap/ldb_ldap.c
===================================================================
--- lib/ldb/ldb_ldap/ldb_ldap.c	(revision 3047)
+++ lib/ldb/ldb_ldap/ldb_ldap.c	(working copy)
@@ -92,6 +92,33 @@
 }
 
 /*
+  rename a record
+  flags could be LDB_RENAME_FLG_DELETE_OLDRDN
+*/
+static int lldb_rename(struct ldb_context *ldb, const char *olddn, const char *newdn, unsigned int flags)
+{
+	struct lldb_private *lldb = ldb->private_data;
+	int ret = 0;
+	int deleteoldrdn = 0;
+
+	/* ignore ltdb specials */
+	if (olddn[0] == '@' ||newdn[0] == '@') {
+		return 0;
+	}
+
+	if (flags & LDB_RENAME_FLG_DELETE_OLDRDN) {
+		deleteoldrdn = 1;
+	}
+
+	lldb->last_rc = ldap_modrdn2_s(lldb->ldap, olddn, newdn, deleteoldrdn);
+	if (lldb->last_rc != LDAP_SUCCESS) {
+		ret = -1;
+	}
+
+	return ret;
+}
+
+/*
   delete a record
 */
 static int lldb_delete(struct ldb_context *ldb, const char *dn)
@@ -465,6 +492,7 @@
 	lldb_add,
 	lldb_modify,
 	lldb_delete,
+	lldb_rename,
 	lldb_errstring
 };
 
Index: lib/ldb/include/ldb.h
===================================================================
--- lib/ldb/include/ldb.h	(revision 3047)
+++ lib/ldb/include/ldb.h	(working copy)
@@ -2,6 +2,7 @@
    ldb database library
 
    Copyright (C) Andrew Tridgell  2004
+   Copyright (C) Stefan Metzmacher  2004
 
      ** NOTE! The following LGPL license applies to the ldb
      ** library. This does NOT imply that all of Samba is released
@@ -30,6 +31,7 @@
  *  Description: defines for base ldb API
  *
  *  Author: Andrew Tridgell
+ *  Author: Stefan Metzmacher
  */
 
 #ifndef _LDB_H_
@@ -131,6 +133,7 @@
 	int (*add_record)(struct ldb_context *, const struct ldb_message *);
 	int (*modify_record)(struct ldb_context *, const struct ldb_message *);
 	int (*delete_record)(struct ldb_context *, const char *);
+	int (*rename_record)(struct ldb_context *, const char *olddn, const char *newdn, unsigned int flags);
 	const char * (*errstring)(struct ldb_context *);
 
 	/* this is called when the alloc ops changes to ensure we 
@@ -235,6 +238,13 @@
 	       const struct ldb_message *message);
 
 /*
+  rename a record in the database
+*/
+#define LDB_RENAME_FLG_DELETE_OLDRDN (1<<0)
+int ldb_rename(struct ldb_context *ldb, 
+	       const char *olddn, const char *newdn, unsigned int flags);
+
+/*
   delete a record from the database
 */
 int ldb_delete(struct ldb_context *ldb, const char *dn);
Index: lib/ldb/config.m4
===================================================================
--- lib/ldb/config.m4	(revision 3047)
+++ lib/ldb/config.m4	(working copy)
@@ -23,3 +23,5 @@
 SMB_BINARY_MK(ldbsearch,lib/ldb/config.mk)
 
 SMB_BINARY_MK(ldbedit,lib/ldb/config.mk)
+
+SMB_BINARY_MK(ldbrename,lib/ldb/config.mk)
Index: lib/ldb/common/ldb.c
===================================================================
--- lib/ldb/common/ldb.c	(revision 3047)
+++ lib/ldb/common/ldb.c	(working copy)
@@ -140,6 +140,17 @@
 }
 
 /*
+  rename a record in the database
+*/
+int ldb_rename(struct ldb_context *ldb, const char *olddn, const char *newdn, unsigned int flags)
+{
+	int ret;
+	ret = ldb->ops->rename_record(ldb, olddn, newdn, flags);
+	ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_rename(%s,%s,%d) -> %d\n", olddn, newdn, flags, ret);
+	return ret;
+}
+
+/*
   return extended error information 
 */
 const char *ldb_errstring(struct ldb_context *ldb)
Index: lib/ldb/ldb_tdb/ldb_tdb.c
===================================================================
--- lib/ldb/ldb_tdb/ldb_tdb.c	(revision 3047)
+++ lib/ldb/ldb_tdb/ldb_tdb.c	(working copy)
@@ -582,6 +582,69 @@
 }
 
 /*
+  rename a record
+*/
+static int ltdb_rename(struct ldb_context *ldb, const char *olddn, const char *newdn, unsigned int flags)
+{
+	struct ltdb_private *ltdb = ldb->private_data;
+	int ret;
+	struct ldb_message msg;
+
+	/* TODO: handle flags correct 
+	 *       the LDB_RENAME_FLG_DELETE_OLDRDN should be checked
+	 */
+
+	ltdb->last_err_string = NULL;
+
+	if (ltdb_lock(ldb) != 0) {
+		return -1;
+	}
+
+	if (ltdb_cache_load(ldb) != 0) {
+		ltdb_unlock(ldb);
+		return -1;
+	}
+
+	/* in case any attribute of the message was indexed, we need
+	   to fetch the old record */
+	ret = ltdb_search_dn1(ldb, olddn, &msg);
+	if (ret != 1) {
+		/* not finding the old record is an error */
+		goto failed;
+	}
+
+	msg.dn = discard_const_p(char, newdn);
+
+	ret = ltdb_store(ldb, &msg, TDB_INSERT);
+	if (ret == -1) {
+		ltdb_search_dn1_free(ldb, &msg);
+		goto failed;
+	}
+
+	ret = ltdb_delete_noindex(ldb, olddn);
+	if (ret == -1) {
+		ltdb_delete_noindex(ldb, newdn);
+		ltdb_search_dn1_free(ldb, &msg);
+		goto failed;
+	}
+
+	/* remove any indexed attributes of the old dn */
+	msg.dn = discard_const_p(char, olddn);
+	ret = ltdb_index_del(ldb, &msg);
+
+	ltdb_search_dn1_free(ldb, &msg);
+
+	ltdb_modified(ldb, newdn);
+
+	ltdb_unlock(ldb);
+
+	return ret;
+failed:
+	ltdb_unlock(ldb);
+	return -1;
+}
+
+/*
   close database
 */
 static int ltdb_close(struct ldb_context *ldb)
@@ -621,6 +684,7 @@
 	ltdb_add,
 	ltdb_modify,
 	ltdb_delete,
+	ltdb_rename,
 	ltdb_errstring,
 	ltdb_cache_free
 };
Index: lib/ldb/config.mk
===================================================================
--- lib/ldb/config.mk	(revision 3047)
+++ lib/ldb/config.mk	(working copy)
@@ -102,3 +102,13 @@
 		LIBBASIC CONFIG LIBCMDLINE LIBLDB
 # End BINARY ldbedit
 ################################################
+
+################################################
+# Start BINARY ldbrename
+[BINARY::ldbrename]
+OBJ_FILES= \
+		lib/ldb/tools/ldbrename.o
+REQUIRED_SUBSYSTEMS = \
+		LIBBASIC CONFIG LIBCMDLINE LIBLDB
+# End BINARY ldbrename
+################################################


More information about the samba-technical mailing list