NSDB tools that perform fileserver queries are allowed to follow LDAP referrals if the NSDB's "follow referrals" flag is on.
Signed-off-by: Chuck Lever <[email protected]> --- src/nsdbc/nsdb-list.c | 53 ++++++++++++++++++++++++++++++++++++++ src/nsdbc/nsdb-resolve-fsn.c | 59 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 0 deletions(-) diff --git a/src/nsdbc/nsdb-list.c b/src/nsdbc/nsdb-list.c index 0e271b2..e3a8ab0 100644 --- a/src/nsdbc/nsdb-list.c +++ b/src/nsdbc/nsdb-list.c @@ -142,6 +142,52 @@ nsdb_list_resolve_and_display_fsn(nsdb_t host, const char *nce, const char *fsn_ } /** + * Attempt to follow an LDAP referral to another NSDB + * + * @param host OUT: pointer to an initialized nsdb_t that may be replaced + * @return a FedFsStatus code + */ +static FedFsStatus +nsdb_list_follow_ldap_referral(nsdb_t *host) +{ + static unsigned int nest = 0; + FedFsStatus retval; + nsdb_t old, refer; + + old = *host; + if (!nsdb_follow_referrals(old)) { + fprintf(stderr, "LDAP referrals for NSDB %s:%u disallowed\n", + nsdb_hostname(old), nsdb_port(old)); + return FEDFS_ERR_NSDB_LDAP_REFERRAL_NOTFOLLOWED; + } + + if (nest++ > 10) { + fprintf(stderr, "Possible referral loop for NSDB %s:%u\n", + nsdb_hostname(old), nsdb_port(old)); + return FEDFS_ERR_NSDB_LDAP_REFERRAL_NOTFOLLOWED; + } + + retval = nsdb_lookup_nsdb_by_uri(nsdb_referred_to(old), &refer); + switch (retval) { + case FEDFS_OK: + break; + case FEDFS_ERR_NSDB_PARAMS: + fprintf(stderr, "Encountered referral to unrecognized NSDB %s\n", + nsdb_referred_to(old)); + return FEDFS_ERR_NSDB_LDAP_REFERRAL_NOTFOLLOWED; + default: + fprintf(stderr, "Problem following referral: %s", + nsdb_display_fedfsstatus(retval)); + return retval; + } + + nsdb_close_nsdb(old); + nsdb_free_nsdb(old); + *host = refer; + return FEDFS_OK; +} + +/** * Program entry point * * @param argc count of command line arguments @@ -232,6 +278,7 @@ main(int argc, char **argv) goto out; } +again: retval = nsdb_open_nsdb(host, NULL, NULL, &ldap_err); switch (retval) { case FEDFS_OK: @@ -280,6 +327,12 @@ main(int argc, char **argv) fprintf(stderr, "NCE %s does not exist\n", nce); break; case FEDFS_ERR_NSDB_LDAP_VAL: + if (ldap_err == LDAP_REFERRAL) { + retval = nsdb_list_follow_ldap_referral(&host); + if (retval != FEDFS_OK) + break; + goto again; + } fprintf(stderr, "Failed to list FSNs: %s\n", ldap_err2string(ldap_err)); break; diff --git a/src/nsdbc/nsdb-resolve-fsn.c b/src/nsdbc/nsdb-resolve-fsn.c index 0056200..23d292d 100644 --- a/src/nsdbc/nsdb-resolve-fsn.c +++ b/src/nsdbc/nsdb-resolve-fsn.c @@ -190,6 +190,52 @@ nsdb_resolve_fsn_display_fsls(struct fedfs_fsl *fsls) } /** + * Attempt to follow an LDAP referral to another NSDB + * + * @param host OUT: pointer to an initialized nsdb_t that may be replaced + * @return a FedFsStatus code + */ +static FedFsStatus +nsdb_resolve_fsn_follow_ldap_referral(nsdb_t *host) +{ + static unsigned int nest = 0; + FedFsStatus retval; + nsdb_t old, refer; + + old = *host; + if (!nsdb_follow_referrals(old)) { + fprintf(stderr, "LDAP referrals for NSDB %s:%u disallowed\n", + nsdb_hostname(old), nsdb_port(old)); + return FEDFS_ERR_NSDB_LDAP_REFERRAL_NOTFOLLOWED; + } + + if (nest++ > 10) { + fprintf(stderr, "Possible referral loop for NSDB %s:%u\n", + nsdb_hostname(old), nsdb_port(old)); + return FEDFS_ERR_NSDB_LDAP_REFERRAL_NOTFOLLOWED; + } + + retval = nsdb_lookup_nsdb_by_uri(nsdb_referred_to(old), &refer); + switch (retval) { + case FEDFS_OK: + break; + case FEDFS_ERR_NSDB_PARAMS: + fprintf(stderr, "Encountered referral to unrecognized NSDB %s\n", + nsdb_referred_to(old)); + return FEDFS_ERR_NSDB_LDAP_REFERRAL_NOTFOLLOWED; + default: + fprintf(stderr, "Problem following referral: %s\n", + nsdb_display_fedfsstatus(retval)); + return retval; + } + + nsdb_close_nsdb(old); + nsdb_free_nsdb(old); + *host = refer; + return FEDFS_OK; +} + +/** * Program entry point * * @param argc count of command line arguments @@ -292,6 +338,7 @@ main(int argc, char **argv) goto out; } +again: retval = nsdb_open_nsdb(host, NULL, NULL, &ldap_err); switch (retval) { case FEDFS_OK: @@ -332,6 +379,12 @@ main(int argc, char **argv) fprintf(stderr, "Failed to find FSN %s\n", fsn_uuid); goto out_close; case FEDFS_ERR_NSDB_LDAP_VAL: + if (ldap_err == LDAP_REFERRAL) { + retval = nsdb_resolve_fsn_follow_ldap_referral(&host); + if (retval != FEDFS_OK) + goto out_close; + goto again; + } fprintf(stderr, "NSDB LDAP error: %s\n", ldap_err2string(ldap_err)); goto out_close; @@ -366,6 +419,12 @@ main(int argc, char **argv) fprintf(stderr, "Failed to find FSN %s\n", fsn_uuid); break; case FEDFS_ERR_NSDB_LDAP_VAL: + if (ldap_err == LDAP_REFERRAL) { + retval = nsdb_resolve_fsn_follow_ldap_referral(&host); + if (retval != FEDFS_OK) + break; + goto again; + } fprintf(stderr, "NSDB LDAP error: %s\n", ldap_err2string(ldap_err)); break; _______________________________________________ fedfs-utils-devel mailing list [email protected] https://oss.oracle.com/mailman/listinfo/fedfs-utils-devel
