So that callers can extract the location of the referred-to LDAP
server, change nsdb_parse_result() to parse an array of referral
URIs, if one is returned.

Signed-off-by: Chuck Lever <[email protected]>
---

 src/libnsdb/administrator.c |    4 +--
 src/libnsdb/fileserver.c    |   10 ++++---
 src/libnsdb/ldap.c          |   60 +++++++++++++++++++++++++++++++++++++++++--
 src/libnsdb/nsdb-internal.h |    2 +
 4 files changed, 65 insertions(+), 11 deletions(-)

diff --git a/src/libnsdb/administrator.c b/src/libnsdb/administrator.c
index a664fa9..aa4aad3 100644
--- a/src/libnsdb/administrator.c
+++ b/src/libnsdb/administrator.c
@@ -474,7 +474,7 @@ again:
                        retval = nsdb_parse_reference(ld, message, ldap_err);
                        break;
                case LDAP_RES_SEARCH_RESULT:
-                       retval = nsdb_parse_result(ld, message, ldap_err);
+                       retval = nsdb_parse_result(ld, message, NULL, ldap_err);
                        break;
                default:
                        xlog(L_ERROR, "%s: Unrecognized LDAP message type",
@@ -1658,7 +1658,7 @@ again:
                        retval = nsdb_parse_reference(ld, message, ldap_err);
                        break;
                case LDAP_RES_SEARCH_RESULT:
-                       retval = nsdb_parse_result(ld, message, ldap_err);
+                       retval = nsdb_parse_result(ld, message, NULL, ldap_err);
                        break;
                default:
                        xlog(L_ERROR, "%s: Unrecognized LDAP message type",
diff --git a/src/libnsdb/fileserver.c b/src/libnsdb/fileserver.c
index cb25f3b..d4519d6 100644
--- a/src/libnsdb/fileserver.c
+++ b/src/libnsdb/fileserver.c
@@ -443,7 +443,7 @@ nsdb_get_ncedn_s(nsdb_t host, const char *naming_context, 
char **dn,
                        retval = nsdb_parse_reference(ld, message, ldap_err);
                        break;
                case LDAP_RES_SEARCH_RESULT:
-                       retval = nsdb_parse_result(ld, message, ldap_err);
+                       retval = nsdb_parse_result(ld, message, NULL, ldap_err);
                        break;
                default:
                        xlog(L_ERROR, "%s: Unrecognized LDAP message type",
@@ -632,7 +632,7 @@ nsdb_get_naming_contexts_s(nsdb_t host, char ***contexts,
                                                        message, ldap_err);
                        break;
                case LDAP_RES_SEARCH_RESULT:
-                       retval = nsdb_parse_result(ld, message, ldap_err);
+                       retval = nsdb_parse_result(ld, message, NULL, ldap_err);
                        break;
                default:
                        xlog(L_ERROR, "%s: Unrecognized LDAP message type",
@@ -1091,7 +1091,7 @@ nsdb_resolve_fsn_find_entry_s(LDAP *ld, const char *nce, 
const char *fsn_uuid,
                        retval = nsdb_parse_reference(ld, message, ldap_err);
                        break;
                case LDAP_RES_SEARCH_RESULT:
-                       retval = nsdb_parse_result(ld, message, ldap_err);
+                       retval = nsdb_parse_result(ld, message, NULL, ldap_err);
                        break;
                default:
                        xlog(L_ERROR, "%s: Unrecognized LDAP message type",
@@ -1404,7 +1404,7 @@ nsdb_get_fsn_find_entry_s(LDAP *ld, const char *nce, 
const char *fsn_uuid,
                        retval = nsdb_parse_reference(ld, message, ldap_err);
                        break;
                case LDAP_RES_SEARCH_RESULT:
-                       retval = nsdb_parse_result(ld, message, ldap_err);
+                       retval = nsdb_parse_result(ld, message, NULL, ldap_err);
                        break;
                default:
                        xlog(L_ERROR, "%s: Unrecognized LDAP message type",
@@ -1663,7 +1663,7 @@ nsdb_list_find_entries_s(LDAP *ld, const char *nce, char 
***fsns,
                        retval = nsdb_parse_reference(ld, message, ldap_err);
                        break;
                case LDAP_RES_SEARCH_RESULT:
-                       retval = nsdb_parse_result(ld, message, ldap_err);
+                       retval = nsdb_parse_result(ld, message, NULL, ldap_err);
                        break;
                default:
                        xlog(L_ERROR, "%s: Unrecognized LDAP message type",
diff --git a/src/libnsdb/ldap.c b/src/libnsdb/ldap.c
index f6b430e..0abbdd2 100644
--- a/src/libnsdb/ldap.c
+++ b/src/libnsdb/ldap.c
@@ -810,18 +810,66 @@ nsdb_parse_reference(LDAP *ld, LDAPMessage *reference,
 }
 
 /**
+ * Duplicate an array of referral URIs
+ *
+ * @param refs an array of NUL-terminated C strings containing LDAP URIs
+ * @param referrals OUT: pointer to an array of NUL-terminated C strings
+ * @return a FedFsStatus code
+ *
+ * Caller must free "referrals" with nsdb_free_string_array().
+ */
+static FedFsStatus
+nsdb_copy_referrals_array(char **refs, char ***referrals)
+{
+       int i, count;
+       char **tmp;
+
+       for (i = 0; refs[i] != NULL; i++)
+               xlog(D_GENERAL, "%s: Referral: %s", __func__, refs[i]);
+       if (referrals == NULL)
+               return FEDFS_OK;
+       count = i;
+
+       tmp = calloc(count, sizeof(char *));
+       if (tmp == NULL) {
+               xlog(D_GENERAL, "%s: no memory for array", __func__);
+               return FEDFS_ERR_SVRFAULT;
+       }
+
+       for (i = 0; i < count; i++) {
+               tmp[i] = strdup(refs[i]);
+               if (tmp[i] == NULL) {
+                       xlog(D_GENERAL, "%s: no memory for string", __func__);
+                       nsdb_free_string_array(tmp);
+                       return FEDFS_ERR_SVRFAULT;
+               }
+       }
+       tmp[i] = NULL;
+
+       *referrals = tmp;
+       return FEDFS_OK;
+}
+
+/**
  * Handle an LDAP search result message
  *
  * @param ld an initialized LDAP server descriptor
  * @param result an LDAP_RES_SEARCH_RESULT message
+ * @param referrals OUT: pointer to an array of NUL-terminated C strings
  * @param ldap_err OUT: possibly an LDAP error code
  * @return a FedFsStatus code
+ *
+ * If "ldap_err" contains LDAP_REFERRAL, caller must free "referrals"
+ * with nsdb_free_string_array().
  */
 FedFsStatus
-nsdb_parse_result(LDAP *ld, LDAPMessage *result, unsigned int *ldap_err)
+nsdb_parse_result(LDAP *ld, LDAPMessage *result, char ***referrals,
+               unsigned int *ldap_err)
 {
        char *matched_dn = NULL, *error_msg = NULL;
        int rc, result_code;
+       char **refs = NULL;
+       FedFsStatus retval;
 
        if (ld == NULL || result == NULL || ldap_err == NULL) {
                xlog(L_ERROR, "%s: Invalid parameter", __func__);
@@ -829,7 +877,7 @@ nsdb_parse_result(LDAP *ld, LDAPMessage *result, unsigned 
int *ldap_err)
        }
 
        rc = ldap_parse_result(ld, result, &result_code,
-                                       &matched_dn, &error_msg, NULL, NULL, 0);
+                               &matched_dn, &error_msg, &refs, NULL, 0);
        if (rc != LDAP_SUCCESS) {
                xlog(D_GENERAL, "%s: Failed to parse result: %s",
                        __func__, ldap_err2string(rc));
@@ -857,11 +905,17 @@ nsdb_parse_result(LDAP *ld, LDAPMessage *result, unsigned 
int *ldap_err)
                ber_memfree(error_msg);
        }
 
+       retval = FEDFS_OK;
+       if (refs != NULL) {
+               retval = nsdb_copy_referrals_array(refs, referrals);
+               ber_memvfree((void **)refs);
+       }
+
        if (result_code != LDAP_SUCCESS) {
                *ldap_err = result_code;
                return FEDFS_ERR_NSDB_LDAP_VAL;
        }
-       return FEDFS_OK;
+       return retval;
 }
 
 /**
diff --git a/src/libnsdb/nsdb-internal.h b/src/libnsdb/nsdb-internal.h
index d293dd7..c2283ed 100644
--- a/src/libnsdb/nsdb-internal.h
+++ b/src/libnsdb/nsdb-internal.h
@@ -102,7 +102,7 @@ FedFsStatus  nsdb_delete_attribute_all_s(LDAP *ld, const 
char *dn,
 FedFsStatus     nsdb_parse_reference(LDAP *ld, LDAPMessage *reference,
                                unsigned int *ldap_err);
 FedFsStatus     nsdb_parse_result(LDAP *ld, LDAPMessage *result,
-                               unsigned int *ldap_err);
+                               char ***referrals, unsigned int *ldap_err);
 _Bool           nsdb_compare_dns(LDAPDN dn1, LDAPDN dn2);
 _Bool           nsdb_compare_dn_string(LDAPDN dn1, const char *dn2_in,
                                unsigned int *ldap_err);


_______________________________________________
fedfs-utils-devel mailing list
[email protected]
https://oss.oracle.com/mailman/listinfo/fedfs-utils-devel

Reply via email to