making ldap DNs a bit easier to work with

tridge at samba.org tridge at samba.org
Thu Dec 10 17:46:59 MST 2009


Hi Simo,

I'm curious what you think about the patch below.

One of the things that has always annoyed me about LDAP is the
verboseness of the command lines, and the fact that you need to keep
changing long DNs when talking to different servers. This also affects
ldif files, test scripts etc. I've typed in long DNs far too often,
and it gets tiring.

So the patch below makes life easier by allowing a special '@'
component in any DN which then expands to the base DN of the
database. This means you can do something like:

  ldbsearch -b CN=Users,@

and the '@' would get auto-replaced by the base DN of the database you
are connecting to. It also works in ldif, so you can do:

 dn: CN=testc,CN=Users,@
 objectclass: container

I think this would make life much easier for testing, for sharing
command lines when helping someone on IRC and when administering lots
of LDAP servers. The number of times I've mis-typed a very long base
DN is huge, and it seems to me that computers are supposed to make
life easier, and remove this sort of drudgery.

So, what do you think?

Cheers, Tridge

PS: I've CCd Howard as he may have comments :-)


diff --git a/source4/lib/ldb/common/ldb_dn.c b/source4/lib/ldb/common/ldb_dn.c
index 6b1278e..865cd72 100644
--- a/source4/lib/ldb/common/ldb_dn.c
+++ b/source4/lib/ldb/common/ldb_dn.c
@@ -91,6 +91,8 @@ struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx,
                                    const struct ldb_val *strdn)
 {
 	struct ldb_dn *dn;
+	char *newstr = NULL;
+	struct ldb_val v;
 
 	if (! ldb) return NULL;
 
@@ -103,8 +105,28 @@ struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx,
 	dn = talloc_zero(mem_ctx, struct ldb_dn);
 	LDB_DN_NULL_FAILED(dn);
 
+
 	dn->ldb = ldb;
 
+	/* magic handling for the @ DN component. This makes scripted
+	   testing much easier, and also saves a lot of typing on
+	   command lines. If the last component of a DN is an @ then
+	   replace it with the basedn of the database. */
+	if (strdn->data && strdn->length && 
+	    strdn->data[strdn->length-1] == '@' &&
+	    (strdn->length==1 || strdn->data[strdn->length-2]==',')) {
+		newstr = talloc_asprintf(dn, "%.*s%s", 
+					    (int)(strdn->length-1), strdn->data,
+					    ldb_dn_get_linearized(ldb_get_default_basedn(ldb)));
+		if (newstr == NULL) {
+			ldb_oom(ldb);
+			return NULL;
+		}
+		v.data = (uint8_t *)newstr;
+		v.length = strlen(newstr);
+		strdn = &v;
+	}
+
 	if (strdn->data && strdn->length) {
 		const char *data = (const char *)strdn->data;
 		size_t length = strdn->length;
@@ -140,6 +162,7 @@ struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx,
 		LDB_DN_NULL_FAILED(dn->linearized);
 	}
 
+	talloc_free(newstr);
 	return dn;
 
 failed:



More information about the samba-technical mailing list