diff mbox

[6/8] libnsdb: Avoid constructing the FSN DN on NSDB clients

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

Commit Message

Chuck Lever Nov. 13, 2013, 9:54 p.m. UTC
The LDAP community prefers that LDAP clients do not construct
Distinguished Names.  Rather, they should obtain DNs from servers,
whenever possible.

Instead of constructing the FSN record's DN on the client, we could
query the server for the FSN object, and then use ldap_get_dn() to
derive the DN for the search base for the FSN's FSLs.  A second
query would then retrieve the children of the FSN record via a
query of scope ONE, using the FSN DN as search base.  However, this
adds extra query steps.

FSL records already have the parent's FSN UUID as one of their
attributes.  We get the same results as above by performing a
subtree query using the NCE as the search base, and filtering on the
value of the fedfsFsnUuid attribute.  This matches similar logic in
administrator.c.

The original queries were based on the LDAP URI specified in section
5.2.2 of the NSDB protocol I-D.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 src/libnsdb/fileserver.c |   48 ++++++++++++++++++++++++++++++----------------
 1 file changed, 31 insertions(+), 17 deletions(-)
diff mbox

Patch

diff --git a/src/libnsdb/fileserver.c b/src/libnsdb/fileserver.c
index 814bce3..4cda9d7 100644
--- a/src/libnsdb/fileserver.c
+++ b/src/libnsdb/fileserver.c
@@ -1010,7 +1010,7 @@  nsdb_resolve_fsn_parse_entry(LDAP *ld, LDAPMessage *entry,
  *
  * @verbatim
 
-   ldapsearch -b fedfsFsnUuid="fsn_uuid","nce" -s one (objectClass=fedfsFsl)
+   ldapsearch -b "nce" -s subtree (&(objectClass=fedfsFsl)(fedfsFsnUuid="uuid"))
    @endverbatim
  */
 static FedFsStatus
@@ -1021,19 +1021,26 @@  nsdb_resolve_fsn_find_entry_s(nsdb_t host, const char *nce, const char *fsn_uuid
 	LDAP *ld = host->fn_ldap;
 	struct fedfs_fsl *tmp;
 	FedFsStatus retval;
-	char base[256];
+	char *filter;
 	int len, rc;
 
-	/* watch out for buffer overflow */
-	len = snprintf(base, sizeof(base),
-			"fedfsFsnUuid=%s,%s", fsn_uuid,nce);
-	if (len < 0 || (size_t)len > sizeof(base)) {
-		xlog(D_GENERAL, "%s: base DN is too long", __func__);
+	filter = malloc(128);
+	if (filter == NULL) {
+		xlog(D_GENERAL, "%s: failed to allocate buffer", __func__);
+		return FEDFS_ERR_SVRFAULT;
+	}
+
+	len = snprintf(filter, 127,
+			"(&(objectClass=fedfsFsl)(fedfsFsnUuid=%s))", fsn_uuid);
+	if (len < 0 || len > 127) {
+		xlog(D_GENERAL, "%s: invalid FSN UUID", __func__);
+		free(filter);
 		return FEDFS_ERR_INVAL;
 	}
 
-	rc = nsdb_search_nsdb_all_s(ld, base, LDAP_SCOPE_ONE,
-					"(objectClass=fedfsFsl)", &response);
+	rc = nsdb_search_nsdb_all_s(ld, nce, LDAP_SCOPE_SUBTREE,
+						filter, &response);
+	free(filter);
 	switch (rc) {
 	case LDAP_SUCCESS:
 	case LDAP_REFERRAL:
@@ -1322,7 +1329,7 @@  nsdb_get_fsn_parse_entry(LDAP *ld, LDAPMessage *entry,
  *
  * @verbatim
 
-   ldapsearch -b fedfsFsnUuid="fsn_uuid","nce" -s one (objectClass=fedfsFsn)
+   ldapsearch -b "nce" -s one (&(objectClass=fedfsFsn)(fedfsFsnUuid="uuid"))
    @endverbatim
  */
 static FedFsStatus
@@ -1333,18 +1340,25 @@  nsdb_get_fsn_find_entry_s(nsdb_t host, const char *nce, const char *fsn_uuid,
 	LDAP *ld = host->fn_ldap;
 	struct fedfs_fsn *tmp;
 	FedFsStatus retval;
-	char base[256];
+	char *filter;
 	int len, rc;
 
-	/* watch out for buffer overflow */
-	len = snprintf(base, sizeof(base), "fedfsFsnUuid=%s,%s", fsn_uuid, nce);
-	if (len < 0 || (size_t)len > sizeof(base)) {
-		xlog(D_GENERAL, "%s: base DN is too long", __func__);
+	filter = malloc(128);
+	if (filter == NULL) {
+		xlog(D_GENERAL, "%s: failed to allocate buffer", __func__);
+		return FEDFS_ERR_SVRFAULT;
+	}
+
+	len = snprintf(filter, 127,
+			"(&(objectClass=fedfsFsn)(fedfsFsnUuid=%s))", fsn_uuid);
+	if (len < 0 || len > 127) {
+		xlog(D_GENERAL, "%s: invalid FSN UUID", __func__);
+		free(filter);
 		return FEDFS_ERR_INVAL;
 	}
 
-	rc = nsdb_search_nsdb_all_s(ld, base, LDAP_SCOPE_ONE,
-					"(objectClass=fedfsFsn)", &response);
+	rc = nsdb_search_nsdb_all_s(ld, nce, LDAP_SCOPE_ONE, filter, &response);
+	free(filter);
 	switch (rc) {
 	case LDAP_SUCCESS:
 	case LDAP_REFERRAL: