From patchwork Fri Dec 14 22:37:35 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 206576 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "aserp1040.oracle.com", Issuer "VeriSign Class 3 International Server CA - G3" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 83ECB2C008F for ; Sat, 15 Dec 2012 09:37:54 +1100 (EST) Received: from acsinet22.oracle.com (acsinet22.oracle.com [141.146.126.238]) by aserp1040.oracle.com (Sentrion-MTA-4.2.2/Sentrion-MTA-4.2.2) with ESMTP id qBEMbp7u027090 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 14 Dec 2012 22:37:51 GMT Received: from oss.oracle.com (oss-external.oracle.com [137.254.96.51]) by acsinet22.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id qBEMboCE003091 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 14 Dec 2012 22:37:51 GMT Received: from localhost ([127.0.0.1] helo=oss.oracle.com) by oss.oracle.com with esmtp (Exim 4.63) (envelope-from ) id 1Tjdt8-0005sy-NW; Fri, 14 Dec 2012 14:37:50 -0800 Received: from ucsinet22.oracle.com ([156.151.31.94]) by oss.oracle.com with esmtp (Exim 4.63) (envelope-from ) id 1Tjdsx-0005s3-89 for fedfs-utils-devel@oss.oracle.com; Fri, 14 Dec 2012 14:37:39 -0800 Received: from userp1030.oracle.com (userp1030.oracle.com [156.151.31.80]) by ucsinet22.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id qBEMbcjr021667 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 14 Dec 2012 22:37:38 GMT Received: from mail-ie0-f171.google.com (mail-ie0-f171.google.com [209.85.223.171]) by userp1030.oracle.com (Sentrion-MTA-4.2.2/Sentrion-MTA-4.2.2) with ESMTP id qBEMbbOn026400 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=OK) for ; Fri, 14 Dec 2012 22:37:38 GMT Received: by mail-ie0-f171.google.com with SMTP id 17so6804109iea.2 for ; Fri, 14 Dec 2012 14:37:37 -0800 (PST) X-Received: by 10.50.91.168 with SMTP id cf8mr3152418igb.20.1355524657373; Fri, 14 Dec 2012 14:37:37 -0800 (PST) Received: from seurat.1015granger.net ([99.26.161.222]) by mx.google.com with ESMTPS id bh3sm7775474igc.0.2012.12.14.14.37.36 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 14 Dec 2012 14:37:36 -0800 (PST) From: Chuck Lever To: fedfs-utils-devel@oss.oracle.com Date: Fri, 14 Dec 2012 17:37:35 -0500 Message-ID: <20121214223735.22243.95891.stgit@seurat.1015granger.net> In-Reply-To: <20121214221556.22243.9462.stgit@seurat.1015granger.net> References: <20121214221556.22243.9462.stgit@seurat.1015granger.net> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 X-Flow-Control-Info: class=Default reputation=ipRepBelow100 ip=209.85.223.171 ct-class=R5 ct-vol1=-97 ct-vol2=9 ct-vol3=8 ct-risk=50 ct-spam1=82 ct-spam2=6 ct-bulk=5 rcpts=1 size=7021 X-MM-CT-Classification: not spam X-MM-CT-RefID: str=0001.0A090202.50CBAA32.0063,ss=1,re=0.000,fgs=0 Subject: [fedfs-utils] [PATCH 02/11] libnsdb: Handle LDAP referrals in an LDAP_RES_SEARCH_RESULT X-BeenThere: fedfs-utils-devel@oss.oracle.com X-Mailman-Version: 2.1.9 Precedence: list Reply-To: fedfs-utils Developers List-Id: fedfs-utils Developers List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: fedfs-utils-devel-bounces@oss.oracle.com Errors-To: fedfs-utils-devel-bounces@oss.oracle.com X-Source-IP: acsinet22.oracle.com [141.146.126.238] 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 --- 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);