svn commit: samba r3099 - in branches/SAMBA_4_0/source/ldap_server: .

metze at samba.org metze at samba.org
Wed Oct 20 23:27:25 GMT 2004


Author: metze
Date: 2004-10-20 23:27:09 +0000 (Wed, 20 Oct 2004)
New Revision: 3099

WebSVN: http://websvn.samba.org/websvn/changeset.php?rep=samba&path=/branches/SAMBA_4_0/source/ldap_server&rev=3099&nolog=1

Log:
implment sldb_ModifyDN()

metze

Modified:
   branches/SAMBA_4_0/source/ldap_server/ldap_simple_ldb.c


Changeset:
Modified: branches/SAMBA_4_0/source/ldap_server/ldap_simple_ldb.c
===================================================================
--- branches/SAMBA_4_0/source/ldap_server/ldap_simple_ldb.c	2004-10-20 23:25:39 UTC (rev 3098)
+++ branches/SAMBA_4_0/source/ldap_server/ldap_simple_ldb.c	2004-10-20 23:27:09 UTC (rev 3099)
@@ -510,12 +510,111 @@
 	return ldapsrv_queue_reply(call, compare_r);
 }
 
+NTSTATUS sldb_ModifyDN(struct ldapsrv_partition *partition, struct ldapsrv_call *call, struct ldap_ModifyDNRequest *r)
+{
+	void *local_ctx;
+	struct ldap_dn *olddn, *newrdn, *newsuperior;
+	struct ldap_Result *modifydn;
+	struct ldapsrv_reply *modifydn_r;
+	int ldb_ret;
+	struct samdb_context *samdb;
+	const char *errstr = NULL;
+	int result = LDAP_SUCCESS;
+	const char *newdn;
+	char *parentdn = NULL;
+
+	local_ctx = talloc_named(call, 0, "sldb_ModifyDN local memory context");
+	ALLOC_CHECK(local_ctx);
+
+	samdb = samdb_connect(local_ctx);
+	ALLOC_CHECK(samdb);
+
+	olddn = ldap_parse_dn(local_ctx, r->dn);
+	VALID_DN_SYNTAX(olddn,2);
+
+	newrdn = ldap_parse_dn(local_ctx, r->newrdn);
+	VALID_DN_SYNTAX(newrdn,1);
+
+	DEBUG(10, ("sldb_ModifyDN: olddn: [%s]\n", olddn->dn));
+	DEBUG(10, ("sldb_ModifyDN: newrdn: [%s]\n", newrdn->dn));
+
+	/* we can't handle the rename if we should not remove the old dn */
+	if (!r->deleteolddn) {
+		result = LDAP_UNWILLING_TO_PERFORM;
+		errstr = "Old RDN must be deleted";
+		goto reply;
+	}
+
+	if (newrdn->comp_num > 1) {
+		result = LDAP_NAMING_VIOLATION;
+		errstr = "Error new RDN invalid";
+		goto reply;
+	}
+
+	if (r->newsuperior) {
+		newsuperior = ldap_parse_dn(local_ctx, r->newsuperior);
+		VALID_DN_SYNTAX(newsuperior,0);
+		DEBUG(10, ("sldb_ModifyDN: newsuperior: [%s]\n", newsuperior->dn));
+		
+		if (newsuperior->comp_num < 1) {
+			result = LDAP_AFFECTS_MULTIPLE_DSAS;
+			errstr = "Error new Superior DN invalid";
+			goto reply;
+		}
+		parentdn = newsuperior->dn;
+	}
+
+	if (!parentdn) {
+		int i;
+		parentdn = talloc_strdup(local_ctx, olddn->components[1]->component);
+		ALLOC_CHECK(parentdn);
+		for(i=2; i < olddn->comp_num; i++) {
+			char *old = parentdn;
+			parentdn = talloc_asprintf(local_ctx, "%s,%s", old, olddn->components[i]->component);
+			ALLOC_CHECK(parentdn);
+			talloc_free(old);
+		}
+	}
+	newdn = talloc_asprintf(local_ctx, "%s,%s", newrdn->dn, parentdn);
+	ALLOC_CHECK(newdn);
+
+reply:
+	modifydn_r = ldapsrv_init_reply(call, LDAP_TAG_ModifyDNResponse);
+	ALLOC_CHECK(modifydn_r);
+
+	if (result == LDAP_SUCCESS) {
+		ldb_set_alloc(samdb->ldb, talloc_realloc_fn, samdb);
+		ldb_ret = ldb_rename(samdb->ldb, olddn->dn, newdn);
+		if (ldb_ret == 0) {
+			result = LDAP_SUCCESS;
+			errstr = NULL;
+		} else {
+			/* currently we have no way to tell if there was an internal ldb error
+			 * or if the object was not found, return the most probable error
+			 */
+			result = LDAP_NO_SUCH_OBJECT;
+			errstr = ldb_errstring(samdb->ldb);
+		}
+	}
+
+	modifydn = &modifydn_r->msg.r.ModifyDNResponse;
+	modifydn->dn = NULL;
+	modifydn->resultcode = result;
+	modifydn->errormessage = (errstr?talloc_strdup(modifydn_r,errstr):NULL);
+	modifydn->referral = NULL;
+
+	talloc_free(local_ctx);
+
+	return ldapsrv_queue_reply(call, modifydn_r);
+}
+
 static const struct ldapsrv_partition_ops sldb_ops = {
 	.Search		= sldb_Search,
 	.Add		= sldb_Add,
 	.Del		= sldb_Del,
 	.Modify		= sldb_Modify,
-	.Compare	= sldb_Compare
+	.Compare	= sldb_Compare,
+	.ModifyDN	= sldb_ModifyDN
 };
 
 const struct ldapsrv_partition_ops *ldapsrv_get_sldb_partition_ops(void)



More information about the samba-cvs mailing list