diff mbox

[7/8] libnsdb: create new-style NCEs

Message ID 20131113215433.23593.9352.stgit@seurat.1015granger.net
State Accepted
Headers show

Commit Message

Chuck Lever Nov. 13, 2013, 9:54 p.m. UTC
When constructing an NSDB, part of the process currently involves
adding a fedfsNceDN attribute to one or more root suffix entries in
an LDAP server's rootDSE.

Simo Sorce (FreeIPA) points out it may be difficult or impossible
for some LDAP server implementations to allow modification of their
root DSE.  Or it could be a problem for some deployments to allow
root DSE modification.  For this reason, LDAP applications typically
use an approach that does not require root DSE modification.

My own experience with OpenLDAP and 389-ds is that rootDSE
modification is quite awkward.  Long-term, we'd like to replace
fedfsNsdbContainerInfo and fedfsNceDN with a form of NCE discovery
that is simpler to configure.

Old-style NCE discovery works like this: For each of the server's
naming contexts, an NSDB client performs this query:

  ldapsearch -b "naming_context" -s base (objectClass=*) fedfsNceDN

The fedfsNceDN attribute contains the full distinguished name of
the NCE residing under that naming context (root suffix).

New-style NCE discovery works like this:  An NCE contains an
auxiliary object class called fedfsNsdbContainerEntry.  For each of
the server's naming contexts, an NSDB client performs this query:

  ldapsearch -b "naming_context" -s subtree \
		(objectClass=fedfsNsdbContainerEntry)

The response carries the distinguished name of the NCE residing
under that naming context, or NO_SUCH_OBJECT.

When creating new-style NCEs, insert the fedfsNsdbContainerEntry
object class.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 src/libnsdb/administrator.c |   58 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 56 insertions(+), 2 deletions(-)
diff mbox

Patch

diff --git a/src/libnsdb/administrator.c b/src/libnsdb/administrator.c
index 4fd93ec..2e4aa0d 100644
--- a/src/libnsdb/administrator.c
+++ b/src/libnsdb/administrator.c
@@ -1242,6 +1242,8 @@  nsdb_update_fsl_s(nsdb_t host, const char *nce, const char *fsl_uuid,
    dn: o=fedfs
    changeType: add
    objectClass: organization
+   objectClass: fedfsNsdbContainerEntry
+   objectClass: top
    o: fedfs
    @endverbatim
  */
@@ -1249,7 +1251,7 @@  static FedFsStatus
 nsdb_create_nce_add_top_entry(LDAP *ld, char **dn,
 		unsigned int *ldap_err)
 {
-	char *ocvals[2], *ouvals[2];
+	char *ocvals[4], *ouvals[2];
 	LDAPMod *attrs[3];
 	LDAPMod attr[2];
 	size_t len;
@@ -1262,6 +1264,9 @@  nsdb_create_nce_add_top_entry(LDAP *ld, char **dn,
 
 	nsdb_init_add_attribute(attrs[i++],
 				"objectClass", ocvals, "organization");
+	ocvals[1] = "fedfsNsdbContainerEntry";
+	ocvals[2] = "top";
+	ocvals[3] = NULL;
 	nsdb_init_add_attribute(attrs[i++],
 				"o", ouvals, "fedfs");
 	attrs[i] = NULL;
@@ -1307,6 +1312,8 @@  nsdb_create_nce_add_top_entry(LDAP *ld, char **dn,
    dn: ou=fedfs,"parent"
    changeType: add
    objectClass: organizationalUnit
+   objectClass: fedfsNsdbContainerEntry
+   objectClass: top
    ou: fedfs
    @endverbatim
  */
@@ -1314,7 +1321,7 @@  static FedFsStatus
 nsdb_create_nce_add_entry(LDAP *ld, const char *parent, char **dn,
 		unsigned int *ldap_err)
 {
-	char *ocvals[2], *ouvals[2];
+	char *ocvals[4], *ouvals[2];
 	LDAPMod *attrs[3];
 	LDAPMod attr[2];
 	size_t len;
@@ -1327,6 +1334,9 @@  nsdb_create_nce_add_entry(LDAP *ld, const char *parent, char **dn,
 
 	nsdb_init_add_attribute(attrs[i++],
 				"objectClass", ocvals, "organizationalUnit");
+	ocvals[1] = "fedfsNsdbContainerEntry";
+	ocvals[2] = "top";
+	ocvals[3] = NULL;
 	nsdb_init_add_attribute(attrs[i++],
 				"ou", ouvals, "fedfs");
 	attrs[i] = NULL;
@@ -1486,6 +1496,45 @@  nsdb_update_nci_s(nsdb_t host, const char *nce, unsigned int *ldap_err)
 }
 
 /**
+ * Remove fedfsNsdbContainerEntry from NCE object
+ *
+ * @param ld an initialized LDAP server descriptor
+ * @param nce a NUL-terminated C string containing DN of an NCE
+ * @param ldap_err OUT: possibly an LDAP error code
+ * @return a FedFsStatus code
+ *
+ * LDIF equivalent:
+ *
+ * @verbatim
+
+   dn: "nce"
+   changeType: modify
+   delete: objectClass
+   objectClass: fedfsNsdbContainerEntry
+   @endverbatim
+ */
+static FedFsStatus
+nsdb_remove_nce_objectclass_s(LDAP *ld, const char *nce,
+		unsigned int *ldap_err)
+{
+	LDAPMod *mods[3];
+	char *ocvals[2];
+	LDAPMod mod[2];
+	int i;
+
+	for (i = 0; i < 2; i++)
+		mods[i] = &mod[i];
+	i = 0;
+
+	nsdb_init_del_attribute(mods[i++],
+				"objectClass", ocvals,
+				"fedfsNsdbContainerEntry");
+	mods[i] = NULL;
+
+	return nsdb_modify_nsdb_s(ld, nce, mods, ldap_err);
+}
+
+/**
  * Remove NSDB Container Info from a namingContext object
  *
  * @param ld an initialized LDAP server descriptor
@@ -1555,8 +1604,13 @@  nsdb_remove_nci_s(nsdb_t host, const char *nce, unsigned int *ldap_err)
 	if (retval != FEDFS_OK)
 		return retval;
 
+	retval = nsdb_remove_nce_objectclass_s(host->fn_ldap, nce, ldap_err);
+	if (retval != FEDFS_OK)
+		goto out;
+
 	retval = nsdb_remove_nci_attributes_s(host->fn_ldap, context, ldap_err);
 
+out:
 	free(context);
 	return retval;
 }